2016-04-17 8 views
0

私は文法の原因となるエラーのこの部分を知っていますが、それを修正する方法はわかりません。%左右を使用していますが、助けにはなりません。誰でもこの文法の問題点を知るために私を助けてください。 ご協力いただきありがとうございます。yaccでシフト/エラーを減らす

%token VARIABLE NUM 
%right '=' 
%left '+' '-' 
%left '*' '/' 
%left '^' 
%start S_PROOP 

EQUATION_SEQUENCE 
    : FORMULA '=' EQUATION 
    ; 
EQUATION 
    : FORMULA 
    | FORMULA '=' EQUATION 
    ; 
FORMULA 
    : SUM EXPRESSION 
    | PRODUCT EXPRESSION 
    | EXPRESSION '+' EXPRESSION 
    | EXPRESSION '*' EXPRESSION 
    | EXPRESSION '/' EXPRESSION 
    | EXPRESSION '^' EXPRESSION 
    | EXPRESSION '-' EXPRESSION 
    | EXPRESSION 
    ; 
EXPRESSION 
    : EXPRESSION EXPRESSION 
    | '(' EXPRESSION ')' 
    | NUM 
    | VARIABLE   
    ; 

答えて

0

通常のスタイルでは、端末には小文字を使用し、端末には大文字を使用します。大文字の大文字を無差別に使用すると、文法を読むのが難しくなります(少なくとも、通常のyacc/bisonスタイルに慣れている人は文法を読みにくくなります)。だから私は、キャップロックキーにあまり頼らずにこの答えを書いた。

基本的な問題は、それが結合性のいずれかの指示を提供していないので、明らかに曖昧で生産

expression: expression expression 

です。点で、それは

expression: expression '+' expression 

異なるではないが、その衝突が優先宣言を使用して解決することができる。

%left '+' 

差が第1生産がそれを行う任意の端末のシンボルを持っていないということです曖昧さを解消するために優先ルールを使用することは不可能です:yacc/bisonでは、優先順位は常に潜在的な削減と潜在的なシフトの比較です。潜在的な削減は、いくらかの生産量を減らすことができます。潜在的なシフトは、いくらかの生産を伸ばすことができるかもしれない末端記号である。電位シフトは終端記号でなければならないので、これが優先順位宣言で使用されるものです。デフォルトでは、潜在的な削減の優先順位は右側の最後の端末記号によって定義されますが、%precのマーカーを使用して別の端末を指定することは可能です。いずれの場合も、優先順位関係は終端記号を含み、文法が2つの終端の並置を許す場合、関連する終端記号は存在しない。

競合を解決するために優先権を使用する義務がないため、回避するのは簡単です。あなただけの競合を避けることができます:

/* Left associative rule */ 
expr_sequence: expr | expr_sequence expr 

/* Alternative: right associative rule */ 
expr_sequence: expr | expr expr_sequence 

あなたが並置によってつもり何兆候がないので、私は上記の選択肢のうちの1つまたは他のをお勧めすることができないんだけど、通常、私は最初のものの方に傾くだろう。

equation_sequenceの文法とはまったく異なるわけではありませんが、equation_sequenceは実際には終端記号を使用しているため、優先順位宣言で処理されている可能性があります。書かれているようにequation_sequenceが右結合であることに注意する価値があります。これは通常、代入演算子には正しいと見なされます(Cのような言語のa = b = c + 3a = (b = c + 3)と解釈され、(a = b) = c + 3として解析されないため、少数の右結合演算子の1つになります)。実際にあなたが意図したものではないかもしれません。