セマンティック述語を取得しようとしています。これは簡単に思えますが、どういうわけか機能しません。ブール条件に基づいて、ルールを実行する (AST を吐き出す) か、または手動でルールを作成する必要があります。
以下はパーサールールです。
displayed_column
:
{columnAliases.containsKey($text)}?
=>-> ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
| sql_expression
;
私はすべてのゲートと曖昧さ回避も試みましたが、コードを実行している間、常に 2 番目のルール (sql_expression) に進みます。
誰でも私を助けてもらえますか?
ありがとう
編集: 述語の実行中に $text が空であることに気付きました。これが、常に2番目のルールに一致する理由です。ルールをこれに変更しましたが、機能します
displayed_column
:
sql_expression
-> {columnAliases.containsKey($text)}? ^(PROPERTY_LIST ^(PROPERTY IDENTIFIER[columnAliases.get($text)]))
-> sql_expression
しかし、私は別の問題に遭遇しました。ツリーを手動で構築してもうまくいかないことに気付きました。新しいテキスト (columnAliases マップの値) でルールdisplayed_columnを再実行する必要があります。それは可能ですか?
これは私の最初の質問でした https://stackoverflow.com/questions/14170541/antlr-dynamic-input-stream-modification-during-parsing
基本的に、私はSQLのようなステートメントをインタラクティブに解析して解釈しようとしています。
select a.b.c from pool;
select min(abc.def[*]) from pool;
列名が少し長くなる可能性があるため、(別のコマンドを使用して) エイリアス列名をユーザーに設定しました。たとえば、ユーザーは設定を設定してコマンドを実行できます。
set column_alias a.b.c d;
select d from pool;
解析中に、生成されたパーサーに設定 (マップ) を挿入し、新しい列を元の列に置き換え/マップしてから、解釈を続けようとしています。列が複数のルールにまたがっているため、ツリーグラマーで処理するのは難しいと思っていたので、パーサーで処理することが唯一の選択肢のように思えました。
文法全体を投稿することもできますが、少し長すぎます。縮小版を次に示します。
select_stmt:
: 'select' displayed_column 'from' pool
;
displayed_column
: sql_expression
;
sql_expression
: term ( (PLUS^ | MINUS^) term)*
;
term : factor ( (ASTERISK^ | DIVIDE^) factor)*
;
... <more_rules> ...
文字列テンプレートを使用して翻訳されたステートメントを出力し、再解析することが唯一のオプションのように思えますが、これには文法全体を書き直してテンプレートを出力する必要があります (現在、AST とそれを解釈する木の文法)。邪魔にならない方法を教えていただければ幸いです。
再度、感謝します。