簡體   English   中英

用微小的Lemon語法解決解析沖突

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM