[英]Solving parsing conflicts in a tiny Lemon grammar
我正在嘗試學習Lemon解析器生成器的基礎知識,但我很快就陷入了困境。
這是一個很小的語法:
%right PLUS_PLUS.
%left DOT.
program ::= expr.
member_expr ::= expr DOT IDENTIFIER.
lhs_expr ::= member_expr.
expr ::= lhs_expr.
expr ::= PLUS_PLUS lhs_expr.
它導致1個解析沖突:
State 3:
(3) expr ::= lhs_expr *
(4) expr ::= PLUS_PLUS lhs_expr *
DOT reduce 3 expr ::= lhs_expr
DOT reduce 4 ** Parsing conflict **
{default} reduce 4 expr ::= PLUS_PLUS lhs_expr
然而,如果我重寫最后一條規則如下:
expr ::= PLUS_PLUS expr DOT IDENTIFIER.
然后它不會導致沖突。 但我不認為這是正確的方法。
如果有人能解釋什么是正確的方式,為什么,我會很感激。
所以你寫了一個含糊不清的語法,它接受:
++ x . y
有兩種解釋:
[++ x ] . y
和
++ [x . y]
[]只是我向分組展示的方式。
Lemon是一個L(AL)R解析器,這樣的解析器根本不處理歧義(多種解釋)。 報告的reduce-reduce沖突是解析器到達中間點時發生的事情; 它將“++ x”分組為“[++ x]”。 還是“++ [x。]”? 兩種選擇都是有效的,不能安全地選擇。
如果您堅持使用Lemon(或其他LALR解析器生成器),則必須通過更改語法來解決問題。 [你可以使用GLR解析器生成器; 它會接受並給你兩個解析。 但是你所做的就是將解決歧義的問題推到解析后的短語。 由於您不希望出現歧義,如果可以,您可以在解析過程中避免使用歧義。 在這種情況下,我認為你可以。]
我想你正在嘗試構建一個類似C語言的語言。 所以你想要這樣的東西:
primitive_target ::= IDENTIFIER ;
primitive_target ::= IDENTIFIER '[' expr ']' ;
access_path ::= primitive_target ;
access_path ::= access_path '.' primitive_target ;
lhs ::= access_path ;
lhs ::= PLUS_PLUS access_path ;
lhs ::= access_path PLUS_PLUS ;
program ::= expr ;
expr ::= term ;
expr ::= expr '+' term ;
term :::= '(' expr ')' ;
term ::= lhs ;
term ::= lhs '=' expr ;
term ::= constant ;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.