【问题标题】:Parsing floating-point number and ranges separated by two periods with ANTLR 3使用 ANTLR 3 解析由两个句点分隔的浮点数和范围
【发布时间】:2013-04-16 09:21:12
【问题描述】:

我正在为具有两个当前“冲突”功能的 DSL 开发解析器:

  1. 123.4 等浮点数。
  2. 范围指定为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 中的外观:

解决此冲突并正确解析span 中的两个INTs 的正确方法是什么?

P.S.我使用的是 ANTLR 3 而不是 ANTLR 4,因为我要生成一个 C# 解析器,目前 ANTLR 4 中没有实现。

【问题讨论】:

标签: parsing antlr antlr3


【解决方案1】:

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 等区间的解析开始顺利进行。

【讨论】:

    【解决方案2】:

    您在上面发布的DOUBLE 规则与.. 运算符不冲突,因为'.' 后面的'0'..'9'+ 至少包含一位数字。 DOUBLE 的以下替代定义实际上会发生冲突:

    DOUBLE : '0'..'9'+ '.' '0'..'9'*;
    

    我怀疑您在 ANTLRWorks 中使用了解释器,众所周知,它在许多情况下会给出不正确的结果。

    【讨论】:

    • 好吧,当我从语法中删除 DOUBLE 规则时,一切正常。如果我将范围分隔符设置为,, 而不是..,那么一切正常。
    • 确实,我在 ANTLRWorks 中使用解释器,但我也使用单元测试覆盖在 C# 中生成的解析器。
    猜你喜欢
    • 2014-06-02
    • 2018-06-30
    • 1970-01-01
    • 2021-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多