diff options
Diffstat (limited to 'tools/d2c_gram.y')
-rw-r--r-- | tools/d2c_gram.y | 133 |
1 files changed, 123 insertions, 10 deletions
diff --git a/tools/d2c_gram.y b/tools/d2c_gram.y index 6fc8fb7..5deb053 100644 --- a/tools/d2c_gram.y +++ b/tools/d2c_gram.y @@ -9,6 +9,7 @@ #include "coder.h" +#include "d2c_tok.h" extern int yylex(); @@ -17,10 +18,10 @@ extern void free_flex_memory(void); /* Affiche un message d'erreur suite à l'analyse en échec. */ -static int d2c_error(rented_coder *coder, char *s); +static int d2c_error(rented_coder *, char *); /* Affiche des indications sur l'utilisation du programme. */ -static void show_usage(const char *argv0); +static void show_usage(const char *); %} @@ -31,12 +32,76 @@ static void show_usage(const char *argv0); /* Pour la définition des expressions conditionnelles... */ #include "coder.h" +#include "conv.h" + struct action_tmp { CondActionType action; const char *details; }; + + + +#define register_named_field_in_coder(c, n, l) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + register_named_field_in_bits(__bits, n, l); \ + }) + +#define register_bit_in_coder(c, v) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + register_bit_in_bits(__bits, v); \ + }) + +#define count_coder_bits(c) \ + ({ \ + encoding_spec *__spec; \ + coding_bits *__bits; \ + __spec = get_current_encoding_spec(c); \ + __bits = get_bits_in_encoding_spec(__spec); \ + count_coded_bits(__bits); \ + }) + +#define register_syntax_item_in_coder(c, n, i) \ + ({ \ + encoding_spec *__spec; \ + asm_syntax *__syntax; \ + __spec = get_current_encoding_spec(c); \ + __syntax = get_syntax_in_encoding_spec(__spec); \ + register_syntax_item(__syntax, n, i); \ + }) + +#define register_conversion_in_coder(c, f) \ + ({ \ + encoding_spec *__spec; \ + conv_list *__list; \ + __spec = get_current_encoding_spec(c); \ + __list = get_conversions_in_encoding_spec(__spec); \ + register_conversion(__list, f); \ + }) + +#define add_conditional_rule_to_coder(c, e, a, d) \ + ({ \ + encoding_spec *__spec; \ + decoding_rules *__rules; \ + __spec = get_current_encoding_spec(c); \ + __rules = get_rules_in_encoding_spec(__spec); \ + register_conditional_rule(__rules, e, a, d); \ + }) + + + + + + } %union { @@ -47,6 +112,13 @@ struct action_tmp int integer; + conv_func *subst; /* Fonction de conversion */ + conv_arg_list_t *conv_list; /* Liste d'arguments de conv. */ + + conv_expr_t *conv; /* Expression de conversion */ + ConvUnaryOperation un_op; /* Opération unaire */ + ConvBinaryOperation bin_op; /* Opération bianire */ + cond_expr *expr; /* Expression de déclenchement */ struct action_tmp tmpa; /* Transfert temporaire */ @@ -68,7 +140,7 @@ struct action_tmp %token SYNTAX OPERAND_INTERNAL OPERAND_VISIBLE -%token CONV EQ ARG +%token CONV EQ OP COMMA CP NOT EOR COLON %token RULES IF EXPR_START EQUAL BINVAL EXPR_END AND THEN SEE @@ -83,7 +155,13 @@ struct action_tmp %type <string> OPERAND_INTERNAL OPERAND_VISIBLE -%type <string> ARG + +%type <subst> substitution +%type <conv_list> conv_arg_list +%type <conv> conv_expr conv_arg_composed +%type <un_op> conv_expr_un_op +%type <bin_op> conv_expr_bin_op +%type <string> conv_arg_field %type <expr> rule_cond %type <string> BINVAL @@ -115,8 +193,20 @@ content : /* empty */ | rules content -bitfield : HALF bits { if (count_coder_bits(coder) != 16) YYABORT; } - | WORD bits { if (count_coder_bits(coder) != 32) YYABORT; } +bitfield : HALF bits { + if (count_coder_bits(coder) != 16) + { + fprintf(stderr, "Unexpected word size: %u vs 16\n", count_coder_bits(coder)); + YYABORT; + } + } + | WORD bits { + if (count_coder_bits(coder) != 32) + { + fprintf(stderr, "Unexpected word size: %u vs 32\n", count_coder_bits(coder)); + YYABORT; + } + } bits : /* empty */ | NAME SIZE bits { register_named_field_in_coder(coder, $1, $2); } @@ -133,7 +223,30 @@ operands : /* empty */ conversions : CONV substitutions substitutions : /* empty */ - | substitutions NAME EQ NAME ARG { register_conversion_in_coder(coder, $2, $4, $5); } + | substitutions substitution { register_conversion_in_coder(coder, $2); } + +substitution : NAME EQ conv_expr { $$ = make_conv_from_expr($1, $3); } + | NAME EQ NAME OP conv_arg_list CP { $$ = make_conv_from_func($1, $3, $5); } + +conv_arg_list : conv_expr { $$ = build_conv_arg_list($1); } + | conv_arg_list COMMA conv_expr { $$ = extend_conv_arg_list($1, $3); printf("extend\n"); } + +conv_expr : NAME { $$ = build_conv_expr_from_name($1); } + | NUMBER { $$ = build_conv_expr_from_number($1); } + | conv_arg_composed { $$ = $1; } + | OP conv_expr CP { $$ = $2; } + | conv_expr_un_op conv_expr { $$ = build_unary_conv_expr($2, $1); } + | OP conv_expr conv_expr_bin_op conv_expr CP { $$ = build_binary_conv_expr($2, $4, $3); } + +conv_expr_un_op : NOT { $$ = CUO_NOT; } + +conv_expr_bin_op : EOR { $$ = CBO_EOR; } + +conv_arg_composed : conv_arg_field COLON conv_arg_field { $$ = build_composed_conv_expr($1, $3); } + | conv_arg_composed COLON conv_arg_field { $$ = extend_composed_conv_expr($1, $3); } + +conv_arg_field : NAME { $$ = $1; printf(" composed::name '%s'\n", $1); } + | BINVAL { $$ = $1; printf(" composed::bin '%s'\n", $1); } rules : RULES rules_list @@ -169,7 +282,7 @@ action : SEE INS_DETAILS { $$.action = CAT_SEE; $$.details = $2; } static int d2c_error(rented_coder *coder, char *msg) { - printf("yyerror : %s\n", msg); + printf("yyerror line %d: %s\n", d2c_get_lineno(), msg); return 0; @@ -287,7 +400,7 @@ int main(int argc, char **argv) if (!has_error) { *sep = '\0'; - register_encoding_in_coder(coder, optarg, sep + 1); + register_encoding(get_coder_pre_proc(coder), optarg, sep + 1); } break; @@ -300,7 +413,7 @@ int main(int argc, char **argv) if (!has_error) { *sep = '\0'; - define_macro_for_coder(coder, optarg, sep + 1); + define_macro(get_coder_pre_proc(coder), optarg, sep + 1); } break; |