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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
%{
#include "tokens.h"
#include "../helpers.h"
/* Affiche un message d'erreur suite à l'analyse en échec. */
static int yyerror(decoding_rules *, char *);
%}
%code requires {
#include "decl.h"
#include "../args/decl.h"
}
%union {
char *string; /* Chaîne de caractères #1 */
const char *cstring; /* Chaîne de caractères #2 */
cond_expr *expr; /* Expression de déclenchement */
rule_action raction; /* Action et éléments associés */
}
%define api.pure full
%parse-param { decoding_rules *rules }
%code provides {
#define YY_DECL \
int rules_lex(YYSTYPE *yylvalp)
YY_DECL;
}
%token IF EXPR_START EXPR_END THEN
%token SEE CALL CHK_CALL UNPREDICTABLE
%token NAME
%token EQUAL BINVAL HEXVAL
%token AND AND_LOG
%token RAW_LINE
%type <string> NAME
%type <cstring> RAW_LINE
%type <expr> rule_cond
%type <string> BINVAL HEXVAL
%type <raction> action
%%
rules_list : /* empty */
| rules_list rule
rule : IF EXPR_START rule_cond EXPR_END THEN action { register_conditional_rule(rules, $3, &$6); }
| action { register_conditional_rule(rules, NULL, &$1); }
rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, true); }
| NAME EQUAL HEXVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3, false); }
| NAME AND_LOG BINVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, true); }
| NAME AND_LOG HEXVAL { $$ = build_simple_cond_expression($1, CCT_AND, $3, false); }
| EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END
{ $$ = build_composed_cond_expression($2, COT_AND, $6); }
action : SEE RAW_LINE { $$.type = CAT_SEE; $$.details = make_callable($2, false); }
| UNPREDICTABLE { $$.type = CAT_UNPREDICTABLE; }
| CALL RAW_LINE {
right_op_t rop;
bool status;
status = load_call_from_raw_line(&rop, $2);
if (!status) YYABORT;
$$.type = CAT_CALL; $$.callee = rop.func; $$.args = rop.args;
}
| CHK_CALL RAW_LINE {
right_op_t rop;
bool status;
status = load_call_from_raw_line(&rop, $2);
if (!status) YYABORT;
$$.type = CAT_CHECKED_CALL; $$.callee = rop.func; $$.args = rop.args;
}
%%
/******************************************************************************
* *
* Paramètres : rules = structure impliquée dans le processus. *
* msg = message d'erreur. *
* *
* Description : Affiche un message d'erreur suite à l'analyse en échec. *
* *
* Retour : 0 *
* *
* Remarques : - *
* *
******************************************************************************/
static int yyerror(decoding_rules *rules, char *msg)
{
printf("yyerror line %d: %s\n", yyget_lineno(), msg);
return 0;
}
/******************************************************************************
* *
* Paramètres : rules = structure à constituer à partir de données lues. *
* raw = données brutes à analyser. *
* *
* Description : Interprête des données relatives à un bloc règles. *
* *
* Retour : true si l'opération s'est bien déroulée, false sinon. *
* *
* Remarques : - *
* *
******************************************************************************/
bool load_rules_from_raw_block(decoding_rules *rules, const char *raw)
{
bool result; /* Bilan à faire remonter */
YY_BUFFER_STATE state; /* Support d'analyse */
int status; /* Bilan de l'analyse */
state = yy_scan_string(raw);
status = yyparse(rules);
result = (status == 0);
yy_delete_buffer(state);
return result;
}
|