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.