複雑な文法を書きました。文法は以下で見ることができます:
grammar i;
options {
output=AST;
}
@header {
package com.data;
}
operatorLogic : 'AND' | 'OR';
value : STRING;
query : (select)*;
select : 'SELECT'^ functions 'FROM table' filters?';';
operator : '=' | '!=' | '<' | '>' | '<=' | '>=';
filters : 'WHERE'^ conditions;
conditions : (members (operatorLogic members)*);
members : STRING operator value;
functions : '*';
STRING : ('a'..'z'|'A'..'Z')+;
WS : (' '|'\t'|'\f'|'\n'|'\r')+ {skip();}; // handle white space between keywords
出力は AST を使用して行われます。上記はほんの一例です。しかし、私はいくつかの大きな文法を開発しており、これにアプローチする方法についてアドバイスが必要です.
たとえば、上記の文法に従って、次のように生成できます。
SELECT * from table;
SELECT * from table WHERE name = i AND name = j;
このクエリはさらに複雑になる可能性があります。Java コードに AST を実装したので、ツリーを取り戻すことができます。文法とロジックを分離したかったので、それらはまとまりがあります。したがって、AST が最適なアプローチでした。
ユーザーはクエリを文字列として入力し、私のコードは可能な限り最善の方法でクエリを処理する必要があります。ご覧のとおり、関数パーサーは現在 * であり、これはすべてを選択することを意味します。将来的には、これは他のものを含むように拡張される可能性があります。
私のコードはこれをどのように処理できますか? 最善のアプローチは何ですか?
私はこのようなことができます:
String input = "SELECT * from table;";
if(input.startsWith("SELECT")) {
select();
}
ご覧のとおり、オプションのフィルターも処理する必要があるため、このアプローチはより複雑です。AND と OR である operatorLogic も実行する必要があります。
最善の方法は何ですか?オンラインで調べましたが、これを処理する方法の例が見つかりませんでした。
例を挙げることはできますか?
編集:
String input = "SELECT * FROM table;";
if(input.startsWith("SELECT")) {
select();
}
else if(input.startsWith("SELECT *")) {
findAll();
}