匹配的规则错误



我在词法分析器中有以下内容

INTEGER : DIGIT+;
NOT: '!';
MINUS:'-';
PLUS:'+';
fragment DIGIT: '0'..'9';

我在解析器中有以下内容

expr:
   intLiteral
   | UnaryOp expr;
intLiteral: (PLUS|MINUS)? INTEGER;
UnaryOp: NOT|MINUS;

当我使用 grun 用 -2 测试它时,我得到它与 UnaryOp expr 匹配,而不仅仅是 intLiteral。换句话说,减号被检测为 UnaryOp。为什么会发生这种情况,有没有办法解决它?

做法是对所有大写字母用于词法分析器规则,对解析器规则使用全部小写。如果混合它们,则会导致类似以下错误:

$ grun Question expr -tokens -diagnostics input.txt 
[@0,0:0='-',<UnaryOp>,1:0]
[@1,1:1='2',<INTEGER>,1:1]
[@2,2:1='<EOF>',<EOF>,1:2]

因为它以大写字母开头,所以UnaryOp是一个词法分析器规则,而不是您可能认为的解析器规则,并且-符号已作为UnaryOp标记进行匹配,因为此规则是在MINUS:'-';之前定义的。

如果MINUS规则在UnaryOp之前,则-符号将匹配为减号:

$ grun Question question -tokens -diagnostics input1.txt 
[@0,0:0='-',<'-'>,1:0]
[@1,1:1='2',<INTEGER>,1:1]
[@2,2:1='<EOF>',<EOF>,1:2]

此外,intLiteral可能与expr冲突,应作为可能的表达式之一包括在内。

以下语法遵循我的风格(文件 Question.g4):

grammar Question;
question
@init {System.out.println("Question last update 2108");}
    :   line+ EOF
    ;
line
    :   expr NL
        {System.out.println("Expression found : " + $expr.text); }
    ;
expr
    :   ( PLUS | MINUS ) expr   # exprUnaryOp
    |   expr PLUS  expr         # exprAddition
    |   expr MINUS expr         # exprSutraction
    |   atom                    # exprAtom
    ;
atom
    :   INTEGER
    |   ID
    ;
ID      : LETTER ( LETTER | DIGIT | '_' )* ;      
INTEGER : DIGIT+ ;
NOT     : '!' ;
MINUS   : '-' ;
PLUS    : '+' ;
NL      : [rn] ;
WS      : [ t] -> channel(HIDDEN) ; // -> skip ;
fragment LETTER : [a-zA-Z] ;
fragment DIGIT  : [0-9] ;

文件input.txt

-2
- 2
1 - 2
3 + 4
5
abc + def

执行:

$ grun Question question -tokens -diagnostics input.txt 
[@0,0:0='-',<'-'>,1:0]
[@1,1:1='2',<INTEGER>,1:1]
[@2,2:2='n',<NL>,1:2]
[@3,3:3='-',<'-'>,2:0]
[@4,4:4=' ',<WS>,channel=1,2:1]
[@5,5:5='2',<INTEGER>,2:2]
...
[@25,27:29='def',<ID>,6:6]
[@26,30:30='n',<NL>,6:9]
[@27,31:30='<EOF>',<EOF>,7:0]
Question last update 2108
Expression found : -2
Expression found : - 2
Expression found : 1 - 2
Expression found : 3 + 4
Expression found : 5
Expression found : abc + def

相关内容

  • 没有找到相关文章

最新更新