2

私は今文法を作成していますが、左再帰を取り除く必要がありました.加算演算子を除くすべてで機能するようです.

これが私の文法の関連部分です:

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 はそのようなものの順序を気にするのでしょうか?

4

2 に答える 2

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は次のように解析されます。

ここに画像の説明を入力

この関連する回答も参照してください: ANTLR: Is there a simple example?

于 2011-03-04T08:10:46.687 に答える
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;
于 2011-03-04T02:55:32.133 に答える