tags:

views:

53

answers:

3

Hi! 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! =(

A: 

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.

Jonathan Leffler
Thanks it doesn't show that error but it doesn't print the number it prints a 0, it's not working because i changed it to a type char, and it doesn't print anything too.
beecode
@Beecode: so the first question you asked is now resolved - you are able to compile. I got the zero response too. However, I can't tell what you want printed; is it an echo of what was entered, or some translation of what was entered?
Jonathan Leffler
I think i have to send from the lex the int, converting yylval.d=atoi(yytext); return INT; but i'm getting: error YYSTYPE has no member named intval, something like this, i'm checking
beecode
@Beecode: regarding the YYSTYPE error - make sure you've regenerated the sample.tab.h file (bison -d sample.y).
Jonathan Leffler
In the bison file i want to get the value of the ID token because I will store it in a table or smt, and when the SAME ID is entered again it will mark error.
beecode
I have solved it! I added yylval i will modify the code!!
beecode
A: 

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.

beecode
A: 

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.

Chris Dodd
The previous version of the code had $1 there :(
Jonathan Leffler
@Jonathan -- if I fix the code as I've described (use $1 and delete the #define), it works fine for me: `echo 5 | ./a.out` gives me `The id is:5` followed by `Finished`
Chris Dodd
I removed the #define yystype yes it wasn't supposed to be there!
beecode