Parsing 基于其他令牌更改Antlr令牌

Parsing 基于其他令牌更改Antlr令牌,parsing,antlr,antlr4,lexer,Parsing,Antlr,Antlr4,Lexer,是否可以根据字符串上是否存在令牌将令牌类型设置为类型 例如: Hello 100 and: 100 Hello WORD应该是Hello 金额将为100 但对于这一点: 100 3543 and: 3543 100 WORD将是100 金额将为3543 基本上,只有一个单词。问题在于定义哪个数字是单词 或者,这在使用Antlr时根本不可能吗?最好的答案是“不”(“不”是因为这是个坏主意,“不”是因为它可以实现,但只能通过使用可怕的乱七八糟来实现) 识别定义良好的标记类型的相对语法/结构定位是

是否可以根据字符串上是否存在令牌将令牌类型设置为类型

例如:

Hello 100
and:
100 Hello
WORD
应该是Hello

金额将为100

但对于这一点:

100 3543
and:
3543 100
WORD
将是100

金额将为3543

基本上,只有一个单词。问题在于定义哪个数字是单词

或者,这在使用Antlr时根本不可能吗?

最好的答案是“不”(“不”是因为这是个坏主意,“不”是因为它可以实现,但只能通过使用可怕的乱七八糟来实现)

识别定义良好的标记类型的相对语法/结构定位是一个解析器问题。如果标记类型没有很好地定义,那么语法是不明确的——正确的解释依赖于语义。在这种情况下,标记以前是否在语义上用作
单词

如果有完整的解析树可供分析,语义问题最好在树遍历器中处理

考虑:

phrase : a=ID b=ID ;

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

fragment WORD : .... ;
fragment NUMB : .... ;
现在,在遍历解析树时,可以检查每个
PhraseContext
节点。
ID
s的标签使确定相对顺序变得简单:每个
PhraseContext
节点都有变量

TerminalNode a; // the first ID in the node
TerminalNode b; // the second
在草稿行中记录第一次遇到的
ID
s的顺序。在随后的遭遇中,草稿行可以用来一致地定义哪个
ID
应该被视为
单词或
NUMB
最好的答案是“不”(“不”是因为这是一个坏主意,“不”是因为它可以完成,但只能通过使用可怕的乱码)

识别定义良好的标记类型的相对语法/结构定位是一个解析器问题。如果标记类型没有很好地定义,那么语法是不明确的——正确的解释依赖于语义。在这种情况下,标记以前是否在语义上用作
单词

如果有完整的解析树可供分析,语义问题最好在树遍历器中处理

考虑:

phrase : a=ID b=ID ;

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

fragment WORD : .... ;
fragment NUMB : .... ;
现在,在遍历解析树时,可以检查每个
PhraseContext
节点。
ID
s的标签使确定相对顺序变得简单:每个
PhraseContext
节点都有变量

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

在草稿行中记录第一次遇到的
ID
s的顺序。在随后的遭遇中,可以使用草稿行来一致地定义哪个
ID
应该被视为
单词
NUMB

如果您始终保持单词和数字的顺序不变,那么有一个解决方案。例如:

phase: id NUMBER;

id: WORD | NUMBER;
WORD: ...;
NUMBER ...;
它应该为第一个令牌返回
id
,而不管它是数字还是单词,并且始终为第二个令牌返回数字

单独使用解析器是不可能允许对这两个函数任意排序的。如果必须使用任意顺序,您只能按照@GRosenberg的建议将两者都解析为ID,然后进行语义检查,其中哪个词更合理,哪个数字更合理

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

如果您始终保持单词和数字的顺序不变,则有一个解决方案。例如:

phase: id NUMBER;

id: WORD | NUMBER;
WORD: ...;
NUMBER ...;
它应该为第一个令牌返回
id
,而不管它是数字还是单词,并且始终为第二个令牌返回数字

单独使用解析器是不可能允许对这两个函数任意排序的。如果必须使用任意顺序,您只能按照@GRosenberg的建议将两者都解析为ID,然后进行语义检查,其中哪个词更合理,哪个数字更合理

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

因为您所称的
WORD
可以是数字,也可以是
NUMBER
,这是解析器的决定,而不是词法分析器的决定:

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

由于您所称的
WORD
可以是数字,也可以是
NUMBER
,这是解析器的决定,而不是lexer的决定:

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

在第二个例子中,你如何确定哪个数字是单词。假设第一个数字是
WORD
,那么在第二个例子中,您如何确定哪个数字是
WORD
?这一点很好。比如说,将第一个数字设为
WORD
Yes,然后进行语义检查,并将所有内容保持为ID,这是我们要做的解决方案!非常感谢!是的,我们将要做的解决方案是在事后进行语义检查,并将所有内容保持为ID!非常感谢!