[Lex & Yacc] Gestion des ensembles d'entiers
Bonjour, j'aimerais faire un analyseur syntaxique qui gère les ensembles d'entiers. Un identificateur est composé d'une seule lettre et pour gérer les identificateurs et les associer à leur valeur, j'utilise un tableau : tab[0] correspond a l'identificateur a ou A, tab[1] correspond a l'identificateur b ou B et ainsi de suite. J'ai déja bien avancé mais j'ai des erreurs pas très normales. Par exemple, lorsque je tappe a:={3} donc pour définir l'emsemble "a" et que ensuite je veux afficher la valeur de a (pas de tab[a]) il m'affiche 3. alors que normalement a devrait être égal à 0. J'ai l'impression que les valeurs des ensembles interagissent avec les indices de mon tableau. Je vous laisse le code. SI vous avez un petite idée on sait jamais.
mon .y :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
| %{
#include <stdio.h>
long tab[26] ;
%}
%token UNION
%token INTER
%token DIFF
%token COMP
%token ident
%token elem
%token AFFECT
%token DEBUT_E
%token FIN_E
%token SEP
%start liste
%right ':='
%left COMP
%%
liste : {;}
| liste instruction '\n' {;}
;
instruction : ident AFFECT expression {tab[$1] = tab[$1]|$3; }
| ident {affiche(tab[$1]);}
;
expression : operande {$$=$1;}
| operande UNION operande {$$ = $1 | $2; }
| operande INTER {$$ = $1 & $2 ; }
| operande DIFF operande {$$ = $1 & ~$2;}
| COMP operande {$$ = ~$1 ;}
;
operande : ident {$$=tab[$1]; }
| ensemble {$$=$1;}
;
ensemble : DEBUT_E FIN_E {;}
| DEBUT_E liste_element FIN_E {$$=$2;}
;
liste_element : elem {$$=p($1);}
| elem SEP liste_element {$$=p($1)| $3;}
;
%%
long puiss(long n)
{
long res = 1 ;
int k ;
for (k=0 ; k<n ; k++)
res = res * 2 ;
return res ;
}
int yyerror(char *s)
{
printf("%s\n",s);
}
int p(int p)
{
return 1<<(p-1);
}
void affiche(long n)
{
int i ;
int virgule=0 ;
printf("{") ;
for(i=0; i<32 ; i++)
{
long et = n&puiss(i) ;
if (et != 0)
{
if (virgule==0)
{
printf("%d", i+1) ;
virgule = 1 ;
}
else
printf(",%d", i+1) ;
}
}
printf("}\n") ;
}
int main()
{
int k ;
for(k=0 ; k<26 ; k++)
tab[k]=0 ;
yyparse() ;
//affiche(p(23)) ;
}
void afficheTab()
{
int k ;
for(k=0 ; k<32 ; k++)
affiche(tab[k]) ;
} |
et mon .l
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
%{
#include <stdio.h>
#include "y.tab.h"
extern int yylval;
%}
%%
[a-zA-Z] { if(yytext[0]>'a' && yytext[0]<'z')
yylval=yytext[0] -'a' ;
if(yytext[0]>'A' && yytext[0]<'Z')
yylval=yytext[0] - 'A' ;
return ident;
}
[0-9] {yylval=atol(yytext); return elem;}
"UNION" | "union" {return UNION;}
"INTER" | "inter" {return INTER;}
"DIFF" | "diff" {return DIFF;}
"COMP" | "comp" {return COMP;}
":=" {return AFFECT;}
"{" {return DEBUT_E;}
"}" {return FIN_E;}
"," {return SEP;}
"\n" {return *yytext;}
%% |