使用 flex 和 bison 制作一个简单的计算器
Make a simple calculator using flex and bison
我正在尝试使用 flex 和 bison 生成器制作一个非常简单的计算器。
它只适用于整数。
我正确地编译了词法分析器文件,没有错误;但是当我编译解析器文件时,它显示了一些警告:
- warning: 1 nonterminal useless in grammar
- warning: 2 rules useless in grammar
- 21.1-4: warning: nonterminal useless in grammar: Line
- 21.9-1: warning: rule useless in grammar: Line: NWL
- 22.9-55: warning: 1 nonterminal useless in grammar: Exp NWL
显示这些警告后生成输出文件。
我用 gcc 编译了输出文件;它制作了一个 .exe 文件。
当我 运行 .exe 文件并尝试计算时,它向我显示此错误:
- syntax error
请帮助我。
我的代码:
词法分析器文件
%option noyywrap
%{
#define YYSTYPE double
#include <stdio.h>
#include "x.tab.h"
%}
DIG [0-9]
%%
{DIG}+ { yylval = atoi(yytext); return NUM; }
"+" { return PLS; }
"-" { return MNS; }
"*" { return MUL; }
"/" { return DIV; }
"\n" { return NWL; }
"(" { return LFT; }
")" { return RIT; }
%%
解析器文件
%{
#include <stdio.h>
#define YYSTYPE double
int yyerror (char const *s);
extern int yylex (void);
%}
%token PLS MNS
%token MUL DIV
%token NWL
%token NUM
%token LFT RIT
%left PLS MNS
%left MUL DIV
%%
Exp: NUM { $$ = ; };
Exp: Exp PLS Exp { $$ = + ; };
Exp: Exp MNS Exp { $$ = - ; };
Exp: Exp MUL Exp { $$ = * ; };
Exp: Exp DIV Exp { $$ = / ; };
Exp: LFT Exp RIT { $$ = ; };
Line: NWL;
Line: Exp NWL { printf("%f\n", ); };
;
%%
int yyerror(char const *s) {
printf("%s\n", s);
}
int main(){
int ret = yyparse();
if (ret){
fprintf(stderr, "%d error found.\n",ret);
}
return 0;
}
你语法的起始符号是Exp
,不是Line
。要么将 Line
规则放在首位,要么使用 %start Line
声明。 %start
声明应位于 %%
之前,与 %token
声明位于同一部分。
这应该会让您的程序能够处理第一行,例如 3 + 4
;-)
如果您希望它处理多行,您应该添加另一条规则 -- *.y
文件的固定语法部分的示例,以 Seq
(行的序列)作为开始符号:
Seq: /* empty */
| Seq Line
Exp: NUM { $$ = ; };
Exp: Exp PLS Exp { $$ = + ; };
Exp: Exp MNS Exp { $$ = - ; };
Exp: Exp MUL Exp { $$ = * ; };
Exp: Exp DIV Exp { $$ = / ; };
Exp: LFT Exp RIT { $$ = ; };
Line: NWL
Line: Exp NWL { printf("%f\n", ); };
我正在尝试使用 flex 和 bison 生成器制作一个非常简单的计算器。 它只适用于整数。 我正确地编译了词法分析器文件,没有错误;但是当我编译解析器文件时,它显示了一些警告:
- warning: 1 nonterminal useless in grammar
- warning: 2 rules useless in grammar
- 21.1-4: warning: nonterminal useless in grammar: Line
- 21.9-1: warning: rule useless in grammar: Line: NWL
- 22.9-55: warning: 1 nonterminal useless in grammar: Exp NWL
显示这些警告后生成输出文件。
我用 gcc 编译了输出文件;它制作了一个 .exe 文件。
当我 运行 .exe 文件并尝试计算时,它向我显示此错误:
- syntax error
请帮助我。
我的代码:
词法分析器文件
%option noyywrap
%{
#define YYSTYPE double
#include <stdio.h>
#include "x.tab.h"
%}
DIG [0-9]
%%
{DIG}+ { yylval = atoi(yytext); return NUM; }
"+" { return PLS; }
"-" { return MNS; }
"*" { return MUL; }
"/" { return DIV; }
"\n" { return NWL; }
"(" { return LFT; }
")" { return RIT; }
%%
解析器文件
%{
#include <stdio.h>
#define YYSTYPE double
int yyerror (char const *s);
extern int yylex (void);
%}
%token PLS MNS
%token MUL DIV
%token NWL
%token NUM
%token LFT RIT
%left PLS MNS
%left MUL DIV
%%
Exp: NUM { $$ = ; };
Exp: Exp PLS Exp { $$ = + ; };
Exp: Exp MNS Exp { $$ = - ; };
Exp: Exp MUL Exp { $$ = * ; };
Exp: Exp DIV Exp { $$ = / ; };
Exp: LFT Exp RIT { $$ = ; };
Line: NWL;
Line: Exp NWL { printf("%f\n", ); };
;
%%
int yyerror(char const *s) {
printf("%s\n", s);
}
int main(){
int ret = yyparse();
if (ret){
fprintf(stderr, "%d error found.\n",ret);
}
return 0;
}
你语法的起始符号是Exp
,不是Line
。要么将 Line
规则放在首位,要么使用 %start Line
声明。 %start
声明应位于 %%
之前,与 %token
声明位于同一部分。
这应该会让您的程序能够处理第一行,例如 3 + 4
;-)
如果您希望它处理多行,您应该添加另一条规则 -- *.y
文件的固定语法部分的示例,以 Seq
(行的序列)作为开始符号:
Seq: /* empty */
| Seq Line
Exp: NUM { $$ = ; };
Exp: Exp PLS Exp { $$ = + ; };
Exp: Exp MNS Exp { $$ = - ; };
Exp: Exp MUL Exp { $$ = * ; };
Exp: Exp DIV Exp { $$ = / ; };
Exp: LFT Exp RIT { $$ = ; };
Line: NWL
Line: Exp NWL { printf("%f\n", ); };