2012-05-07 4 views
1

저는 연산자 우선 순위가없는 문법을 만들려고합니다. 그러나 하나의 연산자를 사용하거나 괄호로 묶어야합니다. (단순화를 위해 유효한 연산자 대신 여기에 id|int_literal etc+ 대신 test을 사용). 따라서 예 :backtrack = true를 사용하지 않고 어떻게 해결할 수 있습니까?

test + test ///valid! 
(test + test) + test ///valid! 
(test + test) + (test + test) /// valid! 
test + test + test /// invalid! 

backtrack = true가 필요하지 않은 문법을 작성하는 방법이 있습니까? 왼쪽 탈퇴가 실제로 여기에 의미가 있다고 생각하지 않습니다. 그리고 나는 구문 론적 술어가 어떻게 도움이 될지 확신하지 못합니다.

가 여기에 내가 가진 무엇 (backtrack=true 필요) :

fragment 
bexpr : 'test' | '(' cbebr ')'; 

fragment 
cbexpr : bexpr '+' bexpr; 

expr : bexpr | cbexpr; 

답변

1

당신은 How to remove global backtracking from your grammar보고 할 수 있습니다.

expr의 두 가지 대안이 bexpr으로 시작될 수 있다는 사실에 모호성이 있습니다. 이 모호성을 제거해야합니다. 핵심은 전체 표현식 인 경우 +이 괄호 없이만 발생한다는 관찰에 있습니다. 즉

expr : operand ('+' operand)?; 
operand : '(' expr ')' | 'test'; 

: 그래서 우리가 끝낼 운영자 식을 피연산자로 발생하면, 다음 괄호로 묶어야합니다.

+0

그러나 '+'가 중복되지 않으면이 작업을 수행 할 수있는 방법이 있습니까? 더 많은 연산자가있을 때 긴리스트가 두 번 복제되게되면 추한 상태가됩니다. –

+0

'(테스트)'가 유효합니까? –

+0

예. 유효합니다. –