diff options
Diffstat (limited to 'src/mangling/dex/type_gram.y')
-rw-r--r-- | src/mangling/dex/type_gram.y | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/src/mangling/dex/type_gram.y b/src/mangling/dex/type_gram.y new file mode 100644 index 0000000..79c9320 --- /dev/null +++ b/src/mangling/dex/type_gram.y @@ -0,0 +1,159 @@ + +%{ + +#include <stdbool.h> + + +#include "context.h" +#include "../context-int.h" + +typedef void *yyscan_t; + +/* Affiche un message d'erreur concernant l'analyse. */ +static int type_error(GDexDemangler *, yyscan_t, char *); + +/* Procède au décodage d'une chaîne de caractères. */ +bool demangle_dex_type(GDexDemangler *, const char *); + + +%} + + +%code requires { + +#include "../../analysis/types/basic.h" +#include "../../analysis/types/cse.h" +#include "../../common/extstr.h" + +} + +%union { + + GDataType *type; /* Type reconstruit */ + size_t adeep; /* Dimension d'un tableau */ + char *text; /* Chaîne de caractères */ + +} + + + +%define api.pure full +%parse-param { GDexDemangler *demangler } { yyscan_t scanner } +%lex-param { yyscan_t scanner } + + +%token V Z B S C I J F D +%token ARRAY +%token L SEMICOLON +%token SLASH DOLLAR +%token TEXT + +%type <type> type_descriptor field_type_descriptor non_array_field_type_descriptor full_class_name + +%type <text> TEXT simple_name + + +%{ + +/* Déclarations issues de l'analyseur syntaxique... */ + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int type_lex_init(yyscan_t *scanner); +extern YY_BUFFER_STATE type__scan_string(const char *, yyscan_t); +extern void type__delete_buffer(YY_BUFFER_STATE, yyscan_t); +extern int type_lex(YYSTYPE *, yyscan_t); +extern int type_lex_destroy(yyscan_t); + +%} + + +%% + + +input: + type_descriptor { G_DEMANGLING_CONTEXT(demangler)->type = $1; } + +type_descriptor: + V { $$ = g_basic_type_new(BTP_VOID); } + | field_type_descriptor { $$ = $1; } + +field_type_descriptor: + non_array_field_type_descriptor { $$ = $1; } + | ARRAY non_array_field_type_descriptor { $$ = $2; } + +non_array_field_type_descriptor: + Z { $$ = g_basic_type_new(BTP_BOOL); } + | B { $$ = g_basic_type_new(BTP_UCHAR); } + | S { $$ = g_basic_type_new(BTP_SHORT); } + | C { $$ = g_basic_type_new(BTP_CHAR); } + | I { $$ = g_basic_type_new(BTP_INT); } + | J { $$ = g_basic_type_new(BTP_LONG); } + | F { $$ = g_basic_type_new(BTP_FLOAT); } + | D { $$ = g_basic_type_new(BTP_DOUBLE); } + | L full_class_name SEMICOLON { $$ = $2; } + +full_class_name: + simple_name { $$ = g_class_enum_type_new(CET_CLASS, $1); } + | full_class_name SLASH simple_name { + $$ = g_class_enum_type_new(CET_CLASS, $3); + g_data_type_set_namespace($$, $1); + g_object_unref($1); + } +simple_name: + TEXT { $$ = strdup($1); } + | simple_name TEXT { $$ = stradd($1, $2); } + +%% + + +/****************************************************************************** +* * +* Paramètres : demangler = contexte associé à la procédure de décodage. * +* scanner = données internes aux analyseurs. * +* msg = indications humaines sur l'événement. * +* * +* Description : Affiche un message d'erreur concernant l'analyse. * +* * +* Retour : Valeur historique, ignorée. * +* * +* Remarques : - * +* * +******************************************************************************/ +static int type_error(GDexDemangler *demangler, yyscan_t scanner, char *msg) +{ + return -1; + +} + + +/****************************************************************************** +* * +* Paramètres : demangler = contexte de décodage à utiliser. * +* desc = chaîne de caractères à décoder. * +* * +* Description : Procède au décodage d'une chaîne de caractères. * +* * +* Retour : Bilan de l'opération. * +* * +* Remarques : - * +* * +******************************************************************************/ + +bool demangle_dex_type(GDexDemangler *demangler, const char *desc) +{ + yyscan_t scanner; /* Données internes */ + YY_BUFFER_STATE buffer; /* Tampon pour bison */ + int ret; /* Bilan de l'appel */ + + type_lex_init(&scanner); + + buffer = type__scan_string(desc, scanner); + ret = yyparse(demangler, scanner); + type__delete_buffer(buffer, scanner); + + type_lex_destroy(scanner); + + return (ret == 0); + +} |