为什么 "point" 规则匹配一个以上的数字?

Why "point" rule matches more then one number?

我尝试用 ANTLR4 编写我的第一个解析器。我在一个已经更大的 grammerfile 中使用的规则之一应该匹配 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

point 中的第一个 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 怎么可以匹配两个标记。有人可以帮忙吗?

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

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 的优先级高于它的子规则。