我正在研究一种具有两种当前“冲突”功能的DSL解析器:
123.4
。ID[2..5]
(ID定义为'a'..'z'+
且无关紧要。部分'[2..5]'最重要。应解析它的测试语法如下所示:
grammar DotTest;
span returns [double value]
: ID'['e=INT'..'f=INT']' { /*some code to process the values*/ $value = (double)(Int32.Parse($e.text) + Int32.Parse($f.text)); } ;
num returns [double value]
: DOUBLE {$value = double.Parse($DOUBLE.text); } ;
INT : '0'..'9'+ ;
DOUBLE : '0'..'9'+'.''0'..'9'+ ;
ID : 'a'..'z'+ ;
WS : ( ' ' | '\t' | '\r' | '\n' ) {$channel=HIDDEN;} ;
问题:规则span
无法正确解析其输入,因为它与DOUBLE
令牌冲突。词法分析器尝试将2..5
与DOUBLE
匹配并失败。以下是它在ANTLR Works中的外观:
解决此冲突的正确方法是什么,并正确解析INT
中的两个span
?
P.S。我正在使用ANTLR 3而不是ANTLR 4,因为我要生成一个C#解析器,目前尚未在ANTLR 4中实现。
答案 0 :(得分:5)
This solution(第二个语法)工作正常。在将词法分析器规则转换为以下内容之后:
NUM : (INT RNG)=> INT {$type=INT;}
| (DOUBLE)=> DOUBLE {$type=DOUBLE;}
| INT {$type=INT;};
fragment INT : '0'..'9'+ ;
fragment DOUBLE : '0'..'9'+'.''0'..'9'+ ;
RNG: '..' ;
解析像1..2
这样的时间间隔开始顺利进行。
答案 1 :(得分:1)
您在上面发布的DOUBLE
规则与..
运营商不冲突,因为'0'..'9'+
后的'.'
至少包含一位数。 DOUBLE
的以下替代定义实际上会发生冲突:
DOUBLE : '0'..'9'+ '.' '0'..'9'*;
我怀疑你在ANTLRWorks中使用解释器,已知在许多情况下会给出错误的结果。