所以在我的語言,我想有斑點的語法表達:奇怪移位/減少不含糊衝突(我認爲)語法
myObject.myProperty
myObject.myProperty.subProperty
而且我要聲明
Object myObject = 1
此外,對象類型可以命名空間:
Object.SubObject mySubObject = 1
的簡化語法如下:
program:
declaration;
| expression;
declaration:
TOKEN_IDENTIFIER TOKEN_IDENTIFIER '=' TOKEN_INTEGER;
| TOKEN_IDENTIFIER '.' TOKEN_IDENTIFIER TOKEN_IDENTIFIER '=' TOKEN_INTEGER;
expression:
TOKEN_IDENTIFIER;
| expression '.' TOKEN_IDENTIFIER;
不幸的是,用Bison編譯這個語法給出了一個shift-reduce衝突。看看狀態機的輸出,在我看來,Bison解釋它的方式是錯誤的。下面是狀態1,這是讀取所述第一標識符之後的狀態:
State 1
3 declaration: "identifier" . "identifier" '=' "integer"
4 | "identifier" . '.' "identifier" "identifier" '=' "integer"
5 expression: "identifier" .
"identifier" shift, and go to state 5
'.' shift, and go to state 6
"end of code" reduce using rule 5 (expression)
'.' [reduce using rule 5 (expression)]
和狀態6(讀取點陣當默認移位狀態)僅表示一個聲明:
State 6
4 declaration: "identifier" '.' . "identifier" "identifier" '=' "integer"
"identifier" shift, and go to state 10
它在我看來,在狀態1中,讀點時不應該有減少的可能性。它應該向前看,如果它看到兩個標識符之後(兩者之間沒有點),它應該轉換到僅聲明狀態,但是如果它看到第二個點或代碼結束,它將減少到表達式。事實上,聲明的規則是兩個標識符可以並排找到而沒有點之間的唯一實例應該消除語法歧義,因此不存在移位減少錯誤。
我試過這與ielr和canonical-lr具有相同的結果(不知道這是否應該重要)。
任何想法?我的解釋是它應該如何工作不正確?
這是告訴你的是,如果我們看到了'TOKEN_IDENTIFIER''。 TOKEN_IDENTIFIER',它不知道,在你之外提供其他提示,是否應該減少,返回一個「表達式」,或者換入另一個標記,因爲它被看作是「聲明」的第一部分。一些額外的語法,例如要求「表達式」和「聲明」以分號或某物結尾,這將有助於減少歧義......用你當前的規則,「xy a」可以是一個表達式, ('xy ab')或者聲明的開頭...... – twalberg
在這個語法中,我不提供遞歸到多個語句中,所以語法不能有多個語句。甚至當我添加';'定界符,我仍然得到轉變/減少衝突。 –
環顧四周,我相信我遇到的問題與http://stackoverflow.com/questions/19335353/a-yacc-shift-reduce-conflict-on-an- unambiguous-grammar一樣,那是的,它是一個明確的語法,但也許它是一個LR(2),野牛不處理。我認爲ielr選項應該解決這個問題。關於如何調整語法的任何想法,因此它是LR(1)。 –