Javacc sample
PARSER_BEGIN(Grammar)
public class Grammar implements NodeType {
public ParseTreeNode GetParseTree(InputStream in) throws ParseException
{
Grammar parser =new Grammar(in);
return parser。Expression();
}
}
PARSER_END(Grammar)
SKIP :
{
" " | " " | " " | " "
}
TOKEN :
{
< ID: ["a"-"z","A"-"Z","_"> ( ["a"-"z","A"-"Z","_","0"-"9"> )* >
| < NUM: ( ["0"-"9"> )+ >
| < PLUS: "+" >
| < MINUS: "-" >
| < TIMERS: "*" >
| < OVER: "/" >
| < LPAREN: "(" >
| < RPAREN: ")" >
}
ParseTreeNode Expression() :
{
ParseTreeNode ParseTree = null;
ParseTreeNode node;
}
{
( node=Simple_Expression()
{
if(ParseTree == null)
ParseTree =node;
else
{
ParseTreeNode t;
t= ParseTree;
while(t.next != null)
t=t.next;
t.next = node;
}
}
)*
{ return ParseTree; }
}
ParseTreeNode Simple_Expression() :
{
ParseTreeNode node;
ParseTreeNode t;
int op;
}
{
node=Term(){}
(
op=addop() t=Term()
{
ParseTreeNode newNode = new ParseTreeNode();
newNode.nodetype = op;
newNode.child[0] = node;
newNode.child[1] = t;
switch(op)
{
case PlusOP:
newNode.name = "Operator: +";
break;
case MinusOP:
newNode.name = "Operator: -";
break;
}
node = newNode;
}
)*
{ return node; }
}
int addop() : {}
{
|
}
ParseTreeNode Term() :
{
ParseTreeNode node;
ParseTreeNode t;
int op;
}
{
node=Factor(){}
(
op=mulop() t=Factor()
{
ParseTreeNode newNode = new ParseTreeNode();
newNode.nodetype = op;
newNode.child[0] = node;
newNode.child[1] = t;
switch(op)
{
case TimersOP:
newNode.name = "Operator: *";
break;
case OverOP:
newNode.name = "Operator: /";
break;
}
node = newNode;
}
)*
{
return node;
}
}
int mulop() :{}
{
|
}
ParseTreeNode Factor() :
{
ParseTreeNode node;
Token t;
}
{
t=
{
node=new ParseTreeNode();
node.nodetype= IDstmt;
node.name = t.image;
return node;
}
|
t=
{
node=new ParseTreeNode();
node.nodetype= NUMstmt;
node.name = t.image;
node.value= Integer.parseInt(t.image);
return node;
}
|
{
return node;
}
}
其中SKIP中的定義就是在進行詞法分析的同時,忽略掉的記號。TOKEN中的,就是需要在做詞法分析的時候,識別的詞法記號。當然,這一切都是以正規表示式來表示的。
這個例子就有多個非終結符號,可以看出,我們需要為每個非終結符號寫出一個過程。不同的非終結符號的識別過程中可以互相呼叫。
以Simple_Expression()過程為例,它的產生式是Expression -> Term { addop Term },而在javacc的輸入檔案格式是,它的識別是這樣寫的node=Term(){} ( op=addop() t=Term(){ … })* 前面說過,這裡的”*”符號和正規表示式是一樣的,就是0次到無限次的重複。那麼Simple_Expression等於文法Term Addop Term Addop Term Addop Term … 而Addop也就相當於PLUS和MINUS兩個運算子號。這裡我們在寫Expression的文法的時候,同時還使用了賦值表示式,因為這個和Yacc 不同的時候,Javacc把文法識別完全地做到了函式過程中,那麼如果我們要識別Simple_Expression的文法,就相當於按順序識別Term 和Addop兩個文法,而識別那個文法,就相當於呼叫那兩個非終結符的識別函式。正是這一點,我覺得Javacc的文法識別處理上就很接近程式的操作過 程,我們不需要像YACC那樣使用嚴格的文法表示格式,複雜的系統引數了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10230672/viewspace-966506/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Javacc的例子Java
- javacc學習總結Java
- JavaCC學習筆記Java筆記
- 編譯原理與javacc初探編譯原理Java
- sample a texture as a rendertarget
- netty sampleNetty
- Calcite(一):javacc語法框架及使用Java框架
- javacc-LOOKAHEAD MiniTutorial 翻譯Java
- table type usage sample:
- Error in Memento Sample Code?Error
- A Simple Sample for Expression Tree (轉)Express
- Directx3D SimpleSample Sample3D
- (C language Sample ) Compile procedureCompile
- 應用程式日誌Sample
- RCE_sample_ctf_questions(ing)
- [CTO札記]業務流程圖Sample流程圖
- expdp sample 應用一例
- Oracle OAF(Oracle Application Framework) SampleOracleAPPFramework
- 探究grid_sample函式函式
- ARCore學習之旅:ARCore Sample 導讀
- Sample Schemas建庫後手動建立
- Teradata 之top n與sample n
- 動態呼叫儲存過程 sample:儲存過程
- Oracle 自己帶的Sample Sechemas 介紹Oracle
- 征程 6E camera diag sample
- Oracle Database 19c安裝Sample SchemasOracleDatabase
- SAP QM 三種型別的Physical Sample型別
- Oracle 12CR2 Install the Sample SchemasOracle
- Entity Framework Tutorial Basics(43):Download Sample ProjectFrameworkProject
- Entity Framework 6.0 Tutorials(11):Download Sample ProjectFrameworkProject
- 通過Typesafe Activator建立akka java sampleJava
- SAP ABAP和Hybris Commerce的Sample資料
- Kinect Fusion Basics-WPF C# Sample程式碼解析C#
- 微信開發:wx_sample.php內容詳解PHP
- SAMPLE語句在統計資訊收集中應用
- recastnavigation.Sample_TempObstacles程式碼註解 - rcBuildHeightfieldLayersASTNavigationUI
- Lucene學習總結之八:Lucene的查詢語法,JavaCC及QueryParser(1)Java
- Sample上新,從API 8開始支援!速來拿走API