/ / Tous mes jetons dans flex / bison sont affichés comme non déclarés - c, bison, yacc, flex-lexer, lex

Tous mes jetons dans flex / bison sont affichés comme non déclarés - c, bison, yacc, flex-lexer, lex

Je construis mes fichiers avec 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: %sn",str);
}

et

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;       }
[ tnr]       {;                                              }
.               {;                                              }
%%

Puis-je utiliser gcc y.tab.c lex.yy.c -o test

mais je reçois le message d'erreur suivant:

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)

J’ai jeté un œil à d’autres articles et ils ont dit avoir le #include y.tab.h mais j'ai déjà ça. J'ai donc frappé un barrage routier. Pourquoi tous mes jetons ne sont-ils pas déclarés? Je vous remercie!

Réponses:

2 pour la réponse № 1

Utilisez l'option -d lorsque vous compilez le fichier yacc. l'option -d écrit le fichier d'en-tête y.tab.h. c'est à cause de cela que lex n'identifie aucun des jetons

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

J'espère que cela t'aides :)


1 pour la réponse № 2

Ce n'est pas directement lié à votre question (pour autant que je sache), mais il faut absolument le corriger:

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

Les expressions rationnelles Flex ne peuvent pas avoir d'espaces. Ceci est analysé par flex en tant que | action, pas comme un opérateur regex, bien que ce ne soit pas valide | action soit parce que cela devrait être le dernier jeton sur la ligne. Je pense que la plupart des versions de flex vont simplement ignorer le reste de la ligne, mais je ne suis absolument pas sûr. Vous devez supprimer les espaces:

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

Aussi, l'action ici (et dans quelques autres lignes):

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

devrait générer un avertissement lors de la compilation, car la déclaration qui suit un return déclaration n'est jamais exécutée. (Tu devrais utiliser -Wall dans votre commande gcc pour voir les avertissements.) En d’autres termes, l’action en code C normal, donc l’affectation à yylval.ival ne peut pas être exécuté.