ANTLR 3偶数

时间:2014-09-19 18:55:06

标签: antlr grammar

我正在尝试解决一个非常简单的语法问题(我刚开始学习使用ANTLR来开发语法;我有点新,所以只跟我一起)这是定义一个带符号的偶数使用ANTLR

启动令牌的

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

我到目前为止最好的语法如下:

grammar SignedEvenNumber;

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

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

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

3 个答案:

答案 0 :(得分:0)

我对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;

答案 1 :(得分:0)

如果你将EVEN和NOT_EVEN定义为你可以拥有的不相交的令牌

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

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

答案 2 :(得分:0)

是否有必要通过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; }
};