1

まだAntlrに取り組んでいますが、ドキュメントで見つけられないものを検索しています。

文字列の「not」パターンを検出できるパーサーは次のとおりです。

 factor : 'not'^ primary| primary;
 (and some other lines).

しかし、プライマリの後に式を検出したい場合はどうなりますか?例えば

B exists

式の残りの部分を検索するパーサールールを定義するにはどうすればよいですか?類推してみましたが、今までうまくいきませんでした。

 exists : primary 'exists'^ | primary;

私の表現のどこに配置するかによって、私は

line 1:44 extraneous input 'exists' expecting ')'

また

line 1:3 mismatched input 'exists' expecting ')'
line 1:22 missing EOF at ')'

エラー

ありがとうございました !

編集:

私はあなたとまったく同じ文法を持っていますが、一つだけです。これが私のコードです:

// Aiming at parsing a complete BQS formed Query
grammar Logic;

options {
    backtrack=true;
    output=AST;
}

/*------------------------------------------------------------------
 * PARSER RULES
 *------------------------------------------------------------------*/

 parse  
    : expression EOF -> expression
    ; // ommit the EOF token

 expression
    : query
    ;       

 query  
    : term (OR^ term)*    // make `or` the root
    ;

 term   
    : factor (AND^ factor)*
    ;

 factor 
    : NOT^ primary 
    | primary
    ;


 primary // this one has to be completed (a lot)
    : atom (LIKE^ atom)* // right expressions have to be indicated
    | atom (EXISTS^)?
    ;

 atom   
    : ID 
    | '('! expression ')'! // omit both ( and )
    ;

/*------------------------------------------------------------------
 * LEXER RULES
 *------------------------------------------------------------------*/
// GENERAL OPERATORS: 
NOTLIKE :   'notlike'; // whitespaces have been removed
LIKE    :   'like';
EXISTS  :   'exists';

OR          :   'or';
AND         :   'and';
NOT         :   'not';

//ELEMENTS 
ID          :   (CHARACTER)+;   

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+    { $channel = HIDDEN; } ;

したがって、問題は明らかにここから発生します。

私はここで深刻な問題を抱えています。すべてのorを削除した後、またはではなく、プライマリが次の形式のいずれかになることを期待します。

A like B

また

A exists

私のコードの何がそんなに悪いのですか?これはまさに私の主なルールが言っていることだと思いますか?

私は本当に自分自身をデバッグする方法を見つけたいと思っています、なぜならこれは:

line 1:3 mismatched input 'like' expecting ')'  

本当に自明ではありません

助けてくれてありがとう、私は本当にantlrドキュメントのウェブサイトを理解するのに苦労しています:s。

4

1 に答える 1

3

EOFパーサールールの1つにを置き忘れたのではないかと思います。あなたが投稿したルールにはそれほど問題はないようです。少なくとも、あなたが投稿したエラーを引き起こす可能性のあるものではありません。

(可能性のある)将来の質問(ANTLRの質問だけでなく)については、「自己完結型」の文法(またはサンプルコード)を投稿することを強くお勧めします。言い換えれば、あなたは誰かがそれを修正することなく(!)簡単に自分のマシンで実行できる文法を投稿して、あなたが見ているものを正確に見ることができるようにします。これで、他のルールがどのように見えるかを推測しているだけです。

以下:

exists
 : atom (Exists^)?
 ;

自分でテストできるので、魅力のように機能します。

grammar T;

options {
  output=AST;
}

parse
 : expr EOF -> expr
 ;

expr
  :  orexp
  ;

orexp
  :  andexp (Or^ andexp)*
  ;

andexp
  :  not (And^ not)*
  ;

not
 : Not^ exists
 | exists
 ;

exists
 : atom (Exists^)?
 ;

atom
 : Num
 | Id
 | '(' expr ')' -> expr
 ;

Or     : 'or';
And    : 'and';
Exists : 'exists';
Not    : 'not';
Num    : '0'..'9'+;
Id     :  ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'0'..'9'|'_')*;
Space  : ' ' {skip();};

入力:

(A or B) and (not C or D exists) or not E exists

次のASTを生成します。

ここに画像の説明を入力してください

編集

primaryルールの代替案1と代替案2の両方:

 primary
  : atom (LIKE^ atom)* // alternative 1
  | atom (EXISTS^)?    // alternative 2
  ;

単一のに一致しatomます。これが、パーサーが入力を適切に解析できない原因です(そして、を追加する必要がありますがbacktrack=true;、これは避ける必要があります!)。

私はそれをテストしませんでしたが、optionsブロックから削除して、次のようbacktrack=true;に書き直せば、うまくいくと確信しています。primary

primary
 : atom ( (LIKE^ atom)* // alternative 1
        | EXISTS^       // alternative 2
        )
 ;

現在、代替案1は単一atomのにのみ一致し、あいまいさはありません(少なくとも、そのルールにはありません)。

于 2012-05-09T18:07:32.067 に答える