2012-05-07 20 views
1

私は演算子の優先順位を持たない文法を作ろうとしていますが、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

しかし、 '+'の重複がなければこれを行う方法はありますか?より多くの演算子がある場合、長いリストを2回複製することは醜いものになります。 –

+0

'(テスト)'は有効ですか? –

+0

はい。それは有効です。 –

関連する問題