2017-04-21 35 views
0

問題的一部分:這個問題的解決降低,減少衝突的語法

expr_var: var_or_ID 
| expr_var '[' expr ']' 
| NEW expr_var '(' expr_listE ')' 
| expr_var '(' expr_listE ')' 
| expr_var ARROW expr_var 
| expr_var ARROW '{' expr_var '}' 
| expr_var DCOLON expr_var 
| expr_var DCOLON '{' expr_var '}' 
| '(' expr_var ')' 
; 

說明:

expr_var -> NEW expr_var '(' expr_listE ')' . (rule 87) 
expr_var -> expr_var '(' expr_listE ')' . (rule 88) 

DCOLON reduce using rule 87 (expr_var) 
DCOLON [reduce using rule 88 (expr_var)] 
ARROW reduce using rule 87 (expr_var) 
ARROW [reduce using rule 88 (expr_var)] 
'['  reduce using rule 87 (expr_var) 
'['  [reduce using rule 88 (expr_var)] 
'('  reduce using rule 87 (expr_var) 
'('  [reduce using rule 88 (expr_var)] 
$default reduce using rule 87 (expr_var) 

每個操作員(ARROW,DCOLON ...)是左關聯的。運營商NEW是非關聯性的。

我該如何解決衝突?

回答

1

這裏的問題是在不確定性:

new foo(1)(2) 

這可以通過兩種方式來解析:

(new foo(1))(2) // call the new object 
new (foo(1))(2) // function returns class to construct 

哪個(如果任一)的這些語義可行取決於你的語言。當然可以想象,兩者都是有意義的。語法不提供關於語義的任何提示。

因此,您需要決定哪些(如果有)這些是預期的解析,並相應地制定語法。

優先級聲明不會有幫助,因爲優先級僅用於解決移位/減少衝突:優先級關係始終位於生產和預測標記之間,永遠不會位於兩個生產之間。

如同在這種情況下所做的那樣,Bison將解決減少/減少衝突的問題,以支持第一次生產。因此,如果語法合法且毫不含糊,那麼您可以根據需要通過重新排序製作來選擇所需的解析。這會給你留下警告,但你可以用一個%expect-rr聲明來壓制它。

您也可以通過顯式修改語法從正在呼叫的第一個參數排除new表情和/或從一個new的第一個參數,藉助排除通話抑制一種或另一種解析(或兩者)顯式子集expr_var