Parsing FLEX/YACC程序未按预期运行:can';t从整数序列中获取整数值
我正在尝试构建一个解析器,该解析器采用以下格式的字符串列表,并对其所有元素执行加法或乘法运算:Parsing FLEX/YACC程序未按预期运行:can';t从整数序列中获取整数值,parsing,flex-lexer,yacc,Parsing,Flex Lexer,Yacc,我正在尝试构建一个解析器,该解析器采用以下格式的字符串列表,并对其所有元素执行加法或乘法运算: prod 5-6_ sum _ sum 5_ sum 5-6-7_ $ 应在屏幕上打印以下内容: prod = 30 sum = 0 sum = 5 sum = 18 我实际得到的输出是: prod = 0 sum = 0 sum = 5 sum = 5 我的lex文件如下所示: %{ #include <iostream> #include &quo
prod 5-6_
sum _
sum 5_
sum 5-6-7_
$
应在屏幕上打印以下内容:
prod = 30
sum = 0
sum = 5
sum = 18
我实际得到的输出是:
prod = 0
sum = 0
sum = 5
sum = 5
我的lex文件如下所示:
%{
#include <iostream>
#include "y.tab.h"
using namespace std;
extern "C" int yylex();
%}
%option yylineno
digit [0-9]
integer {digit}+
operator "sum"|"prod"
%%
{integer} { return number; }
{operator} { return oper; }
"-" { return '-'; }
"_" { return '_'; }
"$" { return '$'; }
\n { ; }
[\t ]+ { ; }
. { cout << "unknown char" << endl; }
%%
%token oper
%token number
%token '-'
%token '_'
%token '$'
%start valid
%{
#include <iostream>
#include <string>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define YYSTYPE int
extern FILE *yyin;
extern char yytext[];
extern "C" int yylex();
int yyparse();
extern int yyerror(char *);
char op;
%}
%%
valid : expr_seq endfile {}
| {}
;
expr_seq : expr {}
| expr_seq expr {}
;
expr : op sequence nl {if (op == '+') cout << "sum = " ; else cout << "prod = ";}
| op nl {if (op == '+') cout << "sum = 0"; else cout <<"prod = 1";}
;
op : oper { if (yytext[0] == 's') op = '+'; else op = '*';}
;
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + $3; else $$ = $1 * $3;}
;
nl : '_' { cout << endl;}
;
endfile : '$' {}
;
%%
int main(int argc, char *argv[])
{
++argv, --argc;
if(argc > 0) yyin = fopen(argv[0], "r");
else yyin = stdin;
yyparse();
return 0;
}
int yyerror(char * msg)
{
extern int yylineno;
cerr << msg << "on line # " << yylineno << endl;
return 0;
}
%{
#包括
#包括“y.tab.h”
使用名称空间std;
外部“C”int yylex();
%}
%选项yylineno
数字[0-9]
整数{位}+
运算符“sum”|“prod”
%%
{integer}{返回数;}
{operator}{return oper;}
“-”{return'-';}
“{return'}”
“$”{返回“$”;}
\n{;}
[\t]+{;}
. {cout您不能在yacc操作中使用yytext
。yytext
仅在扫描操作期间有效,解析器通常提前读取下一个标记。(事实上,yacc总是读取下一个标记。Bison有时不这样做,但并不总是容易预测。)
您可以将语义值与每个标记(和非终端)关联,您可以在yacc操作中使用$1
、$2
等来引用这些语义值。您甚至可以将不同类型的语义值关联到不同的语法符号。如果您使用bison,您可能正在使用bison,您可以为语法符号命名,以便更容易地引用它们的语义值
所有这些都在。中通过示例进行了深入解释。有效的解决方案只是更改以下行:
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + $3; else $$ = $1 * $3;}
;
为此:
sequence : number { $$ = atoi(yytext);}
| sequence '-' number { if (op == '+') $$ = $1 + atoi(yytext); else $$ = $1 * atoi(yytext);}
;
@Bulbasar:在野牛行动中仅使用$n
是不够的。你还必须在你的灵活行动中为yylval
赋值。你不能在野牛行动中使用yytext。即使它在某些上下文中似乎有效,它最终也会失败。