我刚刚开始使用 Antlr,但遇到了困难。我有以下语法,并试图解决解析输入(如 Field: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都被标识为Field。如何在 Antlr4 (C#) 中解决此问题?
最佳答案
您可以在词法分析器规则中使用语义谓词来执行前视(或后视)而不消耗字符 ( ANTLR4 negative lookahead in lexer )
在这种情况下,为了消除歧义,您可以检查 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;
在第二个中(请注意 Field
和 ValueString
顺序已颠倒):
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;
还可以考虑对 Letter
和 LetterOrDigit
使用 fragment
关键字
fragment Letter : [a-zA-Z];
fragment LetterOrDigit : [a-zA-Z0-9];
“[使用片段关键字]您还可以定义不是标记的规则,而是帮助识别标记。这些片段规则不会导致解析器可见的标记。” (来源https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules)
关于c# - 如何解决简单的歧义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28493732/