我刚开始使用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#)中解决此问题?
答案 0 :(得分:1)
您可以在词法规则中使用语义谓词来执行前瞻(或后面)而不消耗字符(ANTLR4 negative lookahead in lexer)
在你的情况下,为了消除歧义,你可以检查Field
规则之后的字符是:
还是你可以检查ValueString
之前的字符是:
}。
the第一个案例:
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;
另请考虑对fragment
和Letter
LetterOrDigit
关键字
fragment Letter : [a-zA-Z];
fragment LetterOrDigit : [a-zA-Z0-9];
“[使用fragment关键字]您还可以定义不是令牌的规则,而是帮助识别令牌。这些片段规则不会导致解析器看到令牌。” (来源https://theantlrguy.atlassian.net/wiki/display/ANTLR4/Lexer+Rules)
答案 1 :(得分:1)
解决这个问题的方法是简单地定义一个解析器规则,该规则可以是这两个词法分析器中的任何一个:
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;
解析器将按预期工作并且语法保持简单,但您可能需要向访问者或侦听器实现添加方法。