diff options
Diffstat (limited to 'src/analysis/scan/grammar.y')
-rw-r--r-- | src/analysis/scan/grammar.y | 219 |
1 files changed, 212 insertions, 7 deletions
diff --git a/src/analysis/scan/grammar.y b/src/analysis/scan/grammar.y index 70382cf..9ee0f28 100644 --- a/src/analysis/scan/grammar.y +++ b/src/analysis/scan/grammar.y @@ -37,6 +37,7 @@ typedef void *yyscan_t; #include "exprs/literal.h" #include "exprs/logical.h" #include "exprs/set.h" +#include "exprs/setcounter.h" #include "exprs/relational.h" #include "exprs/strop.h" #include "patterns/modifier.h" @@ -128,6 +129,7 @@ YY_DECL; %token BYTES_ID +%token BYTES_FUZZY_ID %token BYTES_ID_COUNTER %token BYTES_ID_START %token BYTES_ID_LENGTH @@ -220,6 +222,7 @@ YY_DECL; %type <sized_cstring> INFO_KEY %type <sized_cstring> BYTES_ID +%type <sized_cstring> BYTES_FUZZY_ID %type <sized_cstring> BYTES_ID_COUNTER %type <sized_cstring> BYTES_ID_START %type <sized_cstring> BYTES_ID_LENGTH @@ -272,7 +275,9 @@ YY_DECL; %type <expr> relational_expr %type <expr> string_op %type <expr> arithm_expr -%type <expr> set_counter +%type <expr> set_match_counter +%type <expr> pattern_set +%type <expr> pattern_set_items %type <expr> set %type <expr> set_items %type <expr> set_access @@ -514,7 +519,7 @@ YY_DECL; char *_msg; int _ret; - _ret = asprintf(&_msg, _("unknown modifier: \"%s\""), $1.data); + _ret = asprintf(&_msg, _("Unknown modifier: \"%s\""), $1.data); if (_ret != -1) { @@ -839,7 +844,7 @@ YY_DECL; | relational_expr { $$ = $1; } | string_op { $$ = $1; } | arithm_expr { $$ = $1; } - | set_counter { $$ = $1; } + | set_match_counter { $$ = $1; } | set { $$ = $1; } | set_access { $$ = $1; } | intersection { $$ = $1; } @@ -993,10 +998,210 @@ relational_expr : cexpression "<" cexpression { $$ = g_scan_relational_operatio | cexpression "%" cexpression { $$ = g_scan_arithmetic_operation_new(AEO_MOD, $1, $3); } ; -set_counter : "none" "of" "them" { $$ = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ true }); } - | "any" "of" "them" { $$ = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ true }); } - | "all" "of" "them" { $$ = g_scan_literal_expression_new(LVT_BOOLEAN, (bool []){ true }); } - ; + + set_match_counter : "none" "of" pattern_set + { + GScanSetMatchCounter *__counter; + __counter = G_SCAN_SET_MATCH_COUNTER($3); + g_scan_set_match_counter_define_expected_matches(__counter, SSCT_NONE, NULL); + $$ = $3; + } + | "any" "of" pattern_set + { + GScanSetMatchCounter *__counter; + __counter = G_SCAN_SET_MATCH_COUNTER($3); + g_scan_set_match_counter_define_expected_matches(__counter, SSCT_ANY, NULL); + $$ = $3; + } + | "all" "of" pattern_set + { + GScanSetMatchCounter *__counter; + __counter = G_SCAN_SET_MATCH_COUNTER($3); + g_scan_set_match_counter_define_expected_matches(__counter, SSCT_ALL, NULL); + $$ = $3; + } + | UNSIGNED_INTEGER "of" pattern_set + { + GScanSetMatchCounter *__counter; + size_t __number; + bool __status; + + __counter = G_SCAN_SET_MATCH_COUNTER($3); + __number = $1; + + __status = g_scan_set_match_counter_define_expected_matches(__counter, + SSCT_NUMBER, &__number); + + if (!__status) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Expected matches counter too high: %zu"), __number); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + YYERROR; + } + + $$ = $3; + + } + ; + + pattern_set : "them" + { + size_t __count; + GSearchPattern **__patterns; + size_t __i; + + __patterns = g_scan_rule_get_local_variables(*built_rule, NULL, &__count); + + $$ = g_scan_set_match_counter_new(__patterns, __count); + + for (__i = 0; __i < __count; __i++) + g_object_unref(G_OBJECT(__patterns[__i])); + + free(__patterns); + + } + | "(" pattern_set_items ")" + { + $$ = $2; + } + ; + + pattern_set_items : BYTES_ID + { + GSearchPattern *__pat; + + __pat = g_scan_rule_get_local_variable(*built_rule, $1.data); + + if (__pat == NULL) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Pattern not found: \"%s\""), $1.data); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + YYERROR; + } + + $$ = g_scan_set_match_counter_new((GSearchPattern *[]) { __pat }, 1); + + g_object_unref(G_OBJECT(__pat)); + + } + | BYTES_FUZZY_ID + { + size_t __count; + GSearchPattern **__patterns; + size_t __i; + + __patterns = g_scan_rule_get_local_variables(*built_rule, $1.data, &__count); + + if (__count == 0) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Patterns not found: \"%s\""), $1.data); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + YYERROR; + } + + $$ = g_scan_set_match_counter_new(__patterns, __count); + + for (__i = 0; __i < __count; __i++) + g_object_unref(G_OBJECT(__patterns[__i])); + + free(__patterns); + + } + | pattern_set_items "," BYTES_ID + { + GSearchPattern *__pat; + GScanSetMatchCounter *__counter; + + __pat = g_scan_rule_get_local_variable(*built_rule, $3.data); + + if (__pat == NULL) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Pattern not found: \"%s\""), $3.data); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + YYERROR; + } + + __counter = G_SCAN_SET_MATCH_COUNTER($1); + g_scan_set_match_counter_add_extra_patterns(__counter, (GSearchPattern *[]) { __pat }, 1); + + g_object_unref(G_OBJECT(__pat)); + + $$ = $1; + + } + | pattern_set_items "," BYTES_FUZZY_ID + { + size_t __count; + GSearchPattern **__patterns; + GScanSetMatchCounter *__counter; + size_t __i; + + __patterns = g_scan_rule_get_local_variables(*built_rule, $3.data, &__count); + + if (__count == 0) + { + char *_msg; + int _ret; + + _ret = asprintf(&_msg, _("Patterns not found: \"%s\""), $3.data); + + if (_ret != -1) + { + raise_error(_msg); + free(_msg); + } + + YYERROR; + } + + __counter = G_SCAN_SET_MATCH_COUNTER($1); + g_scan_set_match_counter_add_extra_patterns(__counter, __patterns, __count); + + for (__i = 0; __i < __count; __i++) + g_object_unref(G_OBJECT(__patterns[__i])); + + free(__patterns); + + $$ = $1; + + } + ; set : "(" ")" |