6

私はLemon parser generatorの基礎を学びたいと思っていますが、私はすぐに立ち往生しました。ここで小さなレモン文法で解析の競合を解決する

は小さな文法です:

%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 

+0

あなたは物事の余分な名前なしでこれを考えることをお勧めします。どこにでも 'lhs_expr'があれば、実際に何が求められているかを明確に見るために' expr DOT IDENTIFIER'と書くことができます。すべてが 'expr'の面であれば、より明確に衝突を見ることができます。 –

+0

これは、 'lhs_expr'は' expr DOT IDENTIFIER'以外のものにすることができます。この特定の文法には他の規則は含まれていません。なぜなら、それを最小限にしたいからです。 'IDENTIFIER'または' expr LBRACKET expr RBRACKET'などです。ルール 'PLUS_PLUS lhs_expr'を一度書くだけで、すべての可能な左辺の式が事前にインクリメントされています。 –

答えて

5

だから、受け入れることを言うあいまいな文法を、書きましたグループに表示する

レモンは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 ; 
+0

答えをありがとう。しかし、 '++ xのあいまいさは避けてください。 yは 'PLUS_PLUS'と' DOT'の優先順位によって解決されますか?私の文法を考えれば、 'DOT'は優先順位が高くなります(' PLUS_PLUS'の後に表示されるため)。 –

+0

ANTLRの%right宣言と%left宣言は分かりません。あなたが本質的に望むのは、+ +を含む左の文脈でドットに出会ったときにシフトするものです。右の%と%は力のシフトを残していることは私には分かりません。 my * guess *はバイナリ演算子で強制連想型ですが、PLUS_PLUSはバイナリ演算子ではありませんので意味がありません。私の治療法は、それらの特別な宣言を避け、文法が私(あなた、あなた)が直接欲しかったことをするように強制することでした。 –

+0

ANTLRではなく、レモンです。とにかく、ありがとう! –

関連する問題