0
...
IF LP assignment-expression RP marker statement {
    backpatch($3.tlist,$5.instr);
    $$.nextList = mergeList($3.flist,$6.nextList);
}
|IF LP assignment-expression RP marker statement ELSE Next statement {
    backpatch($3.tlist,$5.instr);
    backpatch($3.flist,$8.instr);
    YYSTYPE::BackpatchList *temp = mergeList($6.nextList,$8.nextList);
    $$.nextList = mergeList(temp,$9.nextList);
} 
...

代入式は、C 演算子を使用して可能な任意の代入式です=, +=, -=, *=, /=

LP = (
RP = )

markerそしてNextどちらもEMPTYルール

上記の文法規則と実装の問題は、式が次の場合に正しいコードを生成できないことです。

bool a;
if(a){
  printf("hi");
}
else{
  prinf("die");
}

代入式にはreloporORまたはANDtoが含まれている必要がありますgenerate correct code。この場合、relop同じケースの比較を行うため、 と に適用されORますAND

しかし、上記のコードのように、このコードには何も含まれていないため、正しいコードを生成できません。次のルールを使用して正しいコードを生成できますが、これはtwo reduce-reduce conflict.

  ...
  IF LP assignment-expression {
     if($3.flist == NULL && $3.tlist == NULL)
       ...
      } RP marker statement {
            ...
  }
  |IF LP assignment-expression{
    if($3.flist == NULL && $3.tlist == NULL)
    ...
    } RP marker statement ELSE Next statement {
      ...
  } 
  ...

文法規則が期待どおりに機能するようにするには、文法規則でどのような変更を行う必要がありますか?

here と Dragon book のIF ELSE 文法規則を試しましたが、これを解決できませんでした。文法全体はGithubで見つけることができます

4

2 に答える 2

1

あなたの文法では の定義が間違っているようですexpression

代入式は、式に還元できる多くの非終端記号の 1 つにすぎません。if/then/else 構造の場合、通常、括弧内に任意の式が発生することを許可する必要があります。ご指摘のとおり、最初の例は完全に有効な C ですが、代入は含まれていません。

あなたの文法には、次の行があります。

/*Expression list**/
expression:
assignment-expression{}
|expression COMMA assignment-expression{}
;

ただし、式には複数の代入式を含めることができる必要があります。yacc/bison にあまり詳しくないので、これを次のように変更する必要があると思います。

/*Expression **/
expression:
assignment-expression{}
|logical-OR-expression{}
|logical-AND-expression{}
|inclusive-OR-expression{}
|exclusive-OR-expression{}
|inclusive-AND-expression{}
|equality-expression{}
|relational-expression{}
|additive-expression{}
|multiplicative-expression{}
|exponentiation-expression{}
|unary-expression{}
|postfix-expression{}
|primary-expression{}
|expression COMMA expression{}
;

これがうまくいくとは断言できませんし、不完全かもしれませんが、理解していただければ幸いです。それぞれの異なるタイプの式は、式に還元できる必要があります。文法の前半に非常によく似たものがあるstatementので、これはうまくいけば意味があるはずです。

LR 文法がどのように機能するかについてのいくつかのチュートリアルを読んだり、見たりすると役立つ場合があります。

于 2015-04-09T17:17:51.247 に答える
1

ルールの途中のアクションを挿入するには、左因数分解する必要があります。そうしないと、bison で生成されたパーサーは、2 つの MRA のどちらを削減するかを決定できません。(それらはおそらく同一であるにもかかわらず、bison はそれを知りません。)

if_prefix: "if" '(' expression ')' { $$ = $3; /* Normalize the flist */ }
if: if_prefix marker statement { ... }
  | if_prefix marker statement "else" Next statement { ... }

( factor を別の方法で残すこともできます。これは 1 つの提案にすぎません。)

于 2015-04-09T22:33:22.977 に答える