请求成员不是结构或联盟

时间:2010-09-12 06:48:39

标签: bison flex-lexer

我已经工作了几个小时,我无法弄清楚如何从野牛文件中打印令牌,野牛文件是这样的:(这是一个简短的简单文件) 这是修改后的版本:解决问题的方法:

%{

#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'的错误请求,不是结构或联合”。

请帮忙!!!我看过互联网,但没有找到任何东西! =(

3 个答案:

答案 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声明中存在{。}}。