%{ #include #include #include extern void yyerror(char const *); extern int yylineno; extern FILE * yyin; #include "lists.h" #include "val.h" #define NEW(type) (calloc(1,sizeof(type))) %} %union { char *str; Val val; } %left PLUS %token LPAR RPAR %token IF THEN ELSE %token LET EQ IN %token ID %token CONST %type e_expression %type b_expression %start S %% S: {$$.env=NULL;} b_expression { printf("Le type de cette expression est :\n\t"); switch($2.type){ case BOOL: puts("bool"); break; case NAT: puts("nat"); break; default: puts("erreur : cette expression n'est pas typable"); } } ; /* Avec le marqueur */ /* {$$.env=$0.env;} */ /* nous copions l'enviromment juste */ /* a la gauche du non terminal a reduire */ /* de facon que l'environnement se trouve */ /* toujours en positionk $0 */ b_expression: e_expression { $$.type=$1.type; } | LPAR {$$.env=$0.env;} b_expression RPAR { $$.type=$3.type; } | LET ID EQ {$$.env=$0.env;} e_expression IN { // Pair *p=NEW(Pair); p->str=strdup($2); p->type=$5.type; // $$.env=list_add(p,$0.env); } b_expression { $$.type= $8.type; } ; | IF {$$.env=$0.env;} e_expression THEN {$$.env=$0.env;} b_expression ELSE {$$.env=$0.env;} b_expression { if(($3.type == BOOL) && ($6.type == $9.type)) $$.type= $6.type; else $$.type= ERROR; } ; e_expression: ID { Pair *p=NEW(Pair); List l; p->str=$1; l= list_find(p,$0.env); if(l == NULL) $$.type=ERROR; else $$.type=l->content->type; free(p); } | CONST { if((strcmp($1,"true") == 0) || (strcmp($1,"false")==0)) $$.type=BOOL; else $$.type=NAT; } | e_expression PLUS {$$.env=$0.env;} e_expression { if(($1.type == NAT) && ($4.type == NAT)) $$.type = NAT; else $$.type = ERROR; } | LPAR {$$.env=$0.env;} e_expression RPAR { $$.type=$3.type; } ; %% void yyerror(char const *str) { fprintf(stderr,"Ligne %d : %s\n", yylineno, str); exit(EXIT_FAILURE); } int main(int argc, char* argv[]) { if ( argc > 1 ) { if((yyin = fopen( argv[1], "r" ))==NULL) exit(EXIT_FAILURE); yyparse(); fclose(yyin); } else exit(EXIT_FAILURE); exit(EXIT_SUCCESS); }