beecode
beecode

Reputation: 1

request for member in something not a structure or union

I've been working for hours and I can't figure out how to print the token from the bison file, the bison file is this: (it's a short simple file) This is the modified version: the solution to the problem:

%{

#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);
}

And the Flex file is this:

%{
#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);}

%%

What I want to do after I get this, is to store the value of ID in a table and when I read another ID if it is repeated I would mark an error and say: repeated id! For now this codes tells me: "error request for member 'd' in something not a structure or union".

Please help!!! I've looked on internet and haven't found anything! =(

Upvotes: 0

Views: 4359

Answers (3)

Chris Dodd
Chris Dodd

Reputation: 126408

The problem, as Jonathan notes, is that you've #defined YYSTYPE to char cconst * AND used %union (which also defines YYSTYPE.) So in the bison file, yylval is declared as char const *, while in the flex file its declared as the union, so random undefined things will happen. So get rid of the #define

In addition, in the bison file, you almost never want to refer to yylval directly, as that will be the value of the last token scanned (which is probably the lookahead token after the ID you actually want -- bison uses 1-token lookahead so the lexer is generally 1 token ahead of the parser). Instead, you should use $1 here:

instruction: ID { printf("The id is:%d\n", $1);};

Note that your DON'T need the .d in this case, as its present in the %token declaration of ID.

Upvotes: 0

beecode
beecode

Reputation: 1

The code has been modified and it works. I only needed to connect the bison and flex file using yyval, there are comments in the code.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 754550

Your 'request for member' error is resolved by not setting YYSTYPE; you use either %union or YYSTYPE but not both.

Try modifying the flex rule for ID like this:

{ID}    {printf("yylex: %s\n", yytext); yylval.d = *yytext - '0'; return(ID);}

It may not be exactly what you want, but it compiles. Since your ID is currently limited to a single digit, this is OK; if you are planning multi-digit ID values, you'd need to use 'atoi()' or 'strtol()' et al.

Upvotes: 1

Related Questions