2017-12-25 30 views
0

Iのような表現は、以下を有する:(N)カスタム式パーサーの記述またはANTLRライブラリの使用?

eg 1: (f1 AND f2) 

eg 2: ((f1 OR f2) AND f3) 

eg 3: ((f1 OR f2) AND (f3 OR (f4 AND f5))) 

Fのそれぞれは、SQLの断片を生成するために使用され、これらのフラグメントの各々は、ORを使用して接合/ AND式的に説明します。

1)この式

2)それ

3)を発現させるために、 "式ツリー" を生成し、最終的にSQLを生成するには、このツリーを使用し検証を解析:

は今、私はしたいと思います。

私は、トークナイザを書くことにparsers..etc EXをこの一連の記事を見つけました:

http://cogitolearning.co.uk/2013/05/writing-a-parser-in-java-the-expression-tree/

私も、私は私の場合のために使用できるかどうかを疑問に思ったライブラリANTLR、と出くわしました。

ヒント?

+1

ANTLRは、非常に強力なツールである、まだAND/OR-式を解析することはANTLRを使用するためのビット小さすぎる可能性があります(それは動作しますが、利益は小さい)。あるいは、パーサーを手作業でコーディングするか、より簡単なパーサーを使用することができます。たぶんhttps://tomassetti.me/parsing-in-javaが助けになるかもしれません。 – CoronA

+2

この質問はSOにはあまり適していません。ここでは単一のQ&Aスタイルが好まれます。あなたはヒント、ヒント、参考文献などを求めていますが、これは一つの答えではほとんど答えられません。代わりに、パーサーを作成し、特定の問題に質問することを検討してください。 –

答えて

1

あなたはJavaに興味があると思いますが(将来はそうだと思いますが)、言語の選択肢があれば、Pythonとparsyをこのようなタスクに使用することをお勧めします。それはANTLRよりもはるかに軽量です。ここで

は、適切なデータ構造にあなたのサンプルを解析し、私は一緒にノックいくつかのサンプルコードです:

import attr 
from parsy import string, regex, generate 


@attr.s 
class Variable(): 
    name = attr.ib() 


@attr.s 
class Compound(): 
    left_value = attr.ib() 
    right_value = attr.ib() 
    operator = attr.ib() 


@attr.s 
class Expression(): 
    value = attr.ib() 
    # You could put an `evaluate` method here, 
    # or `generate_sql` etc. 


whitespace = regex(r'\s*') 
lexeme = lambda p: whitespace >> p << whitespace 


AND = lexeme(string('AND')) 
OR = lexeme(string('OR')) 
OPERATOR = AND | OR 
LPAREN = lexeme(string('(')) 
RPAREN = lexeme(string(')')) 
variable = lexeme((AND | OR | LPAREN | RPAREN).should_fail("not AND OR ()") >> regex("\w+")).map(Variable) 


@generate 
def compound(): 
    yield LPAREN 
    left = yield variable | compound 
    op = yield OPERATOR 
    right = yield variable | compound 
    yield RPAREN 

    return Compound(left_value=left, 
        right_value=right, 
        operator=op) 


expression = (variable | compound).map(Expression) 

私も、単純なデータ構造にattrsを使用しています。

解析の結果は、式の階層です:

>>> expression.parse("((f1 OR f2) AND (f3 OR (f4 AND f5)))") 
Expression(value=Compound(left_value=Compound(left_value=Variable(name='f1'), right_value=Variable(name='f2'), operator='OR'), right_value=Compound(left_value=Variable(name='f3'), right_value=Compound(left_value=Variable(name='f4'), right_value=Variable(name='f5'), operator='AND'), operator='OR'), operator='AND')) 
関連する問題