2017-12-25 9 views
0

난 식처럼 가지고 다음과사용자 정의 표현 파서 작성 또는 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 각 (N) SQL의 단편을 생성하기 위해 사용되며, 각각의 조각은 OR 사용하여 접합 및/발현에 대하여 설명한다.

1)이 발현

2)

3) 표현에 대해 "표현의 나무"를 생성하고 최종 SQL을 생성하기 위해이 나무를 사용하여 유효성 검사를 구문 분석 :

지금 내가 원하는.

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

나는 또한 내가 내 경우에 사용할 수 있는지 궁금 라이브러리 ANTLR로 건너 온 :

나는 parsers..etc 전, 쓰기 tokenizers에 기사의이 시리즈를 발견했다.

팁이 있습니까?

+1

ANTLR은 매우 강력한 도구입니다, 아직 구문 분석 및/또는-표현식 ANTLR을 사용하여 너무 작은 조금 (이 작동 할 수 있지만, 혜택은 적음). 또는 파서를 손으로 코딩하거나 간단한 파서를 사용할 수도 있습니다. 어쩌면 https://tomassetti.me/parsing-in-java가 도움이 될 수 있습니다. – CoronA

+2

이 질문은 단일 Q & A 스타일을 선호하는 SO에는 적합하지 않습니다. 힌트, 팁, 참고 자료 등을 요구하고 있는데, 이는 단 하나의 대답으로는 거의 대답 할 수 없습니다. 대신 파서 작성을 고려하고 특정 문제에 대해 질문하십시오. –

답변

1

당신은 자바에 관심이있을 것 같아요. (미래에 그렇게 말하는 것이 좋을 것입니다.)하지만 언어를 선택할 수 있다면 파이썬과 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'))