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
|
%{
#include "y.tab.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern int yylineno; // Bidouille pour avoir le numero de ligne du lexer ^^
int yylex();
void yyerror(char *s);
struct list_int {
int val;
struct list_int *next;
};
struct val {
int type;
union ptr_u { char * str; struct list_int *ints; } ptr;
};
%}
%union { char* str; int num; struct list_int *ints; struct val *val; }
%token LEXERROR
%token AFF
%token EOL
%token VIR
%token <str> IDENT
%token <str> STR
%token <num> INT
%type <ints> extra_vals
%type <val> val
%start ini
%%
ini:
| ini decl
| ini EOL
decl: IDENT AFF val EOL {
printf("'%s' <- ", $1);
switch($3->type) {
case 1:// list INT
printf("( ");
struct list_int *curr=$3->ptr.ints;
while (curr!=NULL) {
printf("%i ", curr->val);
curr=curr->next;
}
printf(")\n");
break;
case 0:// STR
printf("'%s'\n",$3->ptr.str);
break;
}
}
val: INT extra_vals { $$=malloc(sizeof(struct val));
$$->type=1;
$$->ptr.ints=malloc(sizeof(struct list_int));
$$->ptr.ints->val=$1;
$$->ptr.ints->next=$2;
}
| STR { $$=malloc(sizeof(struct val));
$$->type=0;
$$->ptr.str=$1;
}
extra_vals: { $$=NULL; }
| extra_vals VIR INT { $$=malloc(sizeof(struct list_int)); $$->val=$3; $$->next=$1; }
%%
void yyerror(char *s)
{
//fprintf(stderr, "Syntax Error : '%s' at l%d,c%d-l%d,c%d\n", s, @$.first_column, @$.last_line, @$.last_column); // Nécessite l'option %locations et un lexer qui va bien
fprintf(stderr, "(stdin):%i: error: %s\n", yylineno, s);
exit(1);
}
int main (int argc, char **argv)
{ // Par défaut, c'est l'analyse LEXICALE qui est lancée !
yyparse();
return 0;
}
|