[Forensics-changes] [yara] 58/160: Improve profiling

Hilko Bengen bengen at moszumanska.debian.org
Sat Jul 1 10:29:18 UTC 2017


This is an automated email from the git hooks/post-receive script.

bengen pushed a commit to annotated tag v3.4.0
in repository yara.

commit 3a4ed03567a57967bbb88a42bf11e2a6f13b9010
Author: Victor M. Alvarez <plusvic at gmail.com>
Date:   Wed Mar 18 12:25:19 2015 +0100

    Improve profiling
    
    + Keep track of the time spent by rules timing-out
    + Include profiling information in yara.TimeoutError
---
 configure.ac                    |   7 +
 libyara/compiler.c              |   3 +-
 libyara/exec.c                  |  10 +
 libyara/grammar.c               | 964 ++++++++++++++++++++--------------------
 libyara/grammar.h               |   5 +-
 libyara/grammar.y               |  30 +-
 libyara/include/yara/arena.h    |   2 +-
 libyara/include/yara/compiler.h |   3 +-
 libyara/include/yara/exec.h     |  36 +-
 libyara/include/yara/parser.h   |   9 +-
 libyara/parser.c                | 115 ++---
 yara-python/setup.py            |  12 +-
 yara-python/yara-python.c       |  20 +-
 13 files changed, 657 insertions(+), 559 deletions(-)

diff --git a/configure.ac b/configure.ac
index 22f75ed..76267bf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -26,6 +26,13 @@ case $host_alias in
      i?86-*-mingw*) CFLAGS="$CFLAGS -D__MINGW_USE_VC2005_COMPAT" ;;
 esac
 
+
+AC_ARG_ENABLE([profiling],
+  [AS_HELP_STRING([--enable-profiling], [enable profiling support])],
+  [if test x$enableval = xyes; then
+    CFLAGS="$CFLAGS -DPROFILING_ENABLED"
+  fi])
+
 AC_ARG_ENABLE([dmalloc],
   [AS_HELP_STRING([--enable-dmalloc],
     [enable dmalloc to debug heap-related issues])],
diff --git a/libyara/compiler.c b/libyara/compiler.c
index 6e468d5..fa0730f 100644
--- a/libyara/compiler.c
+++ b/libyara/compiler.c
@@ -49,13 +49,12 @@ YR_API int yr_compiler_create(
   new_compiler->file_stack_ptr = 0;
   new_compiler->file_name_stack_ptr = 0;
   new_compiler->fixup_stack_head = NULL;
-  new_compiler->current_rule_flags = 0;
   new_compiler->allow_includes = 1;
   new_compiler->loop_depth = 0;
   new_compiler->loop_for_of_mem_offset = -1;
   new_compiler->compiled_rules_arena = NULL;
   new_compiler->namespaces_count = 0;
-  new_compiler->current_rule_strings = NULL;
+  new_compiler->current_rule = NULL;
 
   result = yr_hash_table_create(10007, &new_compiler->rules_table);
 
diff --git a/libyara/exec.c b/libyara/exec.c
index ef7564e..731dacd 100644
--- a/libyara/exec.c
+++ b/libyara/exec.c
@@ -166,6 +166,7 @@ int yr_execute_code(
   STACK_ITEM r2;
   STACK_ITEM r3;
 
+  YR_RULE* current_rule = NULL;
   YR_RULE* rule;
   YR_MATCH* match;
   YR_OBJECT_FUNCTION* function;
@@ -399,6 +400,11 @@ int yr_execute_code(
         push(r1);
         break;
 
+      case OP_INIT_RULE:
+        current_rule = *(YR_RULE**)(ip + 1);
+        ip += sizeof(uint64_t);
+        break;
+
       case OP_MATCH_RULE:
         pop(r1);
         rule = *(YR_RULE**)(ip + 1);
@@ -1071,6 +1077,10 @@ int yr_execute_code(
       {
         if (difftime(time(NULL), start_time) > timeout)
         {
+          #ifdef PROFILING_ENABLED
+          assert(current_rule != NULL);
+          current_rule->clock_ticks += clock() - start;
+          #endif
           result = ERROR_SCAN_TIMEOUT;
           stop = TRUE;
         }
diff --git a/libyara/grammar.c b/libyara/grammar.c
index d22ad71..a995c40 100644
--- a/libyara/grammar.c
+++ b/libyara/grammar.c
@@ -260,7 +260,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 178 "grammar.y"
+#line 180 "grammar.y"
 {
   EXPRESSION      expression;
   SIZED_STRING*   sized_string;
@@ -269,9 +269,10 @@ typedef union YYSTYPE
   double          double_;
   YR_STRING*      string;
   YR_META*        meta;
+  YR_RULE*        rule;
 }
 /* Line 193 of yacc.c.  */
-#line 275 "grammar.c"
+#line 276 "grammar.c"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -284,7 +285,7 @@ typedef union YYSTYPE
 
 
 /* Line 216 of yacc.c.  */
-#line 288 "grammar.c"
+#line 289 "grammar.c"
 
 #ifdef short
 # undef short
@@ -499,16 +500,16 @@ union yyalloc
 /* YYFINAL -- State number of the termination state.  */
 #define YYFINAL  2
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   378
+#define YYLAST   386
 
 /* YYNTOKENS -- Number of terminals.  */
 #define YYNTOKENS  70
 /* YYNNTS -- Number of nonterminals.  */
-#define YYNNTS  37
+#define YYNNTS  38
 /* YYNRULES -- Number of rules.  */
-#define YYNRULES  114
+#define YYNRULES  115
 /* YYNRULES -- Number of states.  */
-#define YYNSTATES  200
+#define YYNSTATES  201
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
@@ -559,17 +560,17 @@ static const yytype_uint8 yytranslate[] =
 static const yytype_uint16 yyprhs[] =
 {
        0,     0,     3,     4,     7,    10,    14,    18,    22,    25,
-      35,    36,    40,    41,    45,    49,    50,    53,    55,    57,
-      58,    61,    63,    66,    68,    71,    75,    79,    83,    87,
-      89,    92,    97,    98,   104,   108,   109,   112,   114,   116,
-     118,   120,   122,   126,   131,   136,   137,   139,   143,   145,
-     147,   149,   151,   155,   159,   161,   165,   169,   170,   171,
-     183,   184,   194,   198,   201,   202,   207,   208,   213,   217,
-     221,   225,   229,   233,   237,   239,   243,   247,   249,   256,
-     258,   262,   263,   268,   270,   272,   276,   278,   280,   282,
-     284,   286,   290,   292,   294,   299,   301,   303,   305,   307,
-     312,   314,   316,   319,   323,   327,   331,   335,   339,   343,
-     347,   351,   354,   358,   362
+      26,    37,    38,    42,    43,    47,    51,    52,    55,    57,
+      59,    60,    63,    65,    68,    70,    73,    77,    81,    85,
+      89,    91,    94,    99,   100,   106,   110,   111,   114,   116,
+     118,   120,   122,   124,   128,   133,   138,   139,   141,   145,
+     147,   149,   151,   153,   157,   161,   163,   167,   171,   172,
+     173,   185,   186,   196,   200,   203,   204,   209,   210,   215,
+     219,   223,   227,   231,   235,   239,   241,   245,   249,   251,
+     258,   260,   264,   265,   270,   272,   274,   278,   280,   282,
+     284,   286,   288,   292,   294,   296,   301,   303,   305,   307,
+     309,   314,   316,   318,   321,   325,   329,   333,   337,   341,
+     345,   349,   353,   356,   360,   364
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
@@ -577,58 +578,58 @@ static const yytype_int8 yyrhs[] =
 {
       71,     0,    -1,    -1,    71,    73,    -1,    71,    72,    -1,
       71,     1,    73,    -1,    71,     1,    72,    -1,    71,     1,
-      59,    -1,    35,    17,    -1,    77,     3,     9,    79,    60,
-      74,    75,    76,    61,    -1,    -1,     6,    62,    81,    -1,
-      -1,     7,    62,    83,    -1,     8,    62,    91,    -1,    -1,
-      77,    78,    -1,     4,    -1,     5,    -1,    -1,    62,    80,
-      -1,     9,    -1,    80,     9,    -1,    82,    -1,    81,    82,
-      -1,     9,    63,    17,    -1,     9,    63,    14,    -1,     9,
-      63,    36,    -1,     9,    63,    37,    -1,    84,    -1,    83,
-      84,    -1,    10,    63,    17,    86,    -1,    -1,    10,    63,
-      85,    19,    86,    -1,    10,    63,    18,    -1,    -1,    86,
-      87,    -1,    21,    -1,    20,    -1,    22,    -1,    23,    -1,
-       9,    -1,    88,    64,     9,    -1,    88,    65,   106,    66,
-      -1,    88,    67,    89,    68,    -1,    -1,    92,    -1,    89,
-      69,    92,    -1,    19,    -1,    92,    -1,    36,    -1,    37,
-      -1,   106,    33,    90,    -1,   106,    34,   106,    -1,    10,
-      -1,    10,    24,   106,    -1,    10,    29,    99,    -1,    -1,
-      -1,    31,   105,     9,    29,    93,    98,    62,    94,    67,
-      91,    68,    -1,    -1,    31,   105,    30,   101,    62,    95,
-      67,    91,    68,    -1,   105,    30,   101,    -1,    58,    91,
-      -1,    -1,    91,    39,    96,    91,    -1,    -1,    91,    38,
-      97,    91,    -1,   106,    48,   106,    -1,   106,    46,   106,
-      -1,   106,    47,   106,    -1,   106,    45,   106,    -1,   106,
-      44,   106,    -1,   106,    43,   106,    -1,   106,    -1,    67,
-      92,    68,    -1,    67,   100,    68,    -1,    99,    -1,    67,
-     106,    64,    64,   106,    68,    -1,   106,    -1,   100,    69,
-     106,    -1,    -1,    67,   102,   103,    68,    -1,    32,    -1,
-     104,    -1,   103,    69,   104,    -1,    10,    -1,    13,    -1,
-     106,    -1,    27,    -1,    28,    -1,    67,   106,    68,    -1,
-      25,    -1,    26,    -1,    16,    67,   106,    68,    -1,    14,
-      -1,    15,    -1,    17,    -1,    11,    -1,    12,    65,   106,
-      66,    -1,    12,    -1,    88,    -1,    52,   106,    -1,   106,
-      51,   106,    -1,   106,    52,   106,    -1,   106,    53,   106,
-      -1,   106,    54,   106,    -1,   106,    55,   106,    -1,   106,
-      41,   106,    -1,   106,    42,   106,    -1,   106,    40,   106,
-      -1,    56,   106,    -1,   106,    50,   106,    -1,   106,    49,
-     106,    -1,    90,    -1
+      59,    -1,    35,    17,    -1,    -1,    78,     3,     9,    80,
+      60,    75,    76,    74,    77,    61,    -1,    -1,     6,    62,
+      82,    -1,    -1,     7,    62,    84,    -1,     8,    62,    92,
+      -1,    -1,    78,    79,    -1,     4,    -1,     5,    -1,    -1,
+      62,    81,    -1,     9,    -1,    81,     9,    -1,    83,    -1,
+      82,    83,    -1,     9,    63,    17,    -1,     9,    63,    14,
+      -1,     9,    63,    36,    -1,     9,    63,    37,    -1,    85,
+      -1,    84,    85,    -1,    10,    63,    17,    87,    -1,    -1,
+      10,    63,    86,    19,    87,    -1,    10,    63,    18,    -1,
+      -1,    87,    88,    -1,    21,    -1,    20,    -1,    22,    -1,
+      23,    -1,     9,    -1,    89,    64,     9,    -1,    89,    65,
+     107,    66,    -1,    89,    67,    90,    68,    -1,    -1,    93,
+      -1,    90,    69,    93,    -1,    19,    -1,    93,    -1,    36,
+      -1,    37,    -1,   107,    33,    91,    -1,   107,    34,   107,
+      -1,    10,    -1,    10,    24,   107,    -1,    10,    29,   100,
+      -1,    -1,    -1,    31,   106,     9,    29,    94,    99,    62,
+      95,    67,    92,    68,    -1,    -1,    31,   106,    30,   102,
+      62,    96,    67,    92,    68,    -1,   106,    30,   102,    -1,
+      58,    92,    -1,    -1,    92,    39,    97,    92,    -1,    -1,
+      92,    38,    98,    92,    -1,   107,    48,   107,    -1,   107,
+      46,   107,    -1,   107,    47,   107,    -1,   107,    45,   107,
+      -1,   107,    44,   107,    -1,   107,    43,   107,    -1,   107,
+      -1,    67,    93,    68,    -1,    67,   101,    68,    -1,   100,
+      -1,    67,   107,    64,    64,   107,    68,    -1,   107,    -1,
+     101,    69,   107,    -1,    -1,    67,   103,   104,    68,    -1,
+      32,    -1,   105,    -1,   104,    69,   105,    -1,    10,    -1,
+      13,    -1,   107,    -1,    27,    -1,    28,    -1,    67,   107,
+      68,    -1,    25,    -1,    26,    -1,    16,    67,   107,    68,
+      -1,    14,    -1,    15,    -1,    17,    -1,    11,    -1,    12,
+      65,   107,    66,    -1,    12,    -1,    89,    -1,    52,   107,
+      -1,   107,    51,   107,    -1,   107,    52,   107,    -1,   107,
+      53,   107,    -1,   107,    54,   107,    -1,   107,    55,   107,
+      -1,   107,    41,   107,    -1,   107,    42,   107,    -1,   107,
+      40,   107,    -1,    56,   107,    -1,   107,    50,   107,    -1,
+     107,    49,   107,    -1,    91,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
 static const yytype_uint16 yyrline[] =
 {
-       0,   191,   191,   193,   194,   195,   196,   197,   202,   214,
-     233,   236,   264,   268,   296,   301,   302,   307,   308,   314,
-     317,   335,   348,   385,   386,   391,   407,   420,   433,   450,
-     451,   456,   470,   469,   488,   505,   506,   511,   512,   513,
-     514,   519,   610,   659,   719,   767,   770,   795,   831,   877,
-     894,   903,   912,   927,   941,   955,   971,   986,  1022,   985,
-    1138,  1137,  1217,  1223,  1230,  1229,  1289,  1288,  1346,  1355,
-    1364,  1373,  1382,  1391,  1400,  1404,  1412,  1413,  1418,  1440,
-    1452,  1468,  1467,  1473,  1482,  1483,  1488,  1493,  1502,  1503,
-    1507,  1515,  1519,  1529,  1543,  1559,  1569,  1578,  1602,  1617,
-    1632,  1655,  1699,  1718,  1736,  1754,  1772,  1790,  1800,  1810,
-    1820,  1830,  1840,  1850,  1860
+       0,   194,   194,   196,   197,   198,   199,   200,   205,   218,
+     217,   247,   250,   278,   281,   308,   313,   314,   319,   320,
+     326,   329,   347,   360,   397,   398,   403,   419,   432,   445,
+     462,   463,   468,   482,   481,   500,   517,   518,   523,   524,
+     525,   526,   531,   622,   671,   731,   779,   782,   807,   843,
+     889,   906,   915,   924,   939,   953,   967,   983,   998,  1034,
+     997,  1150,  1149,  1229,  1235,  1242,  1241,  1302,  1301,  1360,
+    1369,  1378,  1387,  1396,  1405,  1414,  1418,  1426,  1427,  1432,
+    1454,  1466,  1482,  1481,  1487,  1496,  1497,  1502,  1507,  1516,
+    1517,  1521,  1529,  1533,  1543,  1557,  1573,  1583,  1592,  1616,
+    1631,  1646,  1669,  1713,  1732,  1750,  1768,  1786,  1804,  1814,
+    1824,  1834,  1844,  1854,  1864,  1874
 };
 #endif
 
@@ -649,12 +650,12 @@ static const char *const yytname[] =
   "_LT_", "_SHIFT_RIGHT_", "_SHIFT_LEFT_", "'+'", "'-'", "'*'", "'\\\\'",
   "'%'", "'~'", "UNARY_MINUS", "_NOT_", "\"include\"", "'{'", "'}'", "':'",
   "'='", "'.'", "'['", "']'", "'('", "')'", "','", "$accept", "rules",
-  "import", "rule", "meta", "strings", "condition", "rule_modifiers",
+  "import", "rule", "@1", "meta", "strings", "condition", "rule_modifiers",
   "rule_modifier", "tags", "tag_list", "meta_declarations",
-  "meta_declaration", "string_declarations", "string_declaration", "@1",
+  "meta_declaration", "string_declarations", "string_declaration", "@2",
   "string_modifiers", "string_modifier", "identifier", "arguments_list",
-  "regexp", "boolean_expression", "expression", "@2", "@3", "@4", "@5",
-  "@6", "integer_set", "range", "integer_enumeration", "string_set", "@7",
+  "regexp", "boolean_expression", "expression", "@3", "@4", "@5", "@6",
+  "@7", "integer_set", "range", "integer_enumeration", "string_set", "@8",
   "string_enumeration", "string_enumeration_item", "for_expression",
   "primary_expression", 0
 };
@@ -678,35 +679,35 @@ static const yytype_uint16 yytoknum[] =
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const yytype_uint8 yyr1[] =
 {
-       0,    70,    71,    71,    71,    71,    71,    71,    72,    73,
-      74,    74,    75,    75,    76,    77,    77,    78,    78,    79,
-      79,    80,    80,    81,    81,    82,    82,    82,    82,    83,
-      83,    84,    85,    84,    84,    86,    86,    87,    87,    87,
-      87,    88,    88,    88,    88,    89,    89,    89,    90,    91,
-      92,    92,    92,    92,    92,    92,    92,    93,    94,    92,
-      95,    92,    92,    92,    96,    92,    97,    92,    92,    92,
-      92,    92,    92,    92,    92,    92,    98,    98,    99,   100,
-     100,   102,   101,   101,   103,   103,   104,   104,   105,   105,
-     105,   106,   106,   106,   106,   106,   106,   106,   106,   106,
-     106,   106,   106,   106,   106,   106,   106,   106,   106,   106,
-     106,   106,   106,   106,   106
+       0,    70,    71,    71,    71,    71,    71,    71,    72,    74,
+      73,    75,    75,    76,    76,    77,    78,    78,    79,    79,
+      80,    80,    81,    81,    82,    82,    83,    83,    83,    83,
+      84,    84,    85,    86,    85,    85,    87,    87,    88,    88,
+      88,    88,    89,    89,    89,    89,    90,    90,    90,    91,
+      92,    93,    93,    93,    93,    93,    93,    93,    94,    95,
+      93,    96,    93,    93,    93,    97,    93,    98,    93,    93,
+      93,    93,    93,    93,    93,    93,    93,    99,    99,   100,
+     101,   101,   103,   102,   102,   104,   104,   105,   105,   106,
+     106,   106,   107,   107,   107,   107,   107,   107,   107,   107,
+     107,   107,   107,   107,   107,   107,   107,   107,   107,   107,
+     107,   107,   107,   107,   107,   107
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
 static const yytype_uint8 yyr2[] =
 {
-       0,     2,     0,     2,     2,     3,     3,     3,     2,     9,
-       0,     3,     0,     3,     3,     0,     2,     1,     1,     0,
-       2,     1,     2,     1,     2,     3,     3,     3,     3,     1,
-       2,     4,     0,     5,     3,     0,     2,     1,     1,     1,
-       1,     1,     3,     4,     4,     0,     1,     3,     1,     1,
-       1,     1,     3,     3,     1,     3,     3,     0,     0,    11,
-       0,     9,     3,     2,     0,     4,     0,     4,     3,     3,
-       3,     3,     3,     3,     1,     3,     3,     1,     6,     1,
-       3,     0,     4,     1,     1,     3,     1,     1,     1,     1,
-       1,     3,     1,     1,     4,     1,     1,     1,     1,     4,
-       1,     1,     2,     3,     3,     3,     3,     3,     3,     3,
-       3,     2,     3,     3,     1
+       0,     2,     0,     2,     2,     3,     3,     3,     2,     0,
+      10,     0,     3,     0,     3,     3,     0,     2,     1,     1,
+       0,     2,     1,     2,     1,     2,     3,     3,     3,     3,
+       1,     2,     4,     0,     5,     3,     0,     2,     1,     1,
+       1,     1,     1,     3,     4,     4,     0,     1,     3,     1,
+       1,     1,     1,     3,     3,     1,     3,     3,     0,     0,
+      11,     0,     9,     3,     2,     0,     4,     0,     4,     3,
+       3,     3,     3,     3,     3,     1,     3,     3,     1,     6,
+       1,     3,     0,     4,     1,     1,     3,     1,     1,     1,
+       1,     1,     3,     1,     1,     4,     1,     1,     1,     1,
+       4,     1,     1,     2,     3,     3,     3,     3,     3,     3,
+       3,     3,     2,     3,     3,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -714,186 +715,191 @@ static const yytype_uint8 yyr2[] =
    means the default is an error.  */
 static const yytype_uint8 yydefact[] =
 {
-       2,     0,     1,    15,     0,     4,     3,     0,     7,     6,
-       5,     8,     0,    17,    18,    16,    19,     0,     0,    21,
-      20,    10,    22,     0,    12,     0,     0,     0,     0,    11,
-      23,     0,     0,     0,     0,    24,     0,    13,    29,     0,
-       9,    26,    25,    27,    28,    32,    30,    41,    54,    98,
-     100,    95,    96,     0,    97,    48,    92,    93,    89,    90,
-       0,    50,    51,     0,     0,     0,     0,   101,   114,    14,
-      49,     0,    74,    35,    34,     0,     0,     0,     0,     0,
-       0,     0,    88,   102,   111,    63,     0,    49,    74,     0,
-       0,    45,    66,    64,     0,     0,     0,     0,     0,     0,
+       2,     0,     1,    16,     0,     4,     3,     0,     7,     6,
+       5,     8,     0,    18,    19,    17,    20,     0,     0,    22,
+      21,    11,    23,     0,    13,     0,     0,     9,     0,    12,
+      24,     0,     0,     0,    25,     0,    14,    30,     0,     0,
+      27,    26,    28,    29,    33,    31,     0,    10,    36,    35,
+       0,    42,    55,    99,   101,    96,    97,     0,    98,    49,
+      93,    94,    90,    91,     0,    51,    52,     0,     0,     0,
+       0,   102,   115,    15,    50,     0,    75,    32,    36,     0,
+       0,     0,     0,     0,     0,    89,   103,   112,    64,     0,
+      50,    75,     0,     0,    46,    67,    65,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    31,    35,    55,     0,    56,     0,     0,
-       0,     0,     0,    75,    91,    42,     0,     0,    46,     0,
-       0,    83,    81,    62,    52,    53,   110,   108,   109,    73,
-      72,    71,    69,    70,    68,   113,   112,   103,   104,   105,
-     106,   107,    38,    37,    39,    40,    36,    33,     0,    99,
-      94,    57,     0,    43,    44,     0,    67,    65,     0,     0,
-       0,    60,    47,    86,    87,     0,    84,     0,     0,     0,
-      77,     0,    82,     0,     0,     0,    79,    58,     0,    85,
-      78,    76,     0,     0,     0,    80,     0,    61,     0,    59
+       0,     0,     0,     0,     0,     0,    39,    38,    40,    41,
+      37,    34,    56,     0,    57,     0,     0,     0,     0,     0,
+      76,    92,    43,     0,     0,    47,     0,     0,    84,    82,
+      63,    53,    54,   111,   109,   110,    74,    73,    72,    70,
+      71,    69,   114,   113,   104,   105,   106,   107,   108,     0,
+     100,    95,    58,     0,    44,    45,     0,    68,    66,     0,
+       0,     0,    61,    48,    87,    88,     0,    85,     0,     0,
+       0,    78,     0,    83,     0,     0,     0,    80,    59,     0,
+      86,    79,    77,     0,     0,     0,    81,     0,    62,     0,
+      60
 };
 
 /* YYDEFGOTO[NTERM-NUM].  */
 static const yytype_int16 yydefgoto[] =
 {
-      -1,     1,     5,     6,    24,    27,    33,     7,    15,    18,
-      20,    29,    30,    37,    38,    75,   113,   156,    67,   127,
-      68,    86,    70,   170,   193,   181,   130,   129,   179,   117,
-     185,   133,   168,   175,   176,    71,    72
+      -1,     1,     5,     6,    32,    24,    27,    39,     7,    15,
+      18,    20,    29,    30,    36,    37,    50,    77,   120,    71,
+     134,    72,    89,    74,   171,   194,   182,   137,   136,   180,
+     124,   186,   140,   169,   176,   177,    75,    76
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -65
+#define YYPACT_NINF -69
 static const yytype_int16 yypact[] =
 {
-     -65,    79,   -65,   -29,    -3,   -65,   -65,   100,   -65,   -65,
-     -65,   -65,    13,   -65,   -65,   -65,     6,    98,    53,   -65,
-     112,   118,   -65,    67,   127,   126,    81,   138,    91,   126,
-     -65,   134,    94,    97,    -1,   -65,    96,   134,   -65,    50,
-     -65,   -65,   -65,   -65,   -65,    11,   -65,   -65,   -21,   -65,
-      95,   -65,   -65,    99,   -65,   -65,   -65,   -65,   -65,   -65,
-     111,   -65,   -65,   136,   136,    50,    50,   -55,   -65,    17,
-     -65,   135,   269,   -65,   -65,   145,   136,   101,   136,   136,
-     136,     2,   301,   -65,   -65,   -65,    17,   102,   164,   160,
-     136,    50,   -65,   -65,    -9,   155,   136,   136,   136,   136,
-     136,   136,   136,   136,   136,   136,   136,   136,   136,   136,
-     136,   136,   136,    89,   -65,   301,   136,   -65,   224,   131,
-     184,   146,    -9,   -65,   -65,   -65,   242,    20,    61,    50,
-      50,   -65,   -65,   -65,   -65,   301,   316,    43,   323,   301,
-     301,   301,   301,   301,   301,    19,    19,    87,    87,   -65,
-     -65,   -65,   -65,   -65,   -65,   -65,   -65,    89,   285,   -65,
-     -65,   -65,   114,   -65,   -65,    50,   140,   -65,     5,   113,
-     120,   -65,    61,   -65,   -65,    47,   -65,   136,   136,   128,
-     -65,   122,   -65,     5,   204,    63,   285,   -65,    50,   -65,
-     -65,   -65,   136,   124,   -14,   301,    50,   -65,    -5,   -65
+     -69,    76,   -69,   -32,    -2,   -69,   -69,    30,   -69,   -69,
+     -69,   -69,     8,   -69,   -69,   -69,    -9,    46,     9,   -69,
+      73,    98,   -69,    56,   114,   122,    64,   -69,    69,   122,
+     -69,   127,   132,    -8,   -69,    75,   127,   -69,    86,    89,
+     -69,   -69,   -69,   -69,     4,   -69,    47,   -69,   -69,   -69,
+     133,   -69,   -16,   -69,    88,   -69,   -69,    87,   -69,   -69,
+     -69,   -69,   -69,   -69,   108,   -69,   -69,   130,   130,    47,
+      47,   -53,   -69,    58,   -69,   131,   263,    72,   -69,   130,
+      95,   130,   130,   130,     1,   295,   -69,   -69,   -69,    58,
+      97,   158,   154,   130,    47,   -69,   -69,     0,   155,   130,
+     130,   130,   130,   130,   130,   130,   130,   130,   130,   130,
+     130,   130,   130,   130,   130,   130,   -69,   -69,   -69,   -69,
+     -69,    72,   295,   130,   -69,   218,   117,   178,   144,     0,
+     -69,   -69,   -69,   236,    33,    71,    47,    47,   -69,   -69,
+     -69,   -69,   295,   310,   324,   331,   295,   295,   295,   295,
+     295,   295,    34,    34,    53,    53,   -69,   -69,   -69,   279,
+     -69,   -69,   -69,   115,   -69,   -69,    47,   137,   -69,    55,
+     116,   111,   -69,    71,   -69,   -69,    44,   -69,   130,   130,
+     119,   -69,   112,   -69,    55,   198,    60,   279,   -69,    47,
+     -69,   -69,   -69,   130,   120,   -14,   295,    47,   -69,    32,
+     -69
 };
 
 /* YYPGOTO[NTERM-NUM].  */
 static const yytype_int16 yypgoto[] =
 {
-     -65,   -65,   190,   192,   -65,   -65,   -65,   -65,   -65,   -65,
-     -65,   -65,   167,   -65,   163,   -65,    88,   -65,   -65,   -65,
-     106,   -39,   -64,   -65,   -65,   -65,   -65,   -65,   -65,    51,
-     -65,   105,   -65,   -65,    37,   162,   -59
+     -69,   -69,   180,   181,   -69,   -69,   -69,   -69,   -69,   -69,
+     -69,   -69,   -69,   160,   -69,   157,   -69,   118,   -69,   -69,
+     -69,    92,   -46,   -68,   -69,   -69,   -69,   -69,   -69,   -69,
+      23,   -69,    66,   -69,   -69,    31,   150,   -63
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
    positive, shift that token.  If negative, reduce the rule which
    number is the opposite.  If zero, do what YYDEFACT says.
    If YYTABLE_NINF, syntax error.  */
-#define YYTABLE_NINF -89
+#define YYTABLE_NINF -90
 static const yytype_int16 yytable[] =
 {
-      69,    82,    87,    76,    83,    84,     4,    88,    77,    89,
-      90,   121,    91,    41,    11,   173,    42,   115,   174,   118,
-     119,   120,    16,   131,    92,    93,    85,   128,    73,    74,
-       8,   126,   122,    92,    93,    43,    44,   135,   136,   137,
-     138,   139,   140,   141,   142,   143,   144,   145,   146,   147,
-     148,   149,   150,   151,   197,    92,    93,   158,   132,    47,
-      48,    49,    50,   199,    51,    52,    53,    54,    17,    55,
-     108,   109,   110,   111,   112,    56,    57,    58,    59,     2,
-       3,    60,   -15,   -15,   -15,    99,    61,    62,   164,   165,
-     166,   167,   106,   107,   108,   109,   110,   111,   112,   -49,
-     -49,   172,    63,    12,    13,    14,    64,    19,    65,   152,
-     153,   154,   155,    21,     4,   182,   183,    66,   184,   186,
-      47,    22,    49,    50,    23,    51,    52,    53,    54,    25,
-      55,   191,   192,   195,    26,    28,    56,    57,    58,    59,
-     110,   111,   112,    31,    36,    47,    32,    49,    50,   194,
-      51,    52,    53,    54,    34,    55,    39,   198,    40,    45,
-      78,    56,    57,    63,   114,    94,    79,    64,   116,   125,
-     123,    97,    98,    99,    55,   161,   171,   177,    80,    93,
-     106,   107,   108,   109,   110,   111,   112,   178,    63,   188,
-     187,   196,    64,     9,   -88,    10,    35,    95,    96,   160,
-      46,   134,   157,    80,    97,    98,    99,   100,   101,   102,
-     103,   104,   105,   106,   107,   108,   109,   110,   111,   112,
-     189,   180,    81,     0,    97,    98,    99,   162,     0,     0,
-       0,     0,   124,   106,   107,   108,   109,   110,   111,   112,
-       0,     0,     0,     0,    97,    98,    99,     0,     0,     0,
-       0,     0,   124,   106,   107,   108,   109,   110,   111,   112,
-       0,     0,     0,     0,    97,    98,    99,     0,     0,     0,
-       0,     0,   190,   106,   107,   108,   109,   110,   111,   112,
-       0,     0,    97,    98,    99,     0,     0,     0,     0,     0,
-     159,   106,   107,   108,   109,   110,   111,   112,     0,   -88,
-       0,     0,    95,    96,     0,     0,     0,     0,   163,    97,
-      98,    99,   100,   101,   102,   103,   104,   105,   106,   107,
-     108,   109,   110,   111,   112,    97,    98,    99,     0,     0,
-       0,     0,     0,     0,   106,   107,   108,   109,   110,   111,
-     112,    97,    98,    99,     0,     0,     0,     0,     0,   169,
-     106,   107,   108,   109,   110,   111,   112,    98,    99,     0,
-       0,     0,     0,     0,     0,   106,   107,   108,   109,   110,
-     111,   112,   106,   107,   108,   109,   110,   111,   112
+      73,    85,    90,     4,    86,    87,    40,    91,    79,    41,
+     128,    92,    93,    80,    94,    11,   122,    16,   125,   126,
+     127,    48,    49,    88,    95,    96,   135,     8,    42,    43,
+     133,   129,   138,    12,    13,    14,   142,   143,   144,   145,
+     146,   147,   148,   149,   150,   151,   152,   153,   154,   155,
+     156,   157,   158,    17,   198,    19,    51,    52,    53,    54,
+     159,    55,    56,    57,    58,   174,    59,   139,   175,    21,
+      95,    96,    60,    61,    62,    63,     2,     3,    64,   -16,
+     -16,   -16,    22,    65,    66,   111,   112,   113,   114,   115,
+     167,   168,   116,   117,   118,   119,    95,    96,   173,    67,
+     200,   165,   166,    68,    23,    69,   113,   114,   115,   -50,
+     -50,     4,   183,   184,    70,   185,   187,    51,    25,    53,
+      54,    26,    55,    56,    57,    58,    31,    59,   192,   193,
+     196,    28,    33,    60,    61,    62,    63,    35,    44,    51,
+      38,    53,    54,   195,    55,    56,    57,    58,    46,    59,
+      47,   199,    78,    81,    82,    60,    61,   100,   101,   102,
+      67,    97,   123,   132,    68,   130,   109,   110,   111,   112,
+     113,   114,   115,   162,    59,    83,    96,   172,   179,   189,
+     178,   188,    67,     9,    10,   161,    68,   197,   -89,    34,
+     141,    98,    99,    45,   181,   163,   121,    83,   100,   101,
+     102,   103,   104,   105,   106,   107,   108,   109,   110,   111,
+     112,   113,   114,   115,    84,   190,     0,     0,   100,   101,
+     102,     0,     0,     0,     0,     0,   131,   109,   110,   111,
+     112,   113,   114,   115,     0,     0,     0,     0,   100,   101,
+     102,     0,     0,     0,     0,     0,   131,   109,   110,   111,
+     112,   113,   114,   115,     0,     0,     0,     0,   100,   101,
+     102,     0,     0,     0,     0,     0,   191,   109,   110,   111,
+     112,   113,   114,   115,     0,     0,   100,   101,   102,     0,
+       0,     0,     0,     0,   160,   109,   110,   111,   112,   113,
+     114,   115,     0,   -89,     0,     0,    98,    99,     0,     0,
+       0,     0,   164,   100,   101,   102,   103,   104,   105,   106,
+     107,   108,   109,   110,   111,   112,   113,   114,   115,   100,
+     101,   102,     0,     0,     0,     0,     0,     0,   109,   110,
+     111,   112,   113,   114,   115,   100,   101,   102,     0,     0,
+       0,     0,     0,   170,   109,   110,   111,   112,   113,   114,
+     115,   101,   102,     0,     0,     0,     0,     0,     0,   109,
+     110,   111,   112,   113,   114,   115,   102,     0,     0,     0,
+       0,     0,     0,   109,   110,   111,   112,   113,   114,   115,
+     109,   110,   111,   112,   113,   114,   115
 };
 
 static const yytype_int16 yycheck[] =
 {
-      39,    60,    66,    24,    63,    64,    35,    66,    29,    64,
-      65,     9,    67,    14,    17,    10,    17,    76,    13,    78,
-      79,    80,     9,    32,    38,    39,    65,    91,    17,    18,
-      59,    90,    30,    38,    39,    36,    37,    96,    97,    98,
-      99,   100,   101,   102,   103,   104,   105,   106,   107,   108,
-     109,   110,   111,   112,    68,    38,    39,   116,    67,     9,
-      10,    11,    12,    68,    14,    15,    16,    17,    62,    19,
-      51,    52,    53,    54,    55,    25,    26,    27,    28,     0,
-       1,    31,     3,     4,     5,    42,    36,    37,    68,    69,
-     129,   130,    49,    50,    51,    52,    53,    54,    55,    38,
-      39,   165,    52,     3,     4,     5,    56,     9,    58,    20,
-      21,    22,    23,    60,    35,    68,    69,    67,   177,   178,
-       9,     9,    11,    12,     6,    14,    15,    16,    17,    62,
-      19,    68,    69,   192,     7,     9,    25,    26,    27,    28,
-      53,    54,    55,    62,    10,     9,     8,    11,    12,   188,
-      14,    15,    16,    17,    63,    19,    62,   196,    61,    63,
-      65,    25,    26,    52,    19,    30,    67,    56,    67,     9,
-      68,    40,    41,    42,    19,    29,    62,    64,    67,    39,
-      49,    50,    51,    52,    53,    54,    55,    67,    52,    67,
-      62,    67,    56,     3,    30,     3,    29,    33,    34,    68,
-      37,    95,   114,    67,    40,    41,    42,    43,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
-     183,   170,    60,    -1,    40,    41,    42,   122,    -1,    -1,
-      -1,    -1,    68,    49,    50,    51,    52,    53,    54,    55,
-      -1,    -1,    -1,    -1,    40,    41,    42,    -1,    -1,    -1,
-      -1,    -1,    68,    49,    50,    51,    52,    53,    54,    55,
-      -1,    -1,    -1,    -1,    40,    41,    42,    -1,    -1,    -1,
-      -1,    -1,    68,    49,    50,    51,    52,    53,    54,    55,
-      -1,    -1,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,
-      66,    49,    50,    51,    52,    53,    54,    55,    -1,    30,
-      -1,    -1,    33,    34,    -1,    -1,    -1,    -1,    66,    40,
-      41,    42,    43,    44,    45,    46,    47,    48,    49,    50,
+      46,    64,    70,    35,    67,    68,    14,    70,    24,    17,
+       9,    64,    65,    29,    67,    17,    79,     9,    81,    82,
+      83,    17,    18,    69,    38,    39,    94,    59,    36,    37,
+      93,    30,    32,     3,     4,     5,    99,   100,   101,   102,
+     103,   104,   105,   106,   107,   108,   109,   110,   111,   112,
+     113,   114,   115,    62,    68,     9,     9,    10,    11,    12,
+     123,    14,    15,    16,    17,    10,    19,    67,    13,    60,
+      38,    39,    25,    26,    27,    28,     0,     1,    31,     3,
+       4,     5,     9,    36,    37,    51,    52,    53,    54,    55,
+     136,   137,    20,    21,    22,    23,    38,    39,   166,    52,
+      68,    68,    69,    56,     6,    58,    53,    54,    55,    38,
+      39,    35,    68,    69,    67,   178,   179,     9,    62,    11,
+      12,     7,    14,    15,    16,    17,    62,    19,    68,    69,
+     193,     9,    63,    25,    26,    27,    28,    10,    63,     9,
+       8,    11,    12,   189,    14,    15,    16,    17,    62,    19,
+      61,   197,    19,    65,    67,    25,    26,    40,    41,    42,
+      52,    30,    67,     9,    56,    68,    49,    50,    51,    52,
+      53,    54,    55,    29,    19,    67,    39,    62,    67,    67,
+      64,    62,    52,     3,     3,    68,    56,    67,    30,    29,
+      98,    33,    34,    36,   171,   129,    78,    67,    40,    41,
+      42,    43,    44,    45,    46,    47,    48,    49,    50,    51,
+      52,    53,    54,    55,    64,   184,    -1,    -1,    40,    41,
+      42,    -1,    -1,    -1,    -1,    -1,    68,    49,    50,    51,
+      52,    53,    54,    55,    -1,    -1,    -1,    -1,    40,    41,
+      42,    -1,    -1,    -1,    -1,    -1,    68,    49,    50,    51,
+      52,    53,    54,    55,    -1,    -1,    -1,    -1,    40,    41,
+      42,    -1,    -1,    -1,    -1,    -1,    68,    49,    50,    51,
+      52,    53,    54,    55,    -1,    -1,    40,    41,    42,    -1,
+      -1,    -1,    -1,    -1,    66,    49,    50,    51,    52,    53,
+      54,    55,    -1,    30,    -1,    -1,    33,    34,    -1,    -1,
+      -1,    -1,    66,    40,    41,    42,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    40,
+      41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,    50,
       51,    52,    53,    54,    55,    40,    41,    42,    -1,    -1,
-      -1,    -1,    -1,    -1,    49,    50,    51,    52,    53,    54,
-      55,    40,    41,    42,    -1,    -1,    -1,    -1,    -1,    64,
-      49,    50,    51,    52,    53,    54,    55,    41,    42,    -1,
-      -1,    -1,    -1,    -1,    -1,    49,    50,    51,    52,    53,
-      54,    55,    49,    50,    51,    52,    53,    54,    55
+      -1,    -1,    -1,    64,    49,    50,    51,    52,    53,    54,
+      55,    41,    42,    -1,    -1,    -1,    -1,    -1,    -1,    49,
+      50,    51,    52,    53,    54,    55,    42,    -1,    -1,    -1,
+      -1,    -1,    -1,    49,    50,    51,    52,    53,    54,    55,
+      49,    50,    51,    52,    53,    54,    55
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const yytype_uint8 yystos[] =
 {
-       0,    71,     0,     1,    35,    72,    73,    77,    59,    72,
-      73,    17,     3,     4,     5,    78,     9,    62,    79,     9,
-      80,    60,     9,     6,    74,    62,     7,    75,     9,    81,
-      82,    62,     8,    76,    63,    82,    10,    83,    84,    62,
-      61,    14,    17,    36,    37,    63,    84,     9,    10,    11,
-      12,    14,    15,    16,    17,    19,    25,    26,    27,    28,
-      31,    36,    37,    52,    56,    58,    67,    88,    90,    91,
-      92,   105,   106,    17,    18,    85,    24,    29,    65,    67,
-      67,   105,   106,   106,   106,    91,    91,    92,   106,    64,
-      65,    67,    38,    39,    30,    33,    34,    40,    41,    42,
-      43,    44,    45,    46,    47,    48,    49,    50,    51,    52,
-      53,    54,    55,    86,    19,   106,    67,    99,   106,   106,
-     106,     9,    30,    68,    68,     9,   106,    89,    92,    97,
-      96,    32,    67,   101,    90,   106,   106,   106,   106,   106,
-     106,   106,   106,   106,   106,   106,   106,   106,   106,   106,
-     106,   106,    20,    21,    22,    23,    87,    86,   106,    66,
-      68,    29,   101,    66,    68,    69,    91,    91,   102,    64,
-      93,    62,    92,    10,    13,   103,   104,    64,    67,    98,
-      99,    95,    68,    69,   106,   100,   106,    62,    67,   104,
-      68,    68,    69,    94,    91,   106,    67,    68,    91,    68
+       0,    71,     0,     1,    35,    72,    73,    78,    59,    72,
+      73,    17,     3,     4,     5,    79,     9,    62,    80,     9,
+      81,    60,     9,     6,    75,    62,     7,    76,     9,    82,
+      83,    62,    74,    63,    83,    10,    84,    85,     8,    77,
+      14,    17,    36,    37,    63,    85,    62,    61,    17,    18,
+      86,     9,    10,    11,    12,    14,    15,    16,    17,    19,
+      25,    26,    27,    28,    31,    36,    37,    52,    56,    58,
+      67,    89,    91,    92,    93,   106,   107,    87,    19,    24,
+      29,    65,    67,    67,   106,   107,   107,   107,    92,    92,
+      93,   107,    64,    65,    67,    38,    39,    30,    33,    34,
+      40,    41,    42,    43,    44,    45,    46,    47,    48,    49,
+      50,    51,    52,    53,    54,    55,    20,    21,    22,    23,
+      88,    87,   107,    67,   100,   107,   107,   107,     9,    30,
+      68,    68,     9,   107,    90,    93,    98,    97,    32,    67,
+     102,    91,   107,   107,   107,   107,   107,   107,   107,   107,
+     107,   107,   107,   107,   107,   107,   107,   107,   107,   107,
+      66,    68,    29,   102,    66,    68,    69,    92,    92,   103,
+      64,    94,    62,    93,    10,    13,   104,   105,    64,    67,
+      99,   100,    96,    68,    69,   107,   101,   107,    62,    67,
+     105,    68,    68,    69,    95,    92,   107,    67,    68,    92,
+      68
 };
 
 #define yyerrok		(yyerrstatus = 0)
@@ -1414,44 +1420,44 @@ yydestruct (yymsg, yytype, yyvaluep, yyscanner, compiler)
   switch (yytype)
     {
       case 9: /* "_IDENTIFIER_" */
-#line 169 "grammar.y"
+#line 171 "grammar.y"
 	{ yr_free((yyvaluep->c_string)); };
-#line 1420 "grammar.c"
+#line 1426 "grammar.c"
 	break;
       case 10: /* "_STRING_IDENTIFIER_" */
-#line 170 "grammar.y"
+#line 172 "grammar.y"
 	{ yr_free((yyvaluep->c_string)); };
-#line 1425 "grammar.c"
+#line 1431 "grammar.c"
 	break;
       case 11: /* "_STRING_COUNT_" */
-#line 171 "grammar.y"
+#line 173 "grammar.y"
 	{ yr_free((yyvaluep->c_string)); };
-#line 1430 "grammar.c"
+#line 1436 "grammar.c"
 	break;
       case 12: /* "_STRING_OFFSET_" */
-#line 172 "grammar.y"
+#line 174 "grammar.y"
 	{ yr_free((yyvaluep->c_string)); };
-#line 1435 "grammar.c"
+#line 1441 "grammar.c"
 	break;
       case 13: /* "_STRING_IDENTIFIER_WITH_WILDCARD_" */
-#line 173 "grammar.y"
+#line 175 "grammar.y"
 	{ yr_free((yyvaluep->c_string)); };
-#line 1440 "grammar.c"
+#line 1446 "grammar.c"
 	break;
       case 17: /* "_TEXT_STRING_" */
-#line 174 "grammar.y"
+#line 176 "grammar.y"
 	{ yr_free((yyvaluep->sized_string)); };
-#line 1445 "grammar.c"
+#line 1451 "grammar.c"
 	break;
       case 18: /* "_HEX_STRING_" */
-#line 175 "grammar.y"
+#line 177 "grammar.y"
 	{ yr_free((yyvaluep->sized_string)); };
-#line 1450 "grammar.c"
+#line 1456 "grammar.c"
 	break;
       case 19: /* "_REGEXP_" */
-#line 176 "grammar.y"
+#line 178 "grammar.y"
 	{ yr_free((yyvaluep->sized_string)); };
-#line 1455 "grammar.c"
+#line 1461 "grammar.c"
 	break;
 
       default:
@@ -1761,7 +1767,7 @@ yyreduce:
   switch (yyn)
     {
         case 8:
-#line 203 "grammar.y"
+#line 206 "grammar.y"
     {
         int result = yr_parser_reduce_import(yyscanner, (yyvsp[(2) - (2)].sized_string));
 
@@ -1772,31 +1778,45 @@ yyreduce:
     break;
 
   case 9:
-#line 215 "grammar.y"
+#line 218 "grammar.y"
     {
-        int result = yr_parser_reduce_rule_declaration(
+        YR_RULE* rule = yr_parser_reduce_rule_declaration_phase_1(
             yyscanner,
-            (yyvsp[(1) - (9)].integer),
-            (yyvsp[(3) - (9)].c_string),
-            (yyvsp[(4) - (9)].c_string),
-            (yyvsp[(7) - (9)].string),
-            (yyvsp[(6) - (9)].meta));
+            (yyvsp[(1) - (7)].integer),
+            (yyvsp[(3) - (7)].c_string),
+            (yyvsp[(4) - (7)].c_string),
+            (yyvsp[(7) - (7)].string),
+            (yyvsp[(6) - (7)].meta));
 
-        yr_free((yyvsp[(3) - (9)].c_string));
+        ERROR_IF(rule == NULL);
 
-        ERROR_IF(result != ERROR_SUCCESS);
+        (yyval.rule) = rule;
       }
     break;
 
   case 10:
-#line 233 "grammar.y"
+#line 232 "grammar.y"
     {
-        (yyval.meta) = NULL;
+        YR_RULE* rule = (yyvsp[(8) - (10)].rule); // rule created in phase 1
+
+        compiler->last_result = yr_parser_reduce_rule_declaration_phase_2(
+            yyscanner, rule);
+
+        yr_free((yyvsp[(3) - (10)].c_string));
+
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
     break;
 
   case 11:
-#line 237 "grammar.y"
+#line 247 "grammar.y"
+    {
+        (yyval.meta) = NULL;
+      }
+    break;
+
+  case 12:
+#line 251 "grammar.y"
     {
         // Each rule have a list of meta-data info, consisting in a
         // sequence of YR_META structures. The last YR_META structure does
@@ -1821,16 +1841,15 @@ yyreduce:
       }
     break;
 
-  case 12:
-#line 264 "grammar.y"
+  case 13:
+#line 278 "grammar.y"
     {
         (yyval.string) = NULL;
-        compiler->current_rule_strings = (yyval.string);
       }
     break;
 
-  case 13:
-#line 269 "grammar.y"
+  case 14:
+#line 282 "grammar.y"
     {
         // Each rule have a list of strings, consisting in a sequence
         // of YR_STRING structures. The last YR_STRING structure does not
@@ -1851,40 +1870,39 @@ yyreduce:
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        compiler->current_rule_strings = (yyvsp[(3) - (3)].string);
         (yyval.string) = (yyvsp[(3) - (3)].string);
       }
     break;
 
-  case 15:
-#line 301 "grammar.y"
+  case 16:
+#line 313 "grammar.y"
     { (yyval.integer) = 0;  }
     break;
 
-  case 16:
-#line 302 "grammar.y"
+  case 17:
+#line 314 "grammar.y"
     { (yyval.integer) = (yyvsp[(1) - (2)].integer) | (yyvsp[(2) - (2)].integer); }
     break;
 
-  case 17:
-#line 307 "grammar.y"
+  case 18:
+#line 319 "grammar.y"
     { (yyval.integer) = RULE_GFLAGS_PRIVATE; }
     break;
 
-  case 18:
-#line 308 "grammar.y"
+  case 19:
+#line 320 "grammar.y"
     { (yyval.integer) = RULE_GFLAGS_GLOBAL; }
     break;
 
-  case 19:
-#line 314 "grammar.y"
+  case 20:
+#line 326 "grammar.y"
     {
         (yyval.c_string) = NULL;
       }
     break;
 
-  case 20:
-#line 318 "grammar.y"
+  case 21:
+#line 330 "grammar.y"
     {
         // Tags list is represented in the arena as a sequence
         // of null-terminated strings, the sequence ends with an
@@ -1900,8 +1918,8 @@ yyreduce:
       }
     break;
 
-  case 21:
-#line 336 "grammar.y"
+  case 22:
+#line 348 "grammar.y"
     {
         char* identifier;
 
@@ -1916,8 +1934,8 @@ yyreduce:
       }
     break;
 
-  case 22:
-#line 349 "grammar.y"
+  case 23:
+#line 361 "grammar.y"
     {
         char* tag_name = (yyvsp[(1) - (2)].c_string);
         size_t tag_length = tag_name != NULL ? strlen(tag_name) : 0;
@@ -1951,18 +1969,18 @@ yyreduce:
       }
     break;
 
-  case 23:
-#line 385 "grammar.y"
+  case 24:
+#line 397 "grammar.y"
     {  (yyval.meta) = (yyvsp[(1) - (1)].meta); }
     break;
 
-  case 24:
-#line 386 "grammar.y"
+  case 25:
+#line 398 "grammar.y"
     {  (yyval.meta) = (yyvsp[(1) - (2)].meta); }
     break;
 
-  case 25:
-#line 392 "grammar.y"
+  case 26:
+#line 404 "grammar.y"
     {
         SIZED_STRING* sized_string = (yyvsp[(3) - (3)].sized_string);
 
@@ -1980,8 +1998,8 @@ yyreduce:
       }
     break;
 
-  case 26:
-#line 408 "grammar.y"
+  case 27:
+#line 420 "grammar.y"
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -1996,8 +2014,8 @@ yyreduce:
       }
     break;
 
-  case 27:
-#line 421 "grammar.y"
+  case 28:
+#line 433 "grammar.y"
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -2012,8 +2030,8 @@ yyreduce:
       }
     break;
 
-  case 28:
-#line 434 "grammar.y"
+  case 29:
+#line 446 "grammar.y"
     {
         (yyval.meta) = yr_parser_reduce_meta_declaration(
             yyscanner,
@@ -2028,18 +2046,18 @@ yyreduce:
       }
     break;
 
-  case 29:
-#line 450 "grammar.y"
+  case 30:
+#line 462 "grammar.y"
     { (yyval.string) = (yyvsp[(1) - (1)].string); }
     break;
 
-  case 30:
-#line 451 "grammar.y"
+  case 31:
+#line 463 "grammar.y"
     { (yyval.string) = (yyvsp[(1) - (2)].string); }
     break;
 
-  case 31:
-#line 457 "grammar.y"
+  case 32:
+#line 469 "grammar.y"
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner,
@@ -2054,15 +2072,15 @@ yyreduce:
       }
     break;
 
-  case 32:
-#line 470 "grammar.y"
+  case 33:
+#line 482 "grammar.y"
     {
         compiler->error_line = yyget_lineno(yyscanner);
       }
     break;
 
-  case 33:
-#line 474 "grammar.y"
+  case 34:
+#line 486 "grammar.y"
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner,
@@ -2079,8 +2097,8 @@ yyreduce:
       }
     break;
 
-  case 34:
-#line 489 "grammar.y"
+  case 35:
+#line 501 "grammar.y"
     {
         (yyval.string) = yr_parser_reduce_string_declaration(
             yyscanner,
@@ -2095,38 +2113,38 @@ yyreduce:
       }
     break;
 
-  case 35:
-#line 505 "grammar.y"
+  case 36:
+#line 517 "grammar.y"
     { (yyval.integer) = 0; }
     break;
 
-  case 36:
-#line 506 "grammar.y"
+  case 37:
+#line 518 "grammar.y"
     { (yyval.integer) = (yyvsp[(1) - (2)].integer) | (yyvsp[(2) - (2)].integer); }
     break;
 
-  case 37:
-#line 511 "grammar.y"
+  case 38:
+#line 523 "grammar.y"
     { (yyval.integer) = STRING_GFLAGS_WIDE; }
     break;
 
-  case 38:
-#line 512 "grammar.y"
+  case 39:
+#line 524 "grammar.y"
     { (yyval.integer) = STRING_GFLAGS_ASCII; }
     break;
 
-  case 39:
-#line 513 "grammar.y"
+  case 40:
+#line 525 "grammar.y"
     { (yyval.integer) = STRING_GFLAGS_NO_CASE; }
     break;
 
-  case 40:
-#line 514 "grammar.y"
+  case 41:
+#line 526 "grammar.y"
     { (yyval.integer) = STRING_GFLAGS_FULL_WORD; }
     break;
 
-  case 41:
-#line 520 "grammar.y"
+  case 42:
+#line 532 "grammar.y"
     {
         int var_index = yr_parser_lookup_loop_variable(yyscanner, (yyvsp[(1) - (1)].c_string));
 
@@ -2219,8 +2237,8 @@ yyreduce:
       }
     break;
 
-  case 42:
-#line 611 "grammar.y"
+  case 43:
+#line 623 "grammar.y"
     {
         YR_OBJECT* field = NULL;
 
@@ -2271,8 +2289,8 @@ yyreduce:
       }
     break;
 
-  case 43:
-#line 660 "grammar.y"
+  case 44:
+#line 672 "grammar.y"
     {
         if ((yyvsp[(1) - (4)].expression).type == EXPRESSION_TYPE_OBJECT &&
             (yyvsp[(1) - (4)].expression).value.object->type == OBJECT_TYPE_ARRAY)
@@ -2333,8 +2351,8 @@ yyreduce:
       }
     break;
 
-  case 44:
-#line 720 "grammar.y"
+  case 45:
+#line 732 "grammar.y"
     {
         char* args_fmt;
 
@@ -2379,15 +2397,15 @@ yyreduce:
       }
     break;
 
-  case 45:
-#line 767 "grammar.y"
+  case 46:
+#line 779 "grammar.y"
     {
         (yyval.c_string) = yr_strdup("");
       }
     break;
 
-  case 46:
-#line 771 "grammar.y"
+  case 47:
+#line 783 "grammar.y"
     {
         (yyval.c_string) = (char*) yr_malloc(MAX_FUNCTION_ARGS + 1);
 
@@ -2414,8 +2432,8 @@ yyreduce:
       }
     break;
 
-  case 47:
-#line 796 "grammar.y"
+  case 48:
+#line 808 "grammar.y"
     {
         if (strlen((yyvsp[(1) - (3)].c_string)) == MAX_FUNCTION_ARGS)
         {
@@ -2449,8 +2467,8 @@ yyreduce:
       }
     break;
 
-  case 48:
-#line 832 "grammar.y"
+  case 49:
+#line 844 "grammar.y"
     {
         SIZED_STRING* sized_string = (yyvsp[(1) - (1)].sized_string);
         RE* re;
@@ -2494,8 +2512,8 @@ yyreduce:
       }
     break;
 
-  case 49:
-#line 878 "grammar.y"
+  case 50:
+#line 890 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type == EXPRESSION_TYPE_STRING)
         {
@@ -2511,8 +2529,8 @@ yyreduce:
       }
     break;
 
-  case 50:
-#line 895 "grammar.y"
+  case 51:
+#line 907 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 1, NULL, NULL);
@@ -2523,8 +2541,8 @@ yyreduce:
       }
     break;
 
-  case 51:
-#line 904 "grammar.y"
+  case 52:
+#line 916 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, 0, NULL, NULL);
@@ -2535,8 +2553,8 @@ yyreduce:
       }
     break;
 
-  case 52:
-#line 913 "grammar.y"
+  case 53:
+#line 925 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "matches");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_REGEXP, "matches");
@@ -2553,8 +2571,8 @@ yyreduce:
       }
     break;
 
-  case 53:
-#line 928 "grammar.y"
+  case 54:
+#line 940 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_STRING, "contains");
@@ -2570,8 +2588,8 @@ yyreduce:
       }
     break;
 
-  case 54:
-#line 942 "grammar.y"
+  case 55:
+#line 954 "grammar.y"
     {
         int result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2587,8 +2605,8 @@ yyreduce:
       }
     break;
 
-  case 55:
-#line 956 "grammar.y"
+  case 56:
+#line 968 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "at");
 
@@ -2606,8 +2624,8 @@ yyreduce:
       }
     break;
 
-  case 56:
-#line 972 "grammar.y"
+  case 57:
+#line 984 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -2623,8 +2641,8 @@ yyreduce:
       }
     break;
 
-  case 57:
-#line 986 "grammar.y"
+  case 58:
+#line 998 "grammar.y"
     {
         int var_index;
 
@@ -2662,8 +2680,8 @@ yyreduce:
       }
     break;
 
-  case 58:
-#line 1022 "grammar.y"
+  case 59:
+#line 1034 "grammar.y"
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2700,8 +2718,8 @@ yyreduce:
       }
     break;
 
-  case 59:
-#line 1057 "grammar.y"
+  case 60:
+#line 1069 "grammar.y"
     {
         int mem_offset;
 
@@ -2784,8 +2802,8 @@ yyreduce:
       }
     break;
 
-  case 60:
-#line 1138 "grammar.y"
+  case 61:
+#line 1150 "grammar.y"
     {
         int mem_offset = LOOP_LOCAL_VARS * compiler->loop_depth;
         uint8_t* addr;
@@ -2817,8 +2835,8 @@ yyreduce:
       }
     break;
 
-  case 61:
-#line 1168 "grammar.y"
+  case 62:
+#line 1180 "grammar.y"
     {
         int mem_offset;
 
@@ -2870,8 +2888,8 @@ yyreduce:
       }
     break;
 
-  case 62:
-#line 1218 "grammar.y"
+  case 63:
+#line 1230 "grammar.y"
     {
         yr_parser_emit(yyscanner, OP_OF, NULL);
 
@@ -2879,8 +2897,8 @@ yyreduce:
       }
     break;
 
-  case 63:
-#line 1224 "grammar.y"
+  case 64:
+#line 1236 "grammar.y"
     {
         yr_parser_emit(yyscanner, OP_NOT, NULL);
 
@@ -2888,8 +2906,8 @@ yyreduce:
       }
     break;
 
-  case 64:
-#line 1230 "grammar.y"
+  case 65:
+#line 1242 "grammar.y"
     {
         int64_t* jmp_destination_addr;
 
@@ -2916,18 +2934,19 @@ yyreduce:
       }
     break;
 
-  case 65:
-#line 1255 "grammar.y"
+  case 66:
+#line 1267 "grammar.y"
     {
         uint8_t* and_addr;
 
-        // Ensure that we have at least two consecutive bytes in the arena's 
+        // Ensure that we have at least two consecutive bytes in the arena's
         // current page, one for the AND opcode and one for opcode following the
         // AND. This is necessary because we need to compute the address for the
         // opcode following the AND, and we don't want the AND in one page and
         // the following opcode in another page.
 
-        compiler->last_result = yr_arena_reserve_memory(compiler->code_arena, 2);
+        compiler->last_result = yr_arena_reserve_memory(
+            compiler->code_arena, 2);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -2943,9 +2962,9 @@ yyreduce:
         // We know that the AND opcode and the following one are within the same
         // page, so we can compute the address for the opcode following the AND
         // by simply adding one to its address.
-        
+
         *(fixup->address) = PTR_TO_INT64(and_addr + 1);
-        
+
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
@@ -2953,8 +2972,8 @@ yyreduce:
       }
     break;
 
-  case 66:
-#line 1289 "grammar.y"
+  case 67:
+#line 1302 "grammar.y"
     {
         int64_t* jmp_destination_addr;
 
@@ -2980,18 +2999,19 @@ yyreduce:
       }
     break;
 
-  case 67:
-#line 1313 "grammar.y"
+  case 68:
+#line 1326 "grammar.y"
     {
         uint8_t* or_addr;
 
-        // Ensure that we have at least two consecutive bytes in the arena's 
+        // Ensure that we have at least two consecutive bytes in the arena's
         // current page, one for the OR opcode and one for opcode following the
         // OR. This is necessary because we need to compute the address for the
         // opcode following the OR, and we don't want the OR in one page and
         // the following opcode in another page.
 
-        compiler->last_result = yr_arena_reserve_memory(compiler->code_arena, 2);
+        compiler->last_result = yr_arena_reserve_memory(
+            compiler->code_arena, 2);
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
@@ -3017,8 +3037,8 @@ yyreduce:
       }
     break;
 
-  case 68:
-#line 1347 "grammar.y"
+  case 69:
+#line 1361 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3029,8 +3049,8 @@ yyreduce:
       }
     break;
 
-  case 69:
-#line 1356 "grammar.y"
+  case 70:
+#line 1370 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3041,8 +3061,8 @@ yyreduce:
       }
     break;
 
-  case 70:
-#line 1365 "grammar.y"
+  case 71:
+#line 1379 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "<=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3053,8 +3073,8 @@ yyreduce:
       }
     break;
 
-  case 71:
-#line 1374 "grammar.y"
+  case 72:
+#line 1388 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, ">=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3065,8 +3085,8 @@ yyreduce:
       }
     break;
 
-  case 72:
-#line 1383 "grammar.y"
+  case 73:
+#line 1397 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "==", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3077,8 +3097,8 @@ yyreduce:
       }
     break;
 
-  case 73:
-#line 1392 "grammar.y"
+  case 74:
+#line 1406 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "!=", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3089,32 +3109,32 @@ yyreduce:
       }
     break;
 
-  case 74:
-#line 1401 "grammar.y"
+  case 75:
+#line 1415 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(1) - (1)].expression);
       }
     break;
 
-  case 75:
-#line 1405 "grammar.y"
+  case 76:
+#line 1419 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(2) - (3)].expression);
       }
     break;
 
-  case 76:
-#line 1412 "grammar.y"
+  case 77:
+#line 1426 "grammar.y"
     { (yyval.integer) = INTEGER_SET_ENUMERATION; }
     break;
 
-  case 77:
-#line 1413 "grammar.y"
+  case 78:
+#line 1427 "grammar.y"
     { (yyval.integer) = INTEGER_SET_RANGE; }
     break;
 
-  case 78:
-#line 1419 "grammar.y"
+  case 79:
+#line 1433 "grammar.y"
     {
         if ((yyvsp[(2) - (6)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3134,8 +3154,8 @@ yyreduce:
       }
     break;
 
-  case 79:
-#line 1441 "grammar.y"
+  case 80:
+#line 1455 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3149,8 +3169,8 @@ yyreduce:
       }
     break;
 
-  case 80:
-#line 1453 "grammar.y"
+  case 81:
+#line 1467 "grammar.y"
     {
         if ((yyvsp[(3) - (3)].expression).type != EXPRESSION_TYPE_INTEGER)
         {
@@ -3163,61 +3183,61 @@ yyreduce:
       }
     break;
 
-  case 81:
-#line 1468 "grammar.y"
+  case 82:
+#line 1482 "grammar.y"
     {
         // Push end-of-list marker
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
     break;
 
-  case 83:
-#line 1474 "grammar.y"
+  case 84:
+#line 1488 "grammar.y"
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
         yr_parser_emit_pushes_for_strings(yyscanner, "$*");
       }
     break;
 
-  case 86:
-#line 1489 "grammar.y"
+  case 87:
+#line 1503 "grammar.y"
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
         yr_free((yyvsp[(1) - (1)].c_string));
       }
     break;
 
-  case 87:
-#line 1494 "grammar.y"
+  case 88:
+#line 1508 "grammar.y"
     {
         yr_parser_emit_pushes_for_strings(yyscanner, (yyvsp[(1) - (1)].c_string));
         yr_free((yyvsp[(1) - (1)].c_string));
       }
     break;
 
-  case 89:
-#line 1504 "grammar.y"
+  case 90:
+#line 1518 "grammar.y"
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, UNDEFINED, NULL, NULL);
       }
     break;
 
-  case 90:
-#line 1508 "grammar.y"
+  case 91:
+#line 1522 "grammar.y"
     {
         yr_parser_emit_with_arg(yyscanner, OP_PUSH, 1, NULL, NULL);
       }
     break;
 
-  case 91:
-#line 1516 "grammar.y"
+  case 92:
+#line 1530 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(2) - (3)].expression);
       }
     break;
 
-  case 92:
-#line 1520 "grammar.y"
+  case 93:
+#line 1534 "grammar.y"
     {
         compiler->last_result = yr_parser_emit(
             yyscanner, OP_FILESIZE, NULL);
@@ -3229,8 +3249,8 @@ yyreduce:
       }
     break;
 
-  case 93:
-#line 1530 "grammar.y"
+  case 94:
+#line 1544 "grammar.y"
     {
         yywarning(yyscanner,
             "Using deprecated \"entrypoint\" keyword. Use the \"entry_point\" "
@@ -3246,8 +3266,8 @@ yyreduce:
       }
     break;
 
-  case 94:
-#line 1544 "grammar.y"
+  case 95:
+#line 1558 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(3) - (4)].expression), EXPRESSION_TYPE_INTEGER, "intXXXX or uintXXXX");
 
@@ -3265,8 +3285,8 @@ yyreduce:
       }
     break;
 
-  case 95:
-#line 1560 "grammar.y"
+  case 96:
+#line 1574 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner, OP_PUSH, (yyvsp[(1) - (1)].integer), NULL, NULL);
@@ -3278,8 +3298,8 @@ yyreduce:
       }
     break;
 
-  case 96:
-#line 1570 "grammar.y"
+  case 97:
+#line 1584 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg_double(
             yyscanner, OP_PUSH, (yyvsp[(1) - (1)].double_), NULL, NULL);
@@ -3290,8 +3310,8 @@ yyreduce:
       }
     break;
 
-  case 97:
-#line 1579 "grammar.y"
+  case 98:
+#line 1593 "grammar.y"
     {
         SIZED_STRING* sized_string;
 
@@ -3317,8 +3337,8 @@ yyreduce:
       }
     break;
 
-  case 98:
-#line 1603 "grammar.y"
+  case 99:
+#line 1617 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -3335,8 +3355,8 @@ yyreduce:
       }
     break;
 
-  case 99:
-#line 1618 "grammar.y"
+  case 100:
+#line 1632 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_string_identifier(
             yyscanner,
@@ -3353,8 +3373,8 @@ yyreduce:
       }
     break;
 
-  case 100:
-#line 1633 "grammar.y"
+  case 101:
+#line 1647 "grammar.y"
     {
         compiler->last_result = yr_parser_emit_with_arg(
             yyscanner,
@@ -3379,8 +3399,8 @@ yyreduce:
       }
     break;
 
-  case 101:
-#line 1656 "grammar.y"
+  case 102:
+#line 1670 "grammar.y"
     {
         if ((yyvsp[(1) - (1)].expression).type == EXPRESSION_TYPE_INTEGER)  // loop identifier
         {
@@ -3426,8 +3446,8 @@ yyreduce:
       }
     break;
 
-  case 102:
-#line 1700 "grammar.y"
+  case 103:
+#line 1714 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(2) - (2)].expression), EXPRESSION_TYPE_INTEGER | EXPRESSION_TYPE_FLOAT, "-");
 
@@ -3448,8 +3468,8 @@ yyreduce:
       }
     break;
 
-  case 103:
-#line 1719 "grammar.y"
+  case 104:
+#line 1733 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "+", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3469,8 +3489,8 @@ yyreduce:
       }
     break;
 
-  case 104:
-#line 1737 "grammar.y"
+  case 105:
+#line 1751 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "-", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3490,8 +3510,8 @@ yyreduce:
       }
     break;
 
-  case 105:
-#line 1755 "grammar.y"
+  case 106:
+#line 1769 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "*", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3511,8 +3531,8 @@ yyreduce:
       }
     break;
 
-  case 106:
-#line 1773 "grammar.y"
+  case 107:
+#line 1787 "grammar.y"
     {
         compiler->last_result = yr_parser_reduce_operation(
             yyscanner, "\\", (yyvsp[(1) - (3)].expression), (yyvsp[(3) - (3)].expression));
@@ -3532,8 +3552,8 @@ yyreduce:
       }
     break;
 
-  case 107:
-#line 1791 "grammar.y"
+  case 108:
+#line 1805 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "%");
@@ -3545,8 +3565,8 @@ yyreduce:
       }
     break;
 
-  case 108:
-#line 1801 "grammar.y"
+  case 109:
+#line 1815 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3558,8 +3578,8 @@ yyreduce:
       }
     break;
 
-  case 109:
-#line 1811 "grammar.y"
+  case 110:
+#line 1825 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "^");
@@ -3571,8 +3591,8 @@ yyreduce:
       }
     break;
 
-  case 110:
-#line 1821 "grammar.y"
+  case 111:
+#line 1835 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "|");
@@ -3584,8 +3604,8 @@ yyreduce:
       }
     break;
 
-  case 111:
-#line 1831 "grammar.y"
+  case 112:
+#line 1845 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(2) - (2)].expression), EXPRESSION_TYPE_INTEGER, "~");
 
@@ -3597,8 +3617,8 @@ yyreduce:
       }
     break;
 
-  case 112:
-#line 1841 "grammar.y"
+  case 113:
+#line 1855 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, "<<");
@@ -3610,8 +3630,8 @@ yyreduce:
       }
     break;
 
-  case 113:
-#line 1851 "grammar.y"
+  case 114:
+#line 1865 "grammar.y"
     {
         CHECK_TYPE((yyvsp[(1) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
         CHECK_TYPE((yyvsp[(3) - (3)].expression), EXPRESSION_TYPE_INTEGER, ">>");
@@ -3623,8 +3643,8 @@ yyreduce:
       }
     break;
 
-  case 114:
-#line 1861 "grammar.y"
+  case 115:
+#line 1875 "grammar.y"
     {
         (yyval.expression) = (yyvsp[(1) - (1)].expression);
       }
@@ -3632,7 +3652,7 @@ yyreduce:
 
 
 /* Line 1267 of yacc.c.  */
-#line 3636 "grammar.c"
+#line 3656 "grammar.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -3846,6 +3866,6 @@ yyreturn:
 }
 
 
-#line 1866 "grammar.y"
+#line 1880 "grammar.y"
 
 
diff --git a/libyara/grammar.h b/libyara/grammar.h
index e63f102..2fd62f3 100644
--- a/libyara/grammar.h
+++ b/libyara/grammar.h
@@ -142,7 +142,7 @@
 
 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
 typedef union YYSTYPE
-#line 178 "grammar.y"
+#line 180 "grammar.y"
 {
   EXPRESSION      expression;
   SIZED_STRING*   sized_string;
@@ -151,9 +151,10 @@ typedef union YYSTYPE
   double          double_;
   YR_STRING*      string;
   YR_META*        meta;
+  YR_RULE*        rule;
 }
 /* Line 1529 of yacc.c.  */
-#line 157 "grammar.h"
+#line 158 "grammar.h"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
diff --git a/libyara/grammar.y b/libyara/grammar.y
index eaf9c7c..b07e252 100644
--- a/libyara/grammar.y
+++ b/libyara/grammar.y
@@ -137,6 +137,8 @@ limitations under the License.
 %left '*' '\\' '%'
 %right _NOT_ '~' UNARY_MINUS
 
+%type <rule>   rule
+
 %type <string> strings
 %type <string> string_declaration
 %type <string> string_declarations
@@ -183,6 +185,7 @@ limitations under the License.
   double          double_;
   YR_STRING*      string;
   YR_META*        meta;
+  YR_RULE*        rule;
 }
 
 
@@ -211,9 +214,9 @@ import
 
 
 rule
-    : rule_modifiers _RULE_ _IDENTIFIER_ tags '{' meta strings condition '}'
+    : rule_modifiers _RULE_ _IDENTIFIER_ tags '{' meta strings
       {
-        int result = yr_parser_reduce_rule_declaration(
+        YR_RULE* rule = yr_parser_reduce_rule_declaration_phase_1(
             yyscanner,
             $1,
             $3,
@@ -221,9 +224,20 @@ rule
             $7,
             $6);
 
+        ERROR_IF(rule == NULL);
+
+        $$ = rule;
+      }
+      condition '}'
+      {
+        YR_RULE* rule = $<rule>8; // rule created in phase 1
+
+        compiler->last_result = yr_parser_reduce_rule_declaration_phase_2(
+            yyscanner, rule);
+
         yr_free($3);
 
-        ERROR_IF(result != ERROR_SUCCESS);
+        ERROR_IF(compiler->last_result != ERROR_SUCCESS);
       }
     ;
 
@@ -263,7 +277,6 @@ strings
     : /* empty */
       {
         $$ = NULL;
-        compiler->current_rule_strings = $$;
       }
     | _STRINGS_ ':' string_declarations
       {
@@ -286,7 +299,6 @@ strings
 
         ERROR_IF(compiler->last_result != ERROR_SUCCESS);
 
-        compiler->current_rule_strings = $3;
         $$ = $3;
       }
     ;
@@ -1255,7 +1267,7 @@ expression
       {
         uint8_t* and_addr;
 
-        // Ensure that we have at least two consecutive bytes in the arena's 
+        // Ensure that we have at least two consecutive bytes in the arena's
         // current page, one for the AND opcode and one for opcode following the
         // AND. This is necessary because we need to compute the address for the
         // opcode following the AND, and we don't want the AND in one page and
@@ -1278,9 +1290,9 @@ expression
         // We know that the AND opcode and the following one are within the same
         // page, so we can compute the address for the opcode following the AND
         // by simply adding one to its address.
-        
+
         *(fixup->address) = PTR_TO_INT64(and_addr + 1);
-        
+
         compiler->fixup_stack_head = fixup->next;
         yr_free(fixup);
 
@@ -1314,7 +1326,7 @@ expression
       {
         uint8_t* or_addr;
 
-        // Ensure that we have at least two consecutive bytes in the arena's 
+        // Ensure that we have at least two consecutive bytes in the arena's
         // current page, one for the OR opcode and one for opcode following the
         // OR. This is necessary because we need to compute the address for the
         // opcode following the OR, and we don't want the OR in one page and
diff --git a/libyara/include/yara/arena.h b/libyara/include/yara/arena.h
index de2cee3..a24553c 100644
--- a/libyara/include/yara/arena.h
+++ b/libyara/include/yara/arena.h
@@ -24,7 +24,7 @@ limitations under the License.
 
 #define ARENA_FLAGS_FIXED_SIZE   1
 #define ARENA_FLAGS_COALESCED    2
-#define ARENA_FILE_VERSION       6
+#define ARENA_FILE_VERSION       7
 
 #define EOL ((size_t) -1)
 
diff --git a/libyara/include/yara/compiler.h b/libyara/include/yara/compiler.h
index 797d172..d70d0b2 100644
--- a/libyara/include/yara/compiler.h
+++ b/libyara/include/yara/compiler.h
@@ -71,11 +71,10 @@ typedef struct _YR_COMPILER
   YR_HASH_TABLE*    rules_table;
   YR_HASH_TABLE*    objects_table;
   YR_NAMESPACE*     current_namespace;
-  YR_STRING*        current_rule_strings;
+  YR_RULE*          current_rule;
 
   YR_FIXUP*         fixup_stack_head;
 
-  int               current_rule_flags;
   int               namespaces_count;
 
   uint8_t*          loop_address[MAX_LOOP_NESTING];
diff --git a/libyara/include/yara/exec.h b/libyara/include/yara/exec.h
index f10551d..56266d4 100644
--- a/libyara/include/yara/exec.h
+++ b/libyara/include/yara/exec.h
@@ -55,23 +55,25 @@ limitations under the License.
 #define OP_OFFSET         24
 #define OP_OF             25
 #define OP_PUSH_RULE      26
-#define OP_MATCH_RULE     27
-#define OP_INCR_M         28
-#define OP_CLEAR_M        29
-#define OP_ADD_M          30
-#define OP_POP_M          31
-#define OP_PUSH_M         32
-#define OP_SWAPUNDEF      33
-#define OP_JNUNDEF        34
-#define OP_JLE            35
-#define OP_FILESIZE       36
-#define OP_ENTRYPOINT     37
-#define OP_CONTAINS       38
-#define OP_MATCHES        39
-#define OP_IMPORT         40
-#define OP_LOOKUP_DICT    41
-#define OP_JFALSE         42
-#define OP_JTRUE          43
+#define OP_INIT_RULE      27
+#define OP_MATCH_RULE     28
+#define OP_INCR_M         29
+#define OP_CLEAR_M        30
+#define OP_ADD_M          31
+#define OP_POP_M          32
+#define OP_PUSH_M         33
+#define OP_SWAPUNDEF      34
+#define OP_JNUNDEF        35
+#define OP_JLE            36
+#define OP_FILESIZE       37
+#define OP_ENTRYPOINT     38
+#define OP_CONTAINS       39
+#define OP_MATCHES        40
+#define OP_IMPORT         41
+#define OP_LOOKUP_DICT    42
+#define OP_JFALSE         43
+#define OP_JTRUE          44
+
 
 #define _OP_EQ            0
 #define _OP_NEQ           1
diff --git a/libyara/include/yara/parser.h b/libyara/include/yara/parser.h
index 460e206..05be1af 100644
--- a/libyara/include/yara/parser.h
+++ b/libyara/include/yara/parser.h
@@ -67,15 +67,20 @@ int yr_parser_lookup_loop_variable(
     const char* identifier);
 
 
-int yr_parser_reduce_rule_declaration(
+YR_RULE* yr_parser_reduce_rule_declaration_phase_1(
     yyscan_t yyscanner,
-    int flags,
+    int32_t flags,
     const char* identifier,
     char* tags,
     YR_STRING* strings,
     YR_META* metas);
 
 
+int yr_parser_reduce_rule_declaration_phase_2(
+    yyscan_t yyscanner,
+    YR_RULE* rule);
+
+
 YR_STRING* yr_parser_reduce_string_declaration(
     yyscan_t yyscanner,
     int flags,
diff --git a/libyara/parser.c b/libyara/parser.c
index 31b45b6..c07afa8 100644
--- a/libyara/parser.c
+++ b/libyara/parser.c
@@ -136,7 +136,7 @@ int yr_parser_emit_pushes_for_strings(
     const char* identifier)
 {
   YR_COMPILER* compiler = yyget_extra(yyscanner);
-  YR_STRING* string = compiler->current_rule_strings;
+  YR_STRING* string = compiler->current_rule->strings;
 
   const char* string_identifier;
   const char* target_identifier;
@@ -224,7 +224,7 @@ YR_STRING* yr_parser_lookup_string(
   YR_STRING* string;
   YR_COMPILER* compiler = yyget_extra(yyscanner);
 
-  string = compiler->current_rule_strings;
+  string = compiler->current_rule->strings;
 
   while(!STRING_IS_NULL(string))
   {
@@ -647,7 +647,7 @@ _exit:
 }
 
 
-int yr_parser_reduce_rule_declaration(
+YR_RULE* yr_parser_reduce_rule_declaration_phase_1(
     yyscan_t yyscanner,
     int32_t flags,
     const char* identifier,
@@ -656,9 +656,7 @@ int yr_parser_reduce_rule_declaration(
     YR_META* metas)
 {
   YR_COMPILER* compiler = yyget_extra(yyscanner);
-
-  YR_RULE* rule;
-  YR_STRING* string;
+  YR_RULE* rule = NULL;
 
   if (yr_hash_table_lookup(
         compiler->rules_table,
@@ -674,37 +672,10 @@ int yr_parser_reduce_rule_declaration(
 
     yr_compiler_set_error_extra_info(compiler, identifier);
     compiler->last_result = ERROR_DUPLICATED_IDENTIFIER;
-    return compiler->last_result;
-  }
-
-  // Check for unreferenced (unused) strings.
-
-  string = compiler->current_rule_strings;
-
-  while(!STRING_IS_NULL(string))
-  {
-    // Only the heading fragment in a chain of strings (the one with
-    // chained_to == NULL) must be referenced. All other fragments
-    // are never marked as referenced.
-
-    if (!STRING_IS_REFERENCED(string) &&
-        string->chained_to == NULL)
-    {
-      yr_compiler_set_error_extra_info(compiler, string->identifier);
-      compiler->last_result = ERROR_UNREFERENCED_STRING;
-      break;
-    }
-
-    string = (YR_STRING*) yr_arena_next_address(
-        compiler->strings_arena,
-        string,
-        sizeof(YR_STRING));
+    return NULL;
   }
 
-  if (compiler->last_result != ERROR_SUCCESS)
-    return compiler->last_result;
-
-  FAIL_ON_COMPILER_ERROR(yr_arena_allocate_struct(
+  compiler->last_result = yr_arena_allocate_struct(
       compiler->rules_arena,
       sizeof(YR_RULE),
       (void**) &rule,
@@ -713,9 +684,12 @@ int yr_parser_reduce_rule_declaration(
       offsetof(YR_RULE, strings),
       offsetof(YR_RULE, metas),
       offsetof(YR_RULE, ns),
-      EOL));
+      EOL);
 
-  rule->g_flags = flags | compiler->current_rule_flags;
+  if (compiler->last_result != ERROR_SUCCESS)
+    return NULL;
+
+  rule->g_flags = flags;
   rule->tags = tags;
   rule->strings = strings;
   rule->metas = metas;
@@ -725,31 +699,72 @@ int yr_parser_reduce_rule_declaration(
   rule->clock_ticks = 0;
   #endif
 
-  FAIL_ON_COMPILER_ERROR(yr_arena_write_string(
+  compiler->last_result = yr_arena_write_string(
       compiler->sz_arena,
       identifier,
-      (char**) &rule->identifier));
+      (char**) &rule->identifier);
 
-  FAIL_ON_COMPILER_ERROR(yr_parser_emit_with_arg_reloc(
+  compiler->last_result = yr_parser_emit_with_arg_reloc(
       yyscanner,
-      OP_MATCH_RULE,
+      OP_INIT_RULE,
       PTR_TO_INT64(rule),
       NULL,
-      NULL));
+      NULL);
 
-  FAIL_ON_COMPILER_ERROR(yr_hash_table_add(
-      compiler->rules_table,
-      identifier,
-      compiler->current_namespace->name,
-      (void*) rule));
+  if (compiler->last_result == ERROR_SUCCESS)
+    compiler->last_result = yr_hash_table_add(
+        compiler->rules_table,
+        identifier,
+        compiler->current_namespace->name,
+        (void*) rule);
+
+  compiler->current_rule = rule;
+
+  return rule;
+}
+
+int yr_parser_reduce_rule_declaration_phase_2(
+    yyscan_t yyscanner,
+    YR_RULE* rule)
+{
+  YR_COMPILER* compiler = yyget_extra(yyscanner);
+
+  // Check for unreferenced (unused) strings.
+
+  YR_STRING* string = rule->strings;
+
+  while(!STRING_IS_NULL(string))
+  {
+    // Only the heading fragment in a chain of strings (the one with
+    // chained_to == NULL) must be referenced. All other fragments
+    // are never marked as referenced.
 
-  compiler->current_rule_flags = 0;
-  compiler->current_rule_strings = NULL;
+    if (!STRING_IS_REFERENCED(string) &&
+        string->chained_to == NULL)
+    {
+      yr_compiler_set_error_extra_info(compiler, string->identifier);
+      compiler->last_result = ERROR_UNREFERENCED_STRING;
+      return compiler->last_result;
+    }
+
+    string = (YR_STRING*) yr_arena_next_address(
+        compiler->strings_arena,
+        string,
+        sizeof(YR_STRING));
+  }
+
+  compiler->last_result = yr_parser_emit_with_arg_reloc(
+      yyscanner,
+      OP_MATCH_RULE,
+      PTR_TO_INT64(rule),
+      NULL,
+      NULL);
 
   return compiler->last_result;
 }
 
 
+
 int yr_parser_reduce_string_identifier(
     yyscan_t yyscanner,
     const char* identifier,
@@ -772,7 +787,7 @@ int yr_parser_reduce_string_identifier(
 
       yr_parser_emit(yyscanner, instruction, NULL);
 
-      string = compiler->current_rule_strings;
+      string = compiler->current_rule->strings;
 
       while(!STRING_IS_NULL(string))
       {
diff --git a/yara-python/setup.py b/yara-python/setup.py
index 61f26ae..f484a7a 100644
--- a/yara-python/setup.py
+++ b/yara-python/setup.py
@@ -14,9 +14,18 @@
 # limitations under the License.
 #
 
+import sys
 from distutils.core import setup, Extension
 
-setup(name='yara-python',
+args = sys.argv[1:]
+macros = []
+
+if '--with-profiling' in args:
+  macros.append(('PROFILING_ENABLED','1'))
+  args.remove('--with-profiling')
+
+setup(script_args=args,
+      name='yara-python',
       version='3.3.0',
       author='Victor M. Alvarez',
       author_email='plusvic at gmail.com;vmalvarez at virustotal.com',
@@ -26,5 +35,6 @@ setup(name='yara-python',
         libraries=['yara'],
         include_dirs=['../libyara/include'],
         library_dirs=['../libyara/.libs'],
+        define_macros=macros,
         extra_compile_args=['-std=gnu99']
     )])
diff --git a/yara-python/yara-python.c b/yara-python/yara-python.c
index df687f0..1e9db3c 100644
--- a/yara-python/yara-python.c
+++ b/yara-python/yara-python.c
@@ -1191,9 +1191,27 @@ static PyObject * Rules_match(
       Py_DECREF(callback_data.matches);
 
       if (error == ERROR_CALLBACK_ERROR)
+      {
         return NULL;
+      }
       else
-        return handle_error(error, filepath);
+      {
+        handle_error(error, filepath);
+
+#ifdef PROFILING_ENABLED
+        PyObject* exception = PyErr_Occurred();
+
+        if (exception != NULL && error == ERROR_SCAN_TIMEOUT)
+        {
+          PyObject_SetAttrString(
+              exception,
+              "profiling_info",
+              Rules_profiling_info(self, NULL));
+        }
+#endif
+
+        return NULL;
+      }
     }
   }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/forensics/yara.git



More information about the forensics-changes mailing list