这不是作业,但它来自一本书。
我收到了以下bison
规范文件:
%{
#include <stdio.h>
#include <ctype.h>
int yylex();
int yyerror();
%}
%token NUMBER
%%
command : exp { printf("%d\n", $1); }
; /* allows printing of the result */
exp : exp '+' term { $$ = $1 + $3; }
| exp '-' term { $$ = $1 - $3; }
| term { $$ = $1; }
;
term : term '*' factor { $$ = $1 * $3; }
| factor { $$ = $1; }
;
factor : NUMBER { $$ = $1; }
| '(' exp ')' { $$ = $2; }
;
%%
int main() {
return yyparse();
}
int yylex() {
int c;
/* eliminate blanks*/
while((c = getchar()) == ' ');
if (isdigit(c)) {
ungetc(c, stdin);
scanf("%d", &yylval);
return (NUMBER);
}
/* makes the parse stop */
if (c == '\n') return 0;
return (c);
}
int yyerror(char * s) {
fprintf(stderr, "%s\n", s);
return 0;
} /* allows for printing of an error message */
任务是执行以下操作:
重写规范以添加以下有用的错误消息:
生成
“缺少右括号”,由字符串生成(2 + 3
“缺少左括号”,由字符串 2 + 3)生成
“缺少运算符”,由字符串 2 3 生成
“缺少操作数”,由字符串(2 +)
我能够提出的最简单的解决方案是执行以下操作:
half_exp : exp '+' { $$ = $1; }
| exp '-' { $$ = $1; }
| exp '*' { $$ = $1; }
;
factor : NUMBER { $$ = $1; }
| '(' exp '\n' { yyerror("missing right parenthesis"); }
| exp ')' { yyerror("missing left parenthesis"); }
| '(' exp '\n' { yyerror("missing left parenthesis"); }
| '(' exp ')' { $$ = $2; }
| '(' half_exp ')' { yyerror("missing operand"); exit(0); }
;
exp : exp '+' term { $$ = $1 + $3; }
| exp '-' term { $$ = $1 - $3; }
| term { $$ = $1; }
| exp exp { yyerror("missing operator"); }
;
这些更改有效,但会导致很多冲突。
这是我的问题。
有没有办法以这种方式重写这个语法,以免产生冲突?
感谢任何帮助。
答案 0 :(得分:0)
是的,有可能:
command : exp { printf("%d\n", $1); }
; /* allows printing of the result */
exp: exp '+' exp {
// code
}
| exp '-' exp {
// code
}
| exp '*' exp {
// code
}
| exp '/' exp {
// code
}
|'(' exp ')' {
// code
}
Bison允许不明确的语法。
我不知道如何重写语法以避免冲突。您只是错过了术语,因素等等。当您想要左递归上下文无关语法时,您可以使用这些。
从这个语法:
E -> E+T
|T
T -> T*F
|F
F -> (E)
|num
一旦你从左递归中解放出来,你就会去:
E -> TE' { num , ( }
E' -> +TE' { + }
| eps { ) , EOI }
T -> FT' { ( , num }
T' -> *FT' { * }
|eps { + , ) , EOI }
F -> (E) { ( }
|num { num }
这些集合与规则一起显示了使用该规则必须具有的输入字符。当然这只是简单算术表达式的例子,例如2 *(3 + 4)* 5 +(3 * 3 * 3 + 4 + 5 * 6)等。
如果您想了解有关此主题的更多信息,我建议您阅读&#34;左递归上下文无关语法&#34;。有一些很好的书籍涵盖了这个主题,还包括如何获取输入集。
但正如我上面所说,所有这一切都可以避免,因为 Bison允许模糊语法。