diff options
Diffstat (limited to 'tools/d2c_gram.y')
-rw-r--r-- | tools/d2c_gram.y | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/tools/d2c_gram.y b/tools/d2c_gram.y new file mode 100644 index 0000000..6fc8fb7 --- /dev/null +++ b/tools/d2c_gram.y @@ -0,0 +1,329 @@ + +%{ + +#include <getopt.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +#include "coder.h" + + +extern int yylex(); + +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); + +/* Affiche des indications sur l'utilisation du programme. */ +static void show_usage(const char *argv0); + + +%} + + +%code requires { + +/* Pour la définition des expressions conditionnelles... */ +#include "coder.h" + +struct action_tmp +{ + CondActionType action; + const char *details; +}; + +} + +%union { + + char *string; /* Chaîne de caractères #1 */ + const char *cstring; /* Chaîne de caractères #2 */ + + + int integer; + + + cond_expr *expr; /* Expression de déclenchement */ + struct action_tmp tmpa; /* Transfert temporaire */ + +} + +%parse-param { rented_coder *coder } + + +%token COPYRIGHT +%token TITLE +%token INS_NAME INS_DETAILS + +%token ENCODING +%token THUMB ARCH NUMBER +%token ENC_START ENC_END + +%token WORD HALF NAME SIZE BIT + +%token SYNTAX OPERAND_INTERNAL OPERAND_VISIBLE + +%token CONV EQ ARG + +%token RULES IF EXPR_START EQUAL BINVAL EXPR_END AND THEN SEE + + +%type <string> COPYRIGHT INS_NAME +%type <cstring> INS_DETAILS + +%type <integer> NUMBER + +%type <string> NAME +%type <integer> SIZE BIT + +%type <string> OPERAND_INTERNAL OPERAND_VISIBLE + +%type <string> ARG + +%type <expr> rule_cond +%type <string> BINVAL +%type <tmpa> action + + +%% + + +input : name encodings { if (!dump_all_routines_using_coder(coder)) YYABORT; } + +name : COPYRIGHT TITLE INS_NAME { save_notes_for_coder(coder, $1, $3, NULL); } + | COPYRIGHT TITLE INS_NAME INS_DETAILS { save_notes_for_coder(coder, $1, $3, $4); } + + + + +encodings : /* empty */ + | encoding encodings + +encoding : ENCODING THUMB NUMBER content { push_encoding_spec(coder, strdup("t"), $3); } + | ENCODING ARCH NUMBER content { push_encoding_spec(coder, strdup("a"), $3); } + + +content : /* empty */ + | bitfield content + | syntax content + | conversions content + | rules content + + +bitfield : HALF bits { if (count_coder_bits(coder) != 16) YYABORT; } + | WORD bits { if (count_coder_bits(coder) != 32) YYABORT; } + +bits : /* empty */ + | NAME SIZE bits { register_named_field_in_coder(coder, $1, $2); } + | BIT bits { register_bit_in_coder(coder, $1); } + + +syntax : SYNTAX operands + +operands : /* empty */ + | operands OPERAND_INTERNAL { register_syntax_item_in_coder(coder, $2, true); } + | operands OPERAND_VISIBLE { register_syntax_item_in_coder(coder, $2, false); } + + +conversions : CONV substitutions + +substitutions : /* empty */ + | substitutions NAME EQ NAME ARG { register_conversion_in_coder(coder, $2, $4, $5); } + + +rules : RULES rules_list + +rules_list : /* empty */ + | rules_list rule + +rule : IF EXPR_START rule_cond EXPR_END THEN action + { add_conditional_rule_to_coder(coder, $3, $6.action, $6.details); } + +rule_cond : NAME EQUAL BINVAL { $$ = build_simple_cond_expression($1, CCT_EQUAL, $3); } + | EXPR_START rule_cond EXPR_END AND EXPR_START rule_cond EXPR_END + { $$ = build_composed_cond_expression($2, COT_AND, $6); } + +action : SEE INS_DETAILS { $$.action = CAT_SEE; $$.details = $2; } + + +%% + + +/****************************************************************************** +* * +* Paramètres : coder = codeur impliqué dans le processus. * +* msg = message d'erreur. * +* * +* Description : Affiche un message d'erreur suite à l'analyse en échec. * +* * +* Retour : 0 * +* * +* Remarques : - * +* * +******************************************************************************/ + +static int d2c_error(rented_coder *coder, char *msg) +{ + printf("yyerror : %s\n", msg); + + return 0; + +} + + +/****************************************************************************** +* * +* Paramètres : argv0 = nombre du programme exécuté. * +* * +* Description : Affiche des indications sur l'utilisation du programme. * +* * +* Retour : - * +* * +* Remarques : - * +* * +******************************************************************************/ + +static void show_usage(const char *argv0) +{ + printf("\n"); + + printf("Usage: %s [options] < file\n", argv0); + + printf("\n"); + + printf("Options:\n"); + + printf("\n"); + + printf("\t-h | --help\t\t\tDisplay this messsage.\n"); + printf("\t-d | --dir <string>\t\tSpecify the main output directory.\n"); + printf("\t-a | --arch <string>\t\tDefine the archicture to handle.\n"); + printf("\t-H | --header <string>\t\tSet the base of the #ifndef / #define game.\n"); + printf("\t-e | --encoding <string>\tDefine encoding prefixes for files.\n"); + printf("\t-m | --macro <string>\t\tRegister some conversion functions.\n"); + + printf("\n"); + +} + + +/****************************************************************************** +* * +* Paramètres : argc = nombre d'arguments dans la ligne de commande. * +* argv = arguments de la ligne de commande. * +* * +* Description : Point d'entrée du programme. * +* * +* Retour : EXIT_SUCCESS si le prgm s'est déroulé sans encombres. * +* * +* Remarques : - * +* * +******************************************************************************/ + +int main(int argc, char **argv) +{ + int result; /* Bilan à retourner */ + rented_coder *coder; /* Codeur à briffer & employer */ + int index; /* Indice de fichier à traiter */ + bool need_help; /* Affichage de l'aide ? */ + bool has_error; /* Erreur dans la ligne de cmd.*/ + int ret; /* Bilan d'une lecture d'arg. */ + char *sep; /* Caratère '=' en coupure */ + + static struct option long_options[] = { + + { "help", no_argument, NULL, 'h' }, + { "dir", required_argument, NULL, 'd' }, + { "arch", required_argument, NULL, 'a' }, + { "header", required_argument, NULL, 'H' }, + { "encoding", required_argument, NULL, 'e' }, + { "macro", required_argument, NULL, 'M' }, + { NULL, 0, NULL, 0 } + + }; + + result = EXIT_SUCCESS; + + coder = create_coder(); + + index = 0; + + need_help = false; + has_error = false; + + while (!has_error) + { + ret = getopt_long(argc, argv, "hd:a:H:e:M:", long_options, &index); + if (ret == -1) break; + + switch (ret) + { + case 'h': + need_help = true; + break; + + case 'd': + set_coder_output_directory(coder, optarg); + break; + + case 'a': + set_coder_arch(coder, optarg); + break; + + case 'H': + set_coder_header_base(coder, optarg); + break; + + case 'e': + + sep = strchr(optarg, '='); + has_error = (sep == NULL); + + if (!has_error) + { + *sep = '\0'; + register_encoding_in_coder(coder, optarg, sep + 1); + } + + break; + + case 'M': + + sep = strchr(optarg, '='); + has_error = (sep == NULL); + + if (!has_error) + { + *sep = '\0'; + define_macro_for_coder(coder, optarg, sep + 1); + } + + break; + + } + + } + + if (need_help || has_error || !do_basic_checks_with_coder(coder) || optind != argc) + { + show_usage(argv[0]); + result = (need_help ? EXIT_SUCCESS : EXIT_FAILURE); + goto exit; + } + + result = yyparse(coder); + + exit: + + free_flex_memory(); + + delete_coder(coder); + + return result; + +} |