0

ANTLRで次のような文法を作ろうとしています。

次のような識別子を解析できます。

foo > bar > 67

ここで、foo> barは識別子です。これは、>の後に文字が続く場合は識別子に含まれ、それ以外の場合は大なり演算子であるためです。

そして、私はそれが次のようなものを解析する必要があります

((a = 1) AND (b = 2)) OR (c = 3)

()が必要な場合。

私はこのトピックとANTLRに本当に慣れていないので、誰かが助けてくれることを願っています。

私は現在この文法を持っています

 grammar testgrammer;

start   :   statement EOF;

statement
    :   operation  (AND operation)*;

operation
    :   '(' ID OPERATOR INT ')';

AND :   'AND';

OPERATOR:   '=' | '>';

ID  
  :  ('a'..'z'| 'A'..'Z')+ (WS '>' WS ('a'..'z' | 'A'..'Z')+)?
  ;

WS  
  :  ' '+ {skip();}
  ;

INT :   '0'..'9'+
    ;

しかし、IDの>と演算子としての>を切り替える方法がわかりません。

4

1 に答える 1

1

まず最初に、これは紛らわしいことです:"foo > bar"を識別子と"foo > 67"式にするのです。

このような識別子内にスペースを許可するため、文字を消費しようとし"foo > 67"た後に数字が表示されるため、レクサーは入力を超えてトリップします。また、そこから作成できる単一のトークンがないため"foo > "、レクサーはバックトラックしません(レクサーは、消費した文字をあきらめないことに注意してください!)。"foo > "

これを処理するには、レクサーが" > "それに続くいくつかの文字と一致できることを確認する必要があります。構文述語 (( ... )=>部分)を使用してそれを行うことができます。

Id
 : IdPart ((Spaces? '>' Spaces? IdPart)=> Spaces? '>' Spaces? IdPart)*
 ;

SpaceChars
 : (Spaces | '\r' | '\n') {skip();}
 ;

fragment Digit  : '0'..'9';
fragment Letter : 'a'..'z' | 'A'..'Z';
fragment Spaces : (' ' | '\t')+;
fragment IdPart : Letter (Letter | Digit)*;

そのルールはメソッドを呼び出すため、SpaceChars内部でルールを使用できないことに注意してください。Idskip()

于 2012-06-14T19:45:22.053 に答える