我想为简单计算器制作解析器。
输入格式类似于"10+20;“、"50*60;”、“4+8;1-7;
产量应为30 3000 12 -6。
每个结尾的大小写总是有一个分号“;
我的野牛档案看上去像这样
%{
#include <stdio.h>
extern FILE* yyin;
%}
%token T_NUM
%left '+' '-'
%left '*' '/'
%%
S : S E '\n' { printf("ans = %d\n", $2); }
| /* empty */ { /* empty */ }
;
E : E '+' E { $$ = $1 + $3; }
| E '-' E { $$ = $1 - $3; }
| E '*' E { $$ = $1 * $3; }
| E '/' E { $$ = $1 / $3; }
| T_NUM { $$ = $1; }
| '(' E ')' { $$ = $2; }
;
%%
yyerror (char *s)
{
fprintf(stderr, "%s\n", s);
}
yywrap()
{
return (1);
}
int main(int argc, char **argv)
{
yyin = fopen("testcase.in", "r");
yyparse();
fclose(yyin);
return 0;
}Flex文件如下所示:
%{
#include "cal.tab.h"
%}
%%
[0-9]+ { yylval = atoi(yytext); return T_NUM; }
[-/+*()\n] { return yytext[0]; }
[ \t] { }
[;] { }
. { return 0; /* end when meet everything else */ }
%%testcase.in看起来像这样
34+801;
1+2;
2+3;2+4;
3/2;3*5;
./a.out应该像
八三五
3.
5
6
1
15
但我的结果是“语法错误”
希望你能帮到me.plz~
发布于 2021-12-29 14:36:22
你的程序没有问题,所有的部分都在那里。您只需要尊重您自己的问题描述,并编写您的扫描器和解析器来使用分号作为终止符,而不是换行符。
您声称希望用分号结束表达式,并且示例输入具有这种格式。但是扫描器忽略分号,语法要求表达式以换行符结尾。您需要忽略换行符,并要求表达式以分号结尾:
/* In cal.y, line 6 */
S : S E ';' { printf("ans = %d\n", $2); }
/* ^
* |--------- Changed semicolon to newline.
*/
/* In cal.l, lines 7-8. Lines 9 and 10 removed. */
[-/+*();] { return yytext[0]; }
/* ^
* |-------- Changed newline to semicolon.
*/
[ \t\n] { }
/* ^
* |-----------Changed semicolon to newline.
*/发布于 2021-12-29 13:35:26
将S E '\n'更改为E ';' S,因为每个表达式都以分号结尾。请注意(来自@rici注释),另一条规则是:S: S ';' E。每条规则都会导致一个不同的结果天冬氨酸,供您稍后扫描。选择一个更适合你需要的。
https://stackoverflow.com/questions/70426118
复制相似问题