我必须为C的子集构建一个编译器。显然,因为这是我第一次做这样的事情,所以它并不是很顺利。然而。我正在尝试为所述子集构建词法分析器和解析器。
我决定一块一块地构建它并修复它们出现时的错误。所以我有一个基本的语法,如下所示。这个语法正确解析,我可以做简单的数学运算,包括比较运算符。由于thsi是C的子集,并且它们返回整数值,因此这是可能的。
现在是棘手的部分。我还希望(需要)在!
和-
中建模为一元运算符,这意味着-5 + 5应该等于0.
由于这两个一元运算符绑定了最严格的,我想我需要将它们放在我的语法的术语子句中。所以我将我的术语条款改为:
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; }
|
;
然而,这使得野牛抱怨转移/减少错误。我知道如何解决这些问题的基础知识,然而,这会在几乎所有可能的状态中产生转移/减少错误,所以我现在有点困惑。
我可以通过在-
上选择!
来为我的语法添加更多优先级,但这些优先级相同。
整个语法
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的输出如下:
bison -dv bison.y
bison.y: conflicts: 12 shift/reduce
flex lex.l
cc -o calc bison.tab.c lex.yy.c -lfl
我不会在这里粘贴整个bison.output文件,因为这是一个非常长的文件。
编辑:
下面粘贴的语法不包含SUB
令牌。添加它以便可以复制粘贴。
答案 0 :(得分:2)
term : NUMBER
| NOT term { printf("NOT term\n"); $$ = !$2; }
| LEFTPAR exp RIGHTPAR { printf("expression between parents\n");$$ = $2; }
问题出在这里,空的生产。只需删除它。
|
;