Antlr4 输入端没有可行的替代方案'';

Antlr4 输入端没有可行的替代方案'';,antlr4,Antlr4,我知道以前有人问过这个问题,但我还没有找到解决我具体问题的办法。我将Antlr4与C#目标一起使用,我有以下lexer规则: INT : [0-9]+ ; LETTER : [a-zA-Z_]+ ; WS : [ \t\r\n\u000C]+ -> skip ; LineComment : '#' ~[\r\n]* -> skip ; 这些都是lexer规则,但是有很多解析器规

我知道以前有人问过这个问题,但我还没有找到解决我具体问题的办法。我将Antlr4与C#目标一起使用,我有以下lexer规则:

INT     : [0-9]+
        ;

LETTER  : [a-zA-Z_]+
        ;

WS      : [ \t\r\n\u000C]+ -> skip
        ;

LineComment
        : '#' ~[\r\n]* -> skip
        ;
这些都是lexer规则,但是有很多解析器规则,我不会在这里发布,因为我认为它们不相关。 我的问题是不会跳过空白。当我在lexer运行我的输入之后检查令牌流时,空格仍然在那里,因此导致错误。我使用的输入是相对基本的:

"fd 100"
它将完成解析,直到达到以下解析规则:

noSignFactor
        : ':' ident                 #NoSignFactorArg
        | integer                   #NoSignFactorInt
        | float                     #NoSignFactorFloat
        | BOOLEAN                   #NoSignFactorBool
        | '(' expr ')'              #NoSignFactorExpr
        | 'not' factor              #NoSignFactorNot
        ;
integer : INT                       #IntegerInt
        ;

首先将语法分为单独的lexer语法和parser语法。例如,如果你有一个
语法Foo,创建以下内容:

  • 创建一个文件doublexer.g4,并将所有lexer规则从Foo.g4移动到doublexer.g4

  • 创建一个文件FooParser.g4,并将所有解析器规则从Foo.g4移动到FooParser.g4

  • FooParser.g4中包括以下选项:

    options {
      tokenVocab=FooLexer;
    }
    
  • 这种分离将确保解析器不会默默地为您创建lexer规则。在组合语法中,在解析器规则中使用诸如
    'not'
    之类的文本将为您创建一个lexer规则(如果还不存在)。当这种情况发生时,很容易忘记你的lexer能够产生什么类型的代币。当您使用单独的lexer语法时,您需要显式地声明如下规则,以便在解析器规则中使用
    'not'

    NOT : 'not';
    
    如果您在解析器规则的某个地方包含了文本
    '
    ,那么这应该可以解决空白的问题

    NOT : 'not';