【正文】
}分析器分析一個(gè)文件里面的字符串的話:include include include iostreaminclude fstreamusing namespace std。 | 39。)*(39。PLUS :39。 } )* 。該分析器的功能是分析用戶輸入的一個(gè)算術(shù)表達(dá)式,給出該表達(dá)式的最終結(jié)果。)(39。39。}}編譯之:$g++ o Calc lantlr測(cè)試用例:$ ./Calc1 + 2 * 3 + 5 4/2$ ./Calc(1 + 2) * 3 + 5 4 / (2+2)$ ./Calc(*)+8/(43)*$二.利用ANTLR生成C++描述的分析程序文法文件文法就是語言識(shí)別的規(guī)則。(注: $setType是ANTLR內(nèi)置函數(shù),用來設(shè)置token類型。這些就是基本框架了??蛇x類的開頭是括在{}中的任意文本。一個(gè)語法文件中的語法分析器定義通常是這個(gè)樣子: { optional class code preamble }class YourParserClass extends Parser。 codeBlock[int scope, String name] // input argumentsreturns [int x] // return values: ... 。idList : ( ID )+。然而,ANTLR不會(huì)創(chuàng)建一個(gè)詞法分析器規(guī)則來匹配這些字符串。你可以在你的詞法分析器語法中覆蓋, 39。\37739。 Java語句:指當(dāng)滿足當(dāng)前規(guī)則時(shí)所執(zhí)行的語句。主要用于把讀入的字節(jié)流根據(jù)規(guī)則分段。安裝成功之后在Eclipse的工具欄上會(huì)出現(xiàn)一個(gè)詞法分析器的導(dǎo)航按鈕: 當(dāng)右鍵單點(diǎn)擊你的工程時(shí),你會(huì)發(fā)現(xiàn)控制是否使用ANTLR Studio的開關(guān):當(dāng)打開一個(gè)文法文件之后,可以看到如下界面:在右面的大綱窗口,列有所有Parser和Lexer的元素,可以看到Protected Token(例如Number)和其他普通的Token是不一樣的;在左面,不同的區(qū)域是用不同的顏色塊加亮來區(qū)分的。對(duì)于形如1+23*4/5^6這樣的表達(dá)式,只要寫好語法規(guī)則,就可以在解析過程中直接得到運(yùn)算結(jié)果:首先ANTLR將其編譯成逆波蘭結(jié)構(gòu) ( ( + 1 2 ) ( / ( * 3 4 ) ( ^ 5 6 ) ) ) 。例如是否建立缺省的抽象語法樹,指定LL(K)中的參數(shù)k的值(缺省為1)等等,更詳細(xì)的參數(shù)請(qǐng)參閱ANTLR自帶的手冊(cè)。語法分析器將收到的Tokens組織起來,并轉(zhuǎn)換成為目標(biāo)語言語法定義所允許的序列。很自然的它們分別與詞法分析程序(lexers,以下簡(jiǎn)稱lexer),語言解析程序和樹遍歷程序向匹配。這個(gè)用于定義這些語法的元語言,在所有情況下幾乎一樣的。無論是Lexer還是Parser都是一種識(shí)別器,Lexer是字符序列識(shí)別器而Parser是Token序列識(shí)別器。5.在生成語法樹的過程中,同步計(jì)算表達(dá)式的值。功能介紹ANTLR Studio在Eclipse Help提供了比較詳盡的文檔描述。既把長(zhǎng)面條根據(jù)你要的尺寸切成一段一段:)并不對(duì)其作任何修改。Antlr會(huì)自動(dòng)嵌入生成的java類中。),Unicode字符集(., 39。\\39。()函數(shù):/** This method is called by () * when the lexer has * hit EOF condition. EOF is NOT a character. * This method is not called if EOF is reached * during syntactic predicate evaluation or during * evaluation of normal lexical rules, which * presumably would be an IOException. This * traps the normal EOF * condition. * * uponEOF() is called after the plete evaluation * of the previous token and only if your parser asks * for another token beyond that last nonEOF token. * * You might want to throw token or char stream * exceptions like: Heh, premature eof or a retry * stream exception (I found the end of this file, * go back to referencing file). */public void uponEOF() throws TokenStreamException, CharStreamException{}相反,ANTLR將這些字符串輸入到一個(gè)于詞法分析器關(guān)聯(lián)的字符常量表中。 // parser rule definitionoptionstokens{ optional action for instance vars/methods }parser rules... 當(dāng)在面向?qū)ο笳Z言中生成代碼時(shí),語法分析器類將導(dǎo)致在輸出中是一個(gè)類,規(guī)則都會(huì)變成這個(gè)類的成員函數(shù)。這個(gè)開頭部分,如果它存在,將輸出到被生成的類文件中,在類定義的之前。options里設(shè)置language為”Cpp”,表示要生成c++代碼。就是當(dāng)匹配到(’0′..’9′)*后,設(shè)置token類型為INT,當(dāng)發(fā)現(xiàn)后面跟著小數(shù)點(diǎn)和數(shù)字后,重新設(shè)置token類型為REAL。它是ANTLR生成程序的依據(jù)。039。在該表達(dá)式中允許出現(xiàn)的運(yùn)算符除了加減乘除之外,還包括求冪運(yùn)算符“^”,以及sin、cos和tan三個(gè)三角函數(shù)。 atom returns [double value=0]{double x。+39。.39。\t39。void main(){ fstream from()。 cout The Result is : x endl。 39。939。)39。} : value = atom ( TOK_POW x = atom { value = pow(value,x)。C++程序的例子下面就給出一個(gè)ANTLR生成的C++描述的分析器的實(shí)例。939。 expr 39。e) {cout () endl。 } )? 。class CalcLexer extends Lexer。語法分析器和詞法分析器可以以任何順序出現(xiàn)。一個(gè)語法文件(.g)只包含一個(gè)語法分析器類定義(和詞法分析器和樹遍歷器一起)一個(gè)語法分析器定義在它的選項(xiàng)(options)和規(guī)則定義之前。在[]中的參數(shù)是用被生成的語言的語法定義的,并且用逗號(hào)分開。例如,class MyParser extends Parser。). 在語法分析器規(guī)則中,字符串代表一個(gè)個(gè)標(biāo)記(tokens),并且每個(gè)獨(dú)立的字符串被分派一個(gè)標(biāo)記類型。當(dāng)你將文件結(jié)束當(dāng)一個(gè)字符來檢測(cè)時(shí),它實(shí)際上并不是一個(gè)字符,而是一個(gè)條件。39。它們包含八進(jìn)制轉(zhuǎn)義字符集(., 39。感覺就像是int與Integer的區(qū)別。一、Antlr的主要類: Antlr中有主要類有兩種(其實(shí)還有一種TreeLexer) Lexer:文法分析器類。ANTLR Studio插件的安裝Eclips