4

私はANTLR3を使用して以下を行っています。

SQLクエリがあると仮定します。一般に、WHERE、ORDER BY、およびGROUPBY句はオプションです。ANTLRの文法に関して、私は次のように説明します。

クエリ:select_clause from_clause where_clause?group_by_clause?order_by_clause?

各句のルールは、明らかにそれぞれのキーワードで始まります。

私が実際に必要としているのは、各句の内容を、その内部構造を処理せずに文字列として抽出することです。

これを行うために、私は次の文法から始めました。

クエリ:
    select_clause from_clause where_clause?group_by_clause?order_by_clause?
EOF;

select_clause:
    SELECT_CLAUSE
;

from_clause:
    FROM_CLAUSE
;

where_clause:
    WHERE_CLAUSE
;

group_by_clause:
    GROUP_BY_CLAUSE
;

order_by_clause:
    ORDER_BY_CLAUSE
;

SELECT_CLAUSE:'select' ANY_CHAR *;

FROM_CLAUSE:'from' ANY_CHAR *;

WHERE_CLAUSE:'where' ANY_CHAR *;

GROUP_BY_CLAUSE:'group by' ANY_CHAR *;

ORDER_BY_CLAUSE:'順序'ANY_CHAR *;

ANY_CHAR:。;

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

これはうまくいきませんでした。正しい文法を作成しようと試みましたが、成功しませんでした。このタスクはANTLR3で実行できると思いますが、smthが不足しています。

より一般的には、新しいトークンの開始を示す特定のキーワードに出会うまで、入力ストリームから単一のトークンに文字を収集できるようにしたいと思います。このキーワードは、新しいトークンの一部である必要があります。

手伝ってくれませんか。

4

1 に答える 1

2

それらをトークンに追加する代わりに、代わりANY_CHAR*にパーサールールに移動してみませんか?書き換えルールを使用して、これらの単一のトークンを「接着」することもできます。

簡単なデモ:

grammar T;

options { output=AST; }
tokens  { QUERY; ANY; }

query           : select_clause from_clause where_clause? group_by_clause? order_by_clause? EOF
                  -> ^(QUERY select_clause from_clause where_clause? group_by_clause? order_by_clause?)
                ;
select_clause   : SELECT_CLAUSE^ any;
from_clause     : FROM_CLAUSE^ any;
where_clause    : WHERE_CLAUSE^ any;
group_by_clause : GROUP_BY_CLAUSE^ any;
order_by_clause : ORDER_BY_CLAUSE^ any;
any             : ANY_CHAR* -> ANY[$text];

SELECT_CLAUSE   : 'select';
FROM_CLAUSE     : 'from';
WHERE_CLAUSE    : 'where';
GROUP_BY_CLAUSE : 'group' S+ 'by';
ORDER_BY_CLAUSE : 'order' S+ 'by';
ANY_CHAR        : . ;
WS              : S+ {skip();};

fragment S      : ' ' | '\t' | '\r' | '\n';

ここで入力を解析する場合:

あなたの地下室の注文から何でも何でも選択してください

次のASTが作成されます。

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

レクサーで同様のことを行おうとすると面倒になり、charストリームの先にあるキーワードをチェックするためのカスタムコード(または述語)が必要になります(どちらもきれいではありません!)。

于 2013-02-12T22:23:23.420 に答える