【问题标题】:ANTLR 3 Even NumberANTLR 3 偶数
【发布时间】:2014-10-25 04:20:59
【问题描述】:

我正在尝试解决一个非常简单的语法问题(我刚开始学习使用 ANTLR 开发语法;我有点新,所以请耐心等待),即使用 @ 定义一个有符号偶数987654322@。

A '+' or '-'for 起始标记是可选的,数字可以是 1 位或多位,但最后一位必须是偶数(例如,+4394 将是一个有效的有符号偶数)。

我目前最好的语法如下:

grammar SignedEvenNumber;

DIGIT           : '0'..'9';
EVEN_DIGIT      : '0' | '2' | '4' | '6' | '8';

signedEvenNumber    : ('+' | '-' | ) NUMBER+ EVEN_NUMBER;

我的问题是以强制ANTLR 将偶数作为最后一位数字的方式定义数字;即它总是将最后一个数字视为DIGIT,无论它是偶数还是奇数(因为最后一个数字之前的任何数字都可以)。可能有一个非常简单的解决方案,我只是没有得到,但任何帮助将不胜感激。

【问题讨论】:

    标签: antlr grammar


    【解决方案1】:

    我对 ANTLR 4 有更多经验,但我认为首先定义的令牌优先于语法中定义的其他令牌,因此首先定义 EVEN_DIGIT:

    grammar SignedEvenNumber;
    
    EVEN_DIGIT      : '0' | '2' | '4' | '6' | '8';
    DIGIT           : '0'..'9';
    
    signedEvenNumber    : ('+' | '-')? DIGIT+ EVEN_DIGIT;
    

    .tokens 文件中的标记是:

    DIGIT=4
    T__1=1
    EVEN_DIGIT=3
    T__0=2
    '-'=2
    '+'=1
    

    对于输入测试:

    +1234

    标记是:

    [@0,0:0='+',<1>,1:0]
    [@1,1:1='1',<4>,1:1]
    [@2,2:2='2',<3>,1:2]
    [@3,3:3='3',<4>,1:3]
    [@4,4:4='4',<3>,1:4]
    

    如果优先级不起作用,您可以重新定义令牌并更改规则,如下所示:

    grammar SignedEvenNumber;
    
    EVEN_DIGIT      : '0' | '2' | '4' | '6' | '8';
    DIGIT           : '1' | '3' | '5' | '7' | '9';
    
    signedEvenNumber    : ('+' | '-')? (DIGIT | EVEN_DIGIT)* EVEN_DIGIT;
    

    【讨论】:

    • 第二种解决方案奏效了。例如,更改优先级的问题使其将567 解释为有效语法(当它不应该时)。感谢您的帮助。
    【解决方案2】:

    如果您将 EVEN 和 NOT_EVEN 定义为不相交的标记,您可以拥有

     SignedEvenNumber : ('+' | '-')? (NOT_EVEN* EVEN)+
    

    由于偶数构成常规语言,您可以将其视为 DFA。

    【讨论】:

      【解决方案3】:

      是否需要通过 DFA 进行区分?使用规则操作怎么样?

      tokens {
        EVEN_NUMBER;
        ODD_NUMBER;
      };
      
      fragment
      NUMBER_FRAG: DIGIT+;
      
      NUMBER: t = NUMBER_FRAG
      {
         if ($t->getText()->lastDigitIsEven())
         {   $type = EVEN_NUMBER; }
         else
         {   $type = ODD_NUMBER; }
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多