diff options
author | Cyrille Bagard <nocbos@gmail.com> | 2016-01-28 23:32:25 (GMT) |
---|---|---|
committer | Cyrille Bagard <nocbos@gmail.com> | 2016-01-28 23:32:25 (GMT) |
commit | 16e0fd9d89ef433848678dfc8dd20426844a2868 (patch) | |
tree | 79075ae02c133cea21ffb555b1086aae833b3aac /tools/d2c/rules/grammar.y | |
parent | 66c99d59d6a6d533de0bb65488de8243213bcdea (diff) |
Cleaned, rewritten and improved the whole code of the compiler.
Diffstat (limited to 'tools/d2c/rules/grammar.y')
-rw-r--r-- | tools/d2c/rules/grammar.y | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/tools/d2c/rules/grammar.y b/tools/d2c/rules/grammar.y new file mode 100644 index 0000000..effd4b3 --- /dev/null +++ b/tools/d2c/rules/grammar.y @@ -0,0 +1,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; + +} |