为什么我的语法适用于*, - ,/等运算符,而不是+?

时间:2011-03-04 01:57:00

标签: antlr antlr3 antlrworks

我现在正在创建一个语法,我不得不摆脱左递归,除了加法运算符之外,它似乎适用于所有内容。

这是我语法的相关部分:

SUBTRACT: '-';
PLUS: '+';
DIVIDE: '/';
MULTIPLY: '*';

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      )
      (
        PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr
      )*
      ;

INTEGER: ('0'..'9')*;
IDENTIFIER: ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')*;

然后当我尝试做类似

的事情
x*1

它的工作非常完美。但是,当我尝试做类似

的事情时
x+1

我收到错误说:

  

MismatchedTokenException:不匹配的输入'+'期待'\ u001C'

我已经有一段时间了,但不知道为什么它适用于*, - 和/,但不是+。我有完全相同的代码。

编辑:如果我重新排序并将SUBTRACT置于PLUS上方,+符号现在可以正常工作,但符号不会。为什么antlr会关心那样的东西?

2 个答案:

答案 0 :(得分:1)

避免左递归(在表达式语法中)通常是这样做的:

grammar Expr;

parse
  :  expr EOF
  ;

expr
  :  equalityExpr
  ;

equalityExpr
  :  relationalExpr (('==' | '!=') relationalExpr)*
  ;

relationalExpr
  :  additionExpr (('>=' | '<=' | '>' | '<') additionExpr)*
  ;

additionExpr
  :  multiplyExpr (('+'| '-') multiplyExpr)*
  ;

multiplyExpr
  :  atom (('*' | '/') atom)*
  ;

atom
  :  IDENTIFIER
  |  INTEGER
  |  STRING
  |  TRUE
  |  FALSE
  |  '(' expr ')'
  ;

// ... lexer rules ...

例如,输入A+B+C将按如下方式解析:

enter image description here

另见相关答案:ANTLR: Is there a simple example?

答案 1 :(得分:0)

我通过在删除左递归的末尾为部件制定新规则来修复它:

expr: 
      (
        IDENTIFIER 
        | INTEGER 
        | STRING 
        | TRUE 
        | FALSE
      ) lr*
      ;

lr:         PLUS expr 
        | SUBTRACT expr 
        | MULTIPLY expr 
        | DIVIDE expr 
        | LESS_THAN expr 
        | LESS_THAN_OR_EQUAL expr 
        | EQUALS expr;