2017-03-09 5 views
2

私はバイソンを初めて勉強しました。私は文法を解析することを試みています。 私は今解決していないシフト/リミットのconflightに直面しています。式の文法のシフト/リダクションの衝突を解決する

は、文法は以下の通りです:

%left "[" "(" 
%left "+" 

%% 

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 


expression : "(" expression ")" 
      | STRING_LITERAL  
      | INTEGER_LITERAL   
      | DOUBLE_LITERAL 
      | expression "(" expression_list ")" /*function call*/ 
      | expression "[" expression "]" /*index access*/ 
      | expression "+" expression   
      ; 

これは私の文法ですが、私はこれら二つのルール"(" expression ")"expression "(" expression_list ")"との競合を減らす/シフトに直面しています。 この競合を解決するにはどうすればよいですか?

EDIT:これは優先度クライミングを使用して解決できることはわかっていますが、これは表現文法のほんの一部であり、優先度クライミングを使用して表現文法のサイズが爆発するためです。

+0

これが文法全体である場合は、シフト・リダクションの競合はありません。しかし、私はそれがあなたの文法全体であるとは思わない。 – rici

+0

wow私は今、本当に馬鹿だと感じています...私はこの1つに影響を与えた別のルールでタイプミスを発見しました – Exagon

+0

それは私が[mcve]を求める理由です。 [mcve]を作成すると、問題を明確にするのに役立ちます。 – rici

答えて

2

提示されているようにshift-reduceコンフリクトは文法にはありませんので、完全な文法の抜粋に過ぎません。その場合

%start program 
%% 
program: %empty 
     | program expression 

を、例えば、a(b)与えられ、パーサはそれかどうかわかりませんので、あなたが曖昧に実行されます。具体的には、正確にシフト/競合を減らすには、実際の文法が含まれている場合が挙げられます単一の呼び出し式または2つの連続した式、最初は単一の変数、および2番目のかっこ式です。この問題を回避するには、式(ステートメント)を区切るトークンが必要です。式リストを可能に

expression_list : expression_list "," expression 
       | expression 
       | /*empty*/ 
       ; 

望ましくない可能性がある(f(,foo)のように),foo、可能にする:

は、他のいくつかの問題があります。

arguments: %empty 
     | expr_list 
expr_list: expr 
     | expr_list ',' expr 

そして優先順位はおそらく後ろです。通常は、callやindexのような後置演算子が算術演算子よりも緊密にバインドされることを望んでいるので、最後に来るべきです。それ以外の場合はa+b(7)(a+b)(7)です。これは従来とは異なります。

+0

あなたは正しいです、私は残念です – Exagon

関連する問題