Antlr简介及中文基础手册_第1页
Antlr简介及中文基础手册_第2页
Antlr简介及中文基础手册_第3页
Antlr简介及中文基础手册_第4页
Antlr简介及中文基础手册_第5页
已阅读5页,还剩31页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Antlr简介

06通讯软件06382027郑毅

本文重要简介了什么是ANTLR,以及ANTLR使用,其中ANTLR使用涉及了ANTLR安装及使用,

ANTLR语法文献解析,ANTLR规则(RULE)解析,ANTLR语法实例一SensorSQL,ANTLRStudio

及其功能简介等。

Antlr(ANotherToolforLanguageRecognition)是一种工具,前身是PCCTS,它为咱们构造自己辨

认得(recognizers)、编译器(compiler)和转换器(translators)提供了•种基本。通过定义自己语言

规则,Antlr可觉得咱们生成相应语言解析器,这样便可以省却了自己全手工打造劳苦。

它是这样•种工具,它可以接受文法语言描述,并能产生辨认这些语言语句程序。作为翻译程序•某

些,你可以使用简朴操作符和动作来参数化你文法,使之告诉ANTLR如何去创立抽象语法树(AST)和如何产

生输出。AXTLR懂得如何去生成辨认程序,语言涉及Java,C++,C#和不久Python。

ANTLR懂得如何构建辨认理序,这些程序可以对如下三种不同输入应用文法构造:(i)字符流,(ii)记

号流,和(iii)两维树构造。很自然它们分别与词法分析程序(lexers,如下简称lexer),语言解析程序和

树遍历程序向匹配。这个用于定义这些语法元语言,在所有状况下几乎同样。

••旦你对A\TLR和类似工具比较顺手,你会开始以•种新目光来看编程。许多任务强烈需要语言解决

方案,而不是采用老式编程语言做法。例如,这些过程注解都是用特伦斯标记语言写。而ANTLR则能来将

文本(内含某些额外东西和转换)转化为HTML,PDF或者其她那些生成程序文献格式。

最后,ANTLR只是一件工具,仅仅这些。虽然它能通过将容易理解乏味某些自动化来协助你创立软件,

但却不能企图让你指定整个编译器。例如,在单个描述里就不行.那些宣称此类事情非常伟大,可觉得发

布刊物文章编写惊人“一揽子解决方案”,却会悲惨失败在实际项目中。

词法分析器(Lexer)

词法分析器又称为Scanner,Lexicalanalyser和Tokenizer。程序设冲语言普通由核心字和严格定

义语法构造构成。编译最后目是将程序设计语言高层指令翻译成物力机器或虚拟机可以执行指令。此法分

析器工作是分析量化那些本来毫无意义字符流,将她们翻译成离散字符组(也就是一种一种Token)括核

心字,标记符,符号(symbols)和操作符供语法分析器使用。

语法分析器(Parser)

编译器又称为Syntacticalanalyser。在分析字符流时候,Lexer不关怀所生成单个Token语法意义

及其与上下文之间关系,而这就是Parser工作。语法分析器将收到Tokens组织起来,并转换成为目的语

言语法定义所容许序列。

无论是Lexer还是Parser都是•种辨认器,Lexer是字符序列辨认器而Parser是Token序列辨认器。

她们在本质上是类似东西,而只是在分工上有所不同而已。

ANTLR

ANTLR将上述两者结合起来,它容许咱们定义辨认字符流词法规则和用于解释Token流词法分析规则。

然后,ANTLR将依照顾客提供语法文献自动生成相应词法/语法分析器。顾客可以运用她们将输入文本进行

编译,并转换成其她形式(如AST—AbstractSyntaxTree,抽‘象语法树)。

Antlr使用

安装及使用

到下楼最新版本ANTLR开发包和源码(例如版本3.01).将antlrBOljar所在目录配备到你环境

变量中,写好语法文献(例如SensorSQL.g),运营命令"javaanUr.ToolSensorSQL.g"就可以获得自动生

成语法/词法分析器。

/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:序实现、文法+andli»+RText的自动绑定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语法文献解析

:'匕

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();

)

下面扁们对图中所描述ANTLR语法文献做某些详细分析。为了更好使用ANTLR.你还可如下我

ANTLREclipse插件来协助你完毕工作。

1.header域:所有出当前这里某些,都会出当前由ANTLR编译之后生成Java文献最顶部。在本例中你可

以将包名和其她信息放到这一区域中,生成成果如由面相应代码某些所示。

2.你在这一某些所提供内容对于文献中每个语法都是唯一。这一区域内容将出当前实际类定义之前。也就是

说,两个import仅属于类CalcParser,而不属于在同一种文献中定义其她类(如CalcLexer)

3.这里是语法定义某些,你同样可以将它当作是类定义。

4.在Option域中,你可觉得你语法提供可选项。例如与否建立缺省抽象语法树,指定LL(K)中参数k值

(缺省为1)等等,更详细参数请参阅ANTLR自带手册。

5.Token某些用来声明那些在词法分析器中没有被声明"想象"token。这些信息通惯用在TreeParser中指定

“想象”节点。

6.这是另一种Action区,ANTLR将会忠实地将这一区域内信息放置.到类定义当中,相称于类成员办法,重

要为顾客提供一种在Parser种定制可扩展办法途径。

ANTLR规贝!|(RULE)解析

语法规则,就可以在解析过程中直接得到运算成果:一方面ANTLR将其编译成逆波兰构造-(-(+12)(/

(*34)(-56)));在生成语法树过程中,同步计算表达式值,即类似于2.3节中看到表达式计算。成果如

下:

但是这样作有一种缺陷,就是在诸多状况下,你也许并不懂得要用什么样办法来解决。因此当真正要

开始写解决代码时候,就要受限于已有Parser/Lexer中代码。一旦要有所修改,就要重新编译语法文献,

生成新Java代码,不胜繁琐。并且,一旦解决过程有误,就要重复调试修改Antlr生成代。自动生成代码

嘛,构造着实也不怎么样,调试时候也麻烦。因此如果效率容许话,就没有必要让Antlr作额外工作,干脆

就专心于做她语法分析也就是了,其她工作等到生成语法树之后再怎么遍历或者折腾都可以琳J。

f查询语法树(Zl回区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语法分析之后产生成果。在产生这个成果之后,我需要将每一种语法

元素翻译成字节序列打包发送给传感器网络。这时候,为了保证Where语句中优先级,你就可以按照A7TLR

文档中关于生成语法树一章,生成类似丁•这样构造,然后只需前序遍历这颗语法例Where某些就可以达到

目,至于其她某些,顺序遍历一遍就好了。

ANTLRStudio

有了前面基本之后,咱们就可以开始真正工作了。但是用“记事本或Editplus+命令行”或者干脆写个

ANT脚本也不是不可以,但是总觉得在集成化IDE满天飞时代用这个方式有点过于原始,幸好Placid

System为咱们提供了一种Eclipse插件来使咱们有机会直接走出原始社会。下载地址为:,当前最新版本

是1.1.0。唯一令人遗憾是这个插件虽然功能很完善,却是要收贽,否则只有11天试用期。

ANTLRStudioEvaluation

•10day(s)lefttoevaluateANTLRStudio.

ANTLRStudio插件安装

Eclipse下插件安装自不必多说,要注意是从PlacidSystem网站上提供license文献,下载之后它名

字为license.lic.txt,要把它后缀名.txt去抻,然后放到ECLIPSEDIR\plugins\AntlrStudio_x.x.x目录(这里

x.x.x是版本号,例如-1.1.0b安装成功之后在Eclipse工具栏上会浮现一种词法分析器导航按钮:

〔LexerWizard

当右键单点击你工程时,你会发现控制与否使用ANTLRStudio开关:

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

她普通Token是不同样;在左面,不同区域是用不同颜色块加亮来区别。

功能简介

ANTLRStudio在EclipseHelp提供了比较详尽文档描述,因此这里我只简介某些1.1.0版本新功能。

完全支持ANTLR3O1,并支持将之前工程自动升级到1.1.0版本。

SyntaxDiagramView,可以以便查看所输入语法构造。

改进了Debug功能,可以调试比较大又法又献。而在这之前,如果一种文法文献很大诘,ANTLRStudio

就会抛出异常。

支持自动代码补全功能,提供一种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中选取显示这个视图之后,你就可以使用这个很酷功能了

运用这个视图,你可以很容易看到你定义语法语法构造,例如,&SELECT语句定义如下

//SQLdefination

sensorSQL:selectStatement

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

(optWhereClause)?

(optTriggerClause)?

periodExpr

durationExpr

你只需要将光标标放到selectstatement规则任意位置,就可以在SyntaxDiagramView中看到:

T阻万一

于是完整语法构造清晰显示在了咱们而前。这时你只需要将光标放到脱字符号(人)上面(注:脱字符号用

于指明在生成语法树时候,脱字符号所在SubRule要作为树或子树根节点):就会看到:

)n

IectStatement一脱字符所在位置

::SELECTf(ALL|DISTINCT)?selectClai

(optWhereClause)?

ProblemsJavadocDeclarationASTViewerInj

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

——4SELECT!♦ALL-------------H—►

♦DISTINCT—:

相应SubRule被加亮成粉红色,而如果你光标放到位置是一种Token话就会变成淡蓝色,简直太酷了。

增强Debug功能

想要启动或关闭ANTLRStudioDebug功能,需要完毕如下环节:

在工程中启用/取消ANTLRStudio

右犍单击工程,打开“属性”中ANTLRStudio选项卡。

选取/取消'Enabledebuggingingrammarfiles'

22做67完这些后,咱们就可以痛pd快eur使iaot用dioE其nxEDpxerpbrug功能了。•调试其她Java文献同样,咱们可以在语法文

当程序25运营至断点之后,咱们同(样op可tT以r像ig调ge试rC普l通au应s用e)程?序同样使用诸如“跳过",“继续"等Java应用程序

献任意位置插入断点:

24(optWhereCiause)?

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

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

IDebug方式来进行,卜分以便和顺于。

'Debug次

DOa妁1女生丑

IEMy[JavaApphcabon]

注:以上资料均来于网络,鄙人收集整顿。

ANTLR中文手册

06通讯软件06382027郑毅

本文重要概括了某些惯用ANTLR用法,其中有Antlr重要类,Antlr文法文献形

式,生成Java类,如何生成Java类,如何执行以及元语言词汇表。

一、Antlr重要类:

Antlr中有重要类有两种(其实尚有一种TreeLexer)

Lexer:文法分析器类。重要用于把读入字节流依照规则分段。既把长面条依照

你要尺寸切成一段一段:)并不对其作任何修改。

Parser:解析器类。重要用于解决通过Lexer解决后各段。某些详细操作都在这

里。

二、Antlr文法文献形式:

Antlr文献是*.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

详细成分分析:

1、总体构造

ClassPextendsParser

ClassLextendsLexer

两行同JAVA继承同样,P继承Parser类;L继承Lexer类。每个.g文献只能各

有一种。

2、Lexer类分析

普通按照类型名:(匹配详细规则)形式构成。是分隔字节流根据。同步可以看到

里面可以互相引用。如本例中类型名NEWLINE出当前NEW匹配规则中。

3、Parser类分析

普通按照

起始规则名:

规则实例名:类型名或规则名

{Java语句...;)

起始规则名:任意。

规则实例名:就象Java中“Strings;"s同样。规则实例名用于在之后JAVA

语句中调用.

类型名或规则名:可以是在Lexer中定义类型名,也可以是Parser中定义规则

名。感觉就像是int与Integer区别。

Java语句:指当满足当前规则时所执行语句。Antlr会自动嵌入生成java类中。

三、生成Java类

1、从.org上下载ant,-x.x.x.jar

2、配备环境变量:classpalh二.;x:\jdk\lib\tools.jar;x:\antlr-x.x.x.jar

3、在t.g所在目录下执行:

javaantIr.Toolt.g

会在当前目录下生成如下文献:

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

P.java:Parser解析器java类。

PTokenTypes.java:Lexer中定义类型详细化,供Parser解析器调用。

PTokenTypes.txt:当外部(如t2.g)要调用当前类型或规则时要用到本文献。

四、执行

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、执行

c:\>javac*.java

c:\>javaMain

Terence

N

Hithere,Terence

c:\>

元语言词汇表

空格定义空格,tab符号和换行符号在ANTLR分隔诸如标记符这样词汇符号时

作为分隔符。在这之外,它们是被忽视。例如,“FirstNameLastName”对ANTLR

来说两个标记符而不是一种标记符,空格,然后再接着一种标记符。

注释

ANTLR接受C语言风格块注释和C++风格行注释。在语法类和规则中,Java风格

文档注释也是可以接受,在需要时候,这些注释可以被传递给生成输出文献。例

/**Thisgrammarrecognizessimpleexpressions

*@authorTerenceParr

*/

classExprParser;

/**Matchafactor*/

factor:...;

字符集

字符常数像Java中那样被拟定。它们包括八进制转义字符集(e.g.,、377,),

Unicode字符集(e.g.,'\uFF00'),和能被Java辨认惯用字符转义('\b',''r',

'\t','\n','\f,'\\')o在词法分析器规则中,单引号代表一种可以

在输入字符流中能得到匹配字符。在语法分析器中是不被支持单引号字符。

文献结束标志EOF标记用语法分析器规则中自动生成:

rule:(statement)+EOF;

你可以在词法分析器规则动作中检测EOF_CHAR符号:

//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");}

}

当你将文献结束当一种字符来检测时,它事实上并不是一种字符,而是一种条件。

你可以在你词法分析器语法中覆盖CharScanr.er.uponEOF()函数:

/**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

文献结束条件是一种位比特。由于Terence将7当作一种字符而不是一种整型

数。(-1是'\uFFFF').

字符串

字符串常数一种由双引号括起来一系列字符。在字符串中字符可以是作为字符也

同样合法转义字符(八进制,Unicode等)。当前,ANTLR事实上不容许Unicode

出当前字符串常量中(你不得不用转义符)。这是由于在anglr.g文献中设定

charVocabulary选项为ascii.

在词法分析器规则中,字符串被解释成可以在输入流中匹配一系列字符(例如.,

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

在语法分析器规则中,字符串代表一种个标记(tokens),并且每个独立字符串

被分派一种标记类型。然而,ANTLR不会创立一种词法分析器规则来匹配这些字

符串。相反,ANTLR将这些字符串输入到一种于词法分析器关联字符常量表中。

ANTLR将针对字符常量表来产生代码检测每个标记中文木,在手动关掉语法分析

器对该标记解决之前获得一种匹配时,会变化标记类型。你也可以执行手动检

测一一自动代码生成瓦以通过词法分析器选项控制。

你也许想在你动作中使用这些字符串常量标记类型值,例如在错误解决器同步某

些。对丁只由字母字符构成字符串常量来说,这个字符串常量值将是一种形如

LITERAL_xxx常量值,这里xxx是这个标记名字。例如,文字“return”将有一

种LITERAL_return值与之关联。你也可以用标记节(tokenssection)分派一

种特定标号给这个文字。

标记引用

以大写字符开头标记符称为标记引用。接卜♦来字符可以是任何字符,数字或下

划线。在语法分析器规则中一种标记引用将导致匹配特定标记。在词法分析器中

标记引用将导致调用一种词法规则来匹配该标记字符。换句话说,在词法分析器

中标记引用将对当作一种规则引用。

标记定义

在词法分析器中标记定义由和语法规则中相似定义。但是当做标记而不是语法规

则。例如,

classMyParserextendsParser;

idList:(ID)+;//parserruledefinition

classMyLexerextendsLexer;

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

规则引用

以小写字母开头标记符是为ANTLR语法规则。接下来字符可以是任意字母,数字

或下划线。词法规则不能引用语法规则。

动作.

在尖括号中字符序列是语义动作(也许是嵌套)。在字符串和字符中尖括号不是

动作分隔符。

动作参数

在方括号中字符序列是动作参数(也许是嵌套)。在字符串和字符中方括号不是

动作分隔符。在口中参数是用被生成语言语法定义,并且用逗号分开。

codeBlock

[intscope,Stringname]//inputarguments

returns[intx]//returnvalues

//pass2args,getreturn

testcblock

{inty;}

:y=cblock[l,"John"]

»

许多人喜欢咱们用普通括号来括住参数,但是括号在EBNF中已经被较好用来定

义语法组符号(grammaticalgroupingsymbols)。

符号下面表记录了在ANTLR中使用标点符号和核心字。

符号描述

(...)子规则

(..)*闭包子规则(零和各种)

(..)+正闭包子规则(一种和各种)

(...)?可选(零个和一种)

{...}语义动作

[...]规则参数

{..)?语义谓词

(...)=>语法谓词

I可诜符

■.范畴符

〜非

通配符

=赋值

:标号符,规则开始

;规则结束

<•->元素选项

class语法类

extends指定语法基类

returns指定返回类型

optionsoptions节

tokenstokens节

headerheader节

tokenstoken定义节

Header节

一种header节包括了某些将直接被替代到输出语法分析器中源码,这些源码将

在所有ANTLR生成代码之前。这个重要用在C++输出中,由于C++需要某些元素

在引用之前必要被声明。在Java中,这可以用来为最后语法分析器指定某些包

文献。一种header节看起来像下面这样:

header{

sourcecodeinthelanguagegeneratedbyANTLR;

}

header节是语法文献第一种节。依照选取目的语言不同,不同类型header节

都是也许浮现。看各自附录。

语法分析器类定义

所有语法规则必要和一种语法分析器关联。一种语法文献(.g)只包括一种语法

分析器类定义(和词法分析器和树遍历器一起)一种语法分析器定义在它选项

(options)和规则定义之前。一种语法文献中语法分析器定义普通是这个样子:

{optionalclasscodepreamble}

classYourParserClassextendsParser;

options

tokens

{optionalactionforinstancevars/methods!

parserrules...

当在面向对象语言中生成代码时,语法分析器类将导致在输出中是一种类,规则

都会变成这个类成员函数。在C中,类将导致生成一种构造,某些名字混淆

(name-mangling)算法将用在上面使最后规则函数是全局唯一。

可选类预定义可以是包括在{}中任意文本。这个预定义,如果它存在话,将被直

接输出到生成类文献中,并且在类定义之前。

封闭尖括号不能用来分隔类,由于一种左尖括号在文献顶就很难跟踪与之匹配右

括号在文献时。相反,一种语法分析器类假定是持续,懂得遇到下一种类语句。

你可以指定语法分析器超类,它将作为被生成语法分析器超类。这个超类必要是

完整定义,在双引号中。它自己必要是antlr.LlkParser子类。例如

cIassTinyCParserextendsParser("antIr.debug.ParseTreeDebugParser");

词法分析器类定义

一种语法分析器类将导致一种懂得如何依照输入流标记来应用语法构造语法分

析器对象。为了执行词法分析,你需要指定一种词法分析器类,它描述了如何将

输入流分离成标记流。它语法类似于语法分析器类:

{optionalclasscodepreamble}

classYourLexerCJassex二endsLexer;

options

tokens

{optionalactionforinstancevars/methods]

lexerrules...

包括在词法分析器中词法规则在产生类中变成成员办法。每个语法文献(.g)只

包括一种词法分析器。语法分析器和词法分析器可以以任何顺序浮现。

可选类开头是括在{}中任意文本。这个开头某些,如果它存在,将输出到被生成

类文献中,在类定义之前。

你可以定义一种词法分析器超类,它可以被用来作为产生词法分析器超类。这个

超类将是完整定义(fully-qualified),在双引号中,它自身是

antIr.CharScanner子类。

树分析器定义

一种树分析器像语法分析器,不同是它解决二维由节点构成抽象语法树,而不是

解决由标记构成流。树分析潜必要唯一指定给语法分析器,除非规则定义中包括

特殊形式致使它递归下降到树中。同样,一种特定语法文献(.g)中仅仅包括一

种树分析器。

{optionalclasscodepreamble}

classYourTreeParserClassextendsTreeParser;

options

tokens

{optionalactionforinstancevars/methods}

treeparserrules...

你可以定义一种树分析器超类,它可以被用来作为产生树解析器超类。这个超类将是完整定

义(fully-qualified),在双引号中,它自身是antIr.TreeParser子类

注:以上资料均来于网络,鄙人收集整顿。

计算器及文法文献

06通讯软件06382027郑毅

本文重要简介了运用ANTLR达到计算器需求以及运用ANTLR生成C++描述分析程序。

一.运用ANTLR达到计算器需求

1.运算符:+,—,X,(,)

2.支持整型和浮点型

测试样例

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

下面就让咱们动手完毕一种计算器,:)

先搭个框架。文献名是calc.g

options{

language=''Cpp〃;

}

classCalcParserextencsParser;

classCalcLexerextendsLexer;

这些就是基本框架了。

options里设立language为〃Cpp〃,表达要生成C++代码。

CalcParser是咱们计算器语法解析类,继承ANTLR里Parser类。

同理,CalcLexer是词法分析类,继承ANTLR里Lexer类。

接着定义计算器词法规则。

一方面是运算符。

PLUS:

SUB:;

MUL:;

DIV:7';

LPAREN:;

RPAREN:y;

接着是操作数。

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

(法:$setType是ANTLR内置函数,用来设立token类型。就是当匹配到('0'..’9')*后,设

立token类型为INT,当发现背面跟着小数点和数字后,重新设立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

一种计算器语法程序就写好了。让咱们来生成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个文献“

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

测试用例:

$,/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

$

二.运用ANTLR生成C++描述分析程序

文法文献

文法就是语言辨认规则。它是ANTLR生成程序根据。文法文献是ANTLR核心,是程序员和

ANTLR进行交流接口。

文法文献编写基本是面向被解决问题。程序员只需要集中精力思考解决问题逻辑,而不是聃绊于

某种程序设计语言实现细节,因而减少了浮现错误也许性。

文法文献语法简介(转自ANTLR中文手册)

本文只是简朴地简介一种文法文献语法,详细内容可以参阅ANTLR有关文档。

文法文献普通涉及header块、options块、文法分析器类(parser)及规则定义、词法分扫

描器类(lexer)及token定义。其中最为重要是规则和token定义。

规则定义形式和编译理论中扩展巴科斯范式(EBNF)极为相似,涉及规则名、规则体、一种用

作结束标志分号和异常解决某些(可省略)。例如如下规则就描述了C语言中赋值语句话法:

assignmentstat:

id=expr;

9

其意义是:一条赋值语句是由一种id、一种等号、一种表达式和一种分号顺序构成。

Token定义办法与规则类似。例如如下token定义就表达一种十进制整数:

NUM:

9

其意义是:数字(NUM)第一字符是‘1'到'9'中一种字符,背面是。个或各种‘0'到'9'

之间字符。

需要注意一点是:规则名字必要是小写字母开始,而token名字则必要是大写字母开始.

设定ANTLR生成语言(转自ANTLR中文手册)

ANTLR有诸多选项,可以通过在文法文献中options块中进行设立,其中涉及ANTLR最后身

成语言。如果要生成C++描述分析器程序,就要如卜.设定:

options

language="Cpp";

//Otheroptions

}

language选项默认值是“Java”。如果您但愿生成程序是C#,将language设为“Csharp”

就可以了。

C++程序例子

下面就给出一种ANTLR生成C++描述分析器实例。该分析器功能是分析顾客输入一种算术表

达式,给出该表达式最后成果。在该表达式中容许浮现运算符除了加减乘除之外,还涉及求幕运

算符“八",以及sin、cos和tan三个三角函数。

编写文法文献

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等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论