我知道以前有人问过这个问题,但我还没有找到任何解决我的具体问题的方法。我将 Antlr4 与 C# 目标一起使用,并且我有以下词法分析器规则:
INT : [0-9]+
;
LETTER : [a-zA-Z_]+
;
WS : [ \t\r\n\u000C]+ -> skip
;
LineComment
: '#' ~[\r\n]* -> skip
;
Run Code Online (Sandbox Code Playgroud)
这些都是词法分析器规则,但是有很多解析器规则我不会在这里发布,因为我认为它们不相关。我遇到的问题是空格不会被跳过。当我在词法分析器运行我的输入后检查令牌流时,空格仍在那里,因此会导致错误。我使用的输入是比较基础的:
"fd 100"
Run Code Online (Sandbox Code Playgroud)
它解析完成,直到达到此解析器规则:
noSignFactor
: ':' ident #NoSignFactorArg
| integer #NoSignFactorInt
| float #NoSignFactorFloat
| BOOLEAN #NoSignFactorBool
| '(' expr ')' #NoSignFactorExpr
| 'not' factor #NoSignFactorNot
;
integer : INT #IntegerInt
;
Run Code Online (Sandbox Code Playgroud)
首先将您的语法分成单独的词法分析器语法和解析器语法。例如,如果您有一个grammar Foo;,请创建以下内容:
创建一个文件FooLexer.g4,并将所有词法分析器规则从Foo.g4 移动到FooLexer.g4。
创建一个文件FooParser.g4,并将所有解析器规则从Foo.g4 移动到FooParser.g4。
在FooParser.g4 中包含以下选项:
options {
tokenVocab=FooLexer;
}
Run Code Online (Sandbox Code Playgroud)这种分离将确保您的解析器不会默默地为您创建词法分析器规则。在组合语法中,使用文字(例如'not'在解析器规则中)将为您创建一个词法分析器规则(如果尚不存在)。发生这种情况时,很容易忘记您的词法分析器能够生成哪些类型的标记。当您使用单独的词法分析器语法时,您需要显式声明如下所示的规则,以便'not'在解析器规则中使用。
NOT : 'not';
Run Code Online (Sandbox Code Playgroud)
如果您' '在解析器规则中的某处包含文字,这应该可以解决空格问题。