根据其他令牌更改Antlr令牌

时间:2018-02-07 12:55:10

标签: parsing antlr antlr4 lexer

是否可以根据字符串上是否存在令牌来使令牌类型成为类型?

例如:

Hello 100
and:
100 Hello

WORD将是Hello

AMOUNT将为100

但是为此:

100 3543
and:
3543 100

WORD将为100

AMOUNT将是3543

基本上,WORD。问题是定义哪个数字是WORD

或者Antlr无法实现这一点吗?

3 个答案:

答案 0 :(得分:2)

最好的答案是'不'('不',因为这是一个坏主意和'不',因为它可以完成,但只能使用可怕的kludge)。

识别明确定义的令牌类型的相对语法/结构定位恰当是解析器问题。如果令牌类型没有明确定义,那么语法是不明确的 - 正确的解释依赖于语义。在这种情况下,令牌以前是否在语义上用作WORD

语法问题最好在树行走者中处理,因为存在完整的分析树用于分析。

考虑:

phrase : a=ID b=ID ;

ID : WORD | NUMB ;
WS : [ \r\n\t] -> skip ;

fragment WORD : .... ;
fragment NUMB : .... ;

现在,在遍历解析树时,可以检查每个PhraseContext节点。标记ID使得确定相对排序变得简单:每个PhraseContext节点都有变量

TerminalNode a; // the first ID in the node
TerminalNode b; // the second

在暂存器中记录第一次遇到的ID s的顺序。在随后的遭遇中,暂存器可用于一致地定义哪个ID应被视为WORDNUMB

答案 1 :(得分:1)

有一个解决方案,如果你保持WORD和NUMBER的顺序始终相同。例如:

phase: id NUMBER;

id: WORD | NUMBER;
WORD: ...;
NUMBER ...;

对于第一个令牌,它应该返回id,无论它是数字还是单词,并且总是为第二个令牌返回一个数字。

单独使用解析器,不可能任意对这两个进行排序。如果任意顺序是必须的,你只能将其解析为ID,如@GRosenberg所建议的那样,然后进行语义检查,其中哪一个是更合理的WORD,哪个是NUMBER。

<强>更新id规则更改为解析器规则,以避免Jiri提到的麻烦。

答案 2 :(得分:0)

由于你所谓的WORD可以是数字和NUMBER,这是解析器的决定,而不是词法分析决定:

line: id NUMBER | NUMBER WORD;
id: WORD | NUMBER;
WORD: [a-zA-Z];
NUMBER: [0-9];