使用ANTLR 3解析由两个句点分隔的浮点数和范围

时间:2013-04-16 09:21:13

标签: parsing antlr antlr3

我正在研究一种具有两种当前“冲突”功能的DSL解析器:

  1. 浮点数,例如123.4
  2. 范围指定为ID[2..5](ID定义为'a'..'z'+且无关紧要。部分'[2..5]'最重要。
  3. 应解析它的测试语法如下所示:

    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..5DOUBLE匹配并失败。以下是它在ANTLR Works中的外观:

    Mismatched token exception.

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

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

2 个答案:

答案 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中使用解释器,已知在许多情况下会给出错误的结果。