ANTLR 初学者 =>语法问题
我是 ANTLR 的初学者。我只是出于测试目的执行以下操作,并尝试了解其工作方式并产生错误:
INTEGER_NUMBER : ('0'..'9')+;
integer_number:INTEGER_NUMBER;
小数数字:(整数数字'.'整数数字)| ('.'integer_number);
regular_number:decimal_number|integer_number;
我对“regular_number”规则收到以下警告:决策可以匹配诸如“INTEGER_NUMBER '.' 之类的输入” INTEGER_NUMBER”使用多个替代项:1、2 因此,该输入的替代方案 2 被禁用。
它究竟意味着什么?
好的,我已编辑这篇文章以包含重现此错误的代码
program :(price)*;
INTEGER_NUMBER : ('0'..'9')+;
< br> INFO_PRICE : '旧价格';
FRACTION_NUMBER:'1/16'|'1/8'|'3/16'|'1/4'|'5/16'|'3/8'|'7/16'|'1/ 2'|'9/16'|'5/8'|'11/16'|'3/4'|'13/16'|'7/8'|'15/16';
< br> 货币:'欧元'|'美元'|'英镑';
integer_number:INTEGER_NUMBER ;
小数数字:(整数数字?'.')整数数字;
分数数字:(整数数字(('')+))? FRACTION_NUMBER;
常规数字:小数数字|整数数字;
numeric_number :regular_number|fraction_number;
non_numerical_number : INFO_PRICE ((' ')*) ('+'|'-') ((' ')*)(numerical_number)((' ')*) CURRENCY;
价格 : numeric_number |non_numerical_number;
WS : (' ' | '\t' | '\f')+ {$channel=HIDDEN;};
NL :('\r' '\n' | '\r' | '\n') {$channel=HIDDEN;};
并且知道的错误是这个
错误(201):/ ANTLR - Tuto 1/src/Test.g:37:2:以下替代方案永远无法匹配:2 |---> : 小数|整数;
I'm a beginner using ANTLR. I'm just doing the following for test purposes and try to understand the way it works and produce errors:
INTEGER_NUMBER : ('0'..'9')+;
integer_number: INTEGER_NUMBER;
decimal_number: (integer_number '.' integer_number) | ('.' integer_number);
regular_number: decimal_number|integer_number;
I have the following warning on the "regular_number" rule : Decision can match input such as "INTEGER_NUMBER '.' INTEGER_NUMBER" using multiple alternatives: 1, 2
As a result, alternative(s) 2 were disabled for that input.
What exactly does it means ?
Ok I have edited this post to include the code that reproduce this error
program :(price)*;
INTEGER_NUMBER : ('0'..'9')+;
INFO_PRICE : 'OLD PRICE';
FRACTION_NUMBER : '1/16'|'1/8'|'3/16'|'1/4'|'5/16'|'3/8'|'7/16'|'1/2'|'9/16'|'5/8'|'11/16'|'3/4'|'13/16'|'7/8'|'15/16';
CURRENCY : 'EUR'|'USD'|'GBP';
integer_number : INTEGER_NUMBER ;
decimal_number : (integer_number? '.') integer_number ;
fraction_number : (integer_number ((' ')+))? FRACTION_NUMBER;
regular_number : decimal_number|integer_number ;
numerical_number :regular_number|fraction_number;
non_numerical_number : INFO_PRICE ((' ')*) ('+'|'-') ((' ')*)(numerical_number)((' ')*) CURRENCY;
price : numerical_number |non_numerical_number;
WS : (' ' | '\t' | '\f')+ {$channel=HIDDEN;};
NL :('\r' '\n' | '\r' | '\n') {$channel=HIDDEN;};
and the error know is this one
error(201): /ANTLR - Tuto 1/src/Test.g:37:2: The following alternatives can never be matched: 2
|---> : decimal_number|integer_number ;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
正如评论中已经提到的,您发布的语法没有任何问题。
您提到的错误发生在以下语法中:
当解析器尝试为输入字符串
"123"
匹配regular_number
时,它不知道选择哪个替代方案。decimal_number
和integer_number
都匹配"123"
。因此错误消息:编辑
从
regular_number
规则中,字符串“123.456”
可以解析为:或解析为:
为什么不在词法分析器中定义DECIMAL_NUMBER :
?
这应该可以解决这个问题。
但还有更多问题:
当上面的规则尝试处理像
"2 1/8"
这样的输入时,其中的2
可能是您的fraction_number 的一部分
包括1/8
,但也可以将其处理为regular_number
后跟fraction_number
。另外,您不应该在解析器规则中定义空格,您已将它们放在词法分析器中的隐藏通道上,因此解析器不会“看到”它们。
话虽如此,这将是一种可能的替代语法,可能可以满足您的需求:
编辑 II
当遇到(子)字符串
1011 1/16
时,1011
被标记为INTEGER_NUMBER
,空格被放置在 HIDDEN 通道上(并且因此,在传递给解析器的令牌流中不存在),并且1/16
被标记为FRACTION_NUMBER
。对于
101 11/16
,同样适用:101
是INTEGER_NUMBER
,11/16
是FRACTION_NUMBER
。强调一下:当您将空格和换行符放在不同的通道(例如 HIDDEN 通道)上时,它们不会出现在解析器操作的标记流中。因此,在解析器规则中使用这些标记是没有意义的:它们永远不会匹配。
华泰
As already mentioned in the comments, there's nothing wrong with the grammar you posted.
The error you mention occurs with the following grammar:
When the parser tries to match a
regular_number
for the input string"123"
, it does not know which alternative to choose. Bothdecimal_number
andinteger_number
match"123"
. Hence the error message:EDIT
From within the
regular_number
rule, the string"123.456"
could be parsed as:or as:
Why not define a DECIMAL_NUMBER in the lexer:
?
That should fix that problem.
There are more issues though:
when the rule above tries to handle input like
"2 1/8"
, the2
from it could be a part of yourfraction_number
including the1/8
, but it could also be handled as aregular_number
followed by afraction_number
.Also, you shouldn't define spaces inside your parser rules, you've put them on the HIDDEN channel in the lexer, so they won't be "seen" by the parser.
Having said all that, this would be a possible alternative grammar that probably does what you want:
EDIT II
When encountering the (sub) string
1011 1/16
,1011
is tokenized as anINTEGER_NUMBER
, the space is put on the HIDDEN channel (and is therefor not present in the token-stream that is being passed to the parser), and1/16
is tokenized as aFRACTION_NUMBER
.For
101 11/16
the same applies:101
is aINTEGER_NUMBER
and11/16
aFRACTION_NUMBER
.To emphasize: when you put spaces and line breaks on a different channel (like the HIDDEN channel), they are not present in the token stream that the parser operates on. So it makes no sense to use these tokens in parser rules: they're never going to be matched.
HTH
您发布的错误意味着有两个规则与某些输入匹配,在您的情况下,输入
INTEGER_NUMBER '.' INTEGER_NUMBER
。然而,正如巴特评论的那样,您发布的语法不存在这个问题。您确定错误来自您发布的确切内容吗?The error you posted means there are two rules that match certain input, in your case the input
INTEGER_NUMBER '.' INTEGER_NUMBER
. However, as Bart commented, the grammar you posted does not have that problem. Are you sure the error comes from the exact thing you posted?