0

ANTLR を使用して式パーサーを作成しようとしています。式は if ステートメント内にあるため、そのルートは条件です。

問題なくパーサー/レクサーファイルに「コンパイル」する次の文法がありますが、生成されたコード自体にいくつかのエラーがあり、本質的に2つの「空の」ifステートメント、つまりif (())

私が何を間違っているのかわからないので、どんな助けでも大歓迎です。

ありがとう。

以下の Grammar .g ファイル: grammar Expression;

options {
  language=CSharp3;
  output=AST;
}

tokens {
  ROOT;
  UNARY_MIN;
}

@parser::namespace { Antlr3 }
@lexer::namespace { Antlr3 }
public parse
  :  orcond EOF -> ^(ROOT orcond)
  ;

orcond
  :  andcond ('||' andcond)*
  ;

andcond
  :  condition ('&&' condition)*
  ;

condition
  :  exp (('<' | '>' | '==' | '!=' | '<=' | '>=')^ exp)?
  ;

exp
  :  addExp
  ;

addExp
  :  mulExp (('+' | '-')^ mulExp)*
  ;

mulExp
  :  unaryExp (('*' | '/')^ unaryExp)*
  ;

unaryExp
  :  '-' atom -> ^(UNARY_MIN atom)
  |  atom
  ;

atom
  :  Number
  |  '(' parenthesisvalid ')' -> parenthesisvalid
  ;

parenthesisvalid
  :  fullobjectref
  |  orcond
  ;

fullobjectref
  :  objectref ('.' objectref)?
  ;

objectref
  :  objectname ('()' | '(' params ')' | '[' params ']')?
  ;

objectname
  :  (('a'..'z') | ('A'..'Z'))^ (('a'..'z') | ('A'..'Z') | ('0'..'9') | '_')*
  ;

params
  :  paramitem (',' paramitem)?
  ;

paramitem
  :  unaryExp
  ;

Number
  :  ('0'..'9')+ ('.' ('0'..'9')+)?
  ;

Space 
  :  (' ' | '\t' | '\r' | '\n'){Skip();}
  ;
4

2 に答える 2

2

..パーサー規則内で範囲演算子 を使用しないでください。

パーサー ルールを削除しobjectname、レクサー ルールを作成します。

Objectname
  :  ('a'..'z' | 'A'..'Z') ('a'..'z' | 'A'..'Z' | '0'..'9' | '_')*
  ;
于 2012-09-09T19:29:46.487 に答える
0

さらに、フラグメントブロックを使用するとよりきれいになります。この場合、コードは次のようになります。

Objectname  :  LETTER (LETTER  | DIGIT | '_')*;    
Number: DIGIT+ ('.' DIGIT+)?;
fragment DIGIT : '0'..'9' ;
fragment LETTER : ('a'..'z' | 'A'..'Z'); 
于 2012-09-20T06:46:45.617 に答える