Antlr中 options {greedy=false;}


ANTLR词法分析中还可以加入greedy设置项,当greedy=true时当前规则会尽可能的匹配可以匹配的输入。ANTLR中默认情况greedy为true,所以COMMENT:  '/*' . *  '*/'  {$channel=HIDDEN;} ;规则中符号“.”可以匹配“*/”字符,也就是说当遇到“*/”字符时它是匹配“.”还是匹配’*/’出现了二义的情况,前面的例子中已经显示出在这种情况下分析器是可以正确分析的,但加入greedy=false后可以消除这种二义性,就是说greedy=false时分析器遇到“*/”字符时会很确定的做为注释结束符号来匹配,这样的话就消除了二义性。

COMMENT :  '/*'  (options {greedy=false;} : . ) * '*/'  {$channel=HIDDEN;} ;

options{greedy=false;} : 是一种局部设置的写法,其格式为:( options {«option-assignmen ts»} :«subrule-alternatives» )。关键字options后面用“{}”将设置项括起来,使用“:”符号表示对后面部分进行设置,这种设置的方法必须在子规则中设置它只能在子规则中有效。如:'/*'  options {greedy=false;}: . *  '*/' 这样的定义是不无法的。

下面给出一个更加明显的例子。

grammar TestGreedy;

options {

  language=CSharp;

  output=AST;

}

c  :  A B;

A  :  'a' 'b' ?;

B  :  'b';

此例子中c规则有A和B两个词法符号,其中A匹配的是“a”或“ab”字符,B匹配的是“b”字符。这时会出现一个问题就是当输入为“ab”时这个“b”是规则A的b还是规则B的b,这属于二义性问题。此示例在实际运行时如果输入为“abb”时可以正确生成有两个子节点的语法树。


如果输入为“ab”会出现MismatchedTokenException异常,因为现在分析器的greedy属性为true。这时分析器会尽可能的匹配输入的字符“ab”被规则A匹配,这时规则B就没有了可匹配的字符,所以出现了MismatchedTokenException异常。

如果我们将规则A中可选的’b’定义为greedy=false;代码如下。

c  :  A B;

A  :  'a' (options {greedy=false;} : 'b')?;

B  :  'b';

当输入“ab”和“abb”时生成的语法树同样为:

 


规则A中的’b’由于是可选项并且其后规则B中也需要匹配’b’字符所以在Greedy属性为false时规则A不去匹配字符’b’。这样输入的字符串中第一个’b’字符与规则B匹配,第二个’b’字符无处匹配。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值