我目前正在編寫一個類似Visual Basic的LALR(1)語法,並面對這個特殊的轉換/減少衝突,我不知道如何正確解決它。由於括號衝突/減少LALR(1)衝突
語法的問題的部分是(請參見EDIT 1和EDIT 2澄清):
Expression
: IndexExpression
| /* other expressions */
IndexExpression
: MemberExpression
| MemberExpression '(' ArgumentList ')'
MemberExpression
: ParenthesizedExpression
| Identifier
ParenthesizedExpression
: '(' Expression ')'
ArgumentList
: Expression
| Expression ',' ArgumentList
| ',' ArgumentList
和移位/減少衝突是這樣的:
State 109
237 ParenthesizedExpression: '(' Expression ')' .
$default reduce using rule 237 (ParenthesizedExpression)
...
State 295
231 IndexExpression: MemberExpression '(' . ArgumentList ')'
237 ParenthesizedExpression: '(' . Expression ')'
...
Expression go to state 352
...
State 352
182 ArgumentList: Expression .
183 | Expression . ',' ArgumentList
237 ParenthesizedExpression: '(' Expression . ')'
...
')' shift, and go to state 109
')' [reduce using rule 182 (ArgumentList)]
換句話說,解析器在面對由圓括號包裝的表達式時不確定,無論是具有單個expre的ArgumentList ssion或括號表達式。
有什麼辦法可以解決這個衝突,同時把語法保持爲LALR(1)?
謝謝。
編輯1:
/*其他表達式* /在表達其實不是一個空的表情,我只是寫它爲簡潔的方式。實際上它具有其它替代的表達式:
Expression
: IndexExpression
| Expression '+' Expression
| ...
編輯2:
以下是其中@rici指出可能是有問題的語法(尤其聲明的第一右手規則的附加部分):
Statement
: MemberExpression ArgumentList
| MemberExpression '=' Expression
| MemberExpression '(' ArgumentList ')' '=' Expression
| ...
你需要展示更多的語法。或者,更好的是,創建一個具有相同問題但只有少數幾部作品的可重新編譯的語法。順便說一下,'argument_list'語法很奇怪。爲什麼你覺得用左遞歸編寫它是有用的,在LALR(1)解析器中通常應該避免使用左遞歸?多重缺失的觀點意味着什麼?如果所有其他參數都可以省略,爲什麼最後一個不能呢? – rici
您是否允許在不帶圓括號的情況下調用帶有一個參數的函數的VB語法?如果是這樣,那很可能是你的問題。 – rici
@rici **缺少參數**:在這個特定的VB語言中,它允許參數列表具有空參數,除了最後一個。由於我不想讓_Expression_變爲空,我最終將_ArgumentList_中的第三條規則放置了。 **括號括起來的一個參數**:是的!事實上,在昨天更深入地尋找根本原因之後,我得出結論認爲這可能是原因。你有關於如何包含這個語法的建議嗎? –