为什么“指向”规则匹配多个数字?

时间:2018-05-31 21:01:28

标签: antlr4

我尝试用ANTLR4编写我的第一个解析器。我在一个已经更大的语法文件中使用的规则之一应该是将2个数字作为2D点匹配。这里是语法的缩减示例:

grammar example;

WS: [ \t\r\n]+ -> channel(HIDDEN);
INT: [0-9]+;
FLOAT: [0-9]*'.'?[0-9]+ ;
IDSTRING:  [a-zA-Z_] [a-zA-Z0-9_]*;
NUMBER: (INT | FLOAT) ;

id: IDSTRING;
num: NUMBER;
sem: ';' ;
point: num num;

macro: 'MACRO' id macroprops* 'END ' id;
macroprops:  macroorigin ;
macroorigin: 'ORIGIN' point sem;

当我知道输入这样一个基本的例子时:

antlr4 example.g4 -o example/ 
cd example 
javac *.java 
echo -e "MACRO m_1\n  ORIGIN 7 2.0  ;\nEND m_1" | grun example macro -tree

第一个num与两个数字匹配,并且它会抛出一个错误,任何整数(此处为0)都不是数字:

line 3:9 mismatched input '0' expecting NUMBER
(macro MACRO (id m_1) (macroprops (macroorigin ORIGIN (point (num 0 0) (num <missing NUMBER>)) (sem ;))) END  (id m_1))

我尝试了NUMBERpoint的定义,但我认为它应该像这样工作。我甚至不明白num可以匹配两个令牌。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:0)

似乎ANTLR4将TOKENS与它们在语法中给出的顺序相匹配。将fragment添加到INTFLOAT可以解决问题,因为NUMBER是唯一匹配数字定义的TOKEN,允许浮点数和整数。

grammar example2;

WS: [ \t\r\n]+ -> channel(HIDDEN);

NUMBER: (INT | FLOAT) ;
fragment INT: [0-9]+;
fragment FLOAT: [0-9]*'.'?[0-9]+ ;
IDSTRING:  [a-zA-Z_] [a-zA-Z0-9_]*;

id: IDSTRING;
num: NUMBER;
sem: ';' ;
point: num num;

macro: 'MACRO' id macroprops* 'END ' id;
macroprops:  macroorigin ;
macroorigin: 'ORIGIN' point sem;

非常感谢您指出要观看令牌流。但我仍然不明白为什么它会将这两个数字与原始问题中的num规则相匹配。

编辑:另一个错误是,正如GRosenberg所提到的那样,只是按照严格顺序定义语法元素,因此NUMBER具有比其子规则更高的优先级。