あなたは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'))
ANTLRは、非常に強力なツールである、まだAND/OR-式を解析することはANTLRを使用するためのビット小さすぎる可能性があります(それは動作しますが、利益は小さい)。あるいは、パーサーを手作業でコーディングするか、より簡単なパーサーを使用することができます。たぶんhttps://tomassetti.me/parsing-in-javaが助けになるかもしれません。 – CoronA
この質問はSOにはあまり適していません。ここでは単一のQ&Aスタイルが好まれます。あなたはヒント、ヒント、参考文献などを求めていますが、これは一つの答えではほとんど答えられません。代わりに、パーサーを作成し、特定の問題に質問することを検討してください。 –