summaryrefslogtreecommitdiff
path: root/tools/d2c/assert/grammar.y
blob: 3db47e6ce7494f2e6cc3b23b1d5823ecc87f0a51 (plain)
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

%{

#include "tokens.h"


/* Affiche un message d'erreur suite à l'analyse en échec. */
static int yyerror(disass_assert *, char *);

%}


%code requires {

#include "decl.h"

}


%union {

    char *string;                           /* Chaîne de caractères        */

    struct
    {
        char *field;                        /* Nom de champ de bits        */
        DisassCondOp op;                    /* Opération impliquée         */
        char *value;                        /* Valeur soumise à condition  */

    } cond_info;

}


%define api.pure full

%parse-param { disass_assert *dassert }

%code provides {

#define YY_DECL \
    int assert_lex(YYSTYPE *yylvalp)

YY_DECL;

}


%token CR
%token EQ NE
%token AND OR
%token FIELD VALUE

%type <cond_info> condition
%type <string> FIELD
%type <string> VALUE


%%


assert : /* empty */
       | conditions assert

conditions : condition               { register_disass_assert(dassert, DCG_UNIQ, $1.field, $1.op, $1.value); }
           | condition AND and_conds { extend_disass_assert(dassert, $1.field, $1.op, $1.value); }
           | condition OR or_conds   { extend_disass_assert(dassert, $1.field, $1.op, $1.value); }

and_conds : condition                { register_disass_assert(dassert, DCG_AND, $1.field, $1.op, $1.value); }
          | condition AND and_conds  { extend_disass_assert(dassert, $1.field, $1.op, $1.value); }

or_conds : condition                 { register_disass_assert(dassert, DCG_OR, $1.field, $1.op, $1.value); }
         | condition AND or_conds    { extend_disass_assert(dassert, $1.field, $1.op, $1.value); }

condition : FIELD EQ VALUE           { $$.field = $1; $$.op = DCO_EQ; $$.value = $3; }
          | FIELD NE VALUE           { $$.field = $1; $$.op = DCO_NE; $$.value = $3; }


%%


/******************************************************************************
*                                                                             *
*  Paramètres  : dassert = 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(disass_assert *dassert, char *msg)
{
	printf("assert yyerror line %d: %s\n", yyget_lineno(), msg);

	return 0;

}


/******************************************************************************
*                                                                             *
*  Paramètres  : dassert = structure à constituer à partir de données lues.   *
*                raw     = données brutes à analyser.                         *
*                                                                             *
*  Description : Interprête des données relatives à une série de conditions.  *
*                                                                             *
*  Retour      : true si l'opération s'est bien déroulée, false sinon.        *
*                                                                             *
*  Remarques   : -                                                            *
*                                                                             *
******************************************************************************/

bool load_assertions_from_raw_block(disass_assert *dassert, 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(dassert);

    result = (status == 0);

    yy_delete_buffer(state);

    return result;

}