Shift / decrease with equal priority

I need to build a compiler for a subset of C. Obviously, since this is my first time doing such a thing, this is not very good. However. I am currently trying to create a lexer and parser for the specified subset.

I decided to assemble it in parts and correct the errors as they appeared. Therefore, I have a basic grammar as shown below. This grammar parses correctly, and I can do simple math, including comparison operators. Since thsi is a subset of C and they return integer values, this is possible.

Now comes the hard part. I also want (need) to model in !and -how the operators are unary , which means that the value -5 + 5 should be 0.

Since these two unary operators bind the densest, I suggest that I need to put them in the term term of my grammar. Therefore, I changed the term clause to the following:

term        :   NUMBER
            |   NOT term { printf("NOT term\n"); $$ = !$2; }
            |   SUB term { printf("MINUS term\n"); $$ = - ($2);}
            |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
            |   
            ;

However, this makes the bison complain of shift / decrease errors. However, I know the basics of how to fix them, but this causes a shift / decrease error in almost every possible state, so I'm a little confused at the moment.

I could add more priorities to my grammar by choosing -over !, but they are equally tight.

Whole grammar

calclist    : /* nothing */
            | COMMENT { printf("Comment\n"); }
            | calclist comp EOL { printf("= %d\n", $2); } 
            ;

comp        :   exp
            |   comp GREATER exp { printf("comp GREATER factor\n");$$ = $1 > $3; }
            |   comp LESS exp { printf("comp LESS factor\n");$$ = $1 < $3; }
            |   comp EQUAL exp { printf("comp EQUAL factor\n");$$ = $1 == $3; }
            |   comp NEQUAL exp { printf("comp NEQUAL factor\n");$$ = $1 != $3; }
            ;

exp         :   factor
            |   exp ADD factor { printf("exp add factor\n");$$ = $1 + $3; }
            |   exp SUB factor { printf("exp sub factor\n");$$ = $1 - $3; }
            ;

factor      :   term       
            |   factor MUL term { printf("factor mul term\n");$$ = $1 * $3; }
            |   factor DIV term { printf("factor div term\n");$$ = $1 / $3; }
            ;           

term        :   NUMBER
            |   NOT term { printf("NOT term\n"); $$ = !$2; }
            |   SUB term { printf("MINUS term\n"); $$ = - ($2);}
            |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
            |   
            ;

Bison's output is as follows:

bison -dv bison.y
bison.y: conflicts: 12 shift/reduce
flex lex.l
cc -o calc bison.tab.c lex.yy.c -lfl

I will not embed the entire bison.output file here, as it is a rather long file.

Edit:

The grammar inserted below does not contain a token SUB. Added it so that it can be copied.

+4
1
term        :   NUMBER
            |   NOT term { printf("NOT term\n"); $$ = !$2; }
            |   LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }

, . .

            |   
            ;
+2

Source: https://habr.com/ru/post/1529310/


All Articles