快速业务通道

一个简单的语言的语法(二):ANTLR的重写规则 - 编程入门网

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-06-14
ons { greedy = false; } : . )* ''*/'' { $channel = HIDDEN; } 301. ; 302. 303.LineComment 304. : ''//'' ~ (''\n''|''\r'')* ''\r''? ''\n'' { $channel = HIDDEN; } 305. ;

一个简单的语言的语法(二):ANTLR的重写规则(2)

时间:2011-10-07 javaeye RednaxelaFX

稍微说明一下修改点。应该观察到lexer rules部分是完全没有改变的,修改的主要是一些选项和 parser rules。

首先,在文件的开头添加了一组选项:

Java代码

options {
	language = Java;
	output = AST;
	ASTLabelType = CommonTree;
}

ANTLR会知道应该使用生成AST的模式,以CommonTree作为AST的节点类型,并以Java作为生成的解析器 源码的语言。上一篇是在ANTLRWorks里编辑和实验语法的,这次我们需要生成实际能运行的解析器,所以 需要指定这些选项(默认就是生成Java源码,不过后续文章中我应该会换用CSharp2目标。这个以后再说 )。

接下来,可以看到除了原本在lexer rules里定义的实际存在的token类型之外,这次我们在语法文件 的开头还增加了一组虚拟的token类型。这些token类型是为了让生成出来的抽象语法树易于解析而添加的 。

例如,观察VAR_DECL这个token类型。在原本的语法中,没有任何关键字能清楚的标识出当前处理的内 容是一个变量声明。为了方便后续分析,我们可以“制造”出一个虚构的token作为一个变量声明语句的 根元素,然后以变量的类型、标识符和初始值为子元素。

然后就是最重要的部分,树重写规则了。有两种形式来表述树重写规则:一是直接在原本的语法规则 上添加树生成用的运算符(^和!),二是在原本的语法规则后添加一个箭头("->"),并在箭头后显 式指定需要生成的节点的结构。

看两个例子:

while语句。原本的语法是:

Java代码

whileStatement : ''while'' ''('' expression '')'' statement ;

这里我们想让生成出来的子树以''while''为根节点,以expression和statement为子节点。

可以直接在该语法上添加树生成运算符:在某个元素后加上帽子符号(''^'')来表示它是生成的子树的 根节点,在某个元素后加上叹号(''!'')来表示生成的子树中应该忽略该元素。于是修改得到的语法是:

Java代码

whileStatement : ''while''^ ''(''! expression '')''! statement ;

也可以显式指定树重写规则。一棵子树用这种方式来表示:

Java代码

^( root element1 element2 ... )

这里我们要的就是:

Java代码

whileStatement : ''while'' ''('' expression '')'' statement
    -> ^( ''while'' expression statement )
  ;

一个简单的语言的语法(二):ANTLR的重写规则(3)

时间:2011-10-07 javaeye RednaxelaFX

这种形式我们能一目了然看到最终生成的子树的结构。

两种形式是等价的,可以根据具体情况来选择能简单而清晰的表示出树改写规则的版本。

对表达式相关的语法规则,我们几乎都是用添加运算符的形式来表示树改写规则,因为对左结合的双 目运算符,这样是最简洁的。

ANTLR生成的解析器使用LL(*)算法;与一般的LL解析器一样,ANTLR不支持左递归的语法规则。这使得 书写左结合的双目运算符时,一般得写成这样的形式:

Java代码

exprWithHigherPrecedence
  : exprWithLowerPrecedence ( op exprWithLowerPrecedence )*
  ;

而不能以左递归来指定左结合。(但右结合还是可以用右递归来指定的。)

那么在表示树改写规则的时候,使用运算符来修饰语法就是这样:

Java代码

exprWithHigherPrecedence
  : exprWithLowerPrecedence ( op^ exprWithLowerPrecedence )*
  ;

只是在op的后面添加了一个帽子符号(''^''),表明在没有匹配到op运算符时就直接返回 exprWithLowerPrec

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号