我試圖解析表達式序列無定界符表達式序列:解析,以便能夠解析ML/F#風格的函數調用使用YACC
myfunc expr1 expr2 expr3
然而,表達式的順序給我列出了轉移/減少衝突的列表。
我的猜測是衝突是由我的語法的遞歸性質引起的,但我不知道如何解決這些衝突。
我(簡化)的優先級規則和語法如下:
/* Lowest precedence */
%left PLUS
%left TIMES
%left LPAR
/* Highest precedence */
Expr:
| CSTINT { CstI $1 }
| LPAR Expr RPAR { $2 }
| Expr TIMES Expr { Prim("*", $1, $3) }
| Expr PLUS Expr { Prim("+", $1, $3) }
| NAME ExprList { Call(Var $1, $2) }
ExprList:
| { [] }
| Expr ExprList { $1::$2 }
當我通過這fsyacc我得到轉變的列表/減少,減少/減少衝突。一個例子移進/歸約衝突
state 11: shift/reduce error on PLUS
從fsyacc的輸出狀態11:
state 11:
items:
Expr -> Expr . 'TIMES' Expr
Expr -> Expr . 'PLUS' Expr
ExprList -> Expr . ExprList
actions:
action 'EOF' (noprec): reduce ExprList -->
action 'LPAR' (explicit left 10000): shift 6
action 'RPAR' (noprec): reduce ExprList -->
action 'COMMA' (noprec): reduce ExprList -->
action 'PLUS' (explicit left 9998): shift 13
action 'TIMES' (explicit left 9999): shift 12
action 'NAME' (noprec): shift 14
action 'CSTINT' (noprec): shift 5
action 'error' (noprec): reduce ExprList -->
action '#' (noprec): reduce ExprList -->
action '$$' (noprec): reduce ExprList -->
immediate action: <none>
gotos:
goto Expr: 11
goto ExprList: 16
它已經有一段時間我參加了編譯原理的課程,所以雖然我種知道什麼轉換/減少和減少/減少衝突,我不習慣考慮它們。特別是,我不明白如何減少可能導致有效的解析。總而言之,對以下一個或多個問題的深入瞭解將被高度讚賞:
- 爲什麼我的語法看起來模糊不清?
- 我可以使用優先級和/或關聯性規則修復它嗎?如果沒有,我可以使用優先級和/或關聯性規則修復它嗎?如果不是,我需要重寫語法嗎?如果是這樣,粗略地說,我該怎麼做?
- yacc是一個適合這樣的結構的工具嗎?