[英]Shift/reduce conflict in yacc due to look-ahead token limitation?
我一直試圖解決一個看似簡單的轉變/減少沖突,但無濟於事。 當然,如果我忽略沖突,解析器工作正常,但如果我重新組織我的規則,我會覺得更安全。 在這里,我簡化了一個相對復雜的語法到單一沖突:
statement_list
: statement_list statement
|
;
statement
: lvalue '=' expression
| function
;
lvalue
: IDENTIFIER
| '(' expression ')'
;
expression
: lvalue
| function
;
function
: IDENTIFIER '(' ')'
;
使用yacc中的verbose選項,我得到此輸出文件描述具有上述沖突的狀態:
state 2
lvalue -> IDENTIFIER . (rule 5)
function -> IDENTIFIER . '(' ')' (rule 9)
'(' shift, and go to state 7
'(' [reduce using rule 5 (lvalue)]
$default reduce using rule 5 (lvalue)
謝謝你的幫助。
問題是,這需要2令牌前瞻才能知道它何時到達語句的結尾。 如果您輸入了以下表格:
ID = ID ( ID ) = ID
在解析器移動第二個ID(lookahead是(
)之后,它不知道這是否是第一個語句的結尾( (
是第二個語句的開頭),或者這是一個函數。所以它轉移(繼續解析)一個函數),這與上面的示例輸入有關。
如果擴展function
以允許括號內的參數和expression
允許實際表達式,事情會變得更糟,因為前瞻性要求是無限的 - 解析器需要一直到第二個=
來確定這不是函數呼叫。
這里的基本問題是沒有幫助標點符號來幫助解析器找到語句的結尾。 由於作為有效語句開頭的文本也可以出現在有效語句的中間,因此查找語句邊界很難。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.