%{ #include #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_descriptor field_type_descriptor non_array_field_type_descriptor full_class_name %type 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); }