Chris Phillips
Chris Phillips

Reputation: 2124

All of my tokens in flex/bison are being shown as undeclared

Im building my files with yacc -d calclang.y

%{ 
#include <stdlib.h>
#include <stdio.h>
void yyerror(const char *str);


%}

%union 
{
    int ival; 
    float fval;
    char* word;
}
%start line
%type <word> wexp
%type <ival> iexp
%type <fval> fexp

%left PLUS MINUS
%left STAR DIV MOD
%left POW
%token GT
%token LT
%token ASGN
%token LP
%token RP
%token LB
%token RB
%token NOT
%token GTEQ
%token LTEQ
%token EQTO
%token NOTEQ
%token HORN
%token QMARK
%token <word> WORD
%token <fval> FLOAT
%token <ival> INTEGER


%%

line    : HORN wexp QMARK   {   printf("=\t%s", $2);    }
        | HORN iexp QMARK   {   printf("=\t%d", $2);    }
        | HORN fexp QMARK   {   printf("=\t%f", $2);    }
        ;

iexp    : iexp MINUS iexp   { $$ = $1 - $3;             }
        | iexp PLUS iexp    { $$ = $1 + $3;             }
        | INTEGER           { $$ = $1;                  }
        ;

fexp    : FLOAT             { $$ = $1;                  }
        ;

wexp    : WORD              { $$ = $1;                  }
        ;
%%


int main(){
    return yyparse();
}

void yyerror(const char *str)
{
        printf("error: %s\n",str);
}

and

flex calclang.l

%option noyywrap

%{
#include "y.tab.h"
%}

%%
"horn" | "HORN" {   return HORN;                                }
[1-9][0-9]*     {   return INTEGER; yylval.ival = atoi(yytext); }
[0-9]+"."[0-9]+ {   return FLOAT;   yylval.fval = atof(yytext); }
">="            {   return GTEQ;                                }
"<="            {   return LTEQ;                                }
"=="            {   return EQTO;                                }
"!="            {   return NOTEQ;                               }
"+"             {   return PLUS;                                }
"-"             {   return MINUS;                               }
"*"             {   return STAR;                                }
"/"             {   return DIV;                                 }
"^"             {   return POW;                                 }
"%"             {   return MOD;                                 }
">"             {   return GT;                                  }
"<"             {   return LT;                                  }
"("             {   return LP;                                  }
")"             {   return RP;                                  }
"="             {   return ASGN;                                }
"{"             {   return LB;                                  }
"}"             {   return RB;                                  }
"!"             {   return NOT;                                 }
"?"             {   return QMARK;                               }
[a-zA-Z]*       {   return WORD;    yylval.word = yytext;       }
[ \t\n\r]       {;                                              }
.               {;                                              }
%%

Then I'm using gcc y.tab.c lex.yy.c -o test

but I receive the following error message:

calclang.l:9:10: error: ‘INTEGER’ undeclared (first use in this function)
calclang.l:9:10: note: each undeclared identifier is reported only once for each function it appears in
calclang.l:9:19: error: ‘yylval’ undeclared (first use in this function)
calclang.l:10:10: error: ‘FLOAT’ undeclared (first use in this function)
calclang.l:11:10: error: ‘GTEQ’ undeclared (first use in this function)
calclang.l:12:10: error: ‘LTEQ’ undeclared (first use in this function)
calclang.l:13:10: error: ‘EQTO’ undeclared (first use in this function)
calclang.l:14:10: error: ‘NOTEQ’ undeclared (first use in this function)
calclang.l:15:10: error: ‘PLUS’ undeclared (first use in this function)
calclang.l:16:10: error: ‘MINUS’ undeclared (first use in this function)
calclang.l:17:10: error: ‘STAR’ undeclared (first use in this function)
calclang.l:18:10: error: ‘DIV’ undeclared (first use in this function)
calclang.l:19:10: error: ‘POW’ undeclared (first use in this function)
calclang.l:20:10: error: ‘MOD’ undeclared (first use in this function)
calclang.l:21:10: error: ‘GT’ undeclared (first use in this function)
calclang.l:22:10: error: ‘LT’ undeclared (first use in this function)
calclang.l:23:10: error: ‘LP’ undeclared (first use in this function)
calclang.l:24:10: error: ‘RP’ undeclared (first use in this function)
calclang.l:25:10: error: ‘ASGN’ undeclared (first use in this function)
calclang.l:26:10: error: ‘LB’ undeclared (first use in this function)
calclang.l:27:10: error: ‘RB’ undeclared (first use in this function)
calclang.l:28:10: error: ‘NOT’ undeclared (first use in this function)
calclang.l:29:10: error: ‘QMARK’ undeclared (first use in this function)
calclang.l:30:10: error: ‘WORD’ undeclared (first use in this function)

I've looked at other posts, and they said to have the #include y.tab.h but I already have that. So I've hit a roadblock. Why are all of my tokens undeclared? Thank you!

Upvotes: 1

Views: 5902

Answers (2)

Madhavan K R
Madhavan K R

Reputation: 21

Use the -d option when you compile the yacc file. the -d option will write the y.tab.h header file. it is because of that lex is not identifying any of the tokens

    $lex filename.l
    $yacc -d filename.y
    $cc lex.yy.c y.tab.c -ll -ly

hope this helps :)

Upvotes: 2

rici
rici

Reputation: 241671

This is not directly related to your question (as far as I know) but it definitely needs to be fixed:

"horn" | "HORN" {   return HORN;                                }

Flex regular expressions cannot have spaces. This is being parsed by flex as a | action, not as a regex operator, although it's not a valid | action either because that should be the last token on the line. I think that most versions of flex will just ignore the rest of the line, but I'm by no means sure. You should remove the spaces:

"horn"|"HORN"   {   return HORN;                                }

Also, the action here (and in some other lines):

[1-9][0-9]*     {   return INTEGER; yylval.ival = atoi(yytext); }

should generate a warning when compiled, because the statement following a return statement is never executed. (You should use -Wall in your gcc command to see the warnings.) In other words, the action in normal C code, so the assignment to yylval.ival cannot be executed.

Upvotes: 1

Related Questions