转变减少野牛语法中的冲突?

时间:2013-04-13 12:12:38

标签: bison yacc

我有以下Bison Grammar文件,当我做“bison -d filename.y”时,我收到一条消息

冲突:5转/减少。

实际上他们已经8岁了,我设法摆脱了3但不知道其余部分在哪里,我猜这是与COMMA有关的东西,但是嗯.. anyidea在我的语法定义中有什么不对。解析器应该解析部分Prolog语法

%{#include <math.h>
#include <stdio.h>
void yyerror(char *message);
%}
%start program
%token ATOM VAR NUM

%token DOT COMMA
%token PARENTLEFT PARENTRIGHT RSQRBRACKETS LSQRBRACKETS
%token IF CUT IS PIPE
%token SMALLEREQ GREQ SMALLER GREATER EQ
%token PLUS MULTIP DIVIDE MINUS MOD
%token Aus

%left PLUS MINUS
%left DIVIDE MULTIP
%left COMMA

%%
program :           program rule                { printf("programm fertig gelesen \n");} 
        |       program fact                { printf("programm fertig gelesen \n");} 
        |       rule                        { printf("programm fertig gelesen \n");} 
        |       fact                        { printf("programm fertig gelesen \n");}
;

fact :              struct DOT                  { printf("Fakt gelesen\n\n\n"); }
;

rule :              struct IF subProbList DOT   { printf("Regel mit %d Teilprobleme    gelesen\n\n\n", $3); }
;

struct :            ATOM PARENTLEFT parameterList PARENTRIGHT  {printf("%s mit %d    Variablen\n",$1,$3); $$=$3;}
;

subProbList :       subProb                     {$$ = 1; }
        |       subProbList COMMA subProb   {$$ = $1 + 1;}
;

subProb :           struct | assignmentTerm | comparison | CUT { printf("CUT Op\n"); }
;

assignmentTerm :    exp IS exp                  { printf("is mit %d Variabeln\n", ($1 + $3)); $$ = $1 + $3; }
;

exp :               num                         { $$ = 0; }
    |           var                         { printf("Variable %s \n", $1); $$ = 1; } 
    |           exp operation exp           { printf("left exp is %d right exp is %d\n",$1,$3); $$ = $1 + $3;} 
    |           PARENTLEFT exp PARENTRIGHT         { $$ = $2;}
;

parameter :         var                         { printf("Variable %s\n",$1 ); $$ = 1; }
        |       struct                      { $$ = $1; }
        |       list                        { $$ = $1; }
;

parameterList :     parameter                   { $$ = $1;}
            |   parameterList COMMA parameter {$$= $1 + $3;}
;

operation :         PLUS | MINUS | MULTIP | DIVIDE | MOD
;

comparison :        var comparisonOp num        { printf("Variable %s \n", $1);

                                                printf("Vergleich mit 1 Vars\n" );
                                                $$=1;   
                                            }
        |       num comparisonOp var        {  
                                                printf("Variable %s \n", $3);
                                                printf("Vergleich mit 1 Vars\n" );
                                                $$=1;   
                                            }

        |       var comparisonOp var        {   printf("Variable %s \n", $1);
                                                printf("Variable %s \n", $3);
                                                printf("Vergleich mit 2 Vars\n" );
                                                $$=2;   
                                            }
        |       num comparisonOp num        {  
                                                $$=0; 
                                                printf("Vergleich mit 0 Variablen \n");

                                            }
;

comparisonOp :      EQ | GREATER | SMALLER | GREQ | SMALLEREQ
;

list :              LSQRBRACKETS varList RSQRBRACKETS       {$$ = $2;}
    |           LSQRBRACKETS elementList RSQRBRACKETS   {$$ = $2;}
    |           LSQRBRACKETS RSQRBRACKETS               {$$ = 0;}
;
varList :           var PIPE var                {   printf("Variable %s \n", $1);
                                                printf("Variable %s \n", $3);
                                                $$ = 2;
                                            }
;
elementList :       ATOM                        { $$ = 0;}
            |   var                         { printf("Variable %s \n", $1); $$ = 1; } 
            |   elementList COMMA var       { $$ = $1 + 1; } 
            |   elementList COMMA ATOM      { $$ = $1; }
;

num : NUM | MINUS NUM
;
var : VAR | MINUS VAR
;
%%

int main(int argc, char **argv){
    yyparse();
    return 0;
}

void yyerror(char *message) {
    printf("How about no?Well,no,that word doesnt belong to this classy language! \n");
}

1 个答案:

答案 0 :(得分:2)

如果您将exp的定义更改为

exp :           num    
    |           var
    |           exp PLUS exp
    |           exp MINUS exp
    |           exp MULTIP exp
    |           exp DIVIDE exp
    |           exp MOD exp
    |           PARENTLEFT exp PARENTRIGHT
;

即在operation内展开exp(并将其删除)并添加

%left MOD

在其他运营商中,即定义其与其他运营商相关的优先级,那么你应该没问题。