Reputation: 2124
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
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
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