参考手册
献给
项目领导和最高导师TerenceParr旧金山大学支持站点
YourViewoftheJavaUniverse初期代码获益于
JohnLilly,EmpathySoftwareC++代码生成器
PeterWells和RicKlarenC#代码生成
MichealJordan,KunleOdutola和AnthonyOguntimehin。
Python's方面的扩展来自于 WolfgangHäfelingerandMarqKole基础软件支撑来自Perforce: 世界上最好的源码控制系统之一感谢以下朋友贡献了他们的聪明才智 LoringCraymerMontyZukowski JimCokerScottStanchfield JohnMitchellChapmanFlack(UNICODE,流部分)关于Eclipse和NetBeans方面的源码改进来自于MarcovanMeegenandBrianSmithANTLR2.7.5版2004年12月22日 目录 前言ANTLR是什么.........................................................................................................................5
第1章ANTLR规范:元语言(Meta-Language).........................................................................6 1.1
元语言词汇表(Meta-LanguageVocabulary).................................................................61.2Header段(HeaderSection).........................................................................................12
1.3语法分析类的定义(PaserClassDefinitions)............................................................121.4词法分析类定义(LexcalAnalyzerClassDefinitions)...................................................131.5树分析类定义(Tree-parserClassDefinitions).............................................................141.6选项段(OptionSection).......................................................................................14
1.7记号段(TokensSection).......................................................................................14
1.8语法继承(GrammarInheritance)............................................................................161.9规则定义(RuleDefinitions).......................................................................................161.10原子的产生式元素(AtomicProductionElements)................................................191.11简单的产生式元素(SimpleProductionElements)................................................211.12产生式元素操作符(ProductionElementOperators)................................................221.13记号类............................................................................................................................24
1.14谓词................................................................................................................................24
1.15元素标签.........................................................................................................................25
1.16扩展的BNF规则元素(EBNFRuleElements).........................................................251.17语义动作的解释(InterpretationOfSemanticActions)..........................................261.18语义谓词(SemanticPredicates)...............................................................................261.19语法谓词(SyntacticPredicates).................................................................................28 1.19.1
固定深度的超前预测分析和语法谓词(Fixeddepthlookaheadandsyntacticpredicates)...................................................................................................................29
1.20ANTLR元语言文法(ANTLR-metaLanuageGrammar)...........................................30第2章使用ANTLR进行词法分析(LexicalAnalysiswithANTLR)..........................................302.1词法规则(LexicalRules)..............................................................................................31
2.1.1跳过字符(Skippingcharacters)......................................................................322.1.2词法分析规则的区别(Distinguishingbetweenlexerrules)..........................322.1.3返回值(Returnvalues).....................................................................................33
2.2含谓词的LL(k)词法分析..................................................................................................34
2.3关键字和字面值(Keywordsandliterals)....................................................................372.4常见的前缀(Commonprefixes)..................................................................................372.5记号定义文件(Tokendefinitionfiles).........................................................................382.6字符类(Characterclasses)...........................................................................................38
2.7记号属性(TokenAttributes)........................................................................................382.8词法超前分析和记号结束符(Lexicallookaheadandtheend-of-tokensymbol).......382.9扫描二进制文件(ScanningBinaryFiles).....................................................................43第3章ANTLR的树分析器...........................................................................................................44
3.1什么是树分析器?..........................................................................................................45
3.2可以分析什么类型的树?..............................................................................................45
3.3树的语法规则..................................................................................................................46
3.4句法断言..........................................................................................................................47 3.5
语义断言..........................................................................................................................48
3.6一个树遍历器的例子......................................................................................................48
3.7翻译.................................................................................................................................51
3.8一个树翻译的例子..........................................................................................................51
3.9检查/调试AST.................................................................................................................53
第4章记号流(TokenStreams)...............................................................................................54
4.1引言..................................................................................................................................54
4.2自由通过记号流...............................................................................................................55
4.3记号流过滤.......................................................................................................................56
4.4记号流分离.......................................................................................................................57 4.4.1
例子........................................................................................................................58
4.4.2过滤器实现............................................................................................................59
4.4.3如何使用这个过滤器............................................................................................60
4.4.4树的创建................................................................................................................61
4.4.5垃圾回收................................................................................................................62
4.4.6附注........................................................................................................................62
4.5记号流多路技术(又叫"词法分析器多状态").............................................................634.5.1多词法分析器........................................................................................................63
4.5.2词法分析器共享同一字符流................................................................................66
4.5.3分析多元记号流....................................................................................................66
4.5.4多记号流超前扫描的效果....................................................................................68
4.5.5多词法分析器vs调用另一条词法规则...............................................................684.6TokenStreamRewriteEngine简单的语法制导翻译........................................................704.7未来.................................................................................................................................70
第5章记号(token)词汇表......................................................................................................71
5.1引言..................................................................................................................................71
5.1.1ANTLR如何决定哪个词法符号是什么记号类型?
...............................................725.1.2为什么记号类型从4开始....................................................................................725.1.3ANTLR生成什么样的词汇表相关的文件............................................................725.1.4ANTLR怎样同步在同一文件和不同文件里文法的符号类型映射.....................725.2文法继承和词汇表...........................................................................................................74
5.3识别器生成顺序...............................................................................................................75
5.4词汇表的一些使用技巧...................................................................................................76
第6章错误处理及恢复...............................................................................................................78
6.1、ANLTR的异常体系结构................................................................................................78
6.2借助文法来修改默认的错误消息.................................................................................81
6.3解析异常处理.................................................................................................................81
6.4指定解析异常处理方法.................................................................................................82
6.5Lexer中的默认异常处理..............................................................................................83
第7章JavaRuntimeModel.......................................................................................................85
第8章C++RuntimeModel........................................................................................................85
第9章C#RuntimeModel...........................................................................................................85
第10章PythonRuntimeModel.................................................................................................85
第11章ANTLR树构建...................................................................................................................85 11.1
注释................................................................................................................................86
11.2控制AST构建...............................................................................................................86
11.3构建AST的语法注释...................................................................................................86 11.3.1
叶节点................................................................................................................86
11.3.2根节点...............................................................................................................86
11.3.3关闭标准树的构建...........................................................................................87
11.3.4树节点构建........................................................................................................88
11.3.5ASTAction换化..............................................................................................88
11.4执行解析创建树...........................................................................................................90
11.5AST工厂........................................................................................................................90
11.6异类ASTs.......................................................................................................................92
11.6.1一棵表达式树例子...........................................................................................93
11.6.2使用语法描述异构树.....................................................................................100
11.7AST(XML)序列化.....................................................................................................101
11.8AST枚举......................................................................................................................102
11.9一些例子.....................................................................................................................102
11.10标签子规则...............................................................................................................103
11.11引用节点...................................................................................................................107
11.12必需的AST功能与形式...........................................................................................107
第12章语法继承(GrammarInheritance)............................................................................110
12.1语法继承(GrammarInheritance)...........................................................................11012.2功能(Functionality).................................................................................................113
12.3父语法(Supergrammar)可以放置的位置..............................................................11512.4错误信息(ErrorMessages).....................................................................................116
第13章选项(Options)..........................................................................................................116
13.1文件、语法和规则的选项(File,Grammar,andRuleOptions)..............................11613.1.1ANTLR中支持的选项(OptionssupportedinANTLR)..................................11813.1.2language:设置生成的目标语言......................................................................12113.1.3k:设置lookahead(前瞻)的深度................................................................12113.1.4importVocab:初始化语法词汇表....................................................................12213.1.5exportVocab:指定导出词汇表的名称............................................................12313.1.6testLiterals:是否生成常量检测代码...............................................................12413.1.7defaultErrorHandler:设置默认的错误处理器................................................12513.1.8codeGenMakeSwitchThreshold:控制代码的生成...........................................12613.1.9codeGenBitsetTestThreshold:控制代码的生成...............................................12613.1.10buildAST:自动创建抽象语法树(AST).......................................................12713.1.11ASTLabelType:设置节点类型........................................................................12713.1.12charVocabulary:设置词法分析器的字符表..................................................12813.1.13warnWhenFollowAmbig...................................................................................129
13.2命令行选项(CommandLineOptions)....................................................................131 前言ANTLR是什么 ANTLR,语言识别的另一个工具(ANotherToolforLanguageRecognition),(前身是PCCTS)是一种语言工具,它提供了一个框架,可以通过包含Java,C++,或C#动作(action)的语法描述来构造语言识别器,编译器和解析器。
计算机语言的解析已经变成了一种非常普遍的工作。
传统的计算机语言的编译器和工具(如C或Java)仍旧需要被构造,它们的数量与需要开发的那些成千上万的小语言的识别工具和解析工具相比是相形见拙。
程序员为了解析数据格式,图形文件(如,PostScript,AutoCAD),文本文件(如,HTML,SGML等)而需要构造解析器。
ANTLR被设计出来处理所有这些转换工作。
TerenceParr从1989年就和他的同事开始了ANTLR方面的工作,在编译理论和语言工具构造方面做出了巨大的贡献,引发了基于LL(k)文法识别工具的苏醒。
这儿有一个按年份排列的软件历史和ANTLR/PCCTS。
的贡献者的列表。
这儿是ANTLR的软件授权。
可以获得入门教程,从ANTLRFAQat可以找到你的一些问题的答案。
可以参见和术语表。
第1章ANTLR规范:元语言(Meta-Language) ANTLR接受3类语法规范——语法分析器(parsers),词法分析器(lexers),和树分析器(tree-parsers)(也叫树遍历器tree-walkers)。
由于ANTLR使用LL(k)分析所有的3种语法变型,并且语法说明相似,因而产生的lexers和语法分析程序也很类似。
另外产生的识别程序可读性很好,你可以查看输出的内容来明白很多关于ANTLR的机理。
1.1元语言词汇表(Meta-LanguageVocabulary) 空格(Whitespace) 空格、tab符号和换行符是分隔符,在ANTLR中可以分隔诸如标识符这样的词汇符号,但除此之外,它们会被忽略。
例如,“FirstNameLastName”对ANTLR来说是两个记号引用(tokenreference)序列而不是一个记号(token),空格,然后再接着一个记号(token)。
注释(Comments) ANTLR接受C语言风格的块注释和C++风格的行注释。
在语法类和规则中,Java风格的文档注释也是可以接受的,在需要的时候,这些注释可以被传递给生成的输出文件。
例如: /**此文法识别简单的表达式*@作者TerenceParr*/ classExprParser; /**匹配因子*/factor:...; 字符集(Characters) 字符常量像Java中那样被确定。
它们包含八进制转义字符集(e.g.,'\377')、Unicode字符集(e.g.,'\uFF00')和能被Java识别的常用的字符转义('\b','\r','\t','\n','\f','\'','\\')。
在词法分析器规则中,单引号代表一个可以在输入字符流中能得到匹配的字符。
单引号的字符在语法分析器中是不被支持的。
文件结束标志(EOF) EOF记号(Token)可以用如下语法分析器规则自动生成:rule:(statement)+EOF; 你可以在词法分析器规则的动作(action)中检测EOF_CHAR://makesurenothingbutnewlineor//EOFispastthe#endifENDIF{booleaneol=false;} :"#endif"(('\n'|'\r'){eol=true;})?
{if(!
eol){if(LA
(1)==EOF_CHAR){error("EOF");}else{error("Invalidchars");}}} ;同时你可以把文件结束符当作一个字符来检测,但它实际上并不是一个字符,而是一种条件。
你应该在你的词法分析器语法中重载CharScanner。
uponEOF()函数: /**此方法由YourLexer.nextToken()当文法分析器*遇到EOF条件时调用。
*EOF并不是字符。
*当在处理语法谓词或一般的词法规则时到达EOF,并不会调用此方法,*因为可能会抛出IOException。
这是通常EOF条件的陷阱。
*在全部对先前所有的记号求值后,并且当分析程序请求在EOF后的*非EOF记号时,uponEOF()方法会被调用。
*你也许希望抛出记号或字符流异常,可能因为这是一个过早的EOF,*即事实上并未到达文件结尾,或者到达文件结尾后,想回到文件开始*重新引用文件。
*/ publicvoiduponEOF()throwsTokenStreamException,CharStreamException {} 文件结束的情形有点让人困惑(从2.7.1版本开始),因为Terence将-1当作一个字符而不是一个整数(-1是‘\uFFFF’...)。
字符串(Strings) 字符串常量是一个由双引号括起来的字符序列。
字符串中的字符可以是字符集中合法的转义字符(八进制,Unicode等)。
目前ANTLR并不允许Unicode出现在字符串常量中(你不得不用转义符),这是因为在anglr.g文件中设定charVocabulary选项为ascii。
在词法分析规则中,字符串被理解为在输入流中将要进行匹配的字符序列(例如:“for”等效于‘f’‘o’‘r’)。
在语法分析规则中,字符串代表记号(tokens),并且每个唯一的字符串被分派给一个记号类型。
然而,ANTLR并不创建词法分析规则来匹配字符串。
相反,ANTLR将这些字符串输入到一张与词法分析器相关联的字符表中。
在将记号传送给语法分析器前,ANTLR将产生检测代码来检测字符表中的每个记号的内容,每遇到一个匹配都会修改记号的类型。
你也可以执行手动检测――自动代码的生成由词法分析器选项控制。
你也许想在你的动作(action)中使用某个字符的记号类型值,例如在错误处理的同步部分。
对于那些只由字母字符组成的字符串来说,这些字符串的值将是一个形如LITERAL_xxx的常量值,这里xxx是这个记号的名字。
例如,字符串“return”将有一个LITERAL_return值与之关联。
你也可以为记号节(tokenssection)中使用的字符分派一个特定的标号。
记号引用(Tokenreferences) 以大写字符开头的标识符称为记号引用。
接下来的字符可以是任意字符、数字或下划线。
在语法分析规则中一个记号引用将引起匹配特定的记号。
在词法分析规则中的一个记号引用将引起一个匹配记号的字符的词法规则的调用。
换句话说,词法分析器中的记号引用被看作是一个规则引用。
记号定义(Tokendefinitions) 在词法分析器中的记号定义与语法规则的语法定义是相同的,但是指向记号而不是语法规则。
例如: classMyParserextendsParser;idList:(ID)+;//解析规则定义 classMyLexerextendsLexer; ID:('a'..'z')+;//记号定义 规则引用(Rulereferences) 以小写字母开头的标识符是对ANTLR的语法规则的引用。
接下来的字符可以是任意字母,数字或下划线。
词法规则不能引用语法规则。
动作(action)(Actions) 在花括号中的字符序列(可能是嵌套的)是语义动作(action)。
在字符串和字符中的花括号并不是动作(action)分隔符。
动作(action)参数(ArgumentsActions) 在方括号中的字符序列(可能是嵌套的)是动作(action)参数。
在字符串和字符中的方括号不是动作(action)分隔符。
在[]中的参数是用生成语言的语法定义的,并且用逗号分开。
codeBlock [intscope,Stringname]//输入参数 returns[intx] //返回参数 :...; //pass2args,getreturn testcblock {inty;} : y=cblock[
1,"John"] ; 许多人倾向于我们使用普通的括号来表示参数,但是括号在EBNF中已经被很好的用来定义语法组符号(grammaticalgroupingsymbols)。
符号(Symbols) 下面的表统计了在ANTLR中使用的标点符号和关键字。
符号 描述 (...)(...)*(...)+(...)?
{...}[...]{...}?
(...)=> |..~.=:;<...>classextendsreturnsoptions 子规则闭包子规则(零和多个)正闭包子规则(一个和多个)可选(零个和一个)语义动作(action)规则参数语义谓词语法谓词可选符范围符非通配符赋值标号符,规则开始规则结束元素选项语法类指定语法基类指定规则返回类型options段 tokensheadertokens tokens段header段token定义段 1.2Header段(HeaderSection) 一个header段包含了任何由ANTLR生成的代码在被输出到语法分析器前需要被替换的源码(译者注:形为类似include、import)。
这个主要用在C++的输出中,因为C++需要一些元素在引用之前必须被声明。
在Java中,这可以用来为最后的语法分析指定一些包文件。
一个header段看起来像下面这样:header{ sourcecodeinthelanguagegeneratedbyANTLR;}header段是语法文件的第一节。
根据选择的目标语言的不同,会有不同类型header段。
请参考相应的附录。
1.3语法分析类的定义(PaserClassDefinitions) 所有的语法规则必须与一个语法分析类关联。
一个语法文件(.g)只包含一个语法分析类的定义(以及词法分析程序和树分析程序),一个语法分析类的定义先于其选项(options)和规则定义。
语法文件中的语法分析类的定义通常如下所示:{optionalclasscodepreamble}classYourParserClassextendsParser;optionstokens{optionalactionforinstancevars/methods}parserrules... 当在面向对象语言中生成代码时,语法分析类将在输出中生成一个类,规则都会变成这个类的成员函数。
在C中,类将生成一个结构,一些名字分配(name-mangling)的算法将使生成的规则函数是全局唯一的。
前面的可选类可以是包含在{}中的任意文本。
前面的可选类,如果存在的话,将被直接输出到生成类文件中,并且在类定义之前。
封闭的花括号不能用来分隔类,因为它很难将一个文件底部的左花括号与这个文件顶部的花括号联系起来。
然而,一个语法分析类被认为是连续的,直到遇到下一个类的语句。
你可以指定语法分析器的基类,它将作为语法分析器中生成代码所需的基类。
这个基类必须完全可信并在双引号中,它自己必须是ANTLR.LlkParser的子类。
例如: classTinyCParserextendsParser("ANTLR.debug.ParseTreeDebugParser"); 1.4词法分析类定义(LexcalAnalyzerClassDefinitions) 一个语法分析器类将产生一个将相关语法结构应用于输入流中的记号集的语法分析对象。
为了执行词法分析,你需要指定一个词法分析类,它描述了如何将字符输入流分解成记号流。
它的语法类似于语法分析类: {optionalclasscodepreamble}classYourLexerClassextendsLexer;optionstokens{optionalactionforinstancevars/methods}lexerrules... 词法分析类中的词法规则成为生成类中的成员方法。
每个语法文件(.g)只包含一个词法分析类。
语法分析类和词法分析类可以以任意顺序出现在语法文件中。
前面的可选类(optionalclasscodepreamble)是在{}中的任意文本。
前面部分的可选类,如果存在,将输出到生成类的文件中,在类定义的之前。
你可以定义一个词法分析类的超类,它可以被用来作为生成词法分析类的超类。
这个超类必须是完全可信的(fully-qualified),并且在双引号中,而它本身是ANTLR.CharScanner子类。
1.5树分析类定义(Tree-parserClassDefinitions) 一个树分析器就像一个语法分析器,不同的是树分析器处理的是二维的由结点组成的抽象语法树(AbstractSyntaxTree),而不是处理由记号组成的记号流。
树分析器定义类似于语法分析类,不同的是规则定义中可能包含特殊形式来指示其递归下降树。
同样,一个特定的语法文件(.g)中只能包含一个树分析器。
{optionalclasscodepreamble}classYourTreeParserClassextendsTreeParser;optionstokens{optionalactionforinstancevars/methods}treeparserrules... 你可以定义一个树分析器的超类,它可以被用来作为生成树解析器的超类。
这个超类必须是完全可信的(fully-qualified),并且在双引号中,它本身是ANTLR.TreeParser子类。
1.6选项段(OptionSection) 并不是让程序员给分析程序生成器指定多个的命令行参数,文法中的选项段本身就可以达到此目的。
这种方法更受欢迎,因为它将需要的选项关联到文法而不ANTLR的调用。
这部分以options关键字开关,包含多个的选项/值赋值语句。
可以为每个文件、每个文法、每个规则和每个子规则指定一个选项段。
同时你也可以为一个元素指定一个选项段,例如记号引用。
1.7记号段(TokensSection) 如果你需要定义一个“虚拟”的记号,也即没有对应实际输入的符号与其关联,可以使用记号段来定义它们。
虚拟记号通常用于标识树结点,该类树节点用于标记或组织根据实际 输入生成的子树。
例如,你可能希望让EXPR结点成为每一个子树表达式的根结点,DECL表示子树的声明,这样在树的遍历时更容易引用它们。
因为EXPR没有对应的输入符号,你就不能在文法中通过引用来隐含地定义它。
使用如下方法来定义那些虚拟的记号。
tokens{EXPR;DECL; } 通常的语法是: tokenSpec:"tokens"LCURLY(tokenItemSEMI)+RCURLY ; tokenItem:TOKENASSIGNSTRING(tokensSpecOptions)?
|TOKEN(tokensSpecOptions)?
|STRING(tokensSpecOptions)?
; tokensSpecOptions:"<"idASSIGNoptionValue(SEMIidASSIGNoptionValue)*">"; 在token段中你还可以定义字面值,更重要的是,给它们赋与一个有效的标签,如下例所示。
tokens{KEYWORD_VOID="void";EXPR;DECL; INT="int";}以这种方式定义的字符串会被认为你已经在分析程序中对它们进行了引用。
如果文法导入了包含一个记号的词汇表,比如记号
T,然后你可以简单地通过在该文法的记号段中添加表达式T=“字符串常量”来将一个字符串常量关联到该记号类型(也即T)。
类似地,如果导入的词汇表中定义了一个字面值,比如"_int32",但没有相关联的标签,你可以在记号段中关联一个标签,例如INT32="_int32"。
你可以为在记号段中定义的记号定义选项。
目前可用的选项仅有AST=class-type-to-instantiate。
//定义需要创建的多个AST结点//可以在文法中实际引用时重载tokens{ PLUS;STAR;}
1.8语法继承(GrammarInheritance)
面向对象编程语言,例如C++和Java,允许你定义一个新的对象,当它与已经存在的对象有区别时,这种方法提供了很多好处。
“根据差异编程”节省了开发/测试的时间,并且将来对基类的修改也会自动传递给子类。
ANTLR支持语法继承,也就是基于一个基类来创建新的文法类的机制。
文法相关的语法结构和动作(action)均可以单独被修改。
1.9规则定义(RuleDefinitions) 因为ANTLR把词法分析看作是对字符流的分析,所以词法分析规则的语法规则可以同时讨论。
一般讨论规则时,我们使用术语atom代表输入流中的一个元素(可能是字符或记号)。
输入流中atoms的结构通过多个互相引用的规则来指定。
每一个规则有一个名字,一些可选的参数,一个可选"throws"子句,一个可选的初始化动作(action)(init-action),一个可选的返回值,和一个或多个可选项。
ANTLR规则的基本形式为: rulename:alternative_1|alternative_2...|alternative_n; 如果规则需要参数,使用如下形式: rulename[formalparameters]:...;如果你希望从规则返回一个值,使用returns关键字:rulenamereturn[typeid]:...;这里type是一个生成语言的类型指定符,id是生成语言的一个有效标识符。
Java中一个 单一的类型指定符能够满足大部分的应用,但是例如返回一个字符串的数组将需要一对方括号: idreturn[String[]s]:(ID{...})*; 同样,如果生成C++,返回类型可能会很复杂,例如: idreturn[char*[]s]:...;return语句的id会传递给输出代码。
动作(action)可能直接对此id赋值来设置返回值。
不要在动作(action)中使用return指令。
为了指明你的分析器(或树分析规则)可以抛出非ANTLR指定的异常,使用异常子句。
例如:下面是一个简单的通过规则指定的分析程序,该分析程序抛出MyException: classPextendsParser; athrowsMyException:A; ANTLR为规则a生成如下代码: publicfinalvoida()throwsRecognitionException,TokenStreamException,MyException {try{match(A);}catch(RecognitionExceptionex){reportError(ex);consume();consumeUntil(_tokenSet_0);} } 词法规则可能并不指定异常。
初始化动作(action)(Init-actions)在冒号前指定。
初始化动作(action) (Init-actions)与一般的动作(action)不同,因为它们总会执行,并推测模式(guess
mode)无关。
另外,它们适合于局部变量的定义。
rule{ init-action} :...; 词法分析规则(Lexerrules)。
词法分析文法中定义的规则必须有一个以大写字母开头的名字。
这些规则隐含地匹配输入流的字符,而不是记号流中的记号。
被引用的文法元素包括记号引用(tokenreferences)(隐含的词法分析规则引用),字符和字符串。
词法分析规则按照与语法分析规则完全相同的方式被处理,可能会指定参数和返回值,未来,词法分析 规则同样可以使用局部变量和递归使用。
更多关于词法规则请参考第2章ANTLR的词法分析。
语法分析规则(Parserrules)。
语法规则将结构应用于记号流,而词法规则将结构应用于字符流。
语法分析规则不能引用字符的字面值。
语法分析规则中双引号括起的字符会被认为是记号引用(tokenreferences)和迫使ANTLR将字符串常量存储在表中,该表可以由相关词法分析程序中的动作(action)来检查。
所有的语法分析规则必须以小写字母开头。
树分析规则(Tree-parserrules)。
树分析规则中,一个额外的特殊的语法允许被用来指定二维结构的匹配。
一个语法分析规则类似: rule:ABC; 意思是“依次匹配ABC”。
一个树分析规则可能会使用如下语法: rule:#(ABC); 意思是“匹配一个类型A的结点,然后下降它的子结点列表,匹配B和C”。
这个符号可以任意嵌套,可以在EBNF结构能够使用的地方使用#(…),例如: rule:#(AB#(CD(E)*)); 1.10原子的产生式元素(AtomicProductionElements) 字数常量(Characterliteral)。
字数常量仅仅可以在词法分析规则中被引用。
单个的字符会在字符输入流被匹配。
不需要转义正则表达式中的元符号,因为正则表达式并不是用来匹配词法原子符号的。
例如,当你指定字面字符来匹配时,‘{’并不需要转义符。
字数常量和字符串常量外的元符号被用来指定词法结构。
你所引用的所有字符会隐含地添加到全局字符词汇表中(具体请参考charVocabulary节)。
当你引用通配符时,如‘.’或‘~c’(除c外的任意字符),词汇表此时就会起作用。
你不需要特别地处理Unicode字符。
例如,下面是一个名为LETTER的规则,此规则匹配被认为是Unicode字母的字符: protectedLETTER :'\u0024'| '\u0041'..'\u005a'|'\u005f'|'\u0061'..'\u007a'|'\u00c0'..'\u00d6'|'\u00d8'..'\u00f6'|'\u00f8'..'\u00ff'|'\u0100'..'\u1fff'|'\u3040'..'\u318f'|'\u3300'..'\u337f'|'\u3400'..'\u3d2d'|'\u4e00'..'\u9fff'|'\uf900'..'\ufaff'; 你可以在其它规则中引用上述规则: ID:(LETTER)+; ANTLR将生成代码来检查输入字符而不是lexer对象生成的字符集。
字符串常量(Stringliteral)。
语法分析规则中对字符串常量的引用会为此字符串常量定义一个记号类型,并且导致字符串常量在相关lexer的哈希表中被替换。
相关的lexer将会自动检查每一个被匹配的记号,以查看该记号是否匹配一个字面值。
如果匹配,此记号的记号类型会被设为从语法分析程序(parser)导入的为该字面值定义的记号类型。
你可以关掉自动检查,然后在一个类似ID的简单规则手动检查。
在语法分析程序中对字符串常量的引用会被添加一个元素类型的后缀,具体参考下面的记号引用章节。
词法规则中字符串的引用会特定的字符序列,是一种简写方式。
例如,考虑下面的词法规则定义: BEGIN:"begin"; 这个规则可以以另外一种功能相同的方式重写: BEGIN:'b''e''g''i''n'; 没有必要转义正则表达式中的符号,因为正则表达式并不是用来匹配词法分析程序(lexer)中字符。
记号引用(TokenReference)。
语法分析规则中的记号引用意味着你希望使用特定的记号类型来识别一个记号。
实际上这并不会调用相关的词法规则——词法分析阶段将记号流传递给语法分析程序(parser)。
词法分析规则中的记号引用意味着对该规则的一个调用方法,执行与语法分析程序中的规则引用相同的语义分析。
这样的话,你可以指定规则参数和返回值。
详情请参考下一规则引用章节。
你同样可以指定记号引用上的选项。
例如,下面的规则指引ANTLR从INT的引用创建INTNode对象: i:INT;
该语法的选项为:
Python's方面的扩展来自于 WolfgangHäfelingerandMarqKole基础软件支撑来自Perforce: 世界上最好的源码控制系统之一感谢以下朋友贡献了他们的聪明才智 LoringCraymerMontyZukowski JimCokerScottStanchfield JohnMitchellChapmanFlack(UNICODE,流部分)关于Eclipse和NetBeans方面的源码改进来自于MarcovanMeegenandBrianSmithANTLR2.7.5版2004年12月22日 目录 前言ANTLR是什么.........................................................................................................................5
第1章ANTLR规范:元语言(Meta-Language).........................................................................6 1.1
元语言词汇表(Meta-LanguageVocabulary).................................................................61.2Header段(HeaderSection).........................................................................................12
1.3语法分析类的定义(PaserClassDefinitions)............................................................121.4词法分析类定义(LexcalAnalyzerClassDefinitions)...................................................131.5树分析类定义(Tree-parserClassDefinitions).............................................................141.6选项段(OptionSection).......................................................................................14
1.7记号段(TokensSection).......................................................................................14
1.8语法继承(GrammarInheritance)............................................................................161.9规则定义(RuleDefinitions).......................................................................................161.10原子的产生式元素(AtomicProductionElements)................................................191.11简单的产生式元素(SimpleProductionElements)................................................211.12产生式元素操作符(ProductionElementOperators)................................................221.13记号类............................................................................................................................24
1.14谓词................................................................................................................................24
1.15元素标签.........................................................................................................................25
1.16扩展的BNF规则元素(EBNFRuleElements).........................................................251.17语义动作的解释(InterpretationOfSemanticActions)..........................................261.18语义谓词(SemanticPredicates)...............................................................................261.19语法谓词(SyntacticPredicates).................................................................................28 1.19.1
固定深度的超前预测分析和语法谓词(Fixeddepthlookaheadandsyntacticpredicates)...................................................................................................................29
1.20ANTLR元语言文法(ANTLR-metaLanuageGrammar)...........................................30第2章使用ANTLR进行词法分析(LexicalAnalysiswithANTLR)..........................................302.1词法规则(LexicalRules)..............................................................................................31
2.1.1跳过字符(Skippingcharacters)......................................................................322.1.2词法分析规则的区别(Distinguishingbetweenlexerrules)..........................322.1.3返回值(Returnvalues).....................................................................................33
2.2含谓词的LL(k)词法分析..................................................................................................34
2.3关键字和字面值(Keywordsandliterals)....................................................................372.4常见的前缀(Commonprefixes)..................................................................................372.5记号定义文件(Tokendefinitionfiles).........................................................................382.6字符类(Characterclasses)...........................................................................................38
2.7记号属性(TokenAttributes)........................................................................................382.8词法超前分析和记号结束符(Lexicallookaheadandtheend-of-tokensymbol).......382.9扫描二进制文件(ScanningBinaryFiles).....................................................................43第3章ANTLR的树分析器...........................................................................................................44
3.1什么是树分析器?..........................................................................................................45
3.2可以分析什么类型的树?..............................................................................................45
3.3树的语法规则..................................................................................................................46
3.4句法断言..........................................................................................................................47 3.5
语义断言..........................................................................................................................48
3.6一个树遍历器的例子......................................................................................................48
3.7翻译.................................................................................................................................51
3.8一个树翻译的例子..........................................................................................................51
3.9检查/调试AST.................................................................................................................53
第4章记号流(TokenStreams)...............................................................................................54
4.1引言..................................................................................................................................54
4.2自由通过记号流...............................................................................................................55
4.3记号流过滤.......................................................................................................................56
4.4记号流分离.......................................................................................................................57 4.4.1
例子........................................................................................................................58
4.4.2过滤器实现............................................................................................................59
4.4.3如何使用这个过滤器............................................................................................60
4.4.4树的创建................................................................................................................61
4.4.5垃圾回收................................................................................................................62
4.4.6附注........................................................................................................................62
4.5记号流多路技术(又叫"词法分析器多状态").............................................................634.5.1多词法分析器........................................................................................................63
4.5.2词法分析器共享同一字符流................................................................................66
4.5.3分析多元记号流....................................................................................................66
4.5.4多记号流超前扫描的效果....................................................................................68
4.5.5多词法分析器vs调用另一条词法规则...............................................................684.6TokenStreamRewriteEngine简单的语法制导翻译........................................................704.7未来.................................................................................................................................70
第5章记号(token)词汇表......................................................................................................71
5.1引言..................................................................................................................................71
5.1.1ANTLR如何决定哪个词法符号是什么记号类型?
...............................................725.1.2为什么记号类型从4开始....................................................................................725.1.3ANTLR生成什么样的词汇表相关的文件............................................................725.1.4ANTLR怎样同步在同一文件和不同文件里文法的符号类型映射.....................725.2文法继承和词汇表...........................................................................................................74
5.3识别器生成顺序...............................................................................................................75
5.4词汇表的一些使用技巧...................................................................................................76
第6章错误处理及恢复...............................................................................................................78
6.1、ANLTR的异常体系结构................................................................................................78
6.2借助文法来修改默认的错误消息.................................................................................81
6.3解析异常处理.................................................................................................................81
6.4指定解析异常处理方法.................................................................................................82
6.5Lexer中的默认异常处理..............................................................................................83
第7章JavaRuntimeModel.......................................................................................................85
第8章C++RuntimeModel........................................................................................................85
第9章C#RuntimeModel...........................................................................................................85
第10章PythonRuntimeModel.................................................................................................85
第11章ANTLR树构建...................................................................................................................85 11.1
注释................................................................................................................................86
11.2控制AST构建...............................................................................................................86
11.3构建AST的语法注释...................................................................................................86 11.3.1
叶节点................................................................................................................86
11.3.2根节点...............................................................................................................86
11.3.3关闭标准树的构建...........................................................................................87
11.3.4树节点构建........................................................................................................88
11.3.5ASTAction换化..............................................................................................88
11.4执行解析创建树...........................................................................................................90
11.5AST工厂........................................................................................................................90
11.6异类ASTs.......................................................................................................................92
11.6.1一棵表达式树例子...........................................................................................93
11.6.2使用语法描述异构树.....................................................................................100
11.7AST(XML)序列化.....................................................................................................101
11.8AST枚举......................................................................................................................102
11.9一些例子.....................................................................................................................102
11.10标签子规则...............................................................................................................103
11.11引用节点...................................................................................................................107
11.12必需的AST功能与形式...........................................................................................107
第12章语法继承(GrammarInheritance)............................................................................110
12.1语法继承(GrammarInheritance)...........................................................................11012.2功能(Functionality).................................................................................................113
12.3父语法(Supergrammar)可以放置的位置..............................................................11512.4错误信息(ErrorMessages).....................................................................................116
第13章选项(Options)..........................................................................................................116
13.1文件、语法和规则的选项(File,Grammar,andRuleOptions)..............................11613.1.1ANTLR中支持的选项(OptionssupportedinANTLR)..................................11813.1.2language:设置生成的目标语言......................................................................12113.1.3k:设置lookahead(前瞻)的深度................................................................12113.1.4importVocab:初始化语法词汇表....................................................................12213.1.5exportVocab:指定导出词汇表的名称............................................................12313.1.6testLiterals:是否生成常量检测代码...............................................................12413.1.7defaultErrorHandler:设置默认的错误处理器................................................12513.1.8codeGenMakeSwitchThreshold:控制代码的生成...........................................12613.1.9codeGenBitsetTestThreshold:控制代码的生成...............................................12613.1.10buildAST:自动创建抽象语法树(AST).......................................................12713.1.11ASTLabelType:设置节点类型........................................................................12713.1.12charVocabulary:设置词法分析器的字符表..................................................12813.1.13warnWhenFollowAmbig...................................................................................129
13.2命令行选项(CommandLineOptions)....................................................................131 前言ANTLR是什么 ANTLR,语言识别的另一个工具(ANotherToolforLanguageRecognition),(前身是PCCTS)是一种语言工具,它提供了一个框架,可以通过包含Java,C++,或C#动作(action)的语法描述来构造语言识别器,编译器和解析器。
计算机语言的解析已经变成了一种非常普遍的工作。
传统的计算机语言的编译器和工具(如C或Java)仍旧需要被构造,它们的数量与需要开发的那些成千上万的小语言的识别工具和解析工具相比是相形见拙。
程序员为了解析数据格式,图形文件(如,PostScript,AutoCAD),文本文件(如,HTML,SGML等)而需要构造解析器。
ANTLR被设计出来处理所有这些转换工作。
TerenceParr从1989年就和他的同事开始了ANTLR方面的工作,在编译理论和语言工具构造方面做出了巨大的贡献,引发了基于LL(k)文法识别工具的苏醒。
这儿有一个按年份排列的软件历史和ANTLR/PCCTS。
的贡献者的列表。
这儿是ANTLR的软件授权。
可以获得入门教程,从ANTLRFAQat可以找到你的一些问题的答案。
可以参见和术语表。
第1章ANTLR规范:元语言(Meta-Language) ANTLR接受3类语法规范——语法分析器(parsers),词法分析器(lexers),和树分析器(tree-parsers)(也叫树遍历器tree-walkers)。
由于ANTLR使用LL(k)分析所有的3种语法变型,并且语法说明相似,因而产生的lexers和语法分析程序也很类似。
另外产生的识别程序可读性很好,你可以查看输出的内容来明白很多关于ANTLR的机理。
1.1元语言词汇表(Meta-LanguageVocabulary) 空格(Whitespace) 空格、tab符号和换行符是分隔符,在ANTLR中可以分隔诸如标识符这样的词汇符号,但除此之外,它们会被忽略。
例如,“FirstNameLastName”对ANTLR来说是两个记号引用(tokenreference)序列而不是一个记号(token),空格,然后再接着一个记号(token)。
注释(Comments) ANTLR接受C语言风格的块注释和C++风格的行注释。
在语法类和规则中,Java风格的文档注释也是可以接受的,在需要的时候,这些注释可以被传递给生成的输出文件。
例如: /**此文法识别简单的表达式*@作者TerenceParr*/ classExprParser; /**匹配因子*/factor:...; 字符集(Characters) 字符常量像Java中那样被确定。
它们包含八进制转义字符集(e.g.,'\377')、Unicode字符集(e.g.,'\uFF00')和能被Java识别的常用的字符转义('\b','\r','\t','\n','\f','\'','\\')。
在词法分析器规则中,单引号代表一个可以在输入字符流中能得到匹配的字符。
单引号的字符在语法分析器中是不被支持的。
文件结束标志(EOF) EOF记号(Token)可以用如下语法分析器规则自动生成:rule:(statement)+EOF; 你可以在词法分析器规则的动作(action)中检测EOF_CHAR://makesurenothingbutnewlineor//EOFispastthe#endifENDIF{booleaneol=false;} :"#endif"(('\n'|'\r'){eol=true;})?
{if(!
eol){if(LA
(1)==EOF_CHAR){error("EOF");}else{error("Invalidchars");}}} ;同时你可以把文件结束符当作一个字符来检测,但它实际上并不是一个字符,而是一种条件。
你应该在你的词法分析器语法中重载CharScanner。
uponEOF()函数: /**此方法由YourLexer.nextToken()当文法分析器*遇到EOF条件时调用。
*EOF并不是字符。
*当在处理语法谓词或一般的词法规则时到达EOF,并不会调用此方法,*因为可能会抛出IOException。
这是通常EOF条件的陷阱。
*在全部对先前所有的记号求值后,并且当分析程序请求在EOF后的*非EOF记号时,uponEOF()方法会被调用。
*你也许希望抛出记号或字符流异常,可能因为这是一个过早的EOF,*即事实上并未到达文件结尾,或者到达文件结尾后,想回到文件开始*重新引用文件。
*/ publicvoiduponEOF()throwsTokenStreamException,CharStreamException {} 文件结束的情形有点让人困惑(从2.7.1版本开始),因为Terence将-1当作一个字符而不是一个整数(-1是‘\uFFFF’...)。
字符串(Strings) 字符串常量是一个由双引号括起来的字符序列。
字符串中的字符可以是字符集中合法的转义字符(八进制,Unicode等)。
目前ANTLR并不允许Unicode出现在字符串常量中(你不得不用转义符),这是因为在anglr.g文件中设定charVocabulary选项为ascii。
在词法分析规则中,字符串被理解为在输入流中将要进行匹配的字符序列(例如:“for”等效于‘f’‘o’‘r’)。
在语法分析规则中,字符串代表记号(tokens),并且每个唯一的字符串被分派给一个记号类型。
然而,ANTLR并不创建词法分析规则来匹配字符串。
相反,ANTLR将这些字符串输入到一张与词法分析器相关联的字符表中。
在将记号传送给语法分析器前,ANTLR将产生检测代码来检测字符表中的每个记号的内容,每遇到一个匹配都会修改记号的类型。
你也可以执行手动检测――自动代码的生成由词法分析器选项控制。
你也许想在你的动作(action)中使用某个字符的记号类型值,例如在错误处理的同步部分。
对于那些只由字母字符组成的字符串来说,这些字符串的值将是一个形如LITERAL_xxx的常量值,这里xxx是这个记号的名字。
例如,字符串“return”将有一个LITERAL_return值与之关联。
你也可以为记号节(tokenssection)中使用的字符分派一个特定的标号。
记号引用(Tokenreferences) 以大写字符开头的标识符称为记号引用。
接下来的字符可以是任意字符、数字或下划线。
在语法分析规则中一个记号引用将引起匹配特定的记号。
在词法分析规则中的一个记号引用将引起一个匹配记号的字符的词法规则的调用。
换句话说,词法分析器中的记号引用被看作是一个规则引用。
记号定义(Tokendefinitions) 在词法分析器中的记号定义与语法规则的语法定义是相同的,但是指向记号而不是语法规则。
例如: classMyParserextendsParser;idList:(ID)+;//解析规则定义 classMyLexerextendsLexer; ID:('a'..'z')+;//记号定义 规则引用(Rulereferences) 以小写字母开头的标识符是对ANTLR的语法规则的引用。
接下来的字符可以是任意字母,数字或下划线。
词法规则不能引用语法规则。
动作(action)(Actions) 在花括号中的字符序列(可能是嵌套的)是语义动作(action)。
在字符串和字符中的花括号并不是动作(action)分隔符。
动作(action)参数(ArgumentsActions) 在方括号中的字符序列(可能是嵌套的)是动作(action)参数。
在字符串和字符中的方括号不是动作(action)分隔符。
在[]中的参数是用生成语言的语法定义的,并且用逗号分开。
codeBlock [intscope,Stringname]//输入参数 returns[intx] //返回参数 :...; //pass2args,getreturn testcblock {inty;} : y=cblock[
1,"John"] ; 许多人倾向于我们使用普通的括号来表示参数,但是括号在EBNF中已经被很好的用来定义语法组符号(grammaticalgroupingsymbols)。
符号(Symbols) 下面的表统计了在ANTLR中使用的标点符号和关键字。
符号 描述 (...)(...)*(...)+(...)?
{...}[...]{...}?
(...)=> |..~.=:;<...>classextendsreturnsoptions 子规则闭包子规则(零和多个)正闭包子规则(一个和多个)可选(零个和一个)语义动作(action)规则参数语义谓词语法谓词可选符范围符非通配符赋值标号符,规则开始规则结束元素选项语法类指定语法基类指定规则返回类型options段 tokensheadertokens tokens段header段token定义段 1.2Header段(HeaderSection) 一个header段包含了任何由ANTLR生成的代码在被输出到语法分析器前需要被替换的源码(译者注:形为类似include、import)。
这个主要用在C++的输出中,因为C++需要一些元素在引用之前必须被声明。
在Java中,这可以用来为最后的语法分析指定一些包文件。
一个header段看起来像下面这样:header{ sourcecodeinthelanguagegeneratedbyANTLR;}header段是语法文件的第一节。
根据选择的目标语言的不同,会有不同类型header段。
请参考相应的附录。
1.3语法分析类的定义(PaserClassDefinitions) 所有的语法规则必须与一个语法分析类关联。
一个语法文件(.g)只包含一个语法分析类的定义(以及词法分析程序和树分析程序),一个语法分析类的定义先于其选项(options)和规则定义。
语法文件中的语法分析类的定义通常如下所示:{optionalclasscodepreamble}classYourParserClassextendsParser;optionstokens{optionalactionforinstancevars/methods}parserrules... 当在面向对象语言中生成代码时,语法分析类将在输出中生成一个类,规则都会变成这个类的成员函数。
在C中,类将生成一个结构,一些名字分配(name-mangling)的算法将使生成的规则函数是全局唯一的。
前面的可选类可以是包含在{}中的任意文本。
前面的可选类,如果存在的话,将被直接输出到生成类文件中,并且在类定义之前。
封闭的花括号不能用来分隔类,因为它很难将一个文件底部的左花括号与这个文件顶部的花括号联系起来。
然而,一个语法分析类被认为是连续的,直到遇到下一个类的语句。
你可以指定语法分析器的基类,它将作为语法分析器中生成代码所需的基类。
这个基类必须完全可信并在双引号中,它自己必须是ANTLR.LlkParser的子类。
例如: classTinyCParserextendsParser("ANTLR.debug.ParseTreeDebugParser"); 1.4词法分析类定义(LexcalAnalyzerClassDefinitions) 一个语法分析器类将产生一个将相关语法结构应用于输入流中的记号集的语法分析对象。
为了执行词法分析,你需要指定一个词法分析类,它描述了如何将字符输入流分解成记号流。
它的语法类似于语法分析类: {optionalclasscodepreamble}classYourLexerClassextendsLexer;optionstokens{optionalactionforinstancevars/methods}lexerrules... 词法分析类中的词法规则成为生成类中的成员方法。
每个语法文件(.g)只包含一个词法分析类。
语法分析类和词法分析类可以以任意顺序出现在语法文件中。
前面的可选类(optionalclasscodepreamble)是在{}中的任意文本。
前面部分的可选类,如果存在,将输出到生成类的文件中,在类定义的之前。
你可以定义一个词法分析类的超类,它可以被用来作为生成词法分析类的超类。
这个超类必须是完全可信的(fully-qualified),并且在双引号中,而它本身是ANTLR.CharScanner子类。
1.5树分析类定义(Tree-parserClassDefinitions) 一个树分析器就像一个语法分析器,不同的是树分析器处理的是二维的由结点组成的抽象语法树(AbstractSyntaxTree),而不是处理由记号组成的记号流。
树分析器定义类似于语法分析类,不同的是规则定义中可能包含特殊形式来指示其递归下降树。
同样,一个特定的语法文件(.g)中只能包含一个树分析器。
{optionalclasscodepreamble}classYourTreeParserClassextendsTreeParser;optionstokens{optionalactionforinstancevars/methods}treeparserrules... 你可以定义一个树分析器的超类,它可以被用来作为生成树解析器的超类。
这个超类必须是完全可信的(fully-qualified),并且在双引号中,它本身是ANTLR.TreeParser子类。
1.6选项段(OptionSection) 并不是让程序员给分析程序生成器指定多个的命令行参数,文法中的选项段本身就可以达到此目的。
这种方法更受欢迎,因为它将需要的选项关联到文法而不ANTLR的调用。
这部分以options关键字开关,包含多个的选项/值赋值语句。
可以为每个文件、每个文法、每个规则和每个子规则指定一个选项段。
同时你也可以为一个元素指定一个选项段,例如记号引用。
1.7记号段(TokensSection) 如果你需要定义一个“虚拟”的记号,也即没有对应实际输入的符号与其关联,可以使用记号段来定义它们。
虚拟记号通常用于标识树结点,该类树节点用于标记或组织根据实际 输入生成的子树。
例如,你可能希望让EXPR结点成为每一个子树表达式的根结点,DECL表示子树的声明,这样在树的遍历时更容易引用它们。
因为EXPR没有对应的输入符号,你就不能在文法中通过引用来隐含地定义它。
使用如下方法来定义那些虚拟的记号。
tokens{EXPR;DECL; } 通常的语法是: tokenSpec:"tokens"LCURLY(tokenItemSEMI)+RCURLY ; tokenItem:TOKENASSIGNSTRING(tokensSpecOptions)?
|TOKEN(tokensSpecOptions)?
|STRING(tokensSpecOptions)?
; tokensSpecOptions:"<"idASSIGNoptionValue(SEMIidASSIGNoptionValue)*">"; 在token段中你还可以定义字面值,更重要的是,给它们赋与一个有效的标签,如下例所示。
tokens{KEYWORD_VOID="void";EXPR;DECL; INT="int";}以这种方式定义的字符串会被认为你已经在分析程序中对它们进行了引用。
如果文法导入了包含一个记号的词汇表,比如记号
T,然后你可以简单地通过在该文法的记号段中添加表达式T=“字符串常量”来将一个字符串常量关联到该记号类型(也即T)。
类似地,如果导入的词汇表中定义了一个字面值,比如"_int32",但没有相关联的标签,你可以在记号段中关联一个标签,例如INT32="_int32"。
你可以为在记号段中定义的记号定义选项。
目前可用的选项仅有AST=class-type-to-instantiate。
//定义需要创建的多个AST结点//可以在文法中实际引用时重载tokens{ PLUS
“根据差异编程”节省了开发/测试的时间,并且将来对基类的修改也会自动传递给子类。
ANTLR支持语法继承,也就是基于一个基类来创建新的文法类的机制。
文法相关的语法结构和动作(action)均可以单独被修改。
1.9规则定义(RuleDefinitions) 因为ANTLR把词法分析看作是对字符流的分析,所以词法分析规则的语法规则可以同时讨论。
一般讨论规则时,我们使用术语atom代表输入流中的一个元素(可能是字符或记号)。
输入流中atoms的结构通过多个互相引用的规则来指定。
每一个规则有一个名字,一些可选的参数,一个可选"throws"子句,一个可选的初始化动作(action)(init-action),一个可选的返回值,和一个或多个可选项。
ANTLR规则的基本形式为: rulename:alternative_1|alternative_2...|alternative_n; 如果规则需要参数,使用如下形式: rulename[formalparameters]:...;如果你希望从规则返回一个值,使用returns关键字:rulenamereturn[typeid]:...;这里type是一个生成语言的类型指定符,id是生成语言的一个有效标识符。
Java中一个 单一的类型指定符能够满足大部分的应用,但是例如返回一个字符串的数组将需要一对方括号: idreturn[String[]s]:(ID{...})*; 同样,如果生成C++,返回类型可能会很复杂,例如: idreturn[char*[]s]:...;return语句的id会传递给输出代码。
动作(action)可能直接对此id赋值来设置返回值。
不要在动作(action)中使用return指令。
为了指明你的分析器(或树分析规则)可以抛出非ANTLR指定的异常,使用异常子句。
例如:下面是一个简单的通过规则指定的分析程序,该分析程序抛出MyException: classPextendsParser; athrowsMyException:A; ANTLR为规则a生成如下代码: publicfinalvoida()throwsRecognitionException,TokenStreamException,MyException {try{match(A);}catch(RecognitionExceptionex){reportError(ex);consume();consumeUntil(_tokenSet_0);} } 词法规则可能并不指定异常。
初始化动作(action)(Init-actions)在冒号前指定。
初始化动作(action) (Init-actions)与一般的动作(action)不同,因为它们总会执行,并推测模式(guess
mode)无关。
另外,它们适合于局部变量的定义。
rule{ init-action} :...; 词法分析规则(Lexerrules)。
词法分析文法中定义的规则必须有一个以大写字母开头的名字。
这些规则隐含地匹配输入流的字符,而不是记号流中的记号。
被引用的文法元素包括记号引用(tokenreferences)(隐含的词法分析规则引用),字符和字符串。
词法分析规则按照与语法分析规则完全相同的方式被处理,可能会指定参数和返回值,未来,词法分析 规则同样可以使用局部变量和递归使用。
更多关于词法规则请参考第2章ANTLR的词法分析。
语法分析规则(Parserrules)。
语法规则将结构应用于记号流,而词法规则将结构应用于字符流。
语法分析规则不能引用字符的字面值。
语法分析规则中双引号括起的字符会被认为是记号引用(tokenreferences)和迫使ANTLR将字符串常量存储在表中,该表可以由相关词法分析程序中的动作(action)来检查。
所有的语法分析规则必须以小写字母开头。
树分析规则(Tree-parserrules)。
树分析规则中,一个额外的特殊的语法允许被用来指定二维结构的匹配。
一个语法分析规则类似: rule:ABC; 意思是“依次匹配ABC”。
一个树分析规则可能会使用如下语法: rule:#(ABC); 意思是“匹配一个类型A的结点,然后下降它的子结点列表,匹配B和C”。
这个符号可以任意嵌套,可以在EBNF结构能够使用的地方使用#(…),例如: rule:#(AB#(CD(E)*)); 1.10原子的产生式元素(AtomicProductionElements) 字数常量(Characterliteral)。
字数常量仅仅可以在词法分析规则中被引用。
单个的字符会在字符输入流被匹配。
不需要转义正则表达式中的元符号,因为正则表达式并不是用来匹配词法原子符号的。
例如,当你指定字面字符来匹配时,‘{’并不需要转义符。
字数常量和字符串常量外的元符号被用来指定词法结构。
你所引用的所有字符会隐含地添加到全局字符词汇表中(具体请参考charVocabulary节)。
当你引用通配符时,如‘.’或‘~c’(除c外的任意字符),词汇表此时就会起作用。
你不需要特别地处理Unicode字符。
例如,下面是一个名为LETTER的规则,此规则匹配被认为是Unicode字母的字符: protectedLETTER :'\u0024'| '\u0041'..'\u005a'|'\u005f'|'\u0061'..'\u007a'|'\u00c0'..'\u00d6'|'\u00d8'..'\u00f6'|'\u00f8'..'\u00ff'|'\u0100'..'\u1fff'|'\u3040'..'\u318f'|'\u3300'..'\u337f'|'\u3400'..'\u3d2d'|'\u4e00'..'\u9fff'|'\uf900'..'\ufaff'; 你可以在其它规则中引用上述规则: ID:(LETTER)+; ANTLR将生成代码来检查输入字符而不是lexer对象生成的字符集。
字符串常量(Stringliteral)。
语法分析规则中对字符串常量的引用会为此字符串常量定义一个记号类型,并且导致字符串常量在相关lexer的哈希表中被替换。
相关的lexer将会自动检查每一个被匹配的记号,以查看该记号是否匹配一个字面值。
如果匹配,此记号的记号类型会被设为从语法分析程序(parser)导入的为该字面值定义的记号类型。
你可以关掉自动检查,然后在一个类似ID的简单规则手动检查。
在语法分析程序中对字符串常量的引用会被添加一个元素类型的后缀,具体参考下面的记号引用章节。
词法规则中字符串的引用会特定的字符序列,是一种简写方式。
例如,考虑下面的词法规则定义: BEGIN:"begin"; 这个规则可以以另外一种功能相同的方式重写: BEGIN:'b''e''g''i''n'; 没有必要转义正则表达式中的符号,因为正则表达式并不是用来匹配词法分析程序(lexer)中字符。
记号引用(TokenReference)。
语法分析规则中的记号引用意味着你希望使用特定的记号类型来识别一个记号。
实际上这并不会调用相关的词法规则——词法分析阶段将记号流传递给语法分析程序(parser)。
词法分析规则中的记号引用意味着对该规则的一个调用方法,执行与语法分析程序中的规则引用相同的语义分析。
这样的话,你可以指定规则参数和返回值。
详情请参考下一规则引用章节。
你同样可以指定记号引用上的选项。
例如,下面的规则指引ANTLR从INT的引用创建INTNode对象: i:INT
声明:
该资讯来自于互联网网友发布,如有侵犯您的权益请联系我们。