我已经工作了几个小时,我无法弄清楚如何从野牛文件中打印令牌,野牛文件是这样的:(这是一个简短的简单文件) 这是修改后的版本:解决问题的方法:
%{
#include <stdio.h>
#include <stdlib.h>
void yyerror(const char *);
int yylex(void);
int id;
%}
%union {
int d;
}
%error-verbose
%token <d> ID
%%
instruction: ID { //yylval.d is set in the FLEX file, this prints the ID entered
printf("The id is:%d\n",yylval.d);};
%%
int main(){
if (yyparse()==0)
printf("Finished.\n");
else
printf("Error\n");
}
void yyerror(char const *s)
{
fprintf(stderr,"err %s\n",s);
}
Flex文件是这样的:
%{
#include "sample.tab.h"
#include <math.h>
%}
ID [0-9]
ENTER "\n"
SPACE [ \t\n]+
%%
{ID} {//the "d" is from the union of the bison file, it connects to it
yylval.d=atoi(yytext);return(ID);}
{ENTER} {}
{SPACE} {}
. {printf("Strange character: %s\n", yytext);}
%%
我得到这个之后想要做的是将ID的值存储在表中,当我读取另一个ID时,如果重复,我会标记错误并说:重复ID! 现在,这些代码告诉我:“成员'd'的错误请求,不是结构或联合”。
请帮忙!!!我看过互联网,但没有找到任何东西! =(
答案 0 :(得分:1)
您的'会员请求'错误是通过不设置YYSTYPE解决的;你使用%union或YYSTYPE,但不能同时使用两者。
尝试修改ID的flex规则,如下所示:
{ID} {printf("yylex: %s\n", yytext); yylval.d = *yytext - '0'; return(ID);}
它可能不是你想要的,但它编译。由于您的ID目前仅限于一位数,因此可以;如果您计划多位数ID值,则需要使用'atoi()'或'strtol()'等。
答案 1 :(得分:0)
代码已被修改并且有效。我只需要使用yyval连接bison和flex文件,代码中有注释。
答案 2 :(得分:0)
正如Jonathan所说,问题是你#define
YYSTYPE到char cconst *
并使用了%union
(也定义了YYSTYPE。)所以在野牛文件中,yylval是声明为char const *
,而在flex文件中声明为union,因此会发生随机未定义的事情。所以摆脱#define
另外,在bison文件中,你几乎不想直接引用yylval,因为这将是扫描的最后一个标记的值(这可能是你实际想要的ID之后的先行标记 - 野牛使用1 -token lookahead所以词法分析器通常在解析器之前1个令牌)。相反,您应该在这里使用$1
:
instruction: ID { printf("The id is:%d\n", $1);};
请注意,在这种情况下,您不需要.d
,因为%token
ID
声明中存在{。}}。