]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1680] added addrtotext operator to eval parser
authorRazvan Becheriu <razvan@isc.org>
Fri, 12 Mar 2021 19:57:36 +0000 (21:57 +0200)
committerRazvan Becheriu <razvan@isc.org>
Wed, 5 May 2021 17:12:17 +0000 (20:12 +0300)
15 files changed:
src/lib/eval/eval_messages.cc
src/lib/eval/eval_messages.h
src/lib/eval/eval_messages.mes
src/lib/eval/lexer.cc
src/lib/eval/lexer.ll
src/lib/eval/location.hh
src/lib/eval/parser.cc
src/lib/eval/parser.h
src/lib/eval/parser.yy
src/lib/eval/position.hh
src/lib/eval/stack.hh
src/lib/eval/tests/context_unittest.cc
src/lib/eval/tests/token_unittest.cc
src/lib/eval/token.cc
src/lib/eval/token.h

index 55a88cb92ce5a064eb7a002e618d0c8ca24bbb91..5b926dc316c8905a33fa3ab8e031d37808a16539 100644 (file)
@@ -14,6 +14,7 @@ extern const isc::log::MessageID EVAL_DEBUG_HEXSTRING = "EVAL_DEBUG_HEXSTRING";
 extern const isc::log::MessageID EVAL_DEBUG_IFELSE_FALSE = "EVAL_DEBUG_IFELSE_FALSE";
 extern const isc::log::MessageID EVAL_DEBUG_IFELSE_TRUE = "EVAL_DEBUG_IFELSE_TRUE";
 extern const isc::log::MessageID EVAL_DEBUG_IPADDRESS = "EVAL_DEBUG_IPADDRESS";
+extern const isc::log::MessageID EVAL_DEBUG_IPADDRESSTOTEXT = "EVAL_DEBUG_IPADDRESSTOTEXT";
 extern const isc::log::MessageID EVAL_DEBUG_MEMBER = "EVAL_DEBUG_MEMBER";
 extern const isc::log::MessageID EVAL_DEBUG_NOT = "EVAL_DEBUG_NOT";
 extern const isc::log::MessageID EVAL_DEBUG_OPTION = "EVAL_DEBUG_OPTION";
@@ -55,6 +56,7 @@ const char* values[] = {
     "EVAL_DEBUG_IFELSE_FALSE", "Popping %1 (false) and %2, leaving %3",
     "EVAL_DEBUG_IFELSE_TRUE", "Popping %1 (true) and %2, leaving %3",
     "EVAL_DEBUG_IPADDRESS", "Pushing IPAddress %1",
+    "EVAL_DEBUG_IPADDRESSTOTEXT", "Pushing IPAddress %1",
     "EVAL_DEBUG_MEMBER", "Checking membership of '%1', pushing result %2",
     "EVAL_DEBUG_NOT", "Popping %1 pushing %2",
     "EVAL_DEBUG_OPTION", "Pushing option %1 with value %2",
index f887627e532fee984a958585cd67d23a5998be4a..5d3d1cc062fd25a11f70bd4c7eca6e3b6e41054c 100644 (file)
@@ -15,6 +15,7 @@ extern const isc::log::MessageID EVAL_DEBUG_HEXSTRING;
 extern const isc::log::MessageID EVAL_DEBUG_IFELSE_FALSE;
 extern const isc::log::MessageID EVAL_DEBUG_IFELSE_TRUE;
 extern const isc::log::MessageID EVAL_DEBUG_IPADDRESS;
+extern const isc::log::MessageID EVAL_DEBUG_IPADDRESSTOTEXT;
 extern const isc::log::MessageID EVAL_DEBUG_MEMBER;
 extern const isc::log::MessageID EVAL_DEBUG_NOT;
 extern const isc::log::MessageID EVAL_DEBUG_OPTION;
index 3ea89f273de65236d18daa48e9e8aeb6155db6e9..0c6006bf212d07287e661d8435c5c815cfed2a2c 100644 (file)
@@ -53,6 +53,13 @@ This debug message indicates that the given binary string is being pushed
 onto the value stack.  This represents either an IPv4 or IPv6 address.
 The string is displayed in hex.
 
+# For use with TokenIpAddressToText
+
+% EVAL_DEBUG_IPADDRESSTOTEXT Pushing IPAddress %1
+This debug message indicates that the given address string representation is
+being pushed onto the value stack.  This represents either an IPv4 or IPv6
+address.
+
 # For use with TokenMember
 
 % EVAL_DEBUG_MEMBER Checking membership of '%1', pushing result %2
index 86987da75f678f91a08d008c455464822060b28c..5c752033c4daeb3a5a80588bb865175e9c938d88 100644 (file)
@@ -1,6 +1,6 @@
-#line 1 "lexer.cc"
+#line 2 "lexer.cc"
 
-#line 3 "lexer.cc"
+#line 4 "lexer.cc"
 
 #define  YY_INT_ALIGNED short int
 
@@ -719,32 +719,33 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static const flex_int16_t yy_accept[214] =
+static const flex_int16_t yy_accept[222] =
     {   0,
-        0,    0,   56,   54,    1,    2,   54,   47,   48,   52,
-       53,   51,   54,   46,    5,    5,   54,   54,   54,   54,
-       49,   50,   54,   54,   54,   54,   54,   54,   54,   54,
-       54,   54,   54,   54,   54,   54,   54,   54,   54,    1,
-        2,    0,    3,    5,    0,    5,    0,    0,    0,    0,
-        7,    8,    0,    0,    0,    0,    6,    0,    0,    0,
+        0,    0,   56,   54,    1,    2,   54,   48,   49,   53,
+       52,   54,   47,    5,    5,   54,   54,   54,   54,   50,
+       51,   54,   54,   54,   54,   54,   54,   54,   54,   54,
+       54,   54,   54,   54,   54,   54,   54,   54,    1,    2,
+        0,    3,    5,    0,    5,    0,    0,    0,    0,    7,
+        8,    0,    0,    0,    0,    6,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   44,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   45,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    4,
-        7,   38,   43,    0,    0,    0,   20,    0,    0,    0,
-
-       15,    0,    0,    0,    0,   21,    0,   23,    0,    0,
-       42,    0,    0,   17,    0,    0,   19,    0,    0,    0,
-        0,    0,    0,    0,    0,   35,    0,    0,    0,    0,
-       24,    0,    0,    0,    0,    0,    0,    0,    0,   22,
-       30,    0,    0,    0,   14,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   25,   18,    0,    0,    0,
+        7,    0,   38,   44,    0,    0,    0,   20,    0,    0,
+
+        0,   15,    0,    0,    0,    0,   21,    0,   23,    0,
+        0,   43,    0,    0,   17,    0,    0,   19,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,   35,    0,    0,
+        0,    0,   24,    0,    0,    0,    0,    0,    0,    0,
+        0,   22,   30,    0,    0,    0,   14,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   25,   18,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       26,   39,    0,   16,   27,    0,   40,    0,   45,    0,
-        9,    0,   10,   11,   29,    0,    0,   33,   28,    7,
-        0,    0,    0,   31,    0,    0,   32,    0,    0,    0,
+        0,    0,    0,    0,   26,   39,    0,   16,   27,    0,
+       40,    0,   46,    0,    9,    0,   10,   11,   29,    0,
+        0,   33,   28,    7,    0,    0,    0,    0,   31,    0,
 
-       13,   12,    0,    0,    0,   41,   37,    0,   36,    0,
-        0,   34,    0
+        0,   32,    0,    0,    0,    0,   13,   12,    0,    0,
+        0,    0,   41,   37,    0,   42,   36,    0,    0,   34,
+        0
     } ;
 
 static const YY_CHAR yy_ec[256] =
@@ -753,16 +754,16 @@ static const YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    2,    1,    1,    1,    1,    1,    1,    4,    5,
-        6,    7,    8,    9,   10,   11,    1,   12,   13,   13,
-       13,   14,   13,   15,   13,   13,   13,   16,    1,    1,
-       17,    1,    1,    1,   18,   18,   18,   18,   18,   18,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   20,   19,   19,
-       21,    1,   22,    1,   23,    1,   24,   25,   26,   27,
-
-       28,   29,   30,   31,   32,   19,   33,   34,   35,   36,
-       37,   38,   19,   39,   40,   41,   42,   43,   19,   44,
-       45,   19,    1,    1,    1,    1,    1,    1,    1,    1,
+        6,    7,    1,    8,    9,   10,    1,   11,   12,   12,
+       12,   13,   12,   14,   12,   12,   12,   15,    1,    1,
+       16,    1,    1,    1,   17,   17,   17,   17,   17,   17,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   19,   18,   18,
+       20,    1,   21,    1,   22,    1,   23,   24,   25,   26,
+
+       27,   28,   29,   30,   31,   18,   32,   33,   34,   35,
+       36,   37,   18,   38,   39,   40,   41,   42,   18,   43,
+       44,   18,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
@@ -779,159 +780,161 @@ static const YY_CHAR yy_ec[256] =
         1,    1,    1,    1,    1
     } ;
 
-static const YY_CHAR yy_meta[46] =
+static const YY_CHAR yy_meta[45] =
     {   0,
-        1,    1,    2,    1,    1,    1,    1,    1,    1,    1,
-        3,    4,    4,    4,    4,    5,    1,    4,    1,    1,
-        1,    1,    1,    4,    4,    4,    4,    4,    4,    1,
+        1,    1,    2,    1,    1,    1,    1,    1,    1,    3,
+        4,    4,    4,    4,    5,    1,    4,    1,    1,    1,
+        1,    1,    4,    4,    4,    4,    4,    4,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1
+        1,    1,    1,    1
     } ;
 
-static const flex_int16_t yy_base[219] =
+static const flex_int16_t yy_base[227] =
     {   0,
-        0,    0,  326,  327,  323,  321,  319,  327,  327,  327,
-      327,  327,   34,  327,   39,   36,  306,  304,   82,  116,
-      327,  327,   24,   37,   37,   26,  288,   45,  290,   43,
-       48,  281,   43,  105,  289,  107,   50,  288,  283,  312,
-      310,  308,  327,  138,  142,  115,  295,  294,    0,  293,
-        0,  327,  145,  158,    0,    0,  327,  274,  280,  282,
-      269,  263,  262,  261,  269,  276,  255,  270,  252,   63,
-      260,  259,  268,  258,  262,  250,  249,    0,  261,  247,
-      253,  262,  259,  259,  239,  258,  245,  256,  151,    0,
-        0,    0,    0,  252,  252,  253,    0,  248,  235,  247,
-
-      233,  236,  233,  244,  235,    0,  235,    0,  242,  225,
-        0,  233,  225,  122,  239,  235,    0,  221,  219,  223,
-      231,  230,  156,  229,  231,    0,  215,  212,  225,  210,
-        0,  222,  221,  208,  223,  218,  200,  207,  219,    0,
-        0,  197,  214,  199,    0,  199,  201,  210,  161,  197,
-      194,  196,  193,  193,  192,    0,    0,  202,  202,  189,
-      189,  190,  188,  163,  173,  172,  178,  169,  168,  169,
-        0,    0,  167,    0,    0,  173,    0,  177,    0,  175,
-        0,  175,    0,    0,    0,  169,  173,  189,    0,  173,
-      166,  161,  157,    0,  156,  158,    0,  187,  153,  162,
-
-        0,    0,  161,  145,  130,    0,    0,   79,    0,   59,
-       53,    0,  327,  213,  215,  217,   86,  220
+        0,    0,  334,  335,  331,  329,  327,  335,  335,  335,
+      335,   34,  335,   39,   36,  315,  313,   81,  115,  335,
+      335,   35,   38,   34,   37,  297,   48,  299,   58,  108,
+      290,   22,   44,  298,  113,   59,  297,  292,  320,  318,
+      316,  335,  144,  148,   58,  304,  303,    0,  302,    0,
+      335,  131,  143,    0,    0,  335,  290,  282,  288,  290,
+      277,  271,  270,  269,  277,  284,  263,  278,  260,   64,
+      268,  267,  276,  266,  270,  258,  257,    0,  269,  255,
+      261,  270,  267,  267,  247,  266,  253,  264,  155,    0,
+        0,  248,    0,    0,  259,  259,  260,    0,  255,  242,
+
+      254,  240,  243,  240,  251,  242,    0,  242,    0,  249,
+      232,    0,  240,  232,  123,  246,  242,    0,  228,  226,
+      230,  238,  237,  159,  222,  235,  237,    0,  221,  218,
+      231,  216,    0,  228,  227,  214,  229,  224,  206,  213,
+      225,    0,    0,  203,  220,  205,    0,  205,  207,  216,
+      164,  205,  202,  199,  201,  198,  198,  197,    0,    0,
+      207,  207,  194,  194,  195,  203,  135,  190,  189,  195,
+      187,  186,  168,  183,    0,    0,  174,    0,    0,  178,
+        0,  182,    0,  180,    0,  179,    0,    0,    0,  173,
+      177,  193,    0,  172,  174,  169,  164,  160,    0,  159,
+
+      161,    0,  185,  152,  155,  164,    0,    0,  163,  158,
+      150,  162,    0,    0,  140,    0,    0,  114,  111,    0,
+      335,  210,  212,  214,   74,  217
     } ;
 
-static const flex_int16_t yy_def[219] =
+static const flex_int16_t yy_def[227] =
     {   0,
-      213,    1,  213,  213,  213,  213,  214,  213,  213,  213,
-      213,  213,  213,  213,  213,   15,  215,  213,  213,   19,
-      213,  213,   19,   19,   19,   19,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,  213,
-      213,  214,  213,  213,  213,   15,  215,  216,  217,  215,
-      218,  213,  213,   20,   19,   20,  213,   20,   20,   20,
-       20,   19,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,  213,  217,
-      218,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,  213,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,  213,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,  213,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,  213,
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-
-       20,   20,   20,   20,   20,   20,   20,   20,   20,   20,
-       20,   20,    0,  213,  213,  213,  213,  213
+      221,    1,  221,  221,  221,  221,  222,  221,  221,  221,
+      221,  221,  221,  221,   14,  223,  221,  221,   18,  221,
+      221,   18,   18,   18,   18,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,  221,  221,
+      222,  221,  221,  221,   14,  223,  224,  225,  223,  226,
+      221,  221,   19,   18,   19,  221,   18,   19,   19,   19,
+       19,   18,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,  221,  225,
+      226,   18,   19,   19,   19,   19,   19,   19,   19,   19,
+
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,  221,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+      221,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,  221,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,  221,   19,   19,   19,   19,   19,   19,
+
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
+        0,  221,  221,  221,  221,  221
     } ;
 
-static const flex_int16_t yy_nxt[373] =
+static const flex_int16_t yy_nxt[380] =
     {   0,
         4,    5,    6,    7,    8,    9,   10,   11,   12,   13,
-       14,   15,   16,   16,   16,   17,   18,   19,   20,   20,
-       21,   22,    4,   23,   19,   24,   25,   26,   19,   27,
-       28,   29,   20,   30,   31,   32,   33,   34,   35,   36,
-       37,   20,   38,   20,   39,   44,   44,   44,   44,   45,
-       46,   46,   46,   46,   47,  213,   48,   58,   49,   59,
-       62,   64,   48,   48,   48,   48,   48,   48,   60,   65,
-       71,   73,   67,   61,   72,   74,   63,   85,   68,  213,
-       77,   78,   49,   53,   53,   69,  104,   75,   86,   90,
-      105,   54,  212,   55,   55,   55,   55,   47,  211,   55,
-
-       56,   56,  210,   57,   54,   55,   55,   55,   55,   55,
-       55,   56,   56,   56,   56,   56,   56,   56,   56,   56,
-       56,   56,   56,   56,   56,   56,   56,   56,   56,   56,
-       56,  213,   79,   56,  213,  140,  141,   80,   82,   56,
-       56,   56,   56,   56,   56,   83,   53,   53,   84,   44,
-       44,   44,   44,   89,   89,   89,   89,  209,  213,  213,
-      213,  123,   89,   89,   89,   89,   57,  149,  149,  149,
-      149,  170,  149,  149,  149,  149,  183,  184,  208,  213,
-      190,  190,  190,  190,  190,  190,  190,  190,  213,  213,
-      207,  206,  205,  203,  202,  201,  200,  199,  198,  197,
-
-      196,  195,  194,  193,  192,  191,  189,  188,  213,  187,
-      186,  185,  204,   42,  182,   42,   42,   42,   50,   50,
-       48,   48,   91,   91,   91,  181,  180,  179,  178,  177,
-      176,  175,  174,  173,  172,  171,  169,  168,  167,  166,
-      165,  164,  163,  162,  161,  160,  159,  158,  157,  156,
-      155,  154,  153,  152,  151,  150,  148,  147,  146,  145,
-      144,  143,  142,  139,  138,  137,  136,  135,  134,  133,
-      132,  131,  130,  129,  128,  127,  126,  125,  124,  122,
-      121,  120,  119,  118,  117,  116,  115,  114,  113,  112,
-      111,  110,  109,  108,  107,  106,  103,  102,  101,  100,
-
-       99,   98,   97,   96,   95,   94,   93,   92,   51,   47,
-       51,   43,   41,   40,   88,   87,   81,   76,   70,   66,
-       52,   51,   43,   41,   40,  213,    3,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213
+       14,   15,   15,   15,   16,   17,   18,   19,   19,   20,
+       21,    4,   22,   18,   23,   24,   25,   18,   26,   27,
+       28,   19,   29,   30,   31,   32,   33,   34,   35,   36,
+       19,   37,   19,   38,   43,   43,   43,   43,   44,   45,
+       45,   45,   45,   46,  221,   47,   62,   48,   77,   78,
+       57,   47,   47,   47,   47,   47,   47,   58,   60,   59,
+       79,   64,   63,   61,   67,   80,  221,   90,  221,   65,
+       68,   48,   52,   52,   71,   85,  105,   69,   72,   53,
+      106,   54,   54,   54,   54,   46,   86,   54,   55,   55,
+
+      221,   56,   53,   54,   54,   54,   54,   54,   54,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,   55,
+       55,   55,   55,   55,   55,   55,   55,   55,   55,  221,
+       73,   55,   52,   52,   74,  142,  143,   55,   55,   55,
+       55,   55,   55,   82,  221,  221,   75,  187,  188,  220,
+       83,   56,  219,   84,   43,   43,   43,   43,   89,   89,
+       89,   89,  218,  221,  124,   89,   89,   89,   89,  151,
+      151,  151,  151,  173,  151,  151,  151,  151,  194,  194,
+      194,  194,  194,  194,  194,  194,  221,  221,  217,  216,
+      215,  214,  213,  212,  211,  209,  208,  207,  206,  205,
+
+      204,  203,  202,  201,  200,  221,  199,  198,  197,  210,
+       41,  196,   41,   41,   41,   49,   49,   47,   47,   91,
+       91,   91,  195,  193,  192,  191,  190,  189,  186,  185,
+      184,  183,  182,  181,  180,  179,  178,  177,  176,  175,
+      174,  172,  171,  170,  169,  168,  167,  166,  165,  164,
+      163,  162,  161,  160,  159,  158,  157,  156,  155,  154,
+      153,  152,  150,  149,  148,  147,  146,  145,  144,  141,
+      140,  139,  138,  137,  136,  135,  134,  133,  132,  131,
+      130,  129,  128,  127,  126,  125,  123,  122,  121,  120,
+      119,  118,  117,  116,  115,  114,  113,  112,  111,  110,
+
+      109,  108,  107,  104,  103,  102,  101,  100,   99,   98,
+       97,   96,   95,   94,   93,   92,   50,   46,   50,   42,
+       40,   39,   88,   87,   81,   76,   70,   66,   51,   50,
+       42,   40,   39,  221,    3,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221
     } ;
 
-static const flex_int16_t yy_chk[373] =
+static const flex_int16_t yy_chk[380] =
     {   0,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
-        1,    1,    1,    1,    1,   13,   13,   13,   13,   15,
-       15,   15,   15,   15,   15,   16,   15,   23,   15,   23,
-       25,   26,   15,   15,   15,   15,   15,   15,   24,   26,
-       30,   31,   28,   24,   30,   31,   25,   37,   28,   16,
-       33,   33,   15,   19,   19,   28,   70,   31,   37,  217,
-       70,   19,  211,   19,   19,   19,   19,   19,  210,   19,
-
-       19,   19,  208,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   19,   19,   19,
-       19,   19,   19,   19,   19,   19,   19,   20,   20,   20,
-       20,   20,   34,   20,   46,  114,  114,   34,   36,   20,
-       20,   20,   20,   20,   20,   36,   53,   53,   36,   44,
-       44,   44,   44,   45,   45,   45,   45,  205,   46,   54,
-       54,   89,   89,   89,   89,   89,   53,  123,  123,  123,
-      123,  149,  149,  149,  149,  149,  164,  164,  204,   54,
-      170,  170,  170,  170,  190,  190,  190,  190,  198,  198,
-      203,  200,  199,  196,  195,  193,  192,  191,  188,  187,
-
-      186,  182,  180,  178,  176,  173,  169,  168,  198,  167,
-      166,  165,  198,  214,  163,  214,  214,  214,  215,  215,
-      216,  216,  218,  218,  218,  162,  161,  160,  159,  158,
-      155,  154,  153,  152,  151,  150,  148,  147,  146,  144,
-      143,  142,  139,  138,  137,  136,  135,  134,  133,  132,
-      130,  129,  128,  127,  125,  124,  122,  121,  120,  119,
-      118,  116,  115,  113,  112,  110,  109,  107,  105,  104,
-      103,  102,  101,  100,   99,   98,   96,   95,   94,   88,
-       87,   86,   85,   84,   83,   82,   81,   80,   79,   77,
-       76,   75,   74,   73,   72,   71,   69,   68,   67,   66,
-
-       65,   64,   63,   62,   61,   60,   59,   58,   50,   48,
-       47,   42,   41,   40,   39,   38,   35,   32,   29,   27,
-       18,   17,    7,    6,    5,    3,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213,  213,  213,  213,  213,  213,  213,  213,  213,
-      213,  213
+        1,    1,    1,    1,   12,   12,   12,   12,   14,   14,
+       14,   14,   14,   14,   15,   14,   24,   14,   32,   32,
+       22,   14,   14,   14,   14,   14,   14,   22,   23,   22,
+       33,   25,   24,   23,   27,   33,   45,  225,   15,   25,
+       27,   14,   18,   18,   29,   36,   70,   27,   29,   18,
+       70,   18,   18,   18,   18,   18,   36,   18,   18,   18,
+
+       45,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   18,   18,   18,   18,   18,
+       18,   18,   18,   18,   18,   19,   19,   19,   19,   19,
+       30,   19,   52,   52,   30,  115,  115,   19,   19,   19,
+       19,   19,   19,   35,   53,   53,   30,  167,  167,  219,
+       35,   52,  218,   35,   43,   43,   43,   43,   44,   44,
+       44,   44,  215,   53,   89,   89,   89,   89,   89,  124,
+      124,  124,  124,  151,  151,  151,  151,  151,  173,  173,
+      173,  173,  194,  194,  194,  194,  203,  203,  212,  211,
+      210,  209,  206,  205,  204,  201,  200,  198,  197,  196,
+
+      195,  192,  191,  190,  186,  203,  184,  182,  180,  203,
+      222,  177,  222,  222,  222,  223,  223,  224,  224,  226,
+      226,  226,  174,  172,  171,  170,  169,  168,  166,  165,
+      164,  163,  162,  161,  158,  157,  156,  155,  154,  153,
+      152,  150,  149,  148,  146,  145,  144,  141,  140,  139,
+      138,  137,  136,  135,  134,  132,  131,  130,  129,  127,
+      126,  125,  123,  122,  121,  120,  119,  117,  116,  114,
+      113,  111,  110,  108,  106,  105,  104,  103,  102,  101,
+      100,   99,   97,   96,   95,   92,   88,   87,   86,   85,
+       84,   83,   82,   81,   80,   79,   77,   76,   75,   74,
+
+       73,   72,   71,   69,   68,   67,   66,   65,   64,   63,
+       62,   61,   60,   59,   58,   57,   49,   47,   46,   41,
+       40,   39,   38,   37,   34,   31,   28,   26,   17,   16,
+        7,    6,    5,    3,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221,  221,
+      221,  221,  221,  221,  221,  221,  221,  221,  221
     } ;
 
 /* Table of booleans, true if rule could match eol. */
@@ -966,7 +969,7 @@ static const flex_int16_t yy_rule_linenum[55] =
 #define YY_RESTORE_YY_MORE_OFFSET
 char *yytext;
 #line 1 "lexer.ll"
-/* Copyright (C) 2015-2021 Internet Systems Consortium, Inc. ("ISC")
+/* Copyright (C) 2015-2019 Internet Systems Consortium, Inc. ("ISC")
 
    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -1005,7 +1008,7 @@ namespace {
 
 /* To avoid the call to exit... oops! */
 #define YY_FATAL_ERROR(msg) isc::eval::EvalContext::fatal(msg)
-#line 1008 "lexer.cc"
+#line 1012 "lexer.cc"
 /* noyywrap disables automatic rewinding for the next file to parse. Since we
    always parse only a single string, there's no need to do any wraps. And
    using yywrap requires linking with -lfl, which provides the default yywrap
@@ -1030,8 +1033,8 @@ namespace {
    by moving it ahead by yyleng bytes. yyleng specifies the length of the
    currently matched token. */
 #define YY_USER_ACTION  loc.columns(evalleng);
-#line 1033 "lexer.cc"
-#line 1034 "lexer.cc"
+#line 1037 "lexer.cc"
+#line 1038 "lexer.cc"
 
 #define INITIAL 0
 
@@ -1330,7 +1333,7 @@ YY_DECL
 
 
 
-#line 1333 "lexer.cc"
+#line 1337 "lexer.cc"
 
        while ( /*CONSTCOND*/1 )                /* loops until end-of-file is reached */
                {
@@ -1359,13 +1362,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 214 )
+                               if ( yy_current_state >= 222 )
                                        yy_c = yy_meta[yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
                        ++yy_cp;
                        }
-               while ( yy_current_state != 213 );
+               while ( yy_current_state != 221 );
                yy_cp = (yy_last_accepting_cpos);
                yy_current_state = (yy_last_accepting_state);
 
@@ -1699,62 +1702,62 @@ return isc::eval::EvalParser::make_TOHEXSTRING(loc);
 case 42:
 YY_RULE_SETUP
 #line 223 "lexer.ll"
-return isc::eval::EvalParser::make_NOT(loc);
+return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
        YY_BREAK
 case 43:
 YY_RULE_SETUP
 #line 224 "lexer.ll"
-return isc::eval::EvalParser::make_AND(loc);
+return isc::eval::EvalParser::make_NOT(loc);
        YY_BREAK
 case 44:
 YY_RULE_SETUP
 #line 225 "lexer.ll"
-return isc::eval::EvalParser::make_OR(loc);
+return isc::eval::EvalParser::make_AND(loc);
        YY_BREAK
 case 45:
 YY_RULE_SETUP
 #line 226 "lexer.ll"
-return isc::eval::EvalParser::make_MEMBER(loc);
+return isc::eval::EvalParser::make_OR(loc);
        YY_BREAK
 case 46:
 YY_RULE_SETUP
 #line 227 "lexer.ll"
-return isc::eval::EvalParser::make_DOT(loc);
+return isc::eval::EvalParser::make_MEMBER(loc);
        YY_BREAK
 case 47:
 YY_RULE_SETUP
 #line 228 "lexer.ll"
-return isc::eval::EvalParser::make_LPAREN(loc);
+return isc::eval::EvalParser::make_DOT(loc);
        YY_BREAK
 case 48:
 YY_RULE_SETUP
 #line 229 "lexer.ll"
-return isc::eval::EvalParser::make_RPAREN(loc);
+return isc::eval::EvalParser::make_LPAREN(loc);
        YY_BREAK
 case 49:
 YY_RULE_SETUP
 #line 230 "lexer.ll"
-return isc::eval::EvalParser::make_LBRACKET(loc);
+return isc::eval::EvalParser::make_RPAREN(loc);
        YY_BREAK
 case 50:
 YY_RULE_SETUP
 #line 231 "lexer.ll"
-return isc::eval::EvalParser::make_RBRACKET(loc);
+return isc::eval::EvalParser::make_LBRACKET(loc);
        YY_BREAK
 case 51:
 YY_RULE_SETUP
 #line 232 "lexer.ll"
-return isc::eval::EvalParser::make_COMA(loc);
+return isc::eval::EvalParser::make_RBRACKET(loc);
        YY_BREAK
 case 52:
 YY_RULE_SETUP
 #line 233 "lexer.ll"
-return isc::eval::EvalParser::make_ANY(loc);
+return isc::eval::EvalParser::make_COMA(loc);
        YY_BREAK
 case 53:
 YY_RULE_SETUP
 #line 234 "lexer.ll"
-return isc::eval::EvalParser::make_PLUS(loc);
+return isc::eval::EvalParser::make_ANY(loc);
        YY_BREAK
 case 54:
 YY_RULE_SETUP
@@ -1770,7 +1773,7 @@ YY_RULE_SETUP
 #line 237 "lexer.ll"
 ECHO;
        YY_BREAK
-#line 1773 "lexer.cc"
+#line 1777 "lexer.cc"
 
        case YY_END_OF_BUFFER:
                {
@@ -2089,7 +2092,7 @@ static int yy_get_next_buffer (void)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 214 )
+                       if ( yy_current_state >= 222 )
                                yy_c = yy_meta[yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -2122,11 +2125,11 @@ static int yy_get_next_buffer (void)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 214 )
+               if ( yy_current_state >= 222 )
                        yy_c = yy_meta[yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
-       yy_is_jam = (yy_current_state == 213);
+       yy_is_jam = (yy_current_state == 221);
 
                return yy_is_jam ? 0 : yy_current_state;
 }
index aea9d0774a051486cf202cbc54e813bfffc85694..4ee72afb0776ec3b2016989f0a4711637b04ed3f 100644 (file)
@@ -219,6 +219,7 @@ addr6 [0-9a-fA-F]*\:[0-9a-fA-F]*\:[0-9a-fA-F:.]*
 "concat"       return isc::eval::EvalParser::make_CONCAT(loc);
 "ifelse"       return isc::eval::EvalParser::make_IFELSE(loc);
 "hexstring"    return isc::eval::EvalParser::make_TOHEXSTRING(loc);
+"addrtotext"   return isc::eval::EvalParser::make_ADDRTOTEXT(loc);
 "not"          return isc::eval::EvalParser::make_NOT(loc);
 "and"          return isc::eval::EvalParser::make_AND(loc);
 "or"           return isc::eval::EvalParser::make_OR(loc);
index 178bd77e394e8433bc0b825d3795bd61b60a0ba6..803ed44f9981870962bc0c06c57411b75f2bb499 100644 (file)
@@ -1,9 +1,8 @@
-// Generated 202104290830
-// A Bison parser, made by GNU Bison 3.7.6.
+// A Bison parser, made by GNU Bison 3.5.1.
 
 // Locations for Bison parsers in C++
 
-// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
 
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -16,7 +15,7 @@
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // As a special exception, you may create a larger work that contains
 // part or all of the Bison parser skeleton and distribute that work
@@ -62,13 +61,11 @@ namespace isc { namespace eval {
   class position
   {
   public:
-    /// Type for file name.
-    typedef const std::string filename_type;
     /// Type for line and column numbers.
     typedef int counter_type;
 
     /// Construct a position.
-    explicit position (filename_type* f = YY_NULLPTR,
+    explicit position (std::string* f = YY_NULLPTR,
                        counter_type l = 1,
                        counter_type c = 1)
       : filename (f)
@@ -78,7 +75,7 @@ namespace isc { namespace eval {
 
 
     /// Initialization.
-    void initialize (filename_type* fn = YY_NULLPTR,
+    void initialize (std::string* fn = YY_NULLPTR,
                      counter_type l = 1,
                      counter_type c = 1)
     {
@@ -107,7 +104,7 @@ namespace isc { namespace eval {
     /** \} */
 
     /// File name to which this position refers.
-    filename_type* filename;
+    std::string* filename;
     /// Current line number.
     counter_type line;
     /// Current column number.
@@ -150,6 +147,24 @@ namespace isc { namespace eval {
     return res -= width;
   }
 
+  /// Compare two position objects.
+  inline bool
+  operator== (const position& pos1, const position& pos2)
+  {
+    return (pos1.line == pos2.line
+            && pos1.column == pos2.column
+            && (pos1.filename == pos2.filename
+                || (pos1.filename && pos2.filename
+                    && *pos1.filename == *pos2.filename)));
+  }
+
+  /// Compare two position objects.
+  inline bool
+  operator!= (const position& pos1, const position& pos2)
+  {
+    return !(pos1 == pos2);
+  }
+
   /** \brief Intercept output stream redirection.
    ** \param ostr the destination output stream
    ** \param pos a reference to the position to redirect
@@ -167,8 +182,6 @@ namespace isc { namespace eval {
   class location
   {
   public:
-    /// Type for file name.
-    typedef position::filename_type filename_type;
     /// Type for line and column numbers.
     typedef position::counter_type counter_type;
 
@@ -185,7 +198,7 @@ namespace isc { namespace eval {
     {}
 
     /// Construct a 0-width location in \a f, \a l, \a c.
-    explicit location (filename_type* f,
+    explicit location (std::string* f,
                        counter_type l = 1,
                        counter_type c = 1)
       : begin (f, l, c)
@@ -194,7 +207,7 @@ namespace isc { namespace eval {
 
 
     /// Initialization.
-    void initialize (filename_type* f = YY_NULLPTR,
+    void initialize (std::string* f = YY_NULLPTR,
                      counter_type l = 1,
                      counter_type c = 1)
     {
@@ -276,6 +289,20 @@ namespace isc { namespace eval {
     return res -= width;
   }
 
+  /// Compare two location objects.
+  inline bool
+  operator== (const location& loc1, const location& loc2)
+  {
+    return loc1.begin == loc2.begin && loc1.end == loc2.end;
+  }
+
+  /// Compare two location objects.
+  inline bool
+  operator!= (const location& loc1, const location& loc2)
+  {
+    return !(loc1 == loc2);
+  }
+
   /** \brief Intercept output stream redirection.
    ** \param ostr the destination output stream
    ** \param loc a reference to the location to redirect
@@ -302,6 +329,6 @@ namespace isc { namespace eval {
 
 #line 14 "parser.yy"
 } } // isc::eval
-#line 305 "location.hh"
+#line 333 "location.hh"
 
 #endif // !YY_EVAL_LOCATION_HH_INCLUDED
index 815d1819015e711079c951dd82c56e41df59a30f..29abc51ba419995bda6f6ce5d3c3641f8fe23db8 100644 (file)
@@ -1,8 +1,8 @@
-// A Bison parser, made by GNU Bison 3.7.6.
+// A Bison parser, made by GNU Bison 3.5.1.
 
 // Skeleton implementation for Bison LALR(1) parsers in C++
 
-// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
 
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // As a special exception, you may create a larger work that contains
 // part or all of the Bison parser skeleton and distribute that work
@@ -30,9 +30,8 @@
 // This special exception was added by the Free Software Foundation in
 // version 2.2 of Bison.
 
-// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
-// especially those whose name start with YY_ or yy_.  They are
-// private implementation details that can be changed or removed.
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details.  Do not rely on them.
 
 
 // Take the name prefix into account.
@@ -48,7 +47,7 @@
 
 # include "eval_context.h"
 
-#line 52 "parser.cc"
+#line 51 "parser.cc"
 
 
 #ifndef YY_
@@ -63,7 +62,6 @@
 # endif
 #endif
 
-
 // Whether we are compiled with exception support.
 #ifndef YY_EXCEPTIONS
 # if defined __GNUC__ && !defined __EXCEPTIONS
 # define YY_STACK_PRINT()               \
   do {                                  \
     if (yydebug_)                       \
-      yy_stack_print_ ();                \
+      yystack_print_ ();                \
   } while (false)
 
 #else // !EVALDEBUG
 
 # define YYCDEBUG if (false) std::cerr
-# define YY_SYMBOL_PRINT(Title, Symbol)  YY_USE (Symbol)
+# define YY_SYMBOL_PRINT(Title, Symbol)  YYUSE (Symbol)
 # define YY_REDUCE_PRINT(Rule)           static_cast<void> (0)
 # define YY_STACK_PRINT()                static_cast<void> (0)
 
 
 #line 14 "parser.yy"
 namespace isc { namespace eval {
-#line 145 "parser.cc"
+#line 143 "parser.cc"
+
+
+  /* Return YYSTR after stripping away unnecessary quotes and
+     backslashes, so that it's suitable for yyerror.  The heuristic is
+     that double-quoting is unnecessary unless the string contains an
+     apostrophe, a comma, or backslash (other than backslash-backslash).
+     YYSTR is taken from yytname.  */
+  std::string
+  EvalParser::yytnamerr_ (const char *yystr)
+  {
+    if (*yystr == '"')
+      {
+        std::string yyr;
+        char const *yyp = yystr;
+
+        for (;;)
+          switch (*++yyp)
+            {
+            case '\'':
+            case ',':
+              goto do_not_strip_quotes;
+
+            case '\\':
+              if (*++yyp != '\\')
+                goto do_not_strip_quotes;
+              else
+                goto append;
+
+            append:
+            default:
+              yyr += *yyp;
+              break;
+
+            case '"':
+              return yyr;
+            }
+      do_not_strip_quotes: ;
+      }
+
+    return yystr;
+  }
+
 
   /// Build a parser object.
   EvalParser::EvalParser (EvalContext& ctx_yyarg)
@@ -161,7 +201,7 @@ namespace isc { namespace eval {
   {}
 
   /*---------------.
-  | symbol kinds.  |
+  | Symbol types.  |
   `---------------*/
 
 
@@ -192,13 +232,13 @@ namespace isc { namespace eval {
     : state (s)
   {}
 
-  EvalParser::symbol_kind_type
-  EvalParser::by_state::kind () const YY_NOEXCEPT
+  EvalParser::symbol_number_type
+  EvalParser::by_state::type_get () const YY_NOEXCEPT
   {
     if (state == empty_state)
-      return symbol_kind::S_YYEMPTY;
+      return empty_symbol;
     else
-      return YY_CAST (symbol_kind_type, yystos_[+state]);
+      return yystos_[+state];
   }
 
   EvalParser::stack_symbol_type::stack_symbol_type ()
@@ -207,47 +247,47 @@ namespace isc { namespace eval {
   EvalParser::stack_symbol_type::stack_symbol_type (YY_RVREF (stack_symbol_type) that)
     : super_type (YY_MOVE (that.state), YY_MOVE (that.location))
   {
-    switch (that.kind ())
+    switch (that.type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.YY_MOVE_OR_COPY< TokenOption::RepresentationType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.YY_MOVE_OR_COPY< TokenPkt4::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.YY_MOVE_OR_COPY< TokenPkt6::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.YY_MOVE_OR_COPY< TokenPkt::MetadataType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.YY_MOVE_OR_COPY< TokenRelay6Field::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.YY_MOVE_OR_COPY< int8_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.YY_MOVE_OR_COPY< std::string > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.YY_MOVE_OR_COPY< uint16_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.YY_MOVE_OR_COPY< uint32_t > (YY_MOVE (that.value));
         break;
 
@@ -264,47 +304,47 @@ namespace isc { namespace eval {
   EvalParser::stack_symbol_type::stack_symbol_type (state_type s, YY_MOVE_REF (symbol_type) that)
     : super_type (s, YY_MOVE (that.location))
   {
-    switch (that.kind ())
+    switch (that.type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.move< TokenOption::RepresentationType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.move< TokenPkt4::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.move< TokenPkt6::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.move< TokenPkt::MetadataType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.move< TokenRelay6Field::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.move< int8_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.move< std::string > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.move< uint16_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.move< uint32_t > (YY_MOVE (that.value));
         break;
 
@@ -313,7 +353,7 @@ namespace isc { namespace eval {
     }
 
     // that is emptied.
-    that.kind_ = symbol_kind::S_YYEMPTY;
+    that.type = empty_symbol;
   }
 
 #if YY_CPLUSPLUS < 201103L
@@ -321,47 +361,47 @@ namespace isc { namespace eval {
   EvalParser::stack_symbol_type::operator= (const stack_symbol_type& that)
   {
     state = that.state;
-    switch (that.kind ())
+    switch (that.type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.copy< TokenOption::RepresentationType > (that.value);
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.copy< TokenPkt4::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.copy< TokenPkt6::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.copy< TokenPkt::MetadataType > (that.value);
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.copy< TokenRelay6Field::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.copy< int8_t > (that.value);
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.copy< std::string > (that.value);
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.copy< uint16_t > (that.value);
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.copy< uint32_t > (that.value);
         break;
 
@@ -377,47 +417,47 @@ namespace isc { namespace eval {
   EvalParser::stack_symbol_type::operator= (stack_symbol_type& that)
   {
     state = that.state;
-    switch (that.kind ())
+    switch (that.type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.move< TokenOption::RepresentationType > (that.value);
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.move< TokenPkt4::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.move< TokenPkt6::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.move< TokenPkt::MetadataType > (that.value);
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.move< TokenRelay6Field::FieldType > (that.value);
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.move< int8_t > (that.value);
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.move< std::string > (that.value);
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.move< uint16_t > (that.value);
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.move< uint32_t > (that.value);
         break;
 
@@ -443,115 +483,117 @@ namespace isc { namespace eval {
 #if EVALDEBUG
   template <typename Base>
   void
-  EvalParser::yy_print_ (std::ostream& yyo, const basic_symbol<Base>& yysym) const
+  EvalParser::yy_print_ (std::ostream& yyo,
+                                     const basic_symbol<Base>& yysym) const
   {
     std::ostream& yyoutput = yyo;
-    YY_USE (yyoutput);
+    YYUSE (yyoutput);
+    symbol_number_type yytype = yysym.type_get ();
+#if defined __GNUC__ && ! defined __clang__ && ! defined __ICC && __GNUC__ * 100 + __GNUC_MINOR__ <= 408
+    // Avoid a (spurious) G++ 4.8 warning about "array subscript is
+    // below array bounds".
     if (yysym.empty ())
-      yyo << "empty symbol";
-    else
-      {
-        symbol_kind_type yykind = yysym.kind ();
-        yyo << (yykind < YYNTOKENS ? "token" : "nterm")
-            << ' ' << yysym.name () << " ("
-            << yysym.location << ": ";
-        switch (yykind)
+      std::abort ();
+#endif
+    yyo << (yytype < yyntokens_ ? "token" : "nterm")
+        << ' ' << yytname_[yytype] << " ("
+        << yysym.location << ": ";
+    switch (yytype)
     {
-      case symbol_kind::S_STRING: // "constant string"
-#line 114 "parser.yy"
+      case 51: // "constant string"
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < std::string > (); }
-#line 464 "parser.cc"
+#line 507 "parser.cc"
         break;
 
-      case symbol_kind::S_INTEGER: // "integer"
-#line 114 "parser.yy"
+      case 52: // "integer"
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < std::string > (); }
-#line 470 "parser.cc"
+#line 513 "parser.cc"
         break;
 
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-#line 114 "parser.yy"
+      case 53: // "constant hexstring"
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < std::string > (); }
-#line 476 "parser.cc"
+#line 519 "parser.cc"
         break;
 
-      case symbol_kind::S_OPTION_NAME: // "option name"
-#line 114 "parser.yy"
+      case 54: // "option name"
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < std::string > (); }
-#line 482 "parser.cc"
+#line 525 "parser.cc"
         break;
 
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
-#line 114 "parser.yy"
+      case 55: // "ip address"
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < std::string > (); }
-#line 488 "parser.cc"
+#line 531 "parser.cc"
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-#line 114 "parser.yy"
+      case 61: // integer_expr
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < uint32_t > (); }
-#line 494 "parser.cc"
+#line 537 "parser.cc"
         break;
 
-      case symbol_kind::S_option_code: // option_code
-#line 114 "parser.yy"
+      case 62: // option_code
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < uint16_t > (); }
-#line 500 "parser.cc"
+#line 543 "parser.cc"
         break;
 
-      case symbol_kind::S_sub_option_code: // sub_option_code
-#line 114 "parser.yy"
+      case 63: // sub_option_code
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < uint16_t > (); }
-#line 506 "parser.cc"
+#line 549 "parser.cc"
         break;
 
-      case symbol_kind::S_option_repr_type: // option_repr_type
-#line 114 "parser.yy"
+      case 64: // option_repr_type
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < TokenOption::RepresentationType > (); }
-#line 512 "parser.cc"
+#line 555 "parser.cc"
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
-#line 114 "parser.yy"
+      case 65: // nest_level
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < int8_t > (); }
-#line 518 "parser.cc"
+#line 561 "parser.cc"
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
-#line 114 "parser.yy"
+      case 66: // pkt_metadata
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < TokenPkt::MetadataType > (); }
-#line 524 "parser.cc"
+#line 567 "parser.cc"
         break;
 
-      case symbol_kind::S_enterprise_id: // enterprise_id
-#line 114 "parser.yy"
+      case 67: // enterprise_id
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < uint32_t > (); }
-#line 530 "parser.cc"
+#line 573 "parser.cc"
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
-#line 114 "parser.yy"
+      case 68: // pkt4_field
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < TokenPkt4::FieldType > (); }
-#line 536 "parser.cc"
+#line 579 "parser.cc"
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
-#line 114 "parser.yy"
+      case 69: // pkt6_field
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < TokenPkt6::FieldType > (); }
-#line 542 "parser.cc"
+#line 585 "parser.cc"
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
-#line 114 "parser.yy"
+      case 70: // relay6_field
+#line 113 "parser.yy"
                  { yyoutput << yysym.value.template as < TokenRelay6Field::FieldType > (); }
-#line 548 "parser.cc"
+#line 591 "parser.cc"
         break;
 
       default:
         break;
     }
-        yyo << ')';
-      }
+    yyo << ')';
   }
 #endif
 
@@ -610,11 +652,11 @@ namespace isc { namespace eval {
   EvalParser::state_type
   EvalParser::yy_lr_goto_state_ (state_type yystate, int yysym)
   {
-    int yyr = yypgoto_[yysym - YYNTOKENS] + yystate;
+    int yyr = yypgoto_[yysym - yyntokens_] + yystate;
     if (0 <= yyr && yyr <= yylast_ && yycheck_[yyr] == yystate)
       return yytable_[yyr];
     else
-      return yydefgoto_[yysym - YYNTOKENS];
+      return yydefgoto_[yysym - yyntokens_];
   }
 
   bool
@@ -674,7 +716,6 @@ namespace isc { namespace eval {
   `-----------------------------------------------*/
   yynewstate:
     YYCDEBUG << "Entering state " << int (yystack_[0].state) << '\n';
-    YY_STACK_PRINT ();
 
     // Accept?
     if (yystack_[0].state == yyfinal_)
@@ -695,7 +736,7 @@ namespace isc { namespace eval {
     // Read a lookahead token.
     if (yyla.empty ())
       {
-        YYCDEBUG << "Reading a token\n";
+        YYCDEBUG << "Reading a token";
 #if YY_EXCEPTIONS
         try
 #endif // YY_EXCEPTIONS
@@ -714,20 +755,10 @@ namespace isc { namespace eval {
       }
     YY_SYMBOL_PRINT ("Next token is", yyla);
 
-    if (yyla.kind () == symbol_kind::S_YYerror)
-    {
-      // The scanner already issued an error message, process directly
-      // to error recovery.  But do not keep the error token as
-      // lookahead, it is too special and may lead us to an endless
-      // loop in error recovery. */
-      yyla.kind_ = symbol_kind::S_YYUNDEF;
-      goto yyerrlab1;
-    }
-
     /* If the proper action on seeing token YYLA.TYPE is to reduce or
        to detect an error, take that action.  */
-    yyn += yyla.kind ();
-    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.kind ())
+    yyn += yyla.type_get ();
+    if (yyn < 0 || yylast_ < yyn || yycheck_[yyn] != yyla.type_get ())
       {
         goto yydefault;
       }
@@ -774,45 +805,45 @@ namespace isc { namespace eval {
          when using variants.  */
       switch (yyr1_[yyn])
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         yylhs.value.emplace< TokenOption::RepresentationType > ();
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         yylhs.value.emplace< TokenPkt4::FieldType > ();
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         yylhs.value.emplace< TokenPkt6::FieldType > ();
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         yylhs.value.emplace< TokenPkt::MetadataType > ();
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         yylhs.value.emplace< TokenRelay6Field::FieldType > ();
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         yylhs.value.emplace< int8_t > ();
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         yylhs.value.emplace< std::string > ();
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         yylhs.value.emplace< uint16_t > ();
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         yylhs.value.emplace< uint32_t > ();
         break;
 
@@ -836,62 +867,62 @@ namespace isc { namespace eval {
         {
           switch (yyn)
             {
-  case 6: // bool_expr: "not" bool_expr
-#line 134 "parser.yy"
+  case 6:
+#line 133 "parser.yy"
                 {
                     TokenPtr neg(new TokenNot());
                     ctx.expression.push_back(neg);
                 }
-#line 846 "parser.cc"
+#line 877 "parser.cc"
     break;
 
-  case 7: // bool_expr: bool_expr "and" bool_expr
-#line 139 "parser.yy"
+  case 7:
+#line 138 "parser.yy"
                 {
                     TokenPtr neg(new TokenAnd());
                     ctx.expression.push_back(neg);
                 }
-#line 855 "parser.cc"
+#line 886 "parser.cc"
     break;
 
-  case 8: // bool_expr: bool_expr "or" bool_expr
-#line 144 "parser.yy"
+  case 8:
+#line 143 "parser.yy"
                 {
                     TokenPtr neg(new TokenOr());
                     ctx.expression.push_back(neg);
                 }
-#line 864 "parser.cc"
+#line 895 "parser.cc"
     break;
 
-  case 9: // bool_expr: string_expr "==" string_expr
-#line 149 "parser.yy"
+  case 9:
+#line 148 "parser.yy"
                 {
                     TokenPtr eq(new TokenEqual());
                     ctx.expression.push_back(eq);
                 }
-#line 873 "parser.cc"
+#line 904 "parser.cc"
     break;
 
-  case 10: // bool_expr: "option" "[" option_code "]" "." "exists"
-#line 154 "parser.yy"
+  case 10:
+#line 153 "parser.yy"
                 {
                     TokenPtr opt(new TokenOption(yystack_[3].value.as < uint16_t > (), TokenOption::EXISTS));
                     ctx.expression.push_back(opt);
                 }
-#line 882 "parser.cc"
+#line 913 "parser.cc"
     break;
 
-  case 11: // bool_expr: "option" "[" option_code "]" "." "option" "[" sub_option_code "]" "." "exists"
-#line 159 "parser.yy"
+  case 11:
+#line 158 "parser.yy"
                 {
                     TokenPtr opt(new TokenSubOption(yystack_[8].value.as < uint16_t > (), yystack_[3].value.as < uint16_t > (), TokenOption::EXISTS));
                     ctx.expression.push_back(opt);
                 }
-#line 891 "parser.cc"
+#line 922 "parser.cc"
     break;
 
-  case 12: // bool_expr: "relay4" "[" sub_option_code "]" "." "exists"
-#line 164 "parser.yy"
+  case 12:
+#line 163 "parser.yy"
                 {
                    switch (ctx.getUniverse()) {
                    case Option::V4:
@@ -911,11 +942,11 @@ namespace isc { namespace eval {
                        error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                    }
                 }
-#line 915 "parser.cc"
+#line 946 "parser.cc"
     break;
 
-  case 13: // bool_expr: "relay6" "[" nest_level "]" "." "option" "[" sub_option_code "]" "." "exists"
-#line 184 "parser.yy"
+  case 13:
+#line 183 "parser.yy"
                 {
                     switch (ctx.getUniverse()) {
                     case Option::V6:
@@ -929,11 +960,11 @@ namespace isc { namespace eval {
                         error(yystack_[10].location, "relay6 can only be used in DHCPv6.");
                     }
                 }
-#line 933 "parser.cc"
+#line 964 "parser.cc"
     break;
 
-  case 14: // bool_expr: "vendor-class" "[" enterprise_id "]" "." "exists"
-#line 198 "parser.yy"
+  case 14:
+#line 197 "parser.yy"
               {
                   // Expression: vendor-class[1234].exists
                   //
@@ -942,11 +973,11 @@ namespace isc { namespace eval {
                   TokenPtr exist(new TokenVendorClass(ctx.getUniverse(), yystack_[3].value.as < uint32_t > (), TokenOption::EXISTS));
                   ctx.expression.push_back(exist);
               }
-#line 946 "parser.cc"
+#line 977 "parser.cc"
     break;
 
-  case 15: // bool_expr: "vendor" "[" enterprise_id "]" "." "exists"
-#line 207 "parser.yy"
+  case 15:
+#line 206 "parser.yy"
               {
                   // Expression: vendor[1234].exists
                   //
@@ -955,11 +986,11 @@ namespace isc { namespace eval {
                   TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[3].value.as < uint32_t > (), TokenOption::EXISTS));
                   ctx.expression.push_back(exist);
               }
-#line 959 "parser.cc"
+#line 990 "parser.cc"
     break;
 
-  case 16: // bool_expr: "vendor" "[" enterprise_id "]" "." "option" "[" sub_option_code "]" "." "exists"
-#line 216 "parser.yy"
+  case 16:
+#line 215 "parser.yy"
               {
                   // Expression vendor[1234].option[123].exists
                   //
@@ -969,11 +1000,11 @@ namespace isc { namespace eval {
                   TokenPtr exist(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as < uint32_t > (), TokenOption::EXISTS, yystack_[3].value.as < uint16_t > ()));
                   ctx.expression.push_back(exist);
                }
-#line 973 "parser.cc"
+#line 1004 "parser.cc"
     break;
 
-  case 17: // bool_expr: "member" "(" "constant string" ")"
-#line 226 "parser.yy"
+  case 17:
+#line 225 "parser.yy"
               {
                   // Expression member('foo')
                   //
@@ -988,56 +1019,56 @@ namespace isc { namespace eval {
                   TokenPtr member(new TokenMember(cc));
                   ctx.expression.push_back(member);
               }
-#line 992 "parser.cc"
+#line 1023 "parser.cc"
     break;
 
-  case 18: // string_expr: "constant string"
-#line 243 "parser.yy"
+  case 18:
+#line 242 "parser.yy"
                   {
                       TokenPtr str(new TokenString(yystack_[0].value.as < std::string > ()));
                       ctx.expression.push_back(str);
                   }
-#line 1001 "parser.cc"
+#line 1032 "parser.cc"
     break;
 
-  case 19: // string_expr: "constant hexstring"
-#line 248 "parser.yy"
+  case 19:
+#line 247 "parser.yy"
                   {
                       TokenPtr hex(new TokenHexString(yystack_[0].value.as < std::string > ()));
                       ctx.expression.push_back(hex);
                   }
-#line 1010 "parser.cc"
+#line 1041 "parser.cc"
     break;
 
-  case 20: // string_expr: "ip address"
-#line 253 "parser.yy"
+  case 20:
+#line 252 "parser.yy"
                   {
                       TokenPtr ip(new TokenIpAddress(yystack_[0].value.as < std::string > ()));
                       ctx.expression.push_back(ip);
                   }
-#line 1019 "parser.cc"
+#line 1050 "parser.cc"
     break;
 
-  case 21: // string_expr: "option" "[" option_code "]" "." option_repr_type
-#line 258 "parser.yy"
+  case 21:
+#line 257 "parser.yy"
                   {
                       TokenPtr opt(new TokenOption(yystack_[3].value.as < uint16_t > (), yystack_[0].value.as < TokenOption::RepresentationType > ()));
                       ctx.expression.push_back(opt);
                   }
-#line 1028 "parser.cc"
+#line 1059 "parser.cc"
     break;
 
-  case 22: // string_expr: "option" "[" option_code "]" "." "option" "[" sub_option_code "]" "." option_repr_type
-#line 263 "parser.yy"
+  case 22:
+#line 262 "parser.yy"
                   {
                       TokenPtr opt(new TokenSubOption(yystack_[8].value.as < uint16_t > (), yystack_[3].value.as < uint16_t > (), yystack_[0].value.as < TokenOption::RepresentationType > ()));
                       ctx.expression.push_back(opt);
                   }
-#line 1037 "parser.cc"
+#line 1068 "parser.cc"
     break;
 
-  case 23: // string_expr: "relay4" "[" sub_option_code "]" "." option_repr_type
-#line 268 "parser.yy"
+  case 23:
+#line 267 "parser.yy"
                   {
                      switch (ctx.getUniverse()) {
                      case Option::V4:
@@ -1057,11 +1088,11 @@ namespace isc { namespace eval {
                          error(yystack_[5].location, "relay4 can only be used in DHCPv4.");
                      }
                   }
-#line 1061 "parser.cc"
+#line 1092 "parser.cc"
     break;
 
-  case 24: // string_expr: "relay6" "[" nest_level "]" "." "option" "[" sub_option_code "]" "." option_repr_type
-#line 289 "parser.yy"
+  case 24:
+#line 288 "parser.yy"
                   {
                      switch (ctx.getUniverse()) {
                      case Option::V6:
@@ -1075,20 +1106,20 @@ namespace isc { namespace eval {
                          error(yystack_[10].location, "relay6 can only be used in DHCPv6.");
                      }
                   }
-#line 1079 "parser.cc"
+#line 1110 "parser.cc"
     break;
 
-  case 25: // string_expr: "pkt" "." pkt_metadata
-#line 304 "parser.yy"
+  case 25:
+#line 303 "parser.yy"
                   {
                       TokenPtr pkt_metadata(new TokenPkt(yystack_[0].value.as < TokenPkt::MetadataType > ()));
                       ctx.expression.push_back(pkt_metadata);
                   }
-#line 1088 "parser.cc"
+#line 1119 "parser.cc"
     break;
 
-  case 26: // string_expr: "pkt4" "." pkt4_field
-#line 309 "parser.yy"
+  case 26:
+#line 308 "parser.yy"
                   {
                      switch (ctx.getUniverse()) {
                      case Option::V4:
@@ -1102,11 +1133,11 @@ namespace isc { namespace eval {
                          error(yystack_[2].location, "pkt4 can only be used in DHCPv4.");
                      }
                   }
-#line 1106 "parser.cc"
+#line 1137 "parser.cc"
     break;
 
-  case 27: // string_expr: "pkt6" "." pkt6_field
-#line 323 "parser.yy"
+  case 27:
+#line 322 "parser.yy"
                   {
                      switch (ctx.getUniverse()) {
                      case Option::V6:
@@ -1120,11 +1151,11 @@ namespace isc { namespace eval {
                          error(yystack_[2].location, "pkt6 can only be used in DHCPv6.");
                      }
                   }
-#line 1124 "parser.cc"
+#line 1155 "parser.cc"
     break;
 
-  case 28: // string_expr: "relay6" "[" nest_level "]" "." relay6_field
-#line 337 "parser.yy"
+  case 28:
+#line 336 "parser.yy"
                   {
                      switch (ctx.getUniverse()) {
                      case Option::V6:
@@ -1138,56 +1169,56 @@ namespace isc { namespace eval {
                          error(yystack_[5].location, "relay6 can only be used in DHCPv6.");
                      }
                   }
-#line 1142 "parser.cc"
+#line 1173 "parser.cc"
     break;
 
-  case 29: // string_expr: "substring" "(" string_expr "," start_expr "," length_expr ")"
-#line 352 "parser.yy"
+  case 29:
+#line 351 "parser.yy"
                   {
                       TokenPtr sub(new TokenSubstring());
                       ctx.expression.push_back(sub);
                   }
-#line 1151 "parser.cc"
-    break;
-
-  case 30: // string_expr: "concat" "(" string_expr "," string_expr ")"
-#line 357 "parser.yy"
-                  {
-                      TokenPtr conc(new TokenConcat());
-                      ctx.expression.push_back(conc);
-                  }
-#line 1160 "parser.cc"
+#line 1182 "parser.cc"
     break;
 
-  case 31: // string_expr: string_expr "+" string_expr
-#line 362 "parser.yy"
+  case 30:
+#line 356 "parser.yy"
                   {
                       TokenPtr conc(new TokenConcat());
                       ctx.expression.push_back(conc);
                   }
-#line 1169 "parser.cc"
+#line 1191 "parser.cc"
     break;
 
-  case 32: // string_expr: "ifelse" "(" bool_expr "," string_expr "," string_expr ")"
-#line 367 "parser.yy"
+  case 31:
+#line 361 "parser.yy"
                   {
                       TokenPtr cond(new TokenIfElse());
                       ctx.expression.push_back(cond);
                   }
-#line 1178 "parser.cc"
+#line 1200 "parser.cc"
     break;
 
-  case 33: // string_expr: "hexstring" "(" string_expr "," string_expr ")"
-#line 372 "parser.yy"
+  case 32:
+#line 366 "parser.yy"
                   {
                       TokenPtr tohex(new TokenToHexString());
                       ctx.expression.push_back(tohex);
                   }
-#line 1187 "parser.cc"
+#line 1209 "parser.cc"
     break;
 
-  case 34: // string_expr: "vendor" "." "enterprise"
-#line 377 "parser.yy"
+  case 33:
+#line 371 "parser.yy"
+                  {
+                      TokenPtr addrtotext(new TokenIpAddressToText());
+                      ctx.expression.push_back(addrtotext);
+                  }
+#line 1218 "parser.cc"
+    break;
+
+  case 34:
+#line 376 "parser.yy"
                 {
                     // expression: vendor.enterprise
                     //
@@ -1196,11 +1227,11 @@ namespace isc { namespace eval {
                     TokenPtr vendor(new TokenVendor(ctx.getUniverse(), 0, TokenVendor::ENTERPRISE_ID));
                     ctx.expression.push_back(vendor);
                 }
-#line 1200 "parser.cc"
+#line 1231 "parser.cc"
     break;
 
-  case 35: // string_expr: "vendor-class" "." "enterprise"
-#line 386 "parser.yy"
+  case 35:
+#line 385 "parser.yy"
                 {
                     // expression: vendor-class.enterprise
                     //
@@ -1210,11 +1241,11 @@ namespace isc { namespace eval {
                                                          TokenVendor::ENTERPRISE_ID));
                     ctx.expression.push_back(vendor);
                 }
-#line 1214 "parser.cc"
+#line 1245 "parser.cc"
     break;
 
-  case 36: // string_expr: "vendor" "[" enterprise_id "]" "." "option" "[" sub_option_code "]" "." option_repr_type
-#line 396 "parser.yy"
+  case 36:
+#line 395 "parser.yy"
                 {
                     // This token will search for vendor option with
                     // specified enterprise-id.  If found, will search
@@ -1223,11 +1254,11 @@ namespace isc { namespace eval {
                     TokenPtr opt(new TokenVendor(ctx.getUniverse(), yystack_[8].value.as < uint32_t > (), yystack_[0].value.as < TokenOption::RepresentationType > (), yystack_[3].value.as < uint16_t > ()));
                     ctx.expression.push_back(opt);
                 }
-#line 1227 "parser.cc"
+#line 1258 "parser.cc"
     break;
 
-  case 37: // string_expr: "vendor-class" "[" enterprise_id "]" "." "data"
-#line 405 "parser.yy"
+  case 37:
+#line 404 "parser.yy"
                 {
                     // expression: vendor-class[1234].data
                     //
@@ -1240,11 +1271,11 @@ namespace isc { namespace eval {
                                                                TokenVendor::DATA, 0));
                     ctx.expression.push_back(vendor_class);
                 }
-#line 1244 "parser.cc"
+#line 1275 "parser.cc"
     break;
 
-  case 38: // string_expr: "vendor-class" "[" enterprise_id "]" "." "data" "[" "integer" "]"
-#line 418 "parser.yy"
+  case 38:
+#line 417 "parser.yy"
                 {
                     // expression: vendor-class[1234].data[5]
                     //
@@ -1257,255 +1288,255 @@ namespace isc { namespace eval {
                                                                TokenVendor::DATA, index));
                     ctx.expression.push_back(vendor_class);
                 }
-#line 1261 "parser.cc"
+#line 1292 "parser.cc"
     break;
 
-  case 39: // string_expr: integer_expr
-#line 431 "parser.yy"
+  case 39:
+#line 430 "parser.yy"
                 {
                     TokenPtr integer(new TokenInteger(yystack_[0].value.as < uint32_t > ()));
                     ctx.expression.push_back(integer);
                 }
-#line 1270 "parser.cc"
+#line 1301 "parser.cc"
     break;
 
-  case 41: // integer_expr: "integer"
-#line 439 "parser.yy"
+  case 40:
+#line 437 "parser.yy"
                  {
                      yylhs.value.as < uint32_t > () = ctx.convertUint32(yystack_[0].value.as < std::string > (), yystack_[0].location);
                  }
-#line 1278 "parser.cc"
+#line 1309 "parser.cc"
     break;
 
-  case 42: // option_code: "integer"
-#line 445 "parser.yy"
+  case 41:
+#line 443 "parser.yy"
                  {
                      yylhs.value.as < uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as < std::string > (), yystack_[0].location);
                  }
-#line 1286 "parser.cc"
+#line 1317 "parser.cc"
     break;
 
-  case 43: // option_code: "option name"
-#line 449 "parser.yy"
+  case 42:
+#line 447 "parser.yy"
                  {
                      yylhs.value.as < uint16_t > () = ctx.convertOptionName(yystack_[0].value.as < std::string > (), yystack_[0].location);
                  }
-#line 1294 "parser.cc"
+#line 1325 "parser.cc"
     break;
 
-  case 44: // sub_option_code: "integer"
-#line 455 "parser.yy"
+  case 43:
+#line 453 "parser.yy"
                  {
                      yylhs.value.as < uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as < std::string > (), yystack_[0].location);
                  }
-#line 1302 "parser.cc"
+#line 1333 "parser.cc"
     break;
 
-  case 45: // option_repr_type: "text"
-#line 461 "parser.yy"
+  case 44:
+#line 459 "parser.yy"
                       {
                           yylhs.value.as < TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
                       }
-#line 1310 "parser.cc"
+#line 1341 "parser.cc"
     break;
 
-  case 46: // option_repr_type: "hex"
-#line 465 "parser.yy"
+  case 45:
+#line 463 "parser.yy"
                       {
                           yylhs.value.as < TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
                       }
-#line 1318 "parser.cc"
+#line 1349 "parser.cc"
     break;
 
-  case 47: // nest_level: "integer"
-#line 471 "parser.yy"
+  case 46:
+#line 469 "parser.yy"
                  {
                      yylhs.value.as < int8_t > () = ctx.convertNestLevelNumber(yystack_[0].value.as < std::string > (), yystack_[0].location);
                  }
-#line 1326 "parser.cc"
+#line 1357 "parser.cc"
     break;
 
-  case 48: // pkt_metadata: "iface"
-#line 480 "parser.yy"
+  case 47:
+#line 478 "parser.yy"
                   {
                       yylhs.value.as < TokenPkt::MetadataType > () = TokenPkt::IFACE;
                   }
-#line 1334 "parser.cc"
+#line 1365 "parser.cc"
     break;
 
-  case 49: // pkt_metadata: "src"
-#line 484 "parser.yy"
+  case 48:
+#line 482 "parser.yy"
                   {
                       yylhs.value.as < TokenPkt::MetadataType > () = TokenPkt::SRC;
                   }
-#line 1342 "parser.cc"
+#line 1373 "parser.cc"
     break;
 
-  case 50: // pkt_metadata: "dst"
-#line 488 "parser.yy"
+  case 49:
+#line 486 "parser.yy"
                   {
                       yylhs.value.as < TokenPkt::MetadataType > () = TokenPkt::DST;
                   }
-#line 1350 "parser.cc"
+#line 1381 "parser.cc"
     break;
 
-  case 51: // pkt_metadata: "len"
-#line 492 "parser.yy"
+  case 50:
+#line 490 "parser.yy"
                   {
                       yylhs.value.as < TokenPkt::MetadataType > () = TokenPkt::LEN;
                   }
-#line 1358 "parser.cc"
+#line 1389 "parser.cc"
     break;
 
-  case 52: // enterprise_id: "integer"
-#line 498 "parser.yy"
+  case 51:
+#line 496 "parser.yy"
                    {
                        yylhs.value.as < uint32_t > () = ctx.convertUint32(yystack_[0].value.as < std::string > (), yystack_[0].location);
                    }
-#line 1366 "parser.cc"
+#line 1397 "parser.cc"
     break;
 
-  case 53: // enterprise_id: "*"
-#line 502 "parser.yy"
+  case 52:
+#line 500 "parser.yy"
                    {
                        yylhs.value.as < uint32_t > () = 0;
                    }
-#line 1374 "parser.cc"
+#line 1405 "parser.cc"
     break;
 
-  case 54: // pkt4_field: "mac"
-#line 508 "parser.yy"
+  case 53:
+#line 506 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::CHADDR;
                 }
-#line 1382 "parser.cc"
+#line 1413 "parser.cc"
     break;
 
-  case 55: // pkt4_field: "hlen"
-#line 512 "parser.yy"
+  case 54:
+#line 510 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::HLEN;
                 }
-#line 1390 "parser.cc"
+#line 1421 "parser.cc"
     break;
 
-  case 56: // pkt4_field: "htype"
-#line 516 "parser.yy"
+  case 55:
+#line 514 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::HTYPE;
                 }
-#line 1398 "parser.cc"
+#line 1429 "parser.cc"
     break;
 
-  case 57: // pkt4_field: "ciaddr"
-#line 520 "parser.yy"
+  case 56:
+#line 518 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::CIADDR;
                 }
-#line 1406 "parser.cc"
+#line 1437 "parser.cc"
     break;
 
-  case 58: // pkt4_field: "giaddr"
-#line 524 "parser.yy"
+  case 57:
+#line 522 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::GIADDR;
                 }
-#line 1414 "parser.cc"
+#line 1445 "parser.cc"
     break;
 
-  case 59: // pkt4_field: "yiaddr"
-#line 528 "parser.yy"
+  case 58:
+#line 526 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::YIADDR;
                 }
-#line 1422 "parser.cc"
+#line 1453 "parser.cc"
     break;
 
-  case 60: // pkt4_field: "siaddr"
-#line 532 "parser.yy"
+  case 59:
+#line 530 "parser.yy"
                 {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::SIADDR;
                 }
-#line 1430 "parser.cc"
+#line 1461 "parser.cc"
     break;
 
-  case 61: // pkt4_field: "msgtype"
-#line 536 "parser.yy"
+  case 60:
+#line 534 "parser.yy"
                  {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::MSGTYPE;
                  }
-#line 1438 "parser.cc"
+#line 1469 "parser.cc"
     break;
 
-  case 62: // pkt4_field: "transid"
-#line 540 "parser.yy"
+  case 61:
+#line 538 "parser.yy"
                  {
                     yylhs.value.as < TokenPkt4::FieldType > () = TokenPkt4::TRANSID;
                  }
-#line 1446 "parser.cc"
+#line 1477 "parser.cc"
     break;
 
-  case 63: // pkt6_field: "msgtype"
-#line 546 "parser.yy"
+  case 62:
+#line 544 "parser.yy"
                  {
                      yylhs.value.as < TokenPkt6::FieldType > () = TokenPkt6::MSGTYPE;
                  }
-#line 1454 "parser.cc"
+#line 1485 "parser.cc"
     break;
 
-  case 64: // pkt6_field: "transid"
-#line 550 "parser.yy"
+  case 63:
+#line 548 "parser.yy"
                  {
                      yylhs.value.as < TokenPkt6::FieldType > () = TokenPkt6::TRANSID;
                  }
-#line 1462 "parser.cc"
+#line 1493 "parser.cc"
     break;
 
-  case 65: // relay6_field: "peeraddr"
-#line 556 "parser.yy"
+  case 64:
+#line 554 "parser.yy"
                    {
                        yylhs.value.as < TokenRelay6Field::FieldType > () = TokenRelay6Field::PEERADDR;
                    }
-#line 1470 "parser.cc"
+#line 1501 "parser.cc"
     break;
 
-  case 66: // relay6_field: "linkaddr"
-#line 560 "parser.yy"
+  case 65:
+#line 558 "parser.yy"
                    {
                        yylhs.value.as < TokenRelay6Field::FieldType > () = TokenRelay6Field::LINKADDR;
                    }
-#line 1478 "parser.cc"
+#line 1509 "parser.cc"
     break;
 
-  case 67: // start_expr: "integer"
-#line 566 "parser.yy"
+  case 66:
+#line 564 "parser.yy"
                 {
                     TokenPtr str(new TokenString(yystack_[0].value.as < std::string > ()));
                     ctx.expression.push_back(str);
                 }
-#line 1487 "parser.cc"
+#line 1518 "parser.cc"
     break;
 
-  case 68: // length_expr: "integer"
-#line 573 "parser.yy"
+  case 67:
+#line 571 "parser.yy"
                  {
                      TokenPtr str(new TokenString(yystack_[0].value.as < std::string > ()));
                      ctx.expression.push_back(str);
                  }
-#line 1496 "parser.cc"
+#line 1527 "parser.cc"
     break;
 
-  case 69: // length_expr: "all"
-#line 578 "parser.yy"
+  case 68:
+#line 576 "parser.yy"
                  {
                      TokenPtr str(new TokenString("all"));
                      ctx.expression.push_back(str);
                  }
-#line 1505 "parser.cc"
+#line 1536 "parser.cc"
     break;
 
 
-#line 1509 "parser.cc"
+#line 1540 "parser.cc"
 
             default:
               break;
@@ -1522,6 +1553,7 @@ namespace isc { namespace eval {
       YY_SYMBOL_PRINT ("-> $$ =", yylhs);
       yypop_ (yylen);
       yylen = 0;
+      YY_STACK_PRINT ();
 
       // Shift the result of the reduction.
       yypush_ (YY_NULLPTR, YY_MOVE (yylhs));
@@ -1537,9 +1569,7 @@ namespace isc { namespace eval {
     if (!yyerrstatus_)
       {
         ++yynerrs_;
-        context yyctx (*this, yyla);
-        std::string msg = yysyntax_error_ (yyctx);
-        error (yyla.location, YY_MOVE (msg));
+        error (yyla.location, yysyntax_error_ (yystack_[0].state, yyla));
       }
 
 
@@ -1550,7 +1580,7 @@ namespace isc { namespace eval {
            error, discard it.  */
 
         // Return failure if at end of input.
-        if (yyla.kind () == symbol_kind::S_YYEOF)
+        if (yyla.type_get () == yyeof_)
           YYABORT;
         else if (!yyla.empty ())
           {
@@ -1576,7 +1606,6 @@ namespace isc { namespace eval {
        this YYERROR.  */
     yypop_ (yylen);
     yylen = 0;
-    YY_STACK_PRINT ();
     goto yyerrlab1;
 
 
@@ -1585,33 +1614,31 @@ namespace isc { namespace eval {
   `-------------------------------------------------------------*/
   yyerrlab1:
     yyerrstatus_ = 3;   // Each real token shifted decrements this.
-    // Pop stack until we find a state that shifts the error token.
-    for (;;)
-      {
-        yyn = yypact_[+yystack_[0].state];
-        if (!yy_pact_value_is_default_ (yyn))
-          {
-            yyn += symbol_kind::S_YYerror;
-            if (0 <= yyn && yyn <= yylast_
-                && yycheck_[yyn] == symbol_kind::S_YYerror)
-              {
-                yyn = yytable_[yyn];
-                if (0 < yyn)
-                  break;
-              }
-          }
-
-        // Pop the current state because it cannot handle the error token.
-        if (yystack_.size () == 1)
-          YYABORT;
-
-        yyerror_range[1].location = yystack_[0].location;
-        yy_destroy_ ("Error: popping", yystack_[0]);
-        yypop_ ();
-        YY_STACK_PRINT ();
-      }
     {
       stack_symbol_type error_token;
+      for (;;)
+        {
+          yyn = yypact_[+yystack_[0].state];
+          if (!yy_pact_value_is_default_ (yyn))
+            {
+              yyn += yy_error_token_;
+              if (0 <= yyn && yyn <= yylast_ && yycheck_[yyn] == yy_error_token_)
+                {
+                  yyn = yytable_[yyn];
+                  if (0 < yyn)
+                    break;
+                }
+            }
+
+          // Pop the current state because it cannot handle the error token.
+          if (yystack_.size () == 1)
+            YYABORT;
+
+          yyerror_range[1].location = yystack_[0].location;
+          yy_destroy_ ("Error: popping", yystack_[0]);
+          yypop_ ();
+          YY_STACK_PRINT ();
+        }
 
       yyerror_range[2].location = yyla.location;
       YYLLOC_DEFAULT (error_token.location, yyerror_range, 2);
@@ -1649,7 +1676,6 @@ namespace isc { namespace eval {
     /* Do not reclaim the symbols of the rule whose action triggered
        this YYABORT or YYACCEPT.  */
     yypop_ (yylen);
-    YY_STACK_PRINT ();
     while (1 < yystack_.size ())
       {
         yy_destroy_ ("Cleanup: popping", yystack_[0]);
@@ -1683,100 +1709,18 @@ namespace isc { namespace eval {
     error (yyexc.location, yyexc.what ());
   }
 
-  /* Return YYSTR after stripping away unnecessary quotes and
-     backslashes, so that it's suitable for yyerror.  The heuristic is
-     that double-quoting is unnecessary unless the string contains an
-     apostrophe, a comma, or backslash (other than backslash-backslash).
-     YYSTR is taken from yytname.  */
-  std::string
-  EvalParser::yytnamerr_ (const char *yystr)
-  {
-    if (*yystr == '"')
-      {
-        std::string yyr;
-        char const *yyp = yystr;
-
-        for (;;)
-          switch (*++yyp)
-            {
-            case '\'':
-            case ',':
-              goto do_not_strip_quotes;
-
-            case '\\':
-              if (*++yyp != '\\')
-                goto do_not_strip_quotes;
-              else
-                goto append;
-
-            append:
-            default:
-              yyr += *yyp;
-              break;
-
-            case '"':
-              return yyr;
-            }
-      do_not_strip_quotes: ;
-      }
-
-    return yystr;
-  }
-
+  // Generate an error message.
   std::string
-  EvalParser::symbol_name (symbol_kind_type yysymbol)
+  EvalParser::yysyntax_error_ (state_type yystate, const symbol_type& yyla) const
   {
-    return yytnamerr_ (yytname_[yysymbol]);
-  }
-
-
-
-  // EvalParser::context.
-  EvalParser::context::context (const EvalParser& yyparser, const symbol_type& yyla)
-    : yyparser_ (yyparser)
-    , yyla_ (yyla)
-  {}
-
-  int
-  EvalParser::context::expected_tokens (symbol_kind_type yyarg[], int yyargn) const
-  {
-    // Actual number of expected tokens
-    int yycount = 0;
-
-    int yyn = yypact_[+yyparser_.yystack_[0].state];
-    if (!yy_pact_value_is_default_ (yyn))
-      {
-        /* Start YYX at -YYN if negative to avoid negative indexes in
-           YYCHECK.  In other words, skip the first -YYN actions for
-           this state because they are default actions.  */
-        int yyxbegin = yyn < 0 ? -yyn : 0;
-        // Stay within bounds of both yycheck and yytname.
-        int yychecklim = yylast_ - yyn + 1;
-        int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
-        for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
-          if (yycheck_[yyx + yyn] == yyx && yyx != symbol_kind::S_YYerror
-              && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
-            {
-              if (!yyarg)
-                ++yycount;
-              else if (yycount == yyargn)
-                return 0;
-              else
-                yyarg[yycount++] = YY_CAST (symbol_kind_type, yyx);
-            }
-      }
-
-    if (yyarg && yycount == 0 && 0 < yyargn)
-      yyarg[0] = symbol_kind::S_YYEMPTY;
-    return yycount;
-  }
-
-
+    // Number of reported tokens (one for the "unexpected", one per
+    // "expected").
+    std::ptrdiff_t yycount = 0;
+    // Its maximum.
+    enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+    // Arguments of yyformat.
+    char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
 
-  int
-  EvalParser::yy_syntax_error_arguments_ (const context& yyctx,
-                                                 symbol_kind_type yyarg[], int yyargn) const
-  {
     /* There are many possibilities here to consider:
        - If this state is a consistent state with a default action, then
          the only way this function was invoked is if the default action
@@ -1801,26 +1745,35 @@ namespace isc { namespace eval {
          one exception: it will still contain any token that will not be
          accepted due to an error action in a later state.
     */
-
-    if (!yyctx.lookahead ().empty ())
+    if (!yyla.empty ())
       {
-        if (yyarg)
-          yyarg[0] = yyctx.token ();
-        int yyn = yyctx.expected_tokens (yyarg ? yyarg + 1 : yyarg, yyargn - 1);
-        return yyn + 1;
-      }
-    return 0;
-  }
+        symbol_number_type yytoken = yyla.type_get ();
+        yyarg[yycount++] = yytname_[yytoken];
 
-  // Generate an error message.
-  std::string
-  EvalParser::yysyntax_error_ (const context& yyctx) const
-  {
-    // Its maximum.
-    enum { YYARGS_MAX = 5 };
-    // Arguments of yyformat.
-    symbol_kind_type yyarg[YYARGS_MAX];
-    int yycount = yy_syntax_error_arguments_ (yyctx, yyarg, YYARGS_MAX);
+        int yyn = yypact_[+yystate];
+        if (!yy_pact_value_is_default_ (yyn))
+          {
+            /* Start YYX at -YYN if negative to avoid negative indexes in
+               YYCHECK.  In other words, skip the first -YYN actions for
+               this state because they are default actions.  */
+            int yyxbegin = yyn < 0 ? -yyn : 0;
+            // Stay within bounds of both yycheck and yytname.
+            int yychecklim = yylast_ - yyn + 1;
+            int yyxend = yychecklim < yyntokens_ ? yychecklim : yyntokens_;
+            for (int yyx = yyxbegin; yyx < yyxend; ++yyx)
+              if (yycheck_[yyx + yyn] == yyx && yyx != yy_error_token_
+                  && !yy_table_value_is_error_ (yytable_[yyx + yyn]))
+                {
+                  if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+                    {
+                      yycount = 1;
+                      break;
+                    }
+                  else
+                    yyarg[yycount++] = yytname_[yyx];
+                }
+          }
+      }
 
     char const* yyformat = YY_NULLPTR;
     switch (yycount)
@@ -1845,7 +1798,7 @@ namespace isc { namespace eval {
     for (char const* yyp = yyformat; *yyp; ++yyp)
       if (yyp[0] == '%' && yyp[1] == 's' && yyi < yycount)
         {
-          yyres += symbol_name (yyarg[yyi++]);
+          yyres += yytnamerr_ (yyarg[yyi++]);
           ++yyp;
         }
       else
@@ -1854,158 +1807,155 @@ namespace isc { namespace eval {
   }
 
 
-  const signed char EvalParser::yypact_ninf_ = -126;
+  const signed char EvalParser::yypact_ninf_ = -124;
 
   const signed char EvalParser::yytable_ninf_ = -1;
 
   const short
   EvalParser::yypact_[] =
   {
-      36,     7,    86,    22,     7,     7,    21,    48,    84,   101,
-      62,    91,   118,   133,   137,   160,    94,    15,   107,  -126,
-    -126,  -126,  -126,  -126,   122,    12,  -126,    86,   154,   161,
-     162,   140,   141,   142,  -126,    76,     1,  -126,   108,   126,
-     135,   138,   110,    45,    86,    86,     7,    86,   131,   -23,
-     136,   -23,   143,     7,     7,    86,    86,    -1,   108,   126,
-     135,   -23,   -23,  -126,  -126,  -126,  -126,   159,  -126,   163,
-    -126,   165,   178,  -126,  -126,  -126,  -126,  -126,  -126,  -126,
-    -126,  -126,  -126,  -126,  -126,  -126,  -126,  -126,   123,   128,
-      64,   129,  -126,  -126,  -126,  -126,  -126,   167,  -126,   169,
-    -126,  -126,   180,   142,  -126,   172,   174,   176,   177,   179,
-     181,   182,   183,  -126,   144,    86,    86,    86,   184,   185,
-     186,   187,   188,   189,   190,    72,   124,    89,  -126,   158,
-       0,   132,    17,    -7,     6,    75,   153,    92,   150,   199,
-     194,  -126,  -126,  -126,  -126,  -126,  -126,   195,  -126,  -126,
-    -126,   -21,  -126,    86,  -126,  -126,   196,   197,  -126,   198,
-     200,   201,   126,   126,  -126,  -126,   210,    23,   166,   126,
-     126,   126,   126,   203,   204,  -126,  -126,   205,   206,   207,
-     208,   209,   211,   212,  -126,   213,   214,   215,   216,   127,
-     130,   134,   153,   153,   153,  -126,  -126,  -126,  -126,  -126,
-    -126
+      42,    49,   113,     5,    49,    49,    15,    28,    70,    54,
+      91,    92,   117,   125,   133,   134,   135,   104,    88,   114,
+    -124,  -124,  -124,  -124,  -124,    17,   132,  -124,   126,   127,
+     128,   115,   118,  -124,  -124,    67,  -124,    30,    93,    94,
+      97,    56,   -15,   113,   113,    49,   113,   113,    20,   -26,
+      96,   -26,   108,    49,    49,   113,    30,    93,    94,   -26,
+     -26,  -124,  -124,  -124,   139,  -124,   143,  -124,   144,   157,
+    -124,  -124,  -124,  -124,  -124,  -124,  -124,  -124,  -124,  -124,
+    -124,  -124,  -124,  -124,  -124,   131,   136,     3,   137,   158,
+    -124,  -124,  -124,  -124,  -124,   147,  -124,   153,  -124,  -124,
+     164,  -124,   155,   159,   160,   161,   162,   163,   165,   166,
+    -124,   122,   113,   113,   113,  -124,   167,   168,   169,   170,
+     171,   172,   173,    13,    18,    37,  -124,   145,   175,   156,
+     187,   -18,    -1,    16,    80,    63,   146,   185,   180,  -124,
+    -124,  -124,  -124,  -124,  -124,   181,  -124,  -124,  -124,   -31,
+    -124,   113,  -124,  -124,   182,   183,  -124,   184,   186,   188,
+      93,    93,  -124,  -124,   196,   198,   152,    93,    93,    93,
+      93,   189,   190,  -124,  -124,   191,   192,   193,   194,   195,
+     197,   199,  -124,   200,   201,   202,   203,    77,    99,   107,
+      80,    80,    80,  -124,  -124,  -124,  -124,  -124,  -124
   };
 
   const signed char
   EvalParser::yydefact_[] =
   {
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,     0,    18,
-      41,    19,    20,     2,     4,     0,    39,     0,     0,     0,
-       0,     0,     0,     3,     1,     0,     0,     6,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+      18,    40,    19,    20,     2,     4,     0,    39,     0,     0,
+       0,     0,     0,     3,     1,     0,     6,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     5,    40,    42,    43,     0,    44,     0,
-      47,     0,     0,    48,    49,    50,    51,    25,    54,    55,
-      56,    57,    58,    59,    60,    61,    62,    26,     0,     0,
-       0,     0,    63,    64,    27,    53,    52,     0,    35,     0,
-      34,     7,     8,     9,    31,     0,     0,     0,     0,     0,
-       0,     0,     0,    17,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,     0,    67,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,    45,    46,    10,    21,    12,    23,     0,    65,    66,
-      28,     0,    30,     0,    33,    14,    37,     0,    15,     0,
-       0,     0,     0,     0,    69,    68,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    29,    32,     0,     0,     0,
-       0,     0,     0,     0,    38,     0,     0,     0,     0,     0,
-       0,     0,     0,     0,     0,    11,    22,    13,    24,    16,
-      36
+       0,     5,    41,    42,     0,    43,     0,    46,     0,     0,
+      47,    48,    49,    50,    25,    53,    54,    55,    56,    57,
+      58,    59,    60,    61,    26,     0,     0,     0,     0,     0,
+      62,    63,    27,    52,    51,     0,    35,     0,    34,     7,
+       8,     9,     0,     0,     0,     0,     0,     0,     0,     0,
+      17,     0,     0,     0,     0,    33,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,    66,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,    44,
+      45,    10,    21,    12,    23,     0,    64,    65,    28,     0,
+      30,     0,    32,    14,    37,     0,    15,     0,     0,     0,
+       0,     0,    68,    67,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    29,    31,     0,     0,     0,     0,     0,
+       0,     0,    38,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,    11,    22,    13,    24,    16,    36
   };
 
   const short
   EvalParser::yypgoto_[] =
   {
-    -126,  -126,  -126,     3,    -2,  -126,   168,   -53,  -125,   157,
-    -126,   -27,  -126,  -126,  -126,  -126,  -126
+    -124,  -124,  -124,     2,    -2,  -124,   174,   -54,  -123,   154,
+    -124,   -11,  -124,  -124,  -124,  -124,  -124
   };
 
-  const unsigned char
+  const short
   EvalParser::yydefgoto_[] =
   {
-       0,     3,    23,    24,    25,    26,    67,    69,   144,    71,
-      77,    97,    87,    94,   150,   129,   166
+      -1,     3,    24,    25,    26,    27,    64,    66,   142,    68,
+      74,    95,    84,    92,   148,   127,   164
   };
 
   const unsigned char
   EvalParser::yytable_[] =
   {
-      33,   146,    36,    64,   152,    64,   106,    35,    37,    55,
-       4,   146,     5,   155,   164,   157,     6,     7,     8,     9,
-      55,   154,    34,    95,    99,    57,   158,   176,    10,    96,
-      49,   165,    50,    11,   108,   109,    38,    56,    56,    56,
-     156,    12,    88,    89,    13,    91,    14,    15,    16,    90,
-      56,    17,    18,   103,   104,    56,   101,   102,    19,    20,
-      21,    56,    22,    39,   196,   198,   200,   196,   198,   200,
-      53,    54,    78,    79,    80,    81,    82,    83,    84,    42,
-      63,   140,    53,    54,   159,     1,     2,    85,    86,    27,
-     141,   142,   143,   141,   142,    28,    29,    30,   147,    40,
-     116,   160,   148,   149,    41,   148,   149,    10,    43,   173,
-     174,    48,    11,   130,   131,   132,   178,   179,   180,   181,
-      12,    44,    51,    13,    52,    14,    15,    16,    53,    54,
-      31,    32,    73,    74,    75,    76,    45,    19,    20,    21,
-      46,    22,   141,   142,   145,   141,   142,   195,   141,   142,
-     197,   167,   141,   142,   199,    61,    62,    50,    52,   114,
-      65,    56,    66,    47,   115,   117,    56,    56,   153,    58,
-      56,   141,   142,    92,    93,   110,    59,    60,    68,   111,
-      56,   112,   113,   118,    98,   119,    53,    70,   120,    72,
-     121,   100,   122,   123,   151,   124,   128,   156,   125,   126,
-     127,   133,   134,   135,   136,   137,   138,   139,   161,   162,
-     163,   168,   169,   170,   175,   171,   172,   107,   177,   182,
-     183,   184,   185,   186,   187,   188,   105,     0,   189,   190,
-     191,   192,   193,   194
+      33,   144,   153,   103,   162,    34,    35,    36,   155,    53,
+      54,   144,    75,    76,    77,    78,    79,    80,    81,   156,
+      93,   163,   138,    53,    54,   157,    94,    82,    83,   154,
+      37,   139,   140,   141,   139,   140,   139,   140,   143,   113,
+      97,    85,    86,    38,    88,    89,   145,    87,   105,   106,
+     146,   147,     4,   101,     5,    99,   100,    40,     6,     7,
+       8,     9,    90,    91,   194,   196,   198,   194,   196,   198,
+      10,    61,   158,    53,    54,    11,   146,   147,    70,    71,
+      72,    73,    62,    12,    63,    39,    13,    14,    15,    16,
+      17,     1,     2,    18,    19,   139,   140,   193,   139,   140,
+      20,    21,    22,    49,    23,    50,   171,   172,    41,    42,
+     128,   129,   130,   176,   177,   178,   179,   139,   140,   195,
+      43,    48,    28,    29,    30,   139,   140,   197,    44,    51,
+      59,    52,    50,    60,    10,    52,    45,    46,    47,    11,
+      55,    56,    57,    58,    96,    65,    67,    12,    69,   165,
+      13,    14,    15,    16,    17,   107,    98,    31,    32,   108,
+     109,   110,   115,   116,    20,    21,    22,   111,    23,   117,
+      53,   118,   112,   114,   126,   119,   120,   121,   122,   150,
+     123,   149,   124,   125,   131,   132,   133,   134,   135,   136,
+     137,   152,   151,   154,   159,   160,   161,   166,   167,   168,
+     173,   169,   174,   170,   175,   180,   181,   182,   183,   184,
+     185,   186,   104,     0,   187,     0,   188,   189,   190,   191,
+     192,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+     102
   };
 
   const short
   EvalParser::yycheck_[] =
   {
-       2,   126,     4,     4,     4,     4,    59,     4,     5,     8,
-       3,   136,     5,    20,    35,     9,     9,    10,    11,    12,
-       8,     4,     0,    46,    51,    27,    20,     4,    21,    52,
-      15,    52,    17,    26,    61,    62,    15,    38,    38,    38,
-      47,    34,    44,    45,    37,    47,    39,    40,    41,    46,
-      38,    44,    45,    55,    56,    38,    53,    54,    51,    52,
-      53,    38,    55,    15,   189,   190,   191,   192,   193,   194,
-       6,     7,    27,    28,    29,    30,    31,    32,    33,    17,
-       4,     9,     6,     7,     9,    49,    50,    42,    43,     3,
-      18,    19,    20,    18,    19,     9,    10,    11,     9,    15,
-      36,     9,    13,    14,     3,    13,    14,    21,    17,   162,
-     163,    17,    26,   115,   116,   117,   169,   170,   171,   172,
-      34,     3,    15,    37,    17,    39,    40,    41,     6,     7,
-      44,    45,    22,    23,    24,    25,     3,    51,    52,    53,
-       3,    55,    18,    19,    20,    18,    19,    20,    18,    19,
-      20,   153,    18,    19,    20,    15,    15,    17,    17,    36,
-      52,    38,    54,     3,    36,    36,    38,    38,    36,    15,
-      38,    18,    19,    42,    43,    16,    15,    15,    52,    16,
-      38,    16,     4,    16,    48,    16,     6,    52,    16,    51,
-      16,    48,    16,    16,    36,    16,    52,    47,    17,    17,
-      17,    17,    17,    17,    17,    17,    17,    17,     9,    15,
-      15,    15,    15,    15,     4,    15,    15,    60,    52,    16,
-      16,    16,    16,    16,    16,    16,    58,    -1,    17,    17,
-      17,    17,    17,    17
+       2,   124,    20,    57,    35,     0,     4,     5,     9,     6,
+       7,   134,    27,    28,    29,    30,    31,    32,    33,    20,
+      46,    52,     9,     6,     7,     9,    52,    42,    43,    47,
+      15,    18,    19,    20,    18,    19,    18,    19,    20,    36,
+      51,    43,    44,    15,    46,    47,     9,    45,    59,    60,
+      13,    14,     3,    55,     5,    53,    54,     3,     9,    10,
+      11,    12,    42,    43,   187,   188,   189,   190,   191,   192,
+      21,     4,     9,     6,     7,    26,    13,    14,    22,    23,
+      24,    25,    52,    34,    54,    15,    37,    38,    39,    40,
+      41,    49,    50,    44,    45,    18,    19,    20,    18,    19,
+      51,    52,    53,    15,    55,    17,   160,   161,    17,    17,
+     112,   113,   114,   167,   168,   169,   170,    18,    19,    20,
+       3,    17,     9,    10,    11,    18,    19,    20,     3,    15,
+      15,    17,    17,    15,    21,    17,     3,     3,     3,    26,
+       8,    15,    15,    15,    48,    52,    52,    34,    51,   151,
+      37,    38,    39,    40,    41,    16,    48,    44,    45,    16,
+      16,     4,     4,    16,    51,    52,    53,    36,    55,    16,
+       6,    16,    36,    36,    52,    16,    16,    16,    16,     4,
+      17,    36,    17,    17,    17,    17,    17,    17,    17,    17,
+      17,     4,    36,    47,     9,    15,    15,    15,    15,    15,
+       4,    15,     4,    15,    52,    16,    16,    16,    16,    16,
+      16,    16,    58,    -1,    17,    -1,    17,    17,    17,    17,
+      17,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      56
   };
 
   const signed char
   EvalParser::yystos_[] =
   {
        0,    49,    50,    57,     3,     5,     9,    10,    11,    12,
-      21,    26,    34,    37,    39,    40,    41,    44,    45,    51,
-      52,    53,    55,    58,    59,    60,    61,     3,     9,    10,
-      11,    44,    45,    60,     0,    59,    60,    59,    15,    15,
-      15,     3,    17,    17,     3,     3,     3,     3,    17,    15,
-      17,    15,    17,     6,     7,     8,    38,    60,    15,    15,
-      15,    15,    15,     4,     4,    52,    54,    62,    52,    63,
-      52,    65,    51,    22,    23,    24,    25,    66,    27,    28,
-      29,    30,    31,    32,    33,    42,    43,    68,    60,    60,
-      59,    60,    42,    43,    69,    46,    52,    67,    48,    67,
-      48,    59,    59,    60,    60,    62,    63,    65,    67,    67,
-      16,    16,    16,     4,    36,    36,    36,    36,    16,    16,
-      16,    16,    16,    16,    16,    17,    17,    17,    52,    71,
-      60,    60,    60,    17,    17,    17,    17,    17,    17,    17,
-       9,    18,    19,    20,    64,    20,    64,     9,    13,    14,
-      70,    36,     4,    36,     4,    20,    47,     9,    20,     9,
-       9,     9,    15,    15,    35,    52,    72,    60,    15,    15,
-      15,    15,    15,    63,    63,     4,     4,    52,    63,    63,
-      63,    63,    16,    16,    16,    16,    16,    16,    16,    17,
-      17,    17,    17,    17,    17,    20,    64,    20,    64,    20,
-      64
+      21,    26,    34,    37,    38,    39,    40,    41,    44,    45,
+      51,    52,    53,    55,    58,    59,    60,    61,     9,    10,
+      11,    44,    45,    60,     0,    59,    59,    15,    15,    15,
+       3,    17,    17,     3,     3,     3,     3,     3,    17,    15,
+      17,    15,    17,     6,     7,     8,    15,    15,    15,    15,
+      15,     4,    52,    54,    62,    52,    63,    52,    65,    51,
+      22,    23,    24,    25,    66,    27,    28,    29,    30,    31,
+      32,    33,    42,    43,    68,    60,    60,    59,    60,    60,
+      42,    43,    69,    46,    52,    67,    48,    67,    48,    59,
+      59,    60,    62,    63,    65,    67,    67,    16,    16,    16,
+       4,    36,    36,    36,    36,     4,    16,    16,    16,    16,
+      16,    16,    16,    17,    17,    17,    52,    71,    60,    60,
+      60,    17,    17,    17,    17,    17,    17,    17,     9,    18,
+      19,    20,    64,    20,    64,     9,    13,    14,    70,    36,
+       4,    36,     4,    20,    47,     9,    20,     9,     9,     9,
+      15,    15,    35,    52,    72,    60,    15,    15,    15,    15,
+      15,    63,    63,     4,     4,    52,    63,    63,    63,    63,
+      16,    16,    16,    16,    16,    16,    16,    17,    17,    17,
+      17,    17,    17,    20,    64,    20,    64,    20,    64
   };
 
   const signed char
@@ -2015,9 +1965,9 @@ namespace isc { namespace eval {
       59,    59,    59,    59,    59,    59,    59,    59,    60,    60,
       60,    60,    60,    60,    60,    60,    60,    60,    60,    60,
       60,    60,    60,    60,    60,    60,    60,    60,    60,    60,
-      60,    61,    62,    62,    63,    64,    64,    65,    66,    66,
-      66,    66,    67,    67,    68,    68,    68,    68,    68,    68,
-      68,    68,    68,    69,    69,    70,    70,    71,    72,    72
+      61,    62,    62,    63,    64,    64,    65,    66,    66,    66,
+      66,    67,    67,    68,    68,    68,    68,    68,    68,    68,
+      68,    68,    69,    69,    70,    70,    71,    72,    72
   };
 
   const signed char
@@ -2026,27 +1976,27 @@ namespace isc { namespace eval {
        0,     2,     2,     2,     1,     3,     2,     3,     3,     3,
        6,    11,     6,    11,     6,     6,    11,     4,     1,     1,
        1,     6,    11,     6,    11,     3,     3,     3,     6,     8,
-       6,     3,     8,     6,     3,     3,    11,     6,     9,     1,
-       3,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       6,     8,     6,     4,     3,     3,    11,     6,     9,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
-       1,     1,     1,     1,     1,     1,     1,     1,     1,     1
+       1,     1,     1,     1,     1,     1,     1,     1,     1
   };
 
 
-#if EVALDEBUG || 1
+
   // YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
-  // First, the terminals, then, starting at \a YYNTOKENS, nonterminals.
+  // First, the terminals, then, starting at \a yyntokens_, nonterminals.
   const char*
   const EvalParser::yytname_[] =
   {
-  "\"end of file\"", "error", "\"invalid token\"", "\"(\"", "\")\"",
-  "\"not\"", "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"",
-  "\"relay6\"", "\"member\"", "\"peeraddr\"", "\"linkaddr\"", "\"[\"",
-  "\"]\"", "\".\"", "\"text\"", "\"hex\"", "\"exists\"", "\"pkt\"",
-  "\"iface\"", "\"src\"", "\"dst\"", "\"len\"", "\"pkt4\"", "\"mac\"",
-  "\"hlen\"", "\"htype\"", "\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"",
-  "\"siaddr\"", "\"substring\"", "\"all\"", "\",\"", "\"concat\"", "\"+\"",
-  "\"ifelse\"", "\"hexstring\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"",
+  "\"end of file\"", "error", "$undefined", "\"(\"", "\")\"", "\"not\"",
+  "\"and\"", "\"or\"", "\"==\"", "\"option\"", "\"relay4\"", "\"relay6\"",
+  "\"member\"", "\"peeraddr\"", "\"linkaddr\"", "\"[\"", "\"]\"", "\".\"",
+  "\"text\"", "\"hex\"", "\"exists\"", "\"pkt\"", "\"iface\"", "\"src\"",
+  "\"dst\"", "\"len\"", "\"pkt4\"", "\"mac\"", "\"hlen\"", "\"htype\"",
+  "\"ciaddr\"", "\"giaddr\"", "\"yiaddr\"", "\"siaddr\"", "\"substring\"",
+  "\"all\"", "\",\"", "\"concat\"", "\"ifelse\"", "\"hexstring\"",
+  "\"addrtotext\"", "\"pkt6\"", "\"msgtype\"", "\"transid\"",
   "\"vendor-class\"", "\"vendor\"", "\"*\"", "\"data\"", "\"enterprise\"",
   "\"top-level bool\"", "\"top-level string\"", "\"constant string\"",
   "\"integer\"", "\"constant hexstring\"", "\"option name\"",
@@ -2055,24 +2005,23 @@ namespace isc { namespace eval {
   "option_repr_type", "nest_level", "pkt_metadata", "enterprise_id",
   "pkt4_field", "pkt6_field", "relay6_field", "start_expr", "length_expr", YY_NULLPTR
   };
-#endif
-
 
 #if EVALDEBUG
   const short
   EvalParser::yyrline_[] =
   {
-       0,   123,   123,   124,   129,   132,   133,   138,   143,   148,
-     153,   158,   163,   183,   197,   206,   215,   225,   242,   247,
-     252,   257,   262,   267,   288,   303,   308,   322,   336,   351,
-     356,   361,   366,   371,   376,   385,   395,   404,   417,   430,
-     435,   438,   444,   448,   454,   460,   464,   470,   479,   483,
-     487,   491,   497,   501,   507,   511,   515,   519,   523,   527,
-     531,   535,   539,   545,   549,   555,   559,   565,   572,   577
+       0,   122,   122,   123,   128,   131,   132,   137,   142,   147,
+     152,   157,   162,   182,   196,   205,   214,   224,   241,   246,
+     251,   256,   261,   266,   287,   302,   307,   321,   335,   350,
+     355,   360,   365,   370,   375,   384,   394,   403,   416,   429,
+     436,   442,   446,   452,   458,   462,   468,   477,   481,   485,
+     489,   495,   499,   505,   509,   513,   517,   521,   525,   529,
+     533,   537,   543,   547,   553,   557,   563,   570,   575
   };
 
+  // Print the state stack on the debug stream.
   void
-  EvalParser::yy_stack_print_ () const
+  EvalParser::yystack_print_ ()
   {
     *yycdebug_ << "Stack now";
     for (stack_type::const_iterator
@@ -2083,8 +2032,9 @@ namespace isc { namespace eval {
     *yycdebug_ << '\n';
   }
 
+  // Report on the debug stream that the rule \a yyrule is going to be reduced.
   void
-  EvalParser::yy_reduce_print_ (int yyrule) const
+  EvalParser::yy_reduce_print_ (int yyrule)
   {
     int yylno = yyrline_[yyrule];
     int yynrhs = yyr2_[yyrule];
@@ -2101,9 +2051,9 @@ namespace isc { namespace eval {
 
 #line 14 "parser.yy"
 } } // isc::eval
-#line 2105 "parser.cc"
+#line 2055 "parser.cc"
 
-#line 584 "parser.yy"
+#line 582 "parser.yy"
 
 void
 isc::eval::EvalParser::error(const location_type& loc,
index 41b05b60c5f5f7b1b152eaeb601e8ae2c0622b63..9ab029c73672e19ee705cf237fe29ba1360f53dd 100644 (file)
@@ -1,8 +1,8 @@
-// A Bison parser, made by GNU Bison 3.7.6.
+// A Bison parser, made by GNU Bison 3.5.1.
 
 // Skeleton interface for Bison LALR(1) parsers in C++
 
-// Copyright (C) 2002-2015, 2018-2021 Free Software Foundation, Inc.
+// Copyright (C) 2002-2015, 2018-2020 Free Software Foundation, Inc.
 
 // This program is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -15,7 +15,7 @@
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License
-// along with this program.  If not, see <https://www.gnu.org/licenses/>.
+// along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 // As a special exception, you may create a larger work that contains
 // part or all of the Bison parser skeleton and distribute that work
@@ -38,9 +38,8 @@
 
 // C++ LALR(1) parser skeleton written by Akim Demaille.
 
-// DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
-// especially those whose name start with YY_ or yy_.  They are
-// private implementation details that can be changed or removed.
+// Undocumented macros, especially those whose name start with YY_,
+// are private implementation details.  Do not rely on them.
 
 #ifndef YY_EVAL_PARSER_H_INCLUDED
 # define YY_EVAL_PARSER_H_INCLUDED
@@ -56,7 +55,7 @@
 using namespace isc::dhcp;
 using namespace isc::eval;
 
-#line 60 "parser.h"
+#line 59 "parser.h"
 
 # include <cassert>
 # include <cstdlib> // std::abort
@@ -103,9 +102,9 @@ using namespace isc::eval;
 #endif
 # include "location.hh"
 #include <typeinfo>
-#ifndef EVAL_ASSERT
+#ifndef YY_ASSERT
 # include <cassert>
-# define EVAL_ASSERT assert
+# define YY_ASSERT assert
 #endif
 
 
@@ -127,9 +126,9 @@ using namespace isc::eval;
 
 /* Suppress unused-variable warnings by "using" E.  */
 #if ! defined lint || defined __GNUC__
-# define YY_USE(E) ((void) (E))
+# define YYUSE(E) ((void) (E))
 #else
-# define YY_USE(E) /* empty */
+# define YYUSE(E) /* empty */
 #endif
 
 #if defined __GNUC__ && ! defined __ICC && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
@@ -199,7 +198,7 @@ using namespace isc::eval;
 
 #line 14 "parser.yy"
 namespace isc { namespace eval {
-#line 203 "parser.h"
+#line 202 "parser.h"
 
 
 
@@ -231,21 +230,14 @@ namespace isc { namespace eval {
     semantic_type (YY_RVREF (T) t)
       : yytypeid_ (&typeid (T))
     {
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (sizeof (T) <= size);
       new (yyas_<T> ()) T (YY_MOVE (t));
     }
 
-#if 201103L <= YY_CPLUSPLUS
-    /// Non copyable.
-    semantic_type (const self_type&) = delete;
-    /// Non copyable.
-    self_type& operator= (const self_type&) = delete;
-#endif
-
     /// Destruction, allowed only if empty.
     ~semantic_type () YY_NOEXCEPT
     {
-      EVAL_ASSERT (!yytypeid_);
+      YY_ASSERT (!yytypeid_);
     }
 
 # if 201103L <= YY_CPLUSPLUS
@@ -254,8 +246,8 @@ namespace isc { namespace eval {
     T&
     emplace (U&&... u)
     {
-      EVAL_ASSERT (!yytypeid_);
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (!yytypeid_);
+      YY_ASSERT (sizeof (T) <= size);
       yytypeid_ = & typeid (T);
       return *new (yyas_<T> ()) T (std::forward <U>(u)...);
     }
@@ -265,8 +257,8 @@ namespace isc { namespace eval {
     T&
     emplace ()
     {
-      EVAL_ASSERT (!yytypeid_);
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (!yytypeid_);
+      YY_ASSERT (sizeof (T) <= size);
       yytypeid_ = & typeid (T);
       return *new (yyas_<T> ()) T ();
     }
@@ -276,8 +268,8 @@ namespace isc { namespace eval {
     T&
     emplace (const T& t)
     {
-      EVAL_ASSERT (!yytypeid_);
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (!yytypeid_);
+      YY_ASSERT (sizeof (T) <= size);
       yytypeid_ = & typeid (T);
       return *new (yyas_<T> ()) T (t);
     }
@@ -306,9 +298,9 @@ namespace isc { namespace eval {
     T&
     as () YY_NOEXCEPT
     {
-      EVAL_ASSERT (yytypeid_);
-      EVAL_ASSERT (*yytypeid_ == typeid (T));
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (yytypeid_);
+      YY_ASSERT (*yytypeid_ == typeid (T));
+      YY_ASSERT (sizeof (T) <= size);
       return *yyas_<T> ();
     }
 
@@ -317,9 +309,9 @@ namespace isc { namespace eval {
     const T&
     as () const YY_NOEXCEPT
     {
-      EVAL_ASSERT (yytypeid_);
-      EVAL_ASSERT (*yytypeid_ == typeid (T));
-      EVAL_ASSERT (sizeof (T) <= size);
+      YY_ASSERT (yytypeid_);
+      YY_ASSERT (*yytypeid_ == typeid (T));
+      YY_ASSERT (sizeof (T) <= size);
       return *yyas_<T> ();
     }
 
@@ -335,8 +327,8 @@ namespace isc { namespace eval {
     void
     swap (self_type& that) YY_NOEXCEPT
     {
-      EVAL_ASSERT (yytypeid_);
-      EVAL_ASSERT (*yytypeid_ == *that.yytypeid_);
+      YY_ASSERT (yytypeid_);
+      YY_ASSERT (*yytypeid_ == *that.yytypeid_);
       std::swap (as<T> (), that.as<T> ());
     }
 
@@ -385,12 +377,9 @@ namespace isc { namespace eval {
     }
 
   private:
-#if YY_CPLUSPLUS < 201103L
-    /// Non copyable.
-    semantic_type (const self_type&);
-    /// Non copyable.
+    /// Prohibit blind copies.
     self_type& operator= (const self_type&);
-#endif
+    semantic_type (const self_type&);
 
     /// Accessor to raw memory as \a T.
     template <typename T>
@@ -487,172 +476,84 @@ namespace isc { namespace eval {
       location_type location;
     };
 
-    /// Token kinds.
+    /// Tokens.
     struct token
     {
-      enum token_kind_type
-      {
-        TOKEN_EVALEMPTY = -2,
-    TOKEN_END = 0,                 // "end of file"
-    TOKEN_EVALerror = 256,         // error
-    TOKEN_EVALUNDEF = 257,         // "invalid token"
-    TOKEN_LPAREN = 258,            // "("
-    TOKEN_RPAREN = 259,            // ")"
-    TOKEN_NOT = 260,               // "not"
-    TOKEN_AND = 261,               // "and"
-    TOKEN_OR = 262,                // "or"
-    TOKEN_EQUAL = 263,             // "=="
-    TOKEN_OPTION = 264,            // "option"
-    TOKEN_RELAY4 = 265,            // "relay4"
-    TOKEN_RELAY6 = 266,            // "relay6"
-    TOKEN_MEMBER = 267,            // "member"
-    TOKEN_PEERADDR = 268,          // "peeraddr"
-    TOKEN_LINKADDR = 269,          // "linkaddr"
-    TOKEN_LBRACKET = 270,          // "["
-    TOKEN_RBRACKET = 271,          // "]"
-    TOKEN_DOT = 272,               // "."
-    TOKEN_TEXT = 273,              // "text"
-    TOKEN_HEX = 274,               // "hex"
-    TOKEN_EXISTS = 275,            // "exists"
-    TOKEN_PKT = 276,               // "pkt"
-    TOKEN_IFACE = 277,             // "iface"
-    TOKEN_SRC = 278,               // "src"
-    TOKEN_DST = 279,               // "dst"
-    TOKEN_LEN = 280,               // "len"
-    TOKEN_PKT4 = 281,              // "pkt4"
-    TOKEN_CHADDR = 282,            // "mac"
-    TOKEN_HLEN = 283,              // "hlen"
-    TOKEN_HTYPE = 284,             // "htype"
-    TOKEN_CIADDR = 285,            // "ciaddr"
-    TOKEN_GIADDR = 286,            // "giaddr"
-    TOKEN_YIADDR = 287,            // "yiaddr"
-    TOKEN_SIADDR = 288,            // "siaddr"
-    TOKEN_SUBSTRING = 289,         // "substring"
-    TOKEN_ALL = 290,               // "all"
-    TOKEN_COMA = 291,              // ","
-    TOKEN_CONCAT = 292,            // "concat"
-    TOKEN_PLUS = 293,              // "+"
-    TOKEN_IFELSE = 294,            // "ifelse"
-    TOKEN_TOHEXSTRING = 295,       // "hexstring"
-    TOKEN_PKT6 = 296,              // "pkt6"
-    TOKEN_MSGTYPE = 297,           // "msgtype"
-    TOKEN_TRANSID = 298,           // "transid"
-    TOKEN_VENDOR_CLASS = 299,      // "vendor-class"
-    TOKEN_VENDOR = 300,            // "vendor"
-    TOKEN_ANY = 301,               // "*"
-    TOKEN_DATA = 302,              // "data"
-    TOKEN_ENTERPRISE = 303,        // "enterprise"
-    TOKEN_TOPLEVEL_BOOL = 304,     // "top-level bool"
-    TOKEN_TOPLEVEL_STRING = 305,   // "top-level string"
-    TOKEN_STRING = 306,            // "constant string"
-    TOKEN_INTEGER = 307,           // "integer"
-    TOKEN_HEXSTRING = 308,         // "constant hexstring"
-    TOKEN_OPTION_NAME = 309,       // "option name"
-    TOKEN_IP_ADDRESS = 310         // "ip address"
+      enum yytokentype
+      {
+        TOKEN_END = 0,
+        TOKEN_LPAREN = 258,
+        TOKEN_RPAREN = 259,
+        TOKEN_NOT = 260,
+        TOKEN_AND = 261,
+        TOKEN_OR = 262,
+        TOKEN_EQUAL = 263,
+        TOKEN_OPTION = 264,
+        TOKEN_RELAY4 = 265,
+        TOKEN_RELAY6 = 266,
+        TOKEN_MEMBER = 267,
+        TOKEN_PEERADDR = 268,
+        TOKEN_LINKADDR = 269,
+        TOKEN_LBRACKET = 270,
+        TOKEN_RBRACKET = 271,
+        TOKEN_DOT = 272,
+        TOKEN_TEXT = 273,
+        TOKEN_HEX = 274,
+        TOKEN_EXISTS = 275,
+        TOKEN_PKT = 276,
+        TOKEN_IFACE = 277,
+        TOKEN_SRC = 278,
+        TOKEN_DST = 279,
+        TOKEN_LEN = 280,
+        TOKEN_PKT4 = 281,
+        TOKEN_CHADDR = 282,
+        TOKEN_HLEN = 283,
+        TOKEN_HTYPE = 284,
+        TOKEN_CIADDR = 285,
+        TOKEN_GIADDR = 286,
+        TOKEN_YIADDR = 287,
+        TOKEN_SIADDR = 288,
+        TOKEN_SUBSTRING = 289,
+        TOKEN_ALL = 290,
+        TOKEN_COMA = 291,
+        TOKEN_CONCAT = 292,
+        TOKEN_IFELSE = 293,
+        TOKEN_TOHEXSTRING = 294,
+        TOKEN_ADDRTOTEXT = 295,
+        TOKEN_PKT6 = 296,
+        TOKEN_MSGTYPE = 297,
+        TOKEN_TRANSID = 298,
+        TOKEN_VENDOR_CLASS = 299,
+        TOKEN_VENDOR = 300,
+        TOKEN_ANY = 301,
+        TOKEN_DATA = 302,
+        TOKEN_ENTERPRISE = 303,
+        TOKEN_TOPLEVEL_BOOL = 304,
+        TOKEN_TOPLEVEL_STRING = 305,
+        TOKEN_STRING = 306,
+        TOKEN_INTEGER = 307,
+        TOKEN_HEXSTRING = 308,
+        TOKEN_OPTION_NAME = 309,
+        TOKEN_IP_ADDRESS = 310
       };
-      /// Backward compatibility alias (Bison 3.6).
-      typedef token_kind_type yytokentype;
     };
 
-    /// Token kind, as returned by yylex.
-    typedef token::yytokentype token_kind_type;
+    /// (External) token type, as returned by yylex.
+    typedef token::yytokentype token_type;
 
-    /// Backward compatibility alias (Bison 3.6).
-    typedef token_kind_type token_type;
+    /// Symbol type: an internal symbol number.
+    typedef int symbol_number_type;
 
-    /// Symbol kinds.
-    struct symbol_kind
-    {
-      enum symbol_kind_type
-      {
-        YYNTOKENS = 56, ///< Number of tokens.
-        S_YYEMPTY = -2,
-        S_YYEOF = 0,                             // "end of file"
-        S_YYerror = 1,                           // error
-        S_YYUNDEF = 2,                           // "invalid token"
-        S_LPAREN = 3,                            // "("
-        S_RPAREN = 4,                            // ")"
-        S_NOT = 5,                               // "not"
-        S_AND = 6,                               // "and"
-        S_OR = 7,                                // "or"
-        S_EQUAL = 8,                             // "=="
-        S_OPTION = 9,                            // "option"
-        S_RELAY4 = 10,                           // "relay4"
-        S_RELAY6 = 11,                           // "relay6"
-        S_MEMBER = 12,                           // "member"
-        S_PEERADDR = 13,                         // "peeraddr"
-        S_LINKADDR = 14,                         // "linkaddr"
-        S_LBRACKET = 15,                         // "["
-        S_RBRACKET = 16,                         // "]"
-        S_DOT = 17,                              // "."
-        S_TEXT = 18,                             // "text"
-        S_HEX = 19,                              // "hex"
-        S_EXISTS = 20,                           // "exists"
-        S_PKT = 21,                              // "pkt"
-        S_IFACE = 22,                            // "iface"
-        S_SRC = 23,                              // "src"
-        S_DST = 24,                              // "dst"
-        S_LEN = 25,                              // "len"
-        S_PKT4 = 26,                             // "pkt4"
-        S_CHADDR = 27,                           // "mac"
-        S_HLEN = 28,                             // "hlen"
-        S_HTYPE = 29,                            // "htype"
-        S_CIADDR = 30,                           // "ciaddr"
-        S_GIADDR = 31,                           // "giaddr"
-        S_YIADDR = 32,                           // "yiaddr"
-        S_SIADDR = 33,                           // "siaddr"
-        S_SUBSTRING = 34,                        // "substring"
-        S_ALL = 35,                              // "all"
-        S_COMA = 36,                             // ","
-        S_CONCAT = 37,                           // "concat"
-        S_PLUS = 38,                             // "+"
-        S_IFELSE = 39,                           // "ifelse"
-        S_TOHEXSTRING = 40,                      // "hexstring"
-        S_PKT6 = 41,                             // "pkt6"
-        S_MSGTYPE = 42,                          // "msgtype"
-        S_TRANSID = 43,                          // "transid"
-        S_VENDOR_CLASS = 44,                     // "vendor-class"
-        S_VENDOR = 45,                           // "vendor"
-        S_ANY = 46,                              // "*"
-        S_DATA = 47,                             // "data"
-        S_ENTERPRISE = 48,                       // "enterprise"
-        S_TOPLEVEL_BOOL = 49,                    // "top-level bool"
-        S_TOPLEVEL_STRING = 50,                  // "top-level string"
-        S_STRING = 51,                           // "constant string"
-        S_INTEGER = 52,                          // "integer"
-        S_HEXSTRING = 53,                        // "constant hexstring"
-        S_OPTION_NAME = 54,                      // "option name"
-        S_IP_ADDRESS = 55,                       // "ip address"
-        S_YYACCEPT = 56,                         // $accept
-        S_start = 57,                            // start
-        S_expression = 58,                       // expression
-        S_bool_expr = 59,                        // bool_expr
-        S_string_expr = 60,                      // string_expr
-        S_integer_expr = 61,                     // integer_expr
-        S_option_code = 62,                      // option_code
-        S_sub_option_code = 63,                  // sub_option_code
-        S_option_repr_type = 64,                 // option_repr_type
-        S_nest_level = 65,                       // nest_level
-        S_pkt_metadata = 66,                     // pkt_metadata
-        S_enterprise_id = 67,                    // enterprise_id
-        S_pkt4_field = 68,                       // pkt4_field
-        S_pkt6_field = 69,                       // pkt6_field
-        S_relay6_field = 70,                     // relay6_field
-        S_start_expr = 71,                       // start_expr
-        S_length_expr = 72                       // length_expr
-      };
-    };
+    /// The symbol type number to denote an empty symbol.
+    enum { empty_symbol = -2 };
 
-    /// (Internal) symbol kind.
-    typedef symbol_kind::symbol_kind_type symbol_kind_type;
-
-    /// The number of tokens.
-    static const symbol_kind_type YYNTOKENS = symbol_kind::YYNTOKENS;
+    /// Internal symbol number for tokens (subsumed by symbol_number_type).
+    typedef signed char token_number_type;
 
     /// A complete symbol.
     ///
-    /// Expects its Base type to provide access to the symbol kind
-    /// via kind ().
+    /// Expects its Base type to provide access to the symbol type
+    /// via type_get ().
     ///
     /// Provide access to semantic value and location.
     template <typename Base>
@@ -669,66 +570,13 @@ namespace isc { namespace eval {
 
 #if 201103L <= YY_CPLUSPLUS
       /// Move constructor.
-      basic_symbol (basic_symbol&& that)
-        : Base (std::move (that))
-        , value ()
-        , location (std::move (that.location))
-      {
-        switch (this->kind ())
-    {
-      case symbol_kind::S_option_repr_type: // option_repr_type
-        value.move< TokenOption::RepresentationType > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_pkt4_field: // pkt4_field
-        value.move< TokenPkt4::FieldType > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_pkt6_field: // pkt6_field
-        value.move< TokenPkt6::FieldType > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
-        value.move< TokenPkt::MetadataType > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_relay6_field: // relay6_field
-        value.move< TokenRelay6Field::FieldType > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_nest_level: // nest_level
-        value.move< int8_t > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
-        value.move< std::string > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
-        value.move< uint16_t > (std::move (that.value));
-        break;
-
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
-        value.move< uint32_t > (std::move (that.value));
-        break;
-
-      default:
-        break;
-    }
-
-      }
+      basic_symbol (basic_symbol&& that);
 #endif
 
       /// Copy constructor.
       basic_symbol (const basic_symbol& that);
 
-      /// Constructors for typed symbols.
+      /// Constructor for valueless symbols, and symbols from each type.
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, location_type&& l)
         : Base (t)
@@ -740,7 +588,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, TokenOption::RepresentationType&& v, location_type&& l)
         : Base (t)
@@ -754,7 +601,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, TokenPkt4::FieldType&& v, location_type&& l)
         : Base (t)
@@ -768,7 +614,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, TokenPkt6::FieldType&& v, location_type&& l)
         : Base (t)
@@ -782,7 +627,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, TokenPkt::MetadataType&& v, location_type&& l)
         : Base (t)
@@ -796,7 +640,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, TokenRelay6Field::FieldType&& v, location_type&& l)
         : Base (t)
@@ -810,7 +653,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, int8_t&& v, location_type&& l)
         : Base (t)
@@ -824,7 +666,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, std::string&& v, location_type&& l)
         : Base (t)
@@ -838,7 +679,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, uint16_t&& v, location_type&& l)
         : Base (t)
@@ -852,7 +692,6 @@ namespace isc { namespace eval {
         , location (l)
       {}
 #endif
-
 #if 201103L <= YY_CPLUSPLUS
       basic_symbol (typename Base::kind_type t, uint32_t&& v, location_type&& l)
         : Base (t)
@@ -874,60 +713,60 @@ namespace isc { namespace eval {
       }
 
       /// Destroy contents, and record that is empty.
-      void clear () YY_NOEXCEPT
+      void clear ()
       {
         // User destructor.
-        symbol_kind_type yykind = this->kind ();
+        symbol_number_type yytype = this->type_get ();
         basic_symbol<Base>& yysym = *this;
         (void) yysym;
-        switch (yykind)
+        switch (yytype)
         {
        default:
           break;
         }
 
-        // Value type destructor.
-switch (yykind)
+        // Type destructor.
+switch (yytype)
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.template destroy< TokenOption::RepresentationType > ();
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.template destroy< TokenPkt4::FieldType > ();
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.template destroy< TokenPkt6::FieldType > ();
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.template destroy< TokenPkt::MetadataType > ();
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.template destroy< TokenRelay6Field::FieldType > ();
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.template destroy< int8_t > ();
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.template destroy< std::string > ();
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.template destroy< uint16_t > ();
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.template destroy< uint32_t > ();
         break;
 
@@ -938,15 +777,6 @@ switch (yykind)
         Base::clear ();
       }
 
-      /// The user-facing name of this symbol.
-      std::string name () const YY_NOEXCEPT
-      {
-        return EvalParser::symbol_name (this->kind ());
-      }
-
-      /// Backward compatibility (Bison 3.6).
-      symbol_kind_type type_get () const YY_NOEXCEPT;
-
       /// Whether empty.
       bool empty () const YY_NOEXCEPT;
 
@@ -967,51 +797,46 @@ switch (yykind)
     };
 
     /// Type access provider for token (enum) based symbols.
-    struct by_kind
+    struct by_type
     {
       /// Default constructor.
-      by_kind ();
+      by_type ();
 
 #if 201103L <= YY_CPLUSPLUS
       /// Move constructor.
-      by_kind (by_kind&& that);
+      by_type (by_type&& that);
 #endif
 
       /// Copy constructor.
-      by_kind (const by_kind& that);
+      by_type (const by_type& that);
 
-      /// The symbol kind as needed by the constructor.
-      typedef token_kind_type kind_type;
+      /// The symbol type as needed by the constructor.
+      typedef token_type kind_type;
 
       /// Constructor from (external) token numbers.
-      by_kind (kind_type t);
+      by_type (kind_type t);
 
       /// Record that this symbol is empty.
-      void clear () YY_NOEXCEPT;
+      void clear ();
 
-      /// Steal the symbol kind from \a that.
-      void move (by_kind& that);
+      /// Steal the symbol type from \a that.
+      void move (by_type& that);
 
       /// The (internal) type number (corresponding to \a type).
       /// \a empty when empty.
-      symbol_kind_type kind () const YY_NOEXCEPT;
-
-      /// Backward compatibility (Bison 3.6).
-      symbol_kind_type type_get () const YY_NOEXCEPT;
+      symbol_number_type type_get () const YY_NOEXCEPT;
 
-      /// The symbol kind.
-      /// \a S_YYEMPTY when empty.
-      symbol_kind_type kind_;
+      /// The symbol type.
+      /// \a empty_symbol when empty.
+      /// An int, not token_number_type, to be able to store empty_symbol.
+      int type;
     };
 
-    /// Backward compatibility for a private implementation detail (Bison 3.6).
-    typedef by_kind by_type;
-
     /// "External" symbols: returned by the scanner.
-    struct symbol_type : basic_symbol<by_kind>
+    struct symbol_type : basic_symbol<by_type>
     {
       /// Superclass.
-      typedef basic_symbol<by_kind> super_type;
+      typedef basic_symbol<by_type> super_type;
 
       /// Empty symbol.
       symbol_type () {}
@@ -1020,37 +845,35 @@ switch (yykind)
 #if 201103L <= YY_CPLUSPLUS
       symbol_type (int tok, location_type l)
         : super_type(token_type (tok), std::move (l))
+      {
+        YY_ASSERT (tok == token::TOKEN_END || tok == token::TOKEN_LPAREN || tok == token::TOKEN_RPAREN || tok == token::TOKEN_NOT || tok == token::TOKEN_AND || tok == token::TOKEN_OR || tok == token::TOKEN_EQUAL || tok == token::TOKEN_OPTION || tok == token::TOKEN_RELAY4 || tok == token::TOKEN_RELAY6 || tok == token::TOKEN_MEMBER || tok == token::TOKEN_PEERADDR || tok == token::TOKEN_LINKADDR || tok == token::TOKEN_LBRACKET || tok == token::TOKEN_RBRACKET || tok == token::TOKEN_DOT || tok == token::TOKEN_TEXT || tok == token::TOKEN_HEX || tok == token::TOKEN_EXISTS || tok == token::TOKEN_PKT || tok == token::TOKEN_IFACE || tok == token::TOKEN_SRC || tok == token::TOKEN_DST || tok == token::TOKEN_LEN || tok == token::TOKEN_PKT4 || tok == token::TOKEN_CHADDR || tok == token::TOKEN_HLEN || tok == token::TOKEN_HTYPE || tok == token::TOKEN_CIADDR || tok == token::TOKEN_GIADDR || tok == token::TOKEN_YIADDR || tok == token::TOKEN_SIADDR || tok == token::TOKEN_SUBSTRING || tok == token::TOKEN_ALL || tok == token::TOKEN_COMA || tok == token::TOKEN_CONCAT || tok == token::TOKEN_IFELSE || tok == token::TOKEN_TOHEXSTRING || tok == token::TOKEN_ADDRTOTEXT || tok == token::TOKEN_PKT6 || tok == token::TOKEN_MSGTYPE || tok == token::TOKEN_TRANSID || tok == token::TOKEN_VENDOR_CLASS || tok == token::TOKEN_VENDOR || tok == token::TOKEN_ANY || tok == token::TOKEN_DATA || tok == token::TOKEN_ENTERPRISE || tok == token::TOKEN_TOPLEVEL_BOOL || tok == token::TOKEN_TOPLEVEL_STRING);
+      }
 #else
       symbol_type (int tok, const location_type& l)
         : super_type(token_type (tok), l)
-#endif
       {
-        EVAL_ASSERT (tok == token::TOKEN_END
-                   || (token::TOKEN_EVALerror <= tok && tok <= token::TOKEN_TOPLEVEL_STRING));
+        YY_ASSERT (tok == token::TOKEN_END || tok == token::TOKEN_LPAREN || tok == token::TOKEN_RPAREN || tok == token::TOKEN_NOT || tok == token::TOKEN_AND || tok == token::TOKEN_OR || tok == token::TOKEN_EQUAL || tok == token::TOKEN_OPTION || tok == token::TOKEN_RELAY4 || tok == token::TOKEN_RELAY6 || tok == token::TOKEN_MEMBER || tok == token::TOKEN_PEERADDR || tok == token::TOKEN_LINKADDR || tok == token::TOKEN_LBRACKET || tok == token::TOKEN_RBRACKET || tok == token::TOKEN_DOT || tok == token::TOKEN_TEXT || tok == token::TOKEN_HEX || tok == token::TOKEN_EXISTS || tok == token::TOKEN_PKT || tok == token::TOKEN_IFACE || tok == token::TOKEN_SRC || tok == token::TOKEN_DST || tok == token::TOKEN_LEN || tok == token::TOKEN_PKT4 || tok == token::TOKEN_CHADDR || tok == token::TOKEN_HLEN || tok == token::TOKEN_HTYPE || tok == token::TOKEN_CIADDR || tok == token::TOKEN_GIADDR || tok == token::TOKEN_YIADDR || tok == token::TOKEN_SIADDR || tok == token::TOKEN_SUBSTRING || tok == token::TOKEN_ALL || tok == token::TOKEN_COMA || tok == token::TOKEN_CONCAT || tok == token::TOKEN_IFELSE || tok == token::TOKEN_TOHEXSTRING || tok == token::TOKEN_ADDRTOTEXT || tok == token::TOKEN_PKT6 || tok == token::TOKEN_MSGTYPE || tok == token::TOKEN_TRANSID || tok == token::TOKEN_VENDOR_CLASS || tok == token::TOKEN_VENDOR || tok == token::TOKEN_ANY || tok == token::TOKEN_DATA || tok == token::TOKEN_ENTERPRISE || tok == token::TOKEN_TOPLEVEL_BOOL || tok == token::TOKEN_TOPLEVEL_STRING);
       }
+#endif
 #if 201103L <= YY_CPLUSPLUS
       symbol_type (int tok, std::string v, location_type l)
         : super_type(token_type (tok), std::move (v), std::move (l))
+      {
+        YY_ASSERT (tok == token::TOKEN_STRING || tok == token::TOKEN_INTEGER || tok == token::TOKEN_HEXSTRING || tok == token::TOKEN_OPTION_NAME || tok == token::TOKEN_IP_ADDRESS);
+      }
 #else
       symbol_type (int tok, const std::string& v, const location_type& l)
         : super_type(token_type (tok), v, l)
-#endif
       {
-        EVAL_ASSERT ((token::TOKEN_STRING <= tok && tok <= token::TOKEN_IP_ADDRESS));
+        YY_ASSERT (tok == token::TOKEN_STRING || tok == token::TOKEN_INTEGER || tok == token::TOKEN_HEXSTRING || tok == token::TOKEN_OPTION_NAME || tok == token::TOKEN_IP_ADDRESS);
       }
+#endif
     };
 
     /// Build a parser object.
     EvalParser (EvalContext& ctx_yyarg);
     virtual ~EvalParser ();
 
-#if 201103L <= YY_CPLUSPLUS
-    /// Non copyable.
-    EvalParser (const EvalParser&) = delete;
-    /// Non copyable.
-    EvalParser& operator= (const EvalParser&) = delete;
-#endif
-
     /// Parse.  An alias for parse ().
     /// \returns  0 iff parsing succeeded.
     int operator() ();
@@ -1081,10 +904,6 @@ switch (yykind)
     /// Report a syntax error.
     void error (const syntax_error& err);
 
-    /// The user-facing name of the symbol whose (internal) number is
-    /// YYSYMBOL.  No bounds checking.
-    static std::string symbol_name (symbol_kind_type yysymbol);
-
     // Implementation of make_symbol for each symbol type.
 #if 201103L <= YY_CPLUSPLUS
       static
@@ -1101,36 +920,6 @@ switch (yykind)
         return symbol_type (token::TOKEN_END, l);
       }
 #endif
-#if 201103L <= YY_CPLUSPLUS
-      static
-      symbol_type
-      make_EVALerror (location_type l)
-      {
-        return symbol_type (token::TOKEN_EVALerror, std::move (l));
-      }
-#else
-      static
-      symbol_type
-      make_EVALerror (const location_type& l)
-      {
-        return symbol_type (token::TOKEN_EVALerror, l);
-      }
-#endif
-#if 201103L <= YY_CPLUSPLUS
-      static
-      symbol_type
-      make_EVALUNDEF (location_type l)
-      {
-        return symbol_type (token::TOKEN_EVALUNDEF, std::move (l));
-      }
-#else
-      static
-      symbol_type
-      make_EVALUNDEF (const location_type& l)
-      {
-        return symbol_type (token::TOKEN_EVALUNDEF, l);
-      }
-#endif
 #if 201103L <= YY_CPLUSPLUS
       static
       symbol_type
@@ -1659,46 +1448,46 @@ switch (yykind)
 #if 201103L <= YY_CPLUSPLUS
       static
       symbol_type
-      make_PLUS (location_type l)
+      make_IFELSE (location_type l)
       {
-        return symbol_type (token::TOKEN_PLUS, std::move (l));
+        return symbol_type (token::TOKEN_IFELSE, std::move (l));
       }
 #else
       static
       symbol_type
-      make_PLUS (const location_type& l)
+      make_IFELSE (const location_type& l)
       {
-        return symbol_type (token::TOKEN_PLUS, l);
+        return symbol_type (token::TOKEN_IFELSE, l);
       }
 #endif
 #if 201103L <= YY_CPLUSPLUS
       static
       symbol_type
-      make_IFELSE (location_type l)
+      make_TOHEXSTRING (location_type l)
       {
-        return symbol_type (token::TOKEN_IFELSE, std::move (l));
+        return symbol_type (token::TOKEN_TOHEXSTRING, std::move (l));
       }
 #else
       static
       symbol_type
-      make_IFELSE (const location_type& l)
+      make_TOHEXSTRING (const location_type& l)
       {
-        return symbol_type (token::TOKEN_IFELSE, l);
+        return symbol_type (token::TOKEN_TOHEXSTRING, l);
       }
 #endif
 #if 201103L <= YY_CPLUSPLUS
       static
       symbol_type
-      make_TOHEXSTRING (location_type l)
+      make_ADDRTOTEXT (location_type l)
       {
-        return symbol_type (token::TOKEN_TOHEXSTRING, std::move (l));
+        return symbol_type (token::TOKEN_ADDRTOTEXT, std::move (l));
       }
 #else
       static
       symbol_type
-      make_TOHEXSTRING (const location_type& l)
+      make_ADDRTOTEXT (const location_type& l)
       {
-        return symbol_type (token::TOKEN_TOHEXSTRING, l);
+        return symbol_type (token::TOKEN_ADDRTOTEXT, l);
       }
 #endif
 #if 201103L <= YY_CPLUSPLUS
@@ -1928,43 +1717,20 @@ switch (yykind)
 #endif
 
 
-    class context
-    {
-    public:
-      context (const EvalParser& yyparser, const symbol_type& yyla);
-      const symbol_type& lookahead () const YY_NOEXCEPT { return yyla_; }
-      symbol_kind_type token () const YY_NOEXCEPT { return yyla_.kind (); }
-      const location_type& location () const YY_NOEXCEPT { return yyla_.location; }
-
-      /// Put in YYARG at most YYARGN of the expected tokens, and return the
-      /// number of tokens stored in YYARG.  If YYARG is null, return the
-      /// number of expected tokens (guaranteed to be less than YYNTOKENS).
-      int expected_tokens (symbol_kind_type yyarg[], int yyargn) const;
-
-    private:
-      const EvalParser& yyparser_;
-      const symbol_type& yyla_;
-    };
-
   private:
-#if YY_CPLUSPLUS < 201103L
-    /// Non copyable.
+    /// This class is not copyable.
     EvalParser (const EvalParser&);
-    /// Non copyable.
     EvalParser& operator= (const EvalParser&);
-#endif
-
 
     /// Stored state numbers (used for stacks).
     typedef unsigned char state_type;
 
-    /// The arguments of the error message.
-    int yy_syntax_error_arguments_ (const context& yyctx,
-                                    symbol_kind_type yyarg[], int yyargn) const;
-
     /// Generate an error message.
-    /// \param yyctx     the context in which the error occurred.
-    virtual std::string yysyntax_error_ (const context& yyctx) const;
+    /// \param yystate   the state where the error occurred.
+    /// \param yyla      the lookahead token.
+    virtual std::string yysyntax_error_ (state_type yystate,
+                                         const symbol_type& yyla) const;
+
     /// Compute post-reduction state.
     /// \param yystate   the current state
     /// \param yysym     the nonterminal to push on the stack
@@ -1981,17 +1747,10 @@ switch (yykind)
     static const signed char yypact_ninf_;
     static const signed char yytable_ninf_;
 
-    /// Convert a scanner token kind \a t to a symbol kind.
-    /// In theory \a t should be a token_kind_type, but character literals
+    /// Convert a scanner token number \a t to a symbol number.
+    /// In theory \a t should be a token_type, but character literals
     /// are valid, yet not members of the token_type enum.
-    static symbol_kind_type yytranslate_ (int t);
-
-    /// Convert the symbol name \a n to a form suitable for a diagnostic.
-    static std::string yytnamerr_ (const char *yystr);
-
-    /// For a symbol, its name in clear.
-    static const char* const yytname_[];
-
+    static token_number_type yytranslate_ (int t);
 
     // Tables.
     // YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
@@ -2007,7 +1766,7 @@ switch (yykind)
     static const short yypgoto_[];
 
     // YYDEFGOTO[NTERM-NUM].
-    static const unsigned char yydefgoto_[];
+    static const short yydefgoto_[];
 
     // YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM.  If
     // positive, shift that token.  If negative, reduce the rule whose
@@ -2027,20 +1786,26 @@ switch (yykind)
     static const signed char yyr2_[];
 
 
+    /// Convert the symbol name \a n to a form suitable for a diagnostic.
+    static std::string yytnamerr_ (const char *n);
+
+
+    /// For a symbol, its name in clear.
+    static const char* const yytname_[];
 #if EVALDEBUG
     // YYRLINE[YYN] -- Source line where rule number YYN was defined.
     static const short yyrline_[];
     /// Report on the debug stream that the rule \a r is going to be reduced.
-    virtual void yy_reduce_print_ (int r) const;
+    virtual void yy_reduce_print_ (int r);
     /// Print the state stack on the debug stream.
-    virtual void yy_stack_print_ () const;
+    virtual void yystack_print_ ();
 
     /// Debugging level.
     int yydebug_;
     /// Debug stream.
     std::ostream* yycdebug_;
 
-    /// \brief Display a symbol kind, value and location.
+    /// \brief Display a symbol type, value and location.
     /// \param yyo    The output stream.
     /// \param yysym  The symbol.
     template <typename Base>
@@ -2061,7 +1826,7 @@ switch (yykind)
       /// Default constructor.
       by_state () YY_NOEXCEPT;
 
-      /// The symbol kind as needed by the constructor.
+      /// The symbol type as needed by the constructor.
       typedef state_type kind_type;
 
       /// Constructor.
@@ -2073,12 +1838,12 @@ switch (yykind)
       /// Record that this symbol is empty.
       void clear () YY_NOEXCEPT;
 
-      /// Steal the symbol kind from \a that.
+      /// Steal the symbol type from \a that.
       void move (by_state& that);
 
-      /// The symbol kind (corresponding to \a state).
-      /// \a symbol_kind::S_YYEMPTY when empty.
-      symbol_kind_type kind () const YY_NOEXCEPT;
+      /// The (internal) type number (corresponding to \a state).
+      /// \a empty_symbol when empty.
+      symbol_number_type type_get () const YY_NOEXCEPT;
 
       /// The state number used to denote an empty symbol.
       /// We use the initial state, as it does not have a value.
@@ -2117,8 +1882,8 @@ switch (yykind)
     {
     public:
       // Hide our reversed order.
-      typedef typename S::iterator iterator;
-      typedef typename S::const_iterator const_iterator;
+      typedef typename S::reverse_iterator iterator;
+      typedef typename S::const_reverse_iterator const_iterator;
       typedef typename S::size_type size_type;
       typedef typename std::ptrdiff_t index_type;
 
@@ -2126,13 +1891,6 @@ switch (yykind)
         : seq_ (n)
       {}
 
-#if 201103L <= YY_CPLUSPLUS
-      /// Non copyable.
-      stack (const stack&) = delete;
-      /// Non copyable.
-      stack& operator= (const stack&) = delete;
-#endif
-
       /// Random access.
       ///
       /// Index 0 returns the topmost element.
@@ -2183,18 +1941,24 @@ switch (yykind)
         return index_type (seq_.size ());
       }
 
+      std::ptrdiff_t
+      ssize () const YY_NOEXCEPT
+      {
+        return std::ptrdiff_t (size ());
+      }
+
       /// Iterator on top of the stack (going downwards).
       const_iterator
       begin () const YY_NOEXCEPT
       {
-        return seq_.begin ();
+        return seq_.rbegin ();
       }
 
       /// Bottom of the stack.
       const_iterator
       end () const YY_NOEXCEPT
       {
-        return seq_.end ();
+        return seq_.rend ();
       }
 
       /// Present a slice of the top of a stack.
@@ -2218,12 +1982,8 @@ switch (yykind)
       };
 
     private:
-#if YY_CPLUSPLUS < 201103L
-      /// Non copyable.
       stack (const stack&);
-      /// Non copyable.
       stack& operator= (const stack&);
-#endif
       /// The wrapped container.
       S seq_;
     };
@@ -2253,28 +2013,33 @@ switch (yykind)
     /// Pop \a n symbols from the stack.
     void yypop_ (int n = 1);
 
+    /// Some specific tokens.
+    static const token_number_type yy_error_token_ = 1;
+    static const token_number_type yy_undef_token_ = 2;
+
     /// Constants.
     enum
     {
-      yylast_ = 233,     ///< Last index in yytable_.
+      yyeof_ = 0,
+      yylast_ = 230,     ///< Last index in yytable_.
       yynnts_ = 17,  ///< Number of nonterminal symbols.
-      yyfinal_ = 34 ///< Termination state number.
+      yyfinal_ = 34, ///< Termination state number.
+      yyntokens_ = 56  ///< Number of tokens.
     };
 
 
     // User arguments.
     EvalContext& ctx;
-
   };
 
   inline
-  EvalParser::symbol_kind_type
+  EvalParser::token_number_type
   EvalParser::yytranslate_ (int t)
   {
     // YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to
     // TOKEN-NUM as returned by yylex.
     static
-    const signed char
+    const token_number_type
     translate_table[] =
     {
        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -2310,65 +2075,122 @@ switch (yykind)
       45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
       55
     };
-    // Last valid token kind.
-    const int code_max = 310;
+    const int user_token_number_max_ = 310;
 
     if (t <= 0)
-      return symbol_kind::S_YYEOF;
-    else if (t <= code_max)
-      return YY_CAST (symbol_kind_type, translate_table[t]);
+      return yyeof_;
+    else if (t <= user_token_number_max_)
+      return translate_table[t];
     else
-      return symbol_kind::S_YYUNDEF;
+      return yy_undef_token_;
   }
 
   // basic_symbol.
+#if 201103L <= YY_CPLUSPLUS
+  template <typename Base>
+  EvalParser::basic_symbol<Base>::basic_symbol (basic_symbol&& that)
+    : Base (std::move (that))
+    , value ()
+    , location (std::move (that.location))
+  {
+    switch (this->type_get ())
+    {
+      case 64: // option_repr_type
+        value.move< TokenOption::RepresentationType > (std::move (that.value));
+        break;
+
+      case 68: // pkt4_field
+        value.move< TokenPkt4::FieldType > (std::move (that.value));
+        break;
+
+      case 69: // pkt6_field
+        value.move< TokenPkt6::FieldType > (std::move (that.value));
+        break;
+
+      case 66: // pkt_metadata
+        value.move< TokenPkt::MetadataType > (std::move (that.value));
+        break;
+
+      case 70: // relay6_field
+        value.move< TokenRelay6Field::FieldType > (std::move (that.value));
+        break;
+
+      case 65: // nest_level
+        value.move< int8_t > (std::move (that.value));
+        break;
+
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
+        value.move< std::string > (std::move (that.value));
+        break;
+
+      case 62: // option_code
+      case 63: // sub_option_code
+        value.move< uint16_t > (std::move (that.value));
+        break;
+
+      case 61: // integer_expr
+      case 67: // enterprise_id
+        value.move< uint32_t > (std::move (that.value));
+        break;
+
+      default:
+        break;
+    }
+
+  }
+#endif
+
   template <typename Base>
   EvalParser::basic_symbol<Base>::basic_symbol (const basic_symbol& that)
     : Base (that)
     , value ()
     , location (that.location)
   {
-    switch (this->kind ())
+    switch (this->type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.copy< TokenOption::RepresentationType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.copy< TokenPkt4::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.copy< TokenPkt6::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.copy< TokenPkt::MetadataType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.copy< TokenRelay6Field::FieldType > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.copy< int8_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.copy< std::string > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.copy< uint16_t > (YY_MOVE (that.value));
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.copy< uint32_t > (YY_MOVE (that.value));
         break;
 
@@ -2380,18 +2202,11 @@ switch (yykind)
 
 
 
-  template <typename Base>
-  EvalParser::symbol_kind_type
-  EvalParser::basic_symbol<Base>::type_get () const YY_NOEXCEPT
-  {
-    return this->kind ();
-  }
-
   template <typename Base>
   bool
   EvalParser::basic_symbol<Base>::empty () const YY_NOEXCEPT
   {
-    return this->kind () == symbol_kind::S_YYEMPTY;
+    return Base::type_get () == empty_symbol;
   }
 
   template <typename Base>
@@ -2399,47 +2214,47 @@ switch (yykind)
   EvalParser::basic_symbol<Base>::move (basic_symbol& s)
   {
     super_type::move (s);
-    switch (this->kind ())
+    switch (this->type_get ())
     {
-      case symbol_kind::S_option_repr_type: // option_repr_type
+      case 64: // option_repr_type
         value.move< TokenOption::RepresentationType > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_pkt4_field: // pkt4_field
+      case 68: // pkt4_field
         value.move< TokenPkt4::FieldType > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_pkt6_field: // pkt6_field
+      case 69: // pkt6_field
         value.move< TokenPkt6::FieldType > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_pkt_metadata: // pkt_metadata
+      case 66: // pkt_metadata
         value.move< TokenPkt::MetadataType > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_relay6_field: // relay6_field
+      case 70: // relay6_field
         value.move< TokenRelay6Field::FieldType > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_nest_level: // nest_level
+      case 65: // nest_level
         value.move< int8_t > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_STRING: // "constant string"
-      case symbol_kind::S_INTEGER: // "integer"
-      case symbol_kind::S_HEXSTRING: // "constant hexstring"
-      case symbol_kind::S_OPTION_NAME: // "option name"
-      case symbol_kind::S_IP_ADDRESS: // "ip address"
+      case 51: // "constant string"
+      case 52: // "integer"
+      case 53: // "constant hexstring"
+      case 54: // "option name"
+      case 55: // "ip address"
         value.move< std::string > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_option_code: // option_code
-      case symbol_kind::S_sub_option_code: // sub_option_code
+      case 62: // option_code
+      case 63: // sub_option_code
         value.move< uint16_t > (YY_MOVE (s.value));
         break;
 
-      case symbol_kind::S_integer_expr: // integer_expr
-      case symbol_kind::S_enterprise_id: // enterprise_id
+      case 61: // integer_expr
+      case 67: // enterprise_id
         value.move< uint32_t > (YY_MOVE (s.value));
         break;
 
@@ -2450,63 +2265,57 @@ switch (yykind)
     location = YY_MOVE (s.location);
   }
 
-  // by_kind.
+  // by_type.
   inline
-  EvalParser::by_kind::by_kind ()
-    : kind_ (symbol_kind::S_YYEMPTY)
+  EvalParser::by_type::by_type ()
+    : type (empty_symbol)
   {}
 
 #if 201103L <= YY_CPLUSPLUS
   inline
-  EvalParser::by_kind::by_kind (by_kind&& that)
-    : kind_ (that.kind_)
+  EvalParser::by_type::by_type (by_type&& that)
+    : type (that.type)
   {
     that.clear ();
   }
 #endif
 
   inline
-  EvalParser::by_kind::by_kind (const by_kind& that)
-    : kind_ (that.kind_)
+  EvalParser::by_type::by_type (const by_type& that)
+    : type (that.type)
   {}
 
   inline
-  EvalParser::by_kind::by_kind (token_kind_type t)
-    : kind_ (yytranslate_ (t))
+  EvalParser::by_type::by_type (token_type t)
+    : type (yytranslate_ (t))
   {}
 
   inline
   void
-  EvalParser::by_kind::clear () YY_NOEXCEPT
+  EvalParser::by_type::clear ()
   {
-    kind_ = symbol_kind::S_YYEMPTY;
+    type = empty_symbol;
   }
 
   inline
   void
-  EvalParser::by_kind::move (by_kind& that)
+  EvalParser::by_type::move (by_type& that)
   {
-    kind_ = that.kind_;
+    type = that.type;
     that.clear ();
   }
 
   inline
-  EvalParser::symbol_kind_type
-  EvalParser::by_kind::kind () const YY_NOEXCEPT
-  {
-    return kind_;
-  }
-
-  inline
-  EvalParser::symbol_kind_type
-  EvalParser::by_kind::type_get () const YY_NOEXCEPT
+  int
+  EvalParser::by_type::type_get () const YY_NOEXCEPT
   {
-    return this->kind ();
+    return type;
   }
 
 #line 14 "parser.yy"
 } } // isc::eval
-#line 2510 "parser.h"
+#line 2318 "parser.h"
+
 
 
 
index c8314aa5f8dd66e3bd4acc454a0abcedcb5caea4..c213f69c0edce9cb881d207cc262c0e54381c67c 100644 (file)
@@ -76,6 +76,7 @@ using namespace isc::eval;
   PLUS "+"
   IFELSE "ifelse"
   TOHEXSTRING "hexstring"
+  ADDRTOTEXT "addrtotext"
   PKT6 "pkt6"
   MSGTYPE "msgtype"
   TRANSID "transid"
@@ -373,6 +374,11 @@ string_expr : STRING
                       TokenPtr tohex(new TokenToHexString());
                       ctx.expression.push_back(tohex);
                   }
+            | ADDRTOTEXT "(" string_expr ")"
+                  {
+                      TokenPtr addrtotext(new TokenIpAddressToText());
+                      ctx.expression.push_back(addrtotext);
+                  }
             | VENDOR "." ENTERPRISE
                 {
                     // expression: vendor.enterprise
index c9fae75ddab3d3d973038049b19661797324c633..bf34c1c57a7058bedf941ae0a2fbe6dba4f3fd5c 100644 (file)
@@ -1,5 +1,4 @@
-// Generated 202104290830
-// A Bison parser, made by GNU Bison 3.7.6.
+// A Bison parser, made by GNU Bison 3.5.1.
 
 // Starting with Bison 3.2, this file is useless: the structure it
 // used to define is now defined in "location.hh".
index 8d128588a04e2cb1a44e597c1e7190735b08ea09..c15d84c73d52103bcdd2740f5086405ad6039b3c 100644 (file)
@@ -1,5 +1,4 @@
-// Generated 202104290830
-// A Bison parser, made by GNU Bison 3.7.6.
+// A Bison parser, made by GNU Bison 3.5.1.
 
 // Starting with Bison 3.2, this file is useless: the structure it
 // used to define is now defined with the parser itself.
index 15ceed41dc7e0712ab80ed398803e12d747e035b..d4d5e1e0e49bbbfff714ba09a250c5980484bf38 100644 (file)
@@ -470,6 +470,28 @@ public:
         EXPECT_TRUE(tohex);
     }
 
+    /// @brief checks if the given token is a addrtotext operator
+    void checkTokenIpAddressToText(const TokenPtr& token,
+                                   const std::string& expected) {
+        ASSERT_TRUE(token);
+        boost::shared_ptr<TokenIpAddressToText> addrtotext =
+            boost::dynamic_pointer_cast<TokenIpAddressToText>(token);
+        EXPECT_TRUE(addrtotext);
+
+        Pkt4Ptr pkt4(new Pkt4(DHCPDISCOVER, 12345));
+        ValueStack values;
+
+        std::vector<uint8_t> bytes = IOAddress(expected).toBytes();
+        values.push(std::string(bytes.begin(), bytes.end()));
+
+        EXPECT_NO_THROW(token->evaluate(*pkt4, values));
+
+        ASSERT_EQ(1, values.size());
+        string value = values.top();
+
+        EXPECT_EQ(value, expected);
+    }
+
     /// @brief checks if the given expression raises the expected message
     /// when it is parsed.
     void checkError(const string& expr, const string& msg) {
@@ -1455,6 +1477,41 @@ TEST_F(EvalContextTest, toHexString) {
     checkTokenToHexString(tmp3);
 }
 
+// Test the parsing of a addrtotext expression
+TEST_F(EvalContextTest, addressToText) {
+    EvalContext eval(Option::V6);
+
+    EXPECT_NO_THROW(parsed_ = eval.parseString("addrtotext(10.0.0.1) == '10.0.0.1'"));
+    EXPECT_TRUE(parsed_);
+
+    ASSERT_EQ(4, eval.expression.size());
+
+    TokenPtr tmp1 = eval.expression.at(0);
+    TokenPtr tmp2 = eval.expression.at(1);
+    TokenPtr tmp3 = eval.expression.at(2);
+    TokenPtr tmp4 = eval.expression.at(3);
+
+    checkTokenIpAddress(tmp1, "10.0.0.1");
+    checkTokenIpAddressToText(tmp2, "10.0.0.1");
+    checkTokenString(tmp3, "10.0.0.1");
+    checkTokenEq(tmp4);
+
+    EXPECT_NO_THROW(parsed_ = eval.parseString("addrtotext(2001:db8::1) == '2001:db8::1'"));
+    EXPECT_TRUE(parsed_);
+
+    ASSERT_EQ(4, eval.expression.size());
+
+    tmp1 = eval.expression.at(0);
+    tmp2 = eval.expression.at(1);
+    tmp3 = eval.expression.at(2);
+    tmp4 = eval.expression.at(3);
+
+    checkTokenIpAddress(tmp1, "2001:db8::1");
+    checkTokenIpAddressToText(tmp2, "2001:db8::1");
+    checkTokenString(tmp3, "2001:db8::1");
+    checkTokenEq(tmp4);
+}
+
 //
 // Test some scanner error cases
 TEST_F(EvalContextTest, scanErrors) {
@@ -1627,6 +1684,10 @@ TEST_F(EvalContextTest, parseErrors) {
     checkError("'a' + == 'a'", "<string>:1.7-8: syntax error, unexpected ==");
     checkError("'a' ++ 'b' == 'ab'",
                "<string>:1.6: syntax error, unexpected +");
+    checkError("addrtotext('cafebabecafebabe')",
+               "<string>:1.31: syntax error, unexpected end of file, expecting ==");
+    checkError("addrtotext('')",
+               "<string>:1.15: syntax error, unexpected end of file, expecting ==");
 }
 
 // Tests some type error cases
@@ -1659,6 +1720,7 @@ TEST_F(EvalContextTest, typeErrors) {
     checkError("'true' or 'false'",
                "<string>:1.8-9: syntax error, unexpected or, "
                "expecting == or +");
+
     // Ifelse requires a boolean condition and string branches.
     checkError("ifelse('foobar','foo','bar')",
                "<string>:1.16: syntax error, unexpected \",\", "
@@ -1677,6 +1739,10 @@ TEST_F(EvalContextTest, typeErrors) {
     checkError("option[123].option[host-name].exists",
                "<string>:1.20-28: syntax error, unexpected option name, "
                "expecting integer");
+
+    // Addrtotext requires string storing the binary representation of the address.
+    checkError("addrtotext('192.100.1.1')",
+               "<string>:1.26: syntax error, unexpected end of file, expecting ==");
 }
 
 
index 041468c05c784b9630aa748e1c324ae0e9376d80..3a57c8f1d9f2b6e945ee7db363ea5deb63a53ed1 100644 (file)
@@ -758,6 +758,60 @@ TEST_F(TokenTest, ipaddress) {
     EXPECT_TRUE(checkFile());
 }
 
+// This test checks that a TokenIpAddressToText, representing an IP address as
+// a string, can be used in Pkt4/Pkt6 evaluation.
+// (The actual packet is not used)
+TEST_F(TokenTest, addressToText) {
+    TokenPtr address((new TokenIpAddressToText()));
+    std::vector<uint8_t> bytes;
+
+    std::string value;
+    values_.push(value);
+
+    // Invalid data size fails.
+    EXPECT_THROW(address->evaluate(*pkt4_, values_), EvalTypeError);
+
+    value = "10.0.0.1";
+    values_.push(value);
+
+    // Invalid data size fails.
+    EXPECT_THROW(address->evaluate(*pkt4_, values_), EvalTypeError);
+
+    bytes = IOAddress(value).toBytes();
+    values_.push(std::string(bytes.begin(), bytes.end()));
+
+    EXPECT_NO_THROW(address->evaluate(*pkt4_, values_));
+
+    // Check that the evaluation put its value on the values stack.
+    ASSERT_EQ(1, values_.size());
+
+    value = "2001:db8::1";
+    bytes = IOAddress(value).toBytes();
+    values_.push(std::string(bytes.begin(), bytes.end()));
+
+    EXPECT_NO_THROW(address->evaluate(*pkt4_, values_));
+
+    // Check that the evaluation put its value on the values stack.
+    ASSERT_EQ(2, values_.size());
+
+    // Check IPv6 address
+    EXPECT_EQ(11, values_.top().size());
+    EXPECT_EQ("2001:db8::1", values_.top());
+    values_.pop();
+
+    // Check IPv4 address
+    EXPECT_EQ(8, values_.top().size());
+    EXPECT_EQ("10.0.0.1", values_.top());
+    values_.pop();
+
+    // Check that the debug output was correct.  Add the strings
+    // to the test vector in the class and then call checkFile
+    // for comparison
+    addString("EVAL_DEBUG_IPADDRESSTOTEXT Pushing IPAddress 10.0.0.1");
+    addString("EVAL_DEBUG_IPADDRESSTOTEXT Pushing IPAddress 2001:db8::1");
+    EXPECT_TRUE(checkFile());
+}
+
 // This test checks if a token representing an option value is able to extract
 // the option from an IPv4 packet and properly store the option's value.
 TEST_F(TokenTest, optionString4) {
index ab42ac0dfe1ef3c077714d4d609e896754fb5a6d..cc131e57f15de140fd9a9db30b44d4cb6410bb1d 100644 (file)
@@ -103,6 +103,36 @@ TokenIpAddress::evaluate(Pkt& /*pkt*/, ValueStack& values) {
         .arg(toHex(value_));
 }
 
+void
+TokenIpAddressToText::evaluate(Pkt& /*pkt*/, ValueStack& values) {
+    if (values.size() == 0) {
+        isc_throw(EvalBadStack, "Incorrect empty stack.");
+    }
+
+    string op = values.top();
+    values.pop();
+
+    uint8_t size = op.size();
+
+    if ((size != sizeof(uint32_t)) && (size != INET_ADDRSTRLEN)) {
+        isc_throw(EvalTypeError, "Can not convert to valid address.");
+    }
+
+    std::vector<uint8_t> binary(op.begin(), op.end());
+
+    if (size == sizeof(uint32_t)) {
+        op = asiolink::IOAddress::fromBytes(AF_INET, binary.data()).toText();
+    } else {
+        op = asiolink::IOAddress::fromBytes(AF_INET6, binary.data()).toText();
+    }
+
+    values.push(op);
+
+    // Log what we pushed
+    LOG_DEBUG(eval_logger, EVAL_DBG_STACK, EVAL_DEBUG_IPADDRESSTOTEXT)
+        .arg(op);
+}
+
 OptionPtr
 TokenOption::getOption(Pkt& pkt) {
     return (pkt.getOption(option_code_));
index 05cdb646e2b6ed490e67c42902b96ac516eba019..b6e61152b8d0d625db9f570dabd17fd40b5e8115 100644 (file)
@@ -207,6 +207,23 @@ protected:
     std::string value_;
 };
 
+/// @brief Token representing an IP address as a string
+///
+/// This token holds the value of an IP address as a string, for instance
+/// 10.0.0.1 is '10.0.0.1'
+class TokenIpAddressToText : public Token {
+public:
+    /// @brief Constructor (does nothing)
+    TokenIpAddressToText() {}
+
+    /// @brief Token evaluation (puts value of the string on the stack after
+    /// decoding)
+    ///
+    /// @param pkt (ignored)
+    /// @param values (represented IP address as a string will be pushed here)
+    void evaluate(Pkt& pkt, ValueStack& values);
+};
+
 /// @brief Token that represents a value of an option
 ///
 /// This represents a reference to a given option, e.g. in the expression