我已经完成了我的lex文件并开始了解yacc 但是我对我的lex代码有一些疑问:
%{
#include "y.tab.h"
int num_lines = 1;
int comment_mode=0;
int stack =0;
%}
digit ([0-9])
integer ({digit}+)
float_num ({digit}+\.{digit}+)
%%
{integer} { //deal with integer
printf("#%d: NUM:",num_lines); ECHO;printf("\n");
yylval.Integer = atoi(yytext);
return INT;
}
{float_num} {// deal with float
printf("#%d: NUM:",num_lines);ECHO;printf("\n");
yylval.Float = atof(yytext);
return FLOAT;
}
\n { ++num_lines; }
. if(strcmp(yytext," "))ECHO;
%%
int yywrap() {
return 1;
}
每次我得到一个整数或浮点数时,我都会返回令牌并将其保存到yylval中 这是我在parser.y中的代码:
%{
#include <stdio.h>
#define YYDEBUG 1
void yyerror (char const *s) {
fprintf (stderr, "%s\n", s);
}
%}
%union{
int Integer;
float Float;
}
%token <int>INT;
%token <float>FLOAT;
%%
statement :
INT {printf("int yacc\n");}
| FLOAT {printf("float yacc\n");}
|
;
%%
int main(int argc, char** argv)
{
yyparse();
return 0;
}
由...编制 byacc -d parser.y
lex lex.l
gcc lex.yy.c y.tab.c -ll
因为我只是想尝试一些容易上手的东西,我想知道我是否可以解析 只有int和float number,我在输入后将它们打印在.l和.y文件中 整数或浮点数。开头的i输入fisrt随机数,例如123 ,然后我的程序打印:
1:NUM:123
在yylex()和
中&#34; int yacc \ n&#34;
在parser.y中 但如果我输入第二个其他数字,它会显示语法错误和程序关闭 我不知道问题出在哪里。 有什么解决方案吗?
答案 0 :(得分:1)
您的语法只接受一个令牌,INT
或FLOAT
。所以它只接受一个数字,这就是它在读取第二个数字时产生语法错误的原因;它期待一个文件结束。
解决方案是更改语法,使其接受任意数量的&#34;语句&#34;:
program: /* EMPTY */
| program statement
;
两个注释:
1)你的词法分析器中不需要(昂贵的)strcmp。就这样做:
" " /* Do nothing */;
. { return yytext[0]; }
将未知字符返回到解析器会更好,如果字符不对应任何令牌类型(如在简单语法中),则会产生语法错误,而不是仅仅回显字符到stdout
,这会让人感到困惑。有些人更喜欢在词法分析器中为无效输入生成错误消息,但是在开发语法时我认为通过字符更容易,因为这样可以在不重新生成词法分析器的情况下向解析器添加运算符。 / p>
2)在%type
中指定bison
时,使用联合中的标记名,而不是C类型。一些(但不是全部)的野牛版本让你可以使用C类型,如果它是一个简单的类型,但你不能指望它;它不是posix标准,如果你使用较旧或较新版本的野牛,它可能会破裂。 (例如,它不会使用bison 3.0。)所以你应该写一下,例如:
%union{
int Integer;
float Float;
}
%token <Integer>INT;
%token <Float>FLOAT;