-->

如何解决简单的歧义(how to resolve simple ambiguity)

2019-10-21 21:19发布

我刚开始使用ANTLR的和我坚持。 我有以下的语法,我试图解决歧义解析输入像场:的valueString。

expression : Field ':' ValueString;
Field : Letter LetterOrDigit*;
ValueString : ~[:];
Letter : [a-zA-Z];
LetterOrDigit : [a-zA-Z0-9];
WS: [ \t\r\n\u000C]+ -> skip;

假设A:B是在给文法,a和b传递都被确定为场。 如何在Antlr4(C#)解决呢?

Answer 1:

您可以使用语义断言在你的词法规则来执行预读(或后),而无需耗费字符( 在词法ANTLR4负前瞻 )

在你的情况下,删除歧义,你可以检查之后的char Field的规则是:或者您可以检查之前的字符ValueString:

在第一种情况:

expression : Field ':' ValueString;
Field : Letter LetterOrDigit* {_input.LA(1) == ':'}?;
ValueString : ~[:];
Letter : [a-zA-Z];
LetterOrDigit : [a-zA-Z0-9];
WS: [ \t\r\n\u000C]+ -> skip;

在第二个(请注意, FieldValueString秩序已经反转):

expression : Field ':' ValueString;
ValueString : {_input.LA(-1) == ':'}? ~[:];
Field : Letter LetterOrDigit*;
Letter : [a-zA-Z];
LetterOrDigit : [a-zA-Z0-9];
WS: [ \t\r\n\u000C]+ -> skip;

也可以考虑使用fragment关键字的LetterLetterOrDigit

fragment Letter : [a-zA-Z];
fragment LetterOrDigit : [a-zA-Z0-9];

“[附片段关键字]你也可以定义不令牌规则,但在识别标记的帮助,而这些片段规则不会导致令牌解析器可见。” (源https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules )



Answer 2:

解决这个没有先行的一种方法是简单的定义解析器规则可以是任何这两个词法分析器令牌:

expression : Field ':' value;
value : Field | ValueString;
Field : Letter LetterOrDigit*;
ValueString : ~[:];
Letter : [a-zA-Z];
LetterOrDigit : [a-zA-Z0-9];
WS: [ \t\r\n\u000C]+ -> skip;

解析器会按预期工作和语法是保持简单,但你可能需要一个方法添加到您的访客或监听器实现。



文章来源: how to resolve simple ambiguity