2017-01-16 9 views
0

私は、次のしているyacc文法:var:<type> <variables_names or variables_initializations>警告:2競合を削減/削減[-Wconflicts-RR] yacc文法で

%{ 
#include <stdio.h> 
extern FILE* yyin; 
extern char* yytext; 

%} 

%token VAR ID_NAME TYPE_STRING TYPE_BOOL TYPE_NUMBER 
%token CONST VALUE_STRING VALUE_BOOL VALUE_NUMBER 

%% 

program 
    : declarations 
    ; 

declarations 
    : declaration 
    | declarations declaration 
    ; 

declaration 
    : var_declaration 
    | const_declaration 
    ; 

value 
    : VALUE_BOOL 
    | VALUE_STRING 
    | VALUE_NUMBER 
    ; 

assignment 
    : ID_NAME '=' value 
    ; 

assignments 
    : assignment 
    | assignments ',' assignment 
    ; 

id_list 
    : ID_NAME 
    | id_list ',' ID_NAME 
    ; 

declaration_expression 
    : assignments 
    | id_list 
    | assignments ',' declaration_expression 
    | id_list ',' declaration_expression 
    ; 

var_declaration 
    : VAR ':' type declaration_expression ';' { printf("%s var\n", $1); } 
    ; 

const_declaration: CONST ':' type assignments ';' {printf("const\n");} 
    ; 

type: TYPE_NUMBER 
    | TYPE_STRING 
    | TYPE_BOOL 
    ; 

%% 
void yyerror (char const *s) { 
    fprintf (stderr, "%s\n", s); 
} 

int main(int argc, char** argv[]) 
{ 

    yyparse(); 
    return 0; 
} 

これは、フォームの変数と定数の宣言を可能にする小さな言語を記述する必要がありますおよびconst:<type> <constants_initialization>。私は、次の構文のサポートを追加したい

:このような

var:<type> var1, var2=<value>, var3; 

は何か:var:<type> (<variables_names>|<variable_initializations>)+

assignments 
    : assignment 
    | assignments ',' assignment 
    ; 

id_list 
    : ID_NAME 
    | id_list ',' ID_NAME 
    ; 

declaration_expression 
    : assignments 
    | id_list 
    | assignments ',' declaration_expression 
    | id_list ',' declaration_expression 
    ; 

私は(<variables_names>|<variable_initializations>)+一部が有効になります考えた:私は私の文法に対して以下の変更を追加したことを達成するために

。しかし、私は、これらのラインに、reduce/reduce競合を取得:私は間違って何をやっている

| assignments ',' declaration_expression 
    | id_list ',' declaration_expression 

+0

私はあなたの最初のスニペットは非稼働変更後だと思います。まだ動作中のバージョンを使用している場合は、参考になるでしょう。 – rici

+0

@riciこれはhttp://pastebin.com/xb9V3N8Gで動作した最後のバージョンです。しかし、フォームの変数宣言だけをサポートします: 'var: | <初期化>。 'variables_names'と' initializations'を混在させることはできません。 – cristid9

+0

私はそれがどのように見えるのだろうと思ったが、わからなかった。ありがとう。しかし、明確にするために、あなたの質問を編集する方が良いでしょう。 "私はこの定義をdeclaration_expression:"(pastebinから)使用しましたが、 'var'宣言がIDまたは代入の混合項目のリストになるように変更したいと考えました。だから私はそれを次のように変更しました: "(現在の質問から)、それは私に紛争を減らしたり減らしたりしました。 – rici

答えて

1

私が正しく理解していれば、var宣言では裸の変数名と変数の初期化を混在させ、const宣言では初期化のみを許可します。それはかなりストレートフォワードです:あなたは間違っていた何

initialization : ID '=' value 
init_list  : initialization | init_list ',' initialization 
init_or_id  : initialization | ID 
init_or_id_list: init_or_id 
       | init_or_id_list ',' init_or_id 

const_declaration: CONST ':' type init_list 
var_declaration : VAR ':' type init_or_id_list 

はむしろアイテムリスト、との混合リストを拡張することにより、混合リストを作ることでした。それはあいまいなので、減らしたり減らしたりすることになります。

init_listinit_or_id_listは、派生物の同じポイントに(非終端記号として)表示されないため、元のように動作します。そのうちの1つはconstのキーワードに明白に続き、もう1つはvarのキーワードに明白に従います。これは幸運なことです。純粋な割り当てのリストが両方の制作物を満たすため、コンテキストを共有した場合に削減/削減の競合が発生するためです。この問題は解決可能でもあり、ときどき発生するので、解決策を追加しますが、この特定の質問に対してとは関係ありません。です。しかし、類似の問題を持つ後の読者には関係しているかもしれません。

2つの可能なリスト構文を明確にするには、潜在的に純粋な割り当てリストが常に異なるプロダクションの派生物であることを確認する必要があります混合リスト

init_list: initialization | init_list initialization 
init_or_id_list: ID 
       | init_list ',' ID 
       | init_or_id_list ',' init_or_id 

今、 init_or_id_listは必ずしも少なくとも1 ID項目が含まれているので、 init_listと混同することはできません。だから私たちは書くことができます。しかし、今、我々は最終的な結果を使用して、我々は、混合リストを受け入れ状況は、両方のリストの可能性を可能にするために必要であることを覚えておく必要があります。

pure_list: init_list 
mixed_list: init_list | init_or_id_list