それは興味深い質問です。JSqlParser の別のフォーク ( https://github.com/JSQLParser/JSqlParser ) を紹介できますか。これまでは SQL のメタデータ分析に使用していましたが、今まで評価を行う必要はありませんでした。
ここに私の2セントがあります。演算子の優先順位は、部分的に JSqlParsers グラマー内で偽造されます。(@jbaliuka: あなたのフォークを調べたところ、古いバージョンの JSqlParser に基づいていたと思います。sourceforge での最新の開発 (2010?) では、加算と乗算に演算子の優先順位が導入されました。追加の分析式の解析により、私のフォークでいくつかの変更がトリガーされました。 . 試してみていただければ幸いです。)
これは、JSqlParser V0.8.8 を使用した加算と乗算の非常に単純な式評価器です。最初の JSqlParser は、JSqlParser のビジター構造を使用してトラバースする、このツリーから継承されたオブジェクト階層から、解析ツリーまたはより正確には a を提供します。確かに、完全なバージョンを作成するには、まだ多くの作業を行う必要があります。これは概念の証明です。私の例では、括弧の優先順位さえも正しく行われていることを知るのは興味深いことでした。
import java.util.Stack;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
import net.sf.jsqlparser.expression.operators.arithmetic.Multiplication;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.util.deparser.ExpressionDeParser;
public class SimpleEvaluateExpr {
public static void main( String[] args ) throws JSQLParserException {
//examples
evaluate("4+5*6");
evaluate("4*5+6");
evaluate("4*(5+6)");
evaluate("4*(5+6)*(2+3)");
}
static void evaluate(String expr) throws JSQLParserException {
//here is the stack you mentioned ;)
final Stack<Long> stack = new Stack<Long>();
System.out.println("expr=" + expr);
Expression parseExpression = CCJSqlParserUtil.parseExpression(expr);
//Deparser traverses the complete expression hierarchy. It was mainly used
//for SQL output but this is now done using toString but is always a useful
//traversal tool.
ExpressionDeParser deparser = new ExpressionDeParser() {
@Override
public void visit(Addition addition) {
super.visit(addition);
long sum1 = stack.pop();
long sum2 = stack.pop();
stack.push(sum1 + sum2);
}
@Override
public void visit(Multiplication multiplication) {
super.visit(multiplication);
long fac1 = stack.pop();
long fac2 = stack.pop();
stack.push(fac1 * fac2);
}
@Override
public void visit(LongValue longValue) {
super.visit(longValue);
stack.push(longValue.getValue());
}
};
StringBuilder b = new StringBuilder();
deparser.setBuffer(b);
parseExpression.accept(deparser);
System.out.println(expr + " = " + stack.pop() );
}
}
出力は次のとおりです。
expr=4+5*6
4+5*6 = 34
expr=4*5+6
4*5+6 = 26
expr=4*(5+6)
4*(5+6) = 44
expr=4*(5+6)*(2+3)
4*(5+6)*(2+3) = 220
したがって、最初の例の式の解析ツリーは次のようになります。
ビジターは最初の順序で深くトラバースします。