Antlr簡(jiǎn)介及中文基礎(chǔ)手冊(cè)_第1頁
Antlr簡(jiǎn)介及中文基礎(chǔ)手冊(cè)_第2頁
Antlr簡(jiǎn)介及中文基礎(chǔ)手冊(cè)_第3頁
Antlr簡(jiǎn)介及中文基礎(chǔ)手冊(cè)_第4頁
Antlr簡(jiǎn)介及中文基礎(chǔ)手冊(cè)_第5頁
已閱讀5頁,還剩31頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

Antlr簡(jiǎn)介

06通訊軟件06382027鄭毅

本文重要簡(jiǎn)介了什么是ANTLR,以及ANTLR使用,其中ANTLR使用涉及了ANTLR安裝及使用,

ANTLR語法文獻(xiàn)解析,ANTLR規(guī)則(RULE)解析,ANTLR語法實(shí)例一SensorSQL,ANTLRStudio

及其功能簡(jiǎn)介等。

Antlr(ANotherToolforLanguageRecognition)是一種工具,前身是PCCTS,它為咱們構(gòu)造自己辨

認(rèn)得(recognizers)、編譯器(compiler)和轉(zhuǎn)換器(translators)提供了?種基本。通過定義自己語言

規(guī)則,Antlr可覺得咱們生成相應(yīng)語言解析器,這樣便可以省卻了自己全手工打造勞苦。

它是這樣?種工具,它可以接受文法語言描述,并能產(chǎn)生辨認(rèn)這些語言語句程序。作為翻譯程序?某

些,你可以使用簡(jiǎn)樸操作符和動(dòng)作來參數(shù)化你文法,使之告訴ANTLR如何去創(chuàng)立抽象語法樹(AST)和如何產(chǎn)

生輸出。AXTLR懂得如何去生成辨認(rèn)程序,語言涉及Java,C++,C#和不久Python。

ANTLR懂得如何構(gòu)建辨認(rèn)理序,這些程序可以對(duì)如下三種不同輸入應(yīng)用文法構(gòu)造:(i)字符流,(ii)記

號(hào)流,和(iii)兩維樹構(gòu)造。很自然它們分別與詞法分析程序(lexers,如下簡(jiǎn)稱lexer),語言解析程序和

樹遍歷程序向匹配。這個(gè)用于定義這些語法元語言,在所有狀況下幾乎同樣。

??旦你對(duì)A\TLR和類似工具比較順手,你會(huì)開始以?種新目光來看編程。許多任務(wù)強(qiáng)烈需要語言解決

方案,而不是采用老式編程語言做法。例如,這些過程注解都是用特倫斯標(biāo)記語言寫。而ANTLR則能來將

文本(內(nèi)含某些額外東西和轉(zhuǎn)換)轉(zhuǎn)化為HTML,PDF或者其她那些生成程序文獻(xiàn)格式。

最后,ANTLR只是一件工具,僅僅這些。雖然它能通過將容易理解乏味某些自動(dòng)化來協(xié)助你創(chuàng)立軟件,

但卻不能企圖讓你指定整個(gè)編譯器。例如,在單個(gè)描述里就不行.那些宣稱此類事情非常偉大,可覺得發(fā)

布刊物文章編寫驚人“一攬子解決方案”,卻會(huì)悲慘失敗在實(shí)際項(xiàng)目中。

詞法分析器(Lexer)

詞法分析器又稱為Scanner,Lexicalanalyser和Tokenizer。程序設(shè)沖語言普通由核心字和嚴(yán)格定

義語法構(gòu)造構(gòu)成。編譯最后目是將程序設(shè)計(jì)語言高層指令翻譯成物力機(jī)器或虛擬機(jī)可以執(zhí)行指令。此法分

析器工作是分析量化那些本來毫無意義字符流,將她們翻譯成離散字符組(也就是一種一種Token)括核

心字,標(biāo)記符,符號(hào)(symbols)和操作符供語法分析器使用。

語法分析器(Parser)

編譯器又稱為Syntacticalanalyser。在分析字符流時(shí)候,Lexer不關(guān)懷所生成單個(gè)Token語法意義

及其與上下文之間關(guān)系,而這就是Parser工作。語法分析器將收到Tokens組織起來,并轉(zhuǎn)換成為目的語

言語法定義所容許序列。

無論是Lexer還是Parser都是?種辨認(rèn)器,Lexer是字符序列辨認(rèn)器而Parser是Token序列辨認(rèn)器。

她們?cè)诒举|(zhì)上是類似東西,而只是在分工上有所不同而已。

ANTLR

ANTLR將上述兩者結(jié)合起來,它容許咱們定義辨認(rèn)字符流詞法規(guī)則和用于解釋Token流詞法分析規(guī)則。

然后,ANTLR將依照顧客提供語法文獻(xiàn)自動(dòng)生成相應(yīng)詞法/語法分析器。顧客可以運(yùn)用她們將輸入文本進(jìn)行

編譯,并轉(zhuǎn)換成其她形式(如AST—AbstractSyntaxTree,抽‘象語法樹)。

Antlr使用

安裝及使用

到下樓最新版本ANTLR開發(fā)包和源碼(例如版本3.01).將antlrBOljar所在目錄配備到你環(huán)境

變量中,寫好語法文獻(xiàn)(例如SensorSQL.g),運(yùn)營(yíng)命令"javaanUr.ToolSensorSQL.g"就可以獲得自動(dòng)生

成語法/詞法分析器。

/SensorSqlParserTokenTypes.txt2KB文本文檔2006-6-41443

^SensorSqlParserTokenTypes.java2KBJAVA文件2006-6-41443

^SensorSqlParser.java33KBJAVA文件2006-6-41443

傘SensorSqlLexer.java21KBJAVA文件2006-6-41443

ExpressionTreeWalker.java5KBJAVA文件2006-6-41443

cTC:'■工ND0?八Syste>32\od.exe

F:序?qū)崿F(xiàn)、文法+andli?+RText的自動(dòng)綁定XsyntaxAjauaantlr.ToolSensorSql.g

ANTLRParserGeneratorUersion2.7.41989-2004jGuru.con

SensorSql.g:228:16:v;arning:CharacterliteralmustbelowercasewhencaseSensiti

ue=false

SensorSql.g:228:21:warning:CharacterliteralmustbelowercasewliencaseSensiti

ue=£alse

ANTLR語法文獻(xiàn)解析

:'匕

Resource-calc.g-EclipsePlatform//fANTLR2.7.5(20050128)

ckageccm.my.niyPack;

EditNavigateSearchProjectWndowHelp1

importantlr.TokenBuffer;

importantlr.TokenStrean£xcepti

importantlr.TokenStreaxIOExcef

insertantlr.ANTLRException;

packagecom.my.myPack:importantlr.LLkParser;

importantlr.Token;

importantlr.TokenStreax;

importjava.utl.ArrayList;importantlr.RecognitionExcepti

importmy.MyClass;importantlr.NoViableAltExceptj

importantlr.MisniatchedTokenExc

classCalcParserextendsParserimportantlr.SexanticException;

options{

buildAST-true;usesCommoimportantlr.ParserSharedlnputS

insertantlr.collections.ixpl.E

tokens{J

STAR;3ava.util.ArrayLi3t;

INT;

SEMI;importmy.MyCLass;

PLUS;

MINUS;ublicclassCalcParserextends

}(3

publicvoidmyMethod()

publicvoidmyMethod()(

(doSoxethingO;

doSomething();

)

publicvoidniyMetnoazQ

publicvoidmyMethod2O(

{doSoxethingElse();

doSomethingElse();

)

下面扁們對(duì)圖中所描述ANTLR語法文獻(xiàn)做某些詳細(xì)分析。為了更好使用ANTLR.你還可如下我

ANTLREclipse插件來協(xié)助你完畢工作。

1.header域:所有出當(dāng)前這里某些,都會(huì)出當(dāng)前由ANTLR編譯之后生成Java文獻(xiàn)最頂部。在本例中你可

以將包名和其她信息放到這一區(qū)域中,生成成果如由面相應(yīng)代碼某些所示。

2.你在這一某些所提供內(nèi)容對(duì)于文獻(xiàn)中每個(gè)語法都是唯一。這一區(qū)域內(nèi)容將出當(dāng)前實(shí)際類定義之前。也就是

說,兩個(gè)import僅屬于類CalcParser,而不屬于在同一種文獻(xiàn)中定義其她類(如CalcLexer)

3.這里是語法定義某些,你同樣可以將它當(dāng)作是類定義。

4.在Option域中,你可覺得你語法提供可選項(xiàng)。例如與否建立缺省抽象語法樹,指定LL(K)中參數(shù)k值

(缺省為1)等等,更詳細(xì)參數(shù)請(qǐng)參閱ANTLR自帶手冊(cè)。

5.Token某些用來聲明那些在詞法分析器中沒有被聲明"想象"token。這些信息通慣用在TreeParser中指定

“想象”節(jié)點(diǎn)。

6.這是另一種Action區(qū),ANTLR將會(huì)忠實(shí)地將這一區(qū)域內(nèi)信息放置.到類定義當(dāng)中,相稱于類成員辦法,重

要為顧客提供一種在Parser種定制可擴(kuò)展辦法途徑。

ANTLR規(guī)貝!|(RULE)解析

語法規(guī)則,就可以在解析過程中直接得到運(yùn)算成果:一方面ANTLR將其編譯成逆波蘭構(gòu)造-(-(+12)(/

(*34)(-56)));在生成語法樹過程中,同步計(jì)算表達(dá)式值,即類似于2.3節(jié)中看到表達(dá)式計(jì)算。成果如

下:

但是這樣作有一種缺陷,就是在諸多狀況下,你也許并不懂得要用什么樣辦法來解決。因此當(dāng)真正要

開始寫解決代碼時(shí)候,就要受限于已有Parser/Lexer中代碼。一旦要有所修改,就要重新編譯語法文獻(xiàn),

生成新Java代碼,不勝繁瑣。并且,一旦解決過程有誤,就要重復(fù)調(diào)試修改Antlr生成代。自動(dòng)生成代碼

嘛,構(gòu)造著實(shí)也不怎么樣,調(diào)試時(shí)候也麻煩。因此如果效率容許話,就沒有必要讓Antlr作額外工作,干脆

就專心于做她語法分析也就是了,其她工作等到生成語法樹之后再怎么遍歷或者折騰都可以琳J(rèn)。

f查詢語法樹(Zl回區(qū)I

ISELECT

,?light

…?MAX

?temp

白…_jFROM

:…?sensors

3_JWHERE

-i_|and

B-__j>

}??light

;…?0

-_]or

-_?on

-_jtrigger

-_JSELECT

?light

+jFROM

由口WHERE

申」PERIOD

+_|DURATION

l±]_j?

±_JPERIOD

+_jDURATION

上圖就是剛才演示SenscrSQL語法分析之后產(chǎn)生成果。在產(chǎn)生這個(gè)成果之后,我需要將每一種語法

元素翻譯成字節(jié)序列打包發(fā)送給傳感器網(wǎng)絡(luò)。這時(shí)候,為了保證Where語句中優(yōu)先級(jí),你就可以按照A7TLR

文檔中關(guān)于生成語法樹一章,生成類似丁?這樣構(gòu)造,然后只需前序遍歷這顆語法例Where某些就可以達(dá)到

目,至于其她某些,順序遍歷一遍就好了。

ANTLRStudio

有了前面基本之后,咱們就可以開始真正工作了。但是用“記事本或Editplus+命令行”或者干脆寫個(gè)

ANT腳本也不是不可以,但是總覺得在集成化IDE滿天飛時(shí)代用這個(gè)方式有點(diǎn)過于原始,幸好Placid

System為咱們提供了一種Eclipse插件來使咱們有機(jī)會(huì)直接走出原始社會(huì)。下載地址為:,當(dāng)前最新版本

是1.1.0。唯一令人遺憾是這個(gè)插件雖然功能很完善,卻是要收贄,否則只有11天試用期。

ANTLRStudioEvaluation

?10day(s)lefttoevaluateANTLRStudio.

ANTLRStudio插件安裝

Eclipse下插件安裝自不必多說,要注意是從PlacidSystem網(wǎng)站上提供license文獻(xiàn),下載之后它名

字為license.lic.txt,要把它后綴名.txt去抻,然后放到ECLIPSEDIR\plugins\AntlrStudio_x.x.x目錄(這里

x.x.x是版本號(hào),例如-1.1.0b安裝成功之后在Eclipse工具欄上會(huì)浮現(xiàn)一種詞法分析器導(dǎo)航按鈕:

〔LexerWizard

當(dāng)右鍵單點(diǎn)擊你工程時(shí),你會(huì)發(fā)現(xiàn)控制與否使用ANTLRStudio開關(guān):

在右面大綱窗口,列有所有Parser和Lexer元素,可以看到ProtectedToken(例如Number)和其

她普通Token是不同樣;在左面,不同區(qū)域是用不同顏色塊加亮來區(qū)別。

功能簡(jiǎn)介

ANTLRStudio在EclipseHelp提供了比較詳盡文檔描述,因此這里我只簡(jiǎn)介某些1.1.0版本新功能。

完全支持ANTLR3O1,并支持將之前工程自動(dòng)升級(jí)到1.1.0版本。

SyntaxDiagramView,可以以便查看所輸入語法構(gòu)造。

改進(jìn)了Debug功能,可以調(diào)試比較大又法又獻(xiàn)。而在這之前,如果一種文法文獻(xiàn)很大詰,ANTLRStudio

就會(huì)拋出異常。

支持自動(dòng)代碼補(bǔ)全功能,提供一種ANTLR文檔比較全面提示信息(如下所示)。

classCalcParserextendsParser;

options{

buiidAST=true;//usesCo^wonASTbydefault

}AAppendastringtotheendosingdassdefinition.In

Java,thisamountstoacomma-separatedlistof

expr**dassHeaderSuffix

interfacesthatyourlexer,parser,ortreewalker

-defaultErrorHandler

mustimplement.

口buiidAST

ASTLaberrype

mexpainteractive

3importVocab

aexportVocab

atom?codeGenMakeS^ntchTnreshold

■**codeGenDebug

'codeGenBitsetTestThreshold

clas

語法圖表視圖(SyntaxDiagramView)

在Window->ShowView->Other中選取顯示這個(gè)視圖之后,你就可以使用這個(gè)很酷功能了

運(yùn)用這個(gè)視圖,你可以很容易看到你定義語法語法構(gòu)造,例如,&SELECT語句定義如下

//SQLdefination

sensorSQL:selectStatement

seiectStatement|:SELECT^(ALL|DISTINCT)?seiectClausefromClause

(optWhereClause)?

(optTriggerClause)?

periodExpr

durationExpr

你只需要將光標(biāo)標(biāo)放到selectstatement規(guī)則任意位置,就可以在SyntaxDiagramView中看到:

T阻萬一

于是完整語法構(gòu)造清晰顯示在了咱們而前。這時(shí)你只需要將光標(biāo)放到脫字符號(hào)(人)上面(注:脫字符號(hào)用

于指明在生成語法樹時(shí)候,脫字符號(hào)所在SubRule要作為樹或子樹根節(jié)點(diǎn)):就會(huì)看到:

)n

IectStatement一脫字符所在位置

::SELECTf(ALL|DISTINCT)?selectClai

(optWhereClause)?

ProblemsJavadocDeclarationASTViewerInj

------------------I

——4SELECT!?ALL-------------H—?

?DISTINCT—:

相應(yīng)SubRule被加亮成粉紅色,而如果你光標(biāo)放到位置是一種Token話就會(huì)變成淡藍(lán)色,簡(jiǎn)直太酷了。

增強(qiáng)Debug功能

想要啟動(dòng)或關(guān)閉ANTLRStudioDebug功能,需要完畢如下環(huán)節(jié):

在工程中啟用/取消ANTLRStudio

右犍單擊工程,打開“屬性”中ANTLRStudio選項(xiàng)卡。

選取/取消'Enabledebuggingingrammarfiles'

22做67完這些后,咱們就可以痛pd快eur使iaot用dioE其nxEDpxerpbrug功能了。?調(diào)試其她Java文獻(xiàn)同樣,咱們可以在語法文

當(dāng)程序25運(yùn)營(yíng)至斷點(diǎn)之后,咱們同(樣op可tT以r像ig調(diào)ge試rC普l通au應(yīng)s用e)程?序同樣使用諸如“跳過",“繼續(xù)"等Java應(yīng)用程序

獻(xiàn)任意位置插入斷點(diǎn):

24(optWhereCiause)?

△FI1239s//eSlQecLtSdteatfeinmaetinotn:SELECT^(ALL|DISTINCT)seiectClausefromClause

H2O]Line.breakpoint:SeisorSql.g[line:20]|

IDebug方式來進(jìn)行,卜分以便和順于。

'Debug次

DOa妁1女生丑

IEMy[JavaApphcabon]

注:以上資料均來于網(wǎng)絡(luò),鄙人收集整頓。

ANTLR中文手冊(cè)

06通訊軟件06382027鄭毅

本文重要概括了某些慣用ANTLR用法,其中有Antlr重要類,Antlr文法文獻(xiàn)形

式,生成Java類,如何生成Java類,如何執(zhí)行以及元語言詞匯表。

一、Antlr重要類:

Antlr中有重要類有兩種(其實(shí)尚有一種TreeLexer)

Lexer:文法分析器類。重要用于把讀入字節(jié)流依照規(guī)則分段。既把長(zhǎng)面條依照

你要尺寸切成一段一段:)并不對(duì)其作任何修改。

Parser:解析器類。重要用于解決通過Lexer解決后各段。某些詳細(xì)操作都在這

里。

二、Antlr文法文獻(xiàn)形式:

Antlr文獻(xiàn)是*.g形式,即以g為后綴名。

例如:t.g

classPextendsParser;

startRule

:n:NAME

{System,out.printin(?,Hithere,〃n.getText());}

classLextendsLexer;

//one-or-morelettersfollowedbyanewline

NAME:(,a'....'z?\fA'.....'1?)NEWLINE

*

NEWLINE

:,\r-\n,//DOS

/\d//UNIX

9

詳細(xì)成分分析:

1、總體構(gòu)造

ClassPextendsParser

ClassLextendsLexer

兩行同JAVA繼承同樣,P繼承Parser類;L繼承Lexer類。每個(gè).g文獻(xiàn)只能各

有一種。

2、Lexer類分析

普通按照類型名:(匹配詳細(xì)規(guī)則)形式構(gòu)成。是分隔字節(jié)流根據(jù)。同步可以看到

里面可以互相引用。如本例中類型名NEWLINE出當(dāng)前NEW匹配規(guī)則中。

3、Parser類分析

普通按照

起始規(guī)則名:

規(guī)則實(shí)例名:類型名或規(guī)則名

{Java語句...;)

起始規(guī)則名:任意。

規(guī)則實(shí)例名:就象Java中“Strings;"s同樣。規(guī)則實(shí)例名用于在之后JAVA

語句中調(diào)用.

類型名或規(guī)則名:可以是在Lexer中定義類型名,也可以是Parser中定義規(guī)則

名。感覺就像是int與Integer區(qū)別。

Java語句:指當(dāng)滿足當(dāng)前規(guī)則時(shí)所執(zhí)行語句。Antlr會(huì)自動(dòng)嵌入生成java類中。

三、生成Java類

1、從.org上下載ant,-x.x.x.jar

2、配備環(huán)境變量:classpalh二.;x:\jdk\lib\tools.jar;x:\antlr-x.x.x.jar

3、在t.g所在目錄下執(zhí)行:

javaantIr.Toolt.g

會(huì)在當(dāng)前目錄下生成如下文獻(xiàn):

L.java:Lexer文法分析器java類。

P.java:Parser解析器java類。

PTokenTypes.java:Lexer中定義類型詳細(xì)化,供Parser解析器調(diào)用。

PTokenTypes.txt:當(dāng)外部(如t2.g)要調(diào)用當(dāng)前類型或規(guī)則時(shí)要用到本文獻(xiàn)。

四、執(zhí)行

1、編寫Main類

importjava.io.*;

classMain{

publicstaticvoidmain(String[]args){

try{

Llexer=newL(newDatalnputStream(System,in));

Pparscr=ncwP(lexer);

parser.startRule();

)catch(Exceptione){

System,err.println("exception:〃e);

)

2、執(zhí)行

c:\>javac*.java

c:\>javaMain

Terence

N

Hithere,Terence

c:\>

元語言詞匯表

空格定義空格,tab符號(hào)和換行符號(hào)在ANTLR分隔諸如標(biāo)記符這樣詞匯符號(hào)時(shí)

作為分隔符。在這之外,它們是被忽視。例如,“FirstNameLastName”對(duì)ANTLR

來說兩個(gè)標(biāo)記符而不是一種標(biāo)記符,空格,然后再接著一種標(biāo)記符。

注釋

ANTLR接受C語言風(fēng)格塊注釋和C++風(fēng)格行注釋。在語法類和規(guī)則中,Java風(fēng)格

文檔注釋也是可以接受,在需要時(shí)候,這些注釋可以被傳遞給生成輸出文獻(xiàn)。例

/**Thisgrammarrecognizessimpleexpressions

*@authorTerenceParr

*/

classExprParser;

/**Matchafactor*/

factor:...;

字符集

字符常數(shù)像Java中那樣被擬定。它們包括八進(jìn)制轉(zhuǎn)義字符集(e.g.,、377,),

Unicode字符集(e.g.,'\uFF00'),和能被Java辨認(rèn)慣用字符轉(zhuǎn)義('\b',''r',

'\t','\n','\f,'\\')o在詞法分析器規(guī)則中,單引號(hào)代表一種可以

在輸入字符流中能得到匹配字符。在語法分析器中是不被支持單引號(hào)字符。

文獻(xiàn)結(jié)束標(biāo)志EOF標(biāo)記用語法分析器規(guī)則中自動(dòng)生成:

rule:(statement)+EOF;

你可以在詞法分析器規(guī)則動(dòng)作中檢測(cè)EOF_CHAR符號(hào):

//makesurenothingbutnewIineor

//EOFispastthe#endif

ENDIF

(

booleaneoI二faIse;

1

:"#endif"

(C\n'|'\r'j{eol=true;})?

(

if(SeoI){

if(LA(1)=E0F_CHAR){error("EOF");}

else{error("InvaIidchars");}

}

當(dāng)你將文獻(xiàn)結(jié)束當(dāng)一種字符來檢測(cè)時(shí),它事實(shí)上并不是一種字符,而是一種條件。

你可以在你詞法分析器語法中覆蓋CharScanr.er.uponEOF()函數(shù):

/**ThismethodiscalledbyYourLexer.nextTokenO

*whenthelexerhas

*hitEOFcondition.EOFisNOTacharacter.

?ThismethodisnotcalledifEOFisreached

*duringsyntacticpredicateevaIuationorduring

*evaIuationofnormaIlexicalrules,which

*presumablywouIdbeanlOException.This

*trapsthe"normaI"EOF+condition.

*

*uponEOF()iscalledafterthecompIeteevaluation

*oftheprevioustokenandonlyifyourparserasks

*foranothertokenbeyondthatIastnon-EOFtoken.

*

*Youmightwanttothrowtokenorcharstream

*exceptionslike:"Heh,prematureeof"oraretry

*streamexception("Ifoundtheendofthisfile,

*gobacktoreferencingfiIe").

*/

pubIicvoiduponEOF()

throwsTokenStreamException,CharStreamException

文獻(xiàn)結(jié)束條件是一種位比特。由于Terence將7當(dāng)作一種字符而不是一種整型

數(shù)。(-1是'\uFFFF').

字符串

字符串常數(shù)一種由雙引號(hào)括起來一系列字符。在字符串中字符可以是作為字符也

同樣合法轉(zhuǎn)義字符(八進(jìn)制,Unicode等)。當(dāng)前,ANTLR事實(shí)上不容許Unicode

出當(dāng)前字符串常量中(你不得不用轉(zhuǎn)義符)。這是由于在anglr.g文獻(xiàn)中設(shè)定

charVocabulary選項(xiàng)為ascii.

在詞法分析器規(guī)則中,字符串被解釋成可以在輸入流中匹配一系列字符(例如.,

"for"等于f'o''「).

在語法分析器規(guī)則中,字符串代表一種個(gè)標(biāo)記(tokens),并且每個(gè)獨(dú)立字符串

被分派一種標(biāo)記類型。然而,ANTLR不會(huì)創(chuàng)立一種詞法分析器規(guī)則來匹配這些字

符串。相反,ANTLR將這些字符串輸入到一種于詞法分析器關(guān)聯(lián)字符常量表中。

ANTLR將針對(duì)字符常量表來產(chǎn)生代碼檢測(cè)每個(gè)標(biāo)記中文木,在手動(dòng)關(guān)掉語法分析

器對(duì)該標(biāo)記解決之前獲得一種匹配時(shí),會(huì)變化標(biāo)記類型。你也可以執(zhí)行手動(dòng)檢

測(cè)一一自動(dòng)代碼生成瓦以通過詞法分析器選項(xiàng)控制。

你也許想在你動(dòng)作中使用這些字符串常量標(biāo)記類型值,例如在錯(cuò)誤解決器同步某

些。對(duì)丁只由字母字符構(gòu)成字符串常量來說,這個(gè)字符串常量值將是一種形如

LITERAL_xxx常量值,這里xxx是這個(gè)標(biāo)記名字。例如,文字“return”將有一

種LITERAL_return值與之關(guān)聯(lián)。你也可以用標(biāo)記節(jié)(tokenssection)分派一

種特定標(biāo)號(hào)給這個(gè)文字。

標(biāo)記引用

以大寫字符開頭標(biāo)記符稱為標(biāo)記引用。接卜?來字符可以是任何字符,數(shù)字或下

劃線。在語法分析器規(guī)則中一種標(biāo)記引用將導(dǎo)致匹配特定標(biāo)記。在詞法分析器中

標(biāo)記引用將導(dǎo)致調(diào)用一種詞法規(guī)則來匹配該標(biāo)記字符。換句話說,在詞法分析器

中標(biāo)記引用將對(duì)當(dāng)作一種規(guī)則引用。

標(biāo)記定義

在詞法分析器中標(biāo)記定義由和語法規(guī)則中相似定義。但是當(dāng)做標(biāo)記而不是語法規(guī)

則。例如,

classMyParserextendsParser;

idList:(ID)+;//parserruledefinition

classMyLexerextendsLexer;

ID:('a'..'z')+;//tokendefinition

規(guī)則引用

以小寫字母開頭標(biāo)記符是為ANTLR語法規(guī)則。接下來字符可以是任意字母,數(shù)字

或下劃線。詞法規(guī)則不能引用語法規(guī)則。

動(dòng)作.

在尖括號(hào)中字符序列是語義動(dòng)作(也許是嵌套)。在字符串和字符中尖括號(hào)不是

動(dòng)作分隔符。

動(dòng)作參數(shù)

在方括號(hào)中字符序列是動(dòng)作參數(shù)(也許是嵌套)。在字符串和字符中方括號(hào)不是

動(dòng)作分隔符。在口中參數(shù)是用被生成語言語法定義,并且用逗號(hào)分開。

codeBlock

[intscope,Stringname]//inputarguments

returns[intx]//returnvalues

//pass2args,getreturn

testcblock

{inty;}

:y=cblock[l,"John"]

?

許多人喜歡咱們用普通括號(hào)來括住參數(shù),但是括號(hào)在EBNF中已經(jīng)被較好用來定

義語法組符號(hào)(grammaticalgroupingsymbols)。

符號(hào)下面表記錄了在ANTLR中使用標(biāo)點(diǎn)符號(hào)和核心字。

符號(hào)描述

(...)子規(guī)則

(..)*閉包子規(guī)則(零和各種)

(..)+正閉包子規(guī)則(一種和各種)

(...)?可選(零個(gè)和一種)

{...}語義動(dòng)作

[...]規(guī)則參數(shù)

{..)?語義謂詞

(...)=>語法謂詞

I可詵符

■.范疇符

?非

通配符

=賦值

:標(biāo)號(hào)符,規(guī)則開始

;規(guī)則結(jié)束

<?->元素選項(xiàng)

class語法類

extends指定語法基類

returns指定返回類型

optionsoptions節(jié)

tokenstokens節(jié)

headerheader節(jié)

tokenstoken定義節(jié)

Header節(jié)

一種header節(jié)包括了某些將直接被替代到輸出語法分析器中源碼,這些源碼將

在所有ANTLR生成代碼之前。這個(gè)重要用在C++輸出中,由于C++需要某些元素

在引用之前必要被聲明。在Java中,這可以用來為最后語法分析器指定某些包

文獻(xiàn)。一種header節(jié)看起來像下面這樣:

header{

sourcecodeinthelanguagegeneratedbyANTLR;

}

header節(jié)是語法文獻(xiàn)第一種節(jié)。依照選取目的語言不同,不同類型header節(jié)

都是也許浮現(xiàn)??锤髯愿戒?。

語法分析器類定義

所有語法規(guī)則必要和一種語法分析器關(guān)聯(lián)。一種語法文獻(xiàn)(.g)只包括一種語法

分析器類定義(和詞法分析器和樹遍歷器一起)一種語法分析器定義在它選項(xiàng)

(options)和規(guī)則定義之前。一種語法文獻(xiàn)中語法分析器定義普通是這個(gè)樣子:

{optionalclasscodepreamble}

classYourParserClassextendsParser;

options

tokens

{optionalactionforinstancevars/methods!

parserrules...

當(dāng)在面向?qū)ο笳Z言中生成代碼時(shí),語法分析器類將導(dǎo)致在輸出中是一種類,規(guī)則

都會(huì)變成這個(gè)類成員函數(shù)。在C中,類將導(dǎo)致生成一種構(gòu)造,某些名字混淆

(name-mangling)算法將用在上面使最后規(guī)則函數(shù)是全局唯一。

可選類預(yù)定義可以是包括在{}中任意文本。這個(gè)預(yù)定義,如果它存在話,將被直

接輸出到生成類文獻(xiàn)中,并且在類定義之前。

封閉尖括號(hào)不能用來分隔類,由于一種左尖括號(hào)在文獻(xiàn)頂就很難跟蹤與之匹配右

括號(hào)在文獻(xiàn)時(shí)。相反,一種語法分析器類假定是持續(xù),懂得遇到下一種類語句。

你可以指定語法分析器超類,它將作為被生成語法分析器超類。這個(gè)超類必要是

完整定義,在雙引號(hào)中。它自己必要是antlr.LlkParser子類。例如

cIassTinyCParserextendsParser("antIr.debug.ParseTreeDebugParser");

詞法分析器類定義

一種語法分析器類將導(dǎo)致一種懂得如何依照輸入流標(biāo)記來應(yīng)用語法構(gòu)造語法分

析器對(duì)象。為了執(zhí)行詞法分析,你需要指定一種詞法分析器類,它描述了如何將

輸入流分離成標(biāo)記流。它語法類似于語法分析器類:

{optionalclasscodepreamble}

classYourLexerCJassex二endsLexer;

options

tokens

{optionalactionforinstancevars/methods]

lexerrules...

包括在詞法分析器中詞法規(guī)則在產(chǎn)生類中變成成員辦法。每個(gè)語法文獻(xiàn)(.g)只

包括一種詞法分析器。語法分析器和詞法分析器可以以任何順序浮現(xiàn)。

可選類開頭是括在{}中任意文本。這個(gè)開頭某些,如果它存在,將輸出到被生成

類文獻(xiàn)中,在類定義之前。

你可以定義一種詞法分析器超類,它可以被用來作為產(chǎn)生詞法分析器超類。這個(gè)

超類將是完整定義(fully-qualified),在雙引號(hào)中,它自身是

antIr.CharScanner子類。

樹分析器定義

一種樹分析器像語法分析器,不同是它解決二維由節(jié)點(diǎn)構(gòu)成抽象語法樹,而不是

解決由標(biāo)記構(gòu)成流。樹分析潛必要唯一指定給語法分析器,除非規(guī)則定義中包括

特殊形式致使它遞歸下降到樹中。同樣,一種特定語法文獻(xiàn)(.g)中僅僅包括一

種樹分析器。

{optionalclasscodepreamble}

classYourTreeParserClassextendsTreeParser;

options

tokens

{optionalactionforinstancevars/methods}

treeparserrules...

你可以定義一種樹分析器超類,它可以被用來作為產(chǎn)生樹解析器超類。這個(gè)超類將是完整定

義(fully-qualified),在雙引號(hào)中,它自身是antIr.TreeParser子類

注:以上資料均來于網(wǎng)絡(luò),鄙人收集整頓。

計(jì)算器及文法文獻(xiàn)

06通訊軟件06382027鄭毅

本文重要簡(jiǎn)介了運(yùn)用ANTLR達(dá)到計(jì)算器需求以及運(yùn)用ANTLR生成C++描述分析程序。

一.運(yùn)用ANTLR達(dá)到計(jì)算器需求

1.運(yùn)算符:+,—,X,(,)

2.支持整型和浮點(diǎn)型

測(cè)試樣例

1.1+2*34-5-4/2

2.(1+2)*3+5-4/(2+2)

3.(1.2*2.5)+8/(4-3)*2.7

下面就讓咱們動(dòng)手完畢一種計(jì)算器,:)

先搭個(gè)框架。文獻(xiàn)名是calc.g

options{

language=''Cpp〃;

}

classCalcParserextencsParser;

classCalcLexerextendsLexer;

這些就是基本框架了。

options里設(shè)立language為〃Cpp〃,表達(dá)要生成C++代碼。

CalcParser是咱們計(jì)算器語法解析類,繼承ANTLR里Parser類。

同理,CalcLexer是詞法分析類,繼承ANTLR里L(fēng)exer類。

接著定義計(jì)算器詞法規(guī)則。

一方面是運(yùn)算符。

PLUS:

SUB:;

MUL:;

DIV:7';

LPAREN:;

RPAREN:y;

接著是操作數(shù)。

NUM:{$setType(INT):}('0'..9)+{$setType(REAL):})?;

(法:$setType是ANTLR內(nèi)置函數(shù),用來設(shè)立token類型。就是當(dāng)匹配到('0'..’9')*后,設(shè)

立token類型為INT,當(dāng)發(fā)現(xiàn)背面跟著小數(shù)點(diǎn)和數(shù)字后,重新設(shè)立token類型為REAL。)

WS:('、

I'、「')+

$setType(ANTLR_USE_NAMESPACE(antlr)Token::SKIP);

)

*

r

statement:mexpr((PLUS|SUB)mexpr)*

mexpr:expr((MUL|DIV)expr)*

expr:INT

|REAL

|LPARENstatementRPAREN

一種計(jì)算器語法程序就寫好了。讓咱們來生成C++代碼,實(shí)際測(cè)試一下.

$java-cp/usr/share/java/antlr.jarantlr.Toolcalc.g

ANTLRParserGeneratorVersion2.7.6(0528)1989-

$ls

calc.gCalcParser.cppCalcParserTokenTypes.txt

CalcLexer.cppCalcParser.hpp

CalcLexer.hppCalcParserTokenTypes.hpp

$

咱們可以石?到,生成了6個(gè)文獻(xiàn)“

CalcTest.cpp:

#include"CalcLexer.hpp”

#include''CalcParser.hpp,/

#include

usingnamespacestd;

usingnamespaceantlr;

intmain()

{

try{

CalcLexerlexer(cin);

CalcParserparser(lexer);

parser.statement();

}catch(exception&e){

cout<<e,what()<<endl;

}

}

編譯之:

$g++-oCalcCalcTest.cppCalcParser.cppCalcLexer.cpp-lantlr

測(cè)試用例:

$,/Calc

l+2*3+5-4/2

$,/Calc

(1+2)*3+5-4/(2+2)

$,/Calc

(1.2*2.5)+8/(4-3)*2.7

$

二.運(yùn)用ANTLR生成C++描述分析程序

文法文獻(xiàn)

文法就是語言辨認(rèn)規(guī)則。它是ANTLR生成程序根據(jù)。文法文獻(xiàn)是ANTLR核心,是程序員和

ANTLR進(jìn)行交流接口。

文法文獻(xiàn)編寫基本是面向被解決問題。程序員只需要集中精力思考解決問題邏輯,而不是聃絆于

某種程序設(shè)計(jì)語言實(shí)現(xiàn)細(xì)節(jié),因而減少了浮現(xiàn)錯(cuò)誤也許性。

文法文獻(xiàn)語法簡(jiǎn)介(轉(zhuǎn)自ANTLR中文手冊(cè))

本文只是簡(jiǎn)樸地簡(jiǎn)介一種文法文獻(xiàn)語法,詳細(xì)內(nèi)容可以參閱ANTLR有關(guān)文檔。

文法文獻(xiàn)普通涉及header塊、options塊、文法分析器類(parser)及規(guī)則定義、詞法分掃

描器類(lexer)及token定義。其中最為重要是規(guī)則和token定義。

規(guī)則定義形式和編譯理論中擴(kuò)展巴科斯范式(EBNF)極為相似,涉及規(guī)則名、規(guī)則體、一種用

作結(jié)束標(biāo)志分號(hào)和異常解決某些(可省略)。例如如下規(guī)則就描述了C語言中賦值語句話法:

assignmentstat:

id=expr;

9

其意義是:一條賦值語句是由一種id、一種等號(hào)、一種表達(dá)式和一種分號(hào)順序構(gòu)成。

Token定義辦法與規(guī)則類似。例如如下token定義就表達(dá)一種十進(jìn)制整數(shù):

NUM:

9

其意義是:數(shù)字(NUM)第一字符是‘1'到'9'中一種字符,背面是。個(gè)或各種‘0'到'9'

之間字符。

需要注意一點(diǎn)是:規(guī)則名字必要是小寫字母開始,而token名字則必要是大寫字母開始.

設(shè)定ANTLR生成語言(轉(zhuǎn)自ANTLR中文手冊(cè))

ANTLR有諸多選項(xiàng),可以通過在文法文獻(xiàn)中options塊中進(jìn)行設(shè)立,其中涉及ANTLR最后身

成語言。如果要生成C++描述分析器程序,就要如卜.設(shè)定:

options

language="Cpp";

//Otheroptions

}

language選項(xiàng)默認(rèn)值是“Java”。如果您但愿生成程序是C#,將language設(shè)為“Csharp”

就可以了。

C++程序例子

下面就給出一種ANTLR生成C++描述分析器實(shí)例。該分析器功能是分析顧客輸入一種算術(shù)表

達(dá)式,給出該表達(dá)式最后成果。在該表達(dá)式中容許浮現(xiàn)運(yùn)算符除了加減乘除之外,還涉及求幕運(yùn)

算符“八",以及sin、cos和tan三個(gè)三角函數(shù)。

編寫文法文獻(xiàn)

header{

^include<stdlib.h>

#include<stdio.h>

*include<math.h>

)

options

(

language="Cpp”;

classExprParserextendsParser:

)

//rules

exprreturns[doublevalue=0]

(doublex;}

value=term

(

PLUSx=term{value+=x;}

I

MINUSx=term{value-=x;}

)*

exception

catch[ANTLR_USE_NAMESPACE(antIr)ANTLRException&ex]{

//catchallexceptionsandreportit

reportError(e

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論