A cleaner solution is to use the scanner in the flexintended way, which is to consistently return lexical tokens to your caller, one token per call.
, - , . (, , #define s), , , . , yacc bison, .
- " " . , , . yytext ( ), yytext flex - , , yytext , , , . , yylex.
:
: tokens.h
enum Token {
T_FIN = 0,
T_MOTCLE,
T_ID,
T_ENTIER,
T_REEL,
T_OUVRANTE,
T_FERMANTE,
T_OPERATEUR,
T_AFFECT,
T_VIRGULE,
T_POINT_VIRGULE,
T_INCONNU
};
const char* decrire(int jeton);
- enum . , . - . , 0 , .
: tokens.c
#include <stdio.h>
#include "tokens.h"
static const char* descriptions = {
"Fin d'entree",
"Mot_cle",
"ID",
"Nombre entier",
"Nombre reel",
"Parenthese ouvrante",
"Parenthese fermante"
"Operateur arithmetique",
"Operateur d'affectation",
"Virgule",
"Point virgule",
"Caractere inconnu"
};
const char* decrire(int jeton) {
if (jeton >= 0 && jeton <= T_INCONNU)
return descriptions[jeton];
else
return "???";
}
, :
int main() {
puts("Entrez le texte a analyser : ");
int jeton = yylex();
printf("\n%-20s%-30s%-10s\n", "Lexeme", "Unite lexicale", "Indice");
puts("-----------------------------------------------------");
for (int i = 1; jeton; jeton = yylex();) {
printf("%-20s%-30s%-10d\n", yytext, decrire(jeton), token_count++);
puts("------------------------------------------------------");
}
return 0;
}
, :
tokens.l
%{
#include "tokens.h"
int token_count;
%}
%options noinput nounput noyywrap nodefault
%%
"$" { return T_FIN; }
[ \t]+ { /*ignorer*/ }
\n { token_count = 1; }
ENTIER|REEL { return T_MOTCLE; }
[[:alpha:]][[:alnum:]]* { return T_ID; }
[+-]?[[:digit:]]* { return T_ENTIER; }
[+-]?[[:digit:]]+\.[[:digit:]]+([eE][+-]?[[:digit:]]*)? {
return T_REEL; }
"(" { return T_OUVRANTE; }
")" { return T_FERMANTE; }
[-+*/] { return T_OPERATEUR; }
"=" { return T_AFFECT; }
"," { return T_VIRGULE; }
";" { return T_POINT_VIRGULE; }
. { return T_INCONNU; }
( ) ; yylloc ( ) , .