2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-30 13:37:55 +00:00

[4231] Added not operator

This commit is contained in:
Francis Dupont
2015-12-09 14:27:37 +01:00
parent ce332093aa
commit a557a43b39
9 changed files with 368 additions and 245 deletions

View File

@@ -469,8 +469,8 @@ static void yy_fatal_error (yyconst char msg[] );
(yy_c_buf_p) = yy_cp;
/* %% [4.0] data tables for the DFA and the user's section 1 definitions go here */
#define YY_NUM_RULES 20
#define YY_END_OF_BUFFER 21
#define YY_NUM_RULES 21
#define YY_END_OF_BUFFER 22
/* This struct is not used in this scanner,
but its presence is necessary. */
struct yy_trans_info
@@ -478,27 +478,29 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
static yyconst flex_int16_t yy_acclist[90] =
static yyconst flex_int16_t yy_acclist[96] =
{ 0,
21, 19, 20, 1, 19, 20, 2, 20, 19, 20,
14, 19, 20, 15, 19, 20, 18, 19, 20, 19,
20, 13, 19, 20, 5, 19, 20, 5, 19, 20,
19, 20, 19, 20,16390, 16, 19, 20, 17, 19,
20, 19, 20,16390, 19, 20,16390, 19, 20,16390,
19, 20,16390, 19, 20,16390, 1, 2, 3, 5,
7,16390, 8198,16390,16390,16390,16390,16390, 4, 12,
16390, 10,16390,16390,16390,16390,16390,16390, 9,16390,
16390,16390, 8,16390,16390,16390,16390, 11,16390
22, 20, 21, 1, 20, 21, 2, 21, 20, 21,
15, 20, 21, 16, 20, 21, 19, 20, 21, 20,
21, 14, 20, 21, 5, 20, 21, 5, 20, 21,
20, 21, 20, 21,16390, 17, 20, 21, 18, 20,
21, 20, 21,16390, 20, 21,16390, 20, 21,16390,
20, 21,16390, 20, 21,16390, 20, 21,16390, 1,
2, 3, 5, 7,16390, 8198,16390,16390,16390,16390,
16390,16390, 4, 13,16390, 10,16390, 12,16390,16390,
16390,16390,16390,16390, 9,16390,16390,16390, 8,16390,
16390,16390,16390, 11,16390
} ;
static yyconst flex_int16_t yy_accept[58] =
static yyconst flex_int16_t yy_accept[61] =
{ 0,
1, 1, 1, 2, 4, 7, 9, 11, 14, 17,
20, 22, 25, 28, 31, 33, 36, 39, 42, 45,
48, 51, 54, 57, 58, 59, 59, 60, 61, 61,
62, 62, 62, 63, 64, 65, 66, 67, 68, 69,
70, 72, 74, 75, 76, 77, 78, 79, 81, 82,
83, 85, 86, 87, 88, 90, 90
48, 51, 54, 57, 60, 61, 62, 62, 63, 64,
64, 65, 65, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 76, 78, 80, 81, 82, 83, 84,
85, 87, 88, 89, 91, 92, 93, 94, 96, 96
} ;
static yyconst flex_int32_t yy_ec[256] =
@@ -541,81 +543,83 @@ static yyconst flex_int32_t yy_meta[34] =
2, 2, 2
} ;
static yyconst flex_int16_t yy_base[60] =
static yyconst flex_int16_t yy_base[63] =
{ 0,
0, 0, 119, 120, 116, 114, 112, 120, 120, 120,
24, 120, 26, 28, 103, 58, 120, 120, 75, 19,
17, 18, 26, 112, 110, 108, 120, 38, 0, 120,
50, 54, 86, 120, 85, 21, 33, 43, 37, 0,
80, 76, 48, 44, 55, 57, 56, 66, 63, 65,
60, 71, 72, 77, 40, 120, 102, 105, 51
0, 0, 124, 125, 121, 119, 117, 125, 125, 125,
24, 125, 26, 28, 108, 58, 125, 125, 75, 19,
18, 21, 22, 27, 117, 115, 113, 125, 40, 0,
125, 53, 55, 91, 125, 86, 38, 37, 42, 44,
49, 0, 82, 81, 74, 60, 56, 63, 62, 65,
54, 72, 66, 40, 77, 78, 83, 28, 125, 108,
111, 38
} ;
static yyconst flex_int16_t yy_def[60] =
static yyconst flex_int16_t yy_def[63] =
{ 0,
56, 1, 56, 56, 56, 56, 57, 56, 56, 56,
56, 56, 56, 56, 56, 58, 56, 56, 58, 19,
19, 19, 19, 56, 56, 57, 56, 56, 59, 56,
56, 19, 19, 56, 19, 19, 19, 19, 19, 59,
19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 0, 56, 56, 56
59, 1, 59, 59, 59, 59, 60, 59, 59, 59,
59, 59, 59, 59, 59, 61, 59, 59, 61, 19,
19, 19, 19, 19, 59, 59, 60, 59, 59, 62,
59, 59, 19, 19, 59, 19, 19, 19, 19, 19,
19, 62, 19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19, 0, 59,
59, 59
} ;
static yyconst flex_int16_t yy_nxt[154] =
static yyconst flex_int16_t yy_nxt[159] =
{ 0,
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
14, 15, 16, 16, 16, 17, 18, 4, 19, 16,
16, 16, 20, 16, 16, 16, 21, 16, 16, 22,
23, 16, 16, 28, 28, 28, 28, 28, 28, 36,
29, 33, 33, 33, 37, 33, 39, 28, 28, 38,
33, 31, 31, 42, 40, 56, 56, 33, 29, 31,
31, 33, 44, 43, 33, 32, 34, 33, 33, 45,
56, 46, 33, 47, 34, 32, 31, 31, 33, 33,
33, 33, 32, 49, 33, 48, 50, 33, 51, 33,
33, 34, 32, 52, 53, 33, 33, 54, 55, 35,
16, 16, 20, 16, 16, 21, 22, 16, 16, 23,
24, 16, 16, 29, 29, 29, 29, 29, 29, 37,
30, 42, 34, 34, 38, 34, 34, 41, 39, 29,
29, 34, 34, 40, 32, 32, 59, 59, 30, 32,
32, 34, 34, 47, 34, 33, 34, 45, 34, 35,
44, 59, 46, 34, 35, 33, 32, 32, 34, 34,
34, 48, 33, 49, 34, 50, 34, 34, 52, 34,
34, 35, 33, 51, 55, 53, 34, 54, 34, 36,
33, 33, 26, 26, 33, 26, 33, 33, 33, 41,
33, 27, 25, 24, 30, 27, 25, 24, 56, 3,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56
56, 34, 34, 57, 58, 34, 34, 34, 27, 27,
43, 27, 34, 34, 34, 34, 28, 26, 25, 31,
28, 26, 25, 59, 3, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59
} ;
static yyconst flex_int16_t yy_chk[154] =
static yyconst flex_int16_t yy_chk[159] =
{ 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, 11, 11, 13, 13, 14, 14, 20,
13, 21, 22, 20, 21, 36, 23, 28, 28, 22,
23, 31, 31, 36, 59, 32, 32, 37, 13, 16,
16, 39, 38, 37, 55, 16, 31, 38, 44, 39,
32, 43, 43, 44, 16, 16, 19, 19, 32, 45,
47, 46, 19, 46, 51, 45, 47, 49, 49, 50,
48, 19, 19, 50, 52, 52, 53, 53, 54, 19,
13, 62, 21, 20, 21, 22, 23, 24, 22, 29,
29, 24, 58, 23, 32, 32, 33, 33, 13, 16,
16, 38, 37, 40, 54, 16, 39, 38, 40, 32,
37, 33, 39, 41, 16, 16, 19, 19, 51, 33,
47, 41, 19, 46, 46, 47, 49, 48, 49, 50,
53, 19, 19, 48, 53, 50, 52, 52, 45, 19,
42, 54, 57, 57, 41, 57, 58, 58, 58, 35,
33, 26, 25, 24, 15, 7, 6, 5, 3, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56
55, 55, 56, 56, 57, 44, 43, 57, 60, 60,
36, 60, 61, 61, 61, 34, 27, 26, 25, 15,
7, 6, 5, 3, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59, 59, 59,
59, 59, 59, 59, 59, 59, 59, 59
} ;
/* Table of booleans, true if rule could match eol. */
static yyconst flex_int32_t yy_rule_can_match_eol[21] =
static yyconst flex_int32_t yy_rule_can_match_eol[22] =
{ 0,
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, };
0, 0, };
extern int yy_flex_debug;
int yy_flex_debug = 1;
static yyconst flex_int16_t yy_rule_linenum[20] =
static yyconst flex_int16_t yy_rule_linenum[21] =
{ 0,
86, 90, 96, 106, 112, 126, 133, 134, 135, 136,
137, 138, 139, 140, 141, 142, 143, 144, 146
137, 138, 139, 140, 141, 142, 143, 144, 145, 147
} ;
static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;
@@ -700,7 +704,7 @@ static isc::eval::location loc;
// by moving it ahead by yyleng bytes. yyleng specifies the length of the
// currently matched token.
#define YY_USER_ACTION loc.columns(yyleng);
#line 704 "lexer.cc"
#line 708 "lexer.cc"
#define INITIAL 0
@@ -989,7 +993,7 @@ YY_DECL
loc.step();
#line 993 "lexer.cc"
#line 997 "lexer.cc"
while ( 1 ) /* loops until end-of-file is reached */
{
@@ -1017,14 +1021,14 @@ 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 >= 57 )
if ( yy_current_state >= 60 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
*(yy_state_ptr)++ = yy_current_state;
++yy_cp;
}
while ( yy_current_state != 56 );
while ( yy_current_state != 59 );
yy_find_action:
/* %% [10.0] code to find the action number goes here */
@@ -1087,13 +1091,13 @@ do_action: /* This label is used only to access EOF actions. */
{
if ( yy_act == 0 )
fprintf( stderr, "--scanner backing up\n" );
else if ( yy_act < 20 )
else if ( yy_act < 21 )
fprintf( stderr, "--accepting rule at line %ld (\"%s\")\n",
(long)yy_rule_linenum[yy_act], yytext );
else if ( yy_act == 20 )
else if ( yy_act == 21 )
fprintf( stderr, "--accepting default rule (\"%s\")\n",
yytext );
else if ( yy_act == 21 )
else if ( yy_act == 22 )
fprintf( stderr, "--(end of buffer or a NUL)\n" );
else
fprintf( stderr, "--EOF (start condition %d)\n", YY_START );
@@ -1198,53 +1202,58 @@ return isc::eval::EvalParser::make_SUBSTRING(loc);
case 12:
YY_RULE_SETUP
#line 138 "lexer.ll"
return isc::eval::EvalParser::make_ALL(loc);
return isc::eval::EvalParser::make_NOT(loc);
YY_BREAK
case 13:
YY_RULE_SETUP
#line 139 "lexer.ll"
return isc::eval::EvalParser::make_DOT(loc);
return isc::eval::EvalParser::make_ALL(loc);
YY_BREAK
case 14:
YY_RULE_SETUP
#line 140 "lexer.ll"
return isc::eval::EvalParser::make_LPAREN(loc);
return isc::eval::EvalParser::make_DOT(loc);
YY_BREAK
case 15:
YY_RULE_SETUP
#line 141 "lexer.ll"
return isc::eval::EvalParser::make_RPAREN(loc);
return isc::eval::EvalParser::make_LPAREN(loc);
YY_BREAK
case 16:
YY_RULE_SETUP
#line 142 "lexer.ll"
return isc::eval::EvalParser::make_LBRACKET(loc);
return isc::eval::EvalParser::make_RPAREN(loc);
YY_BREAK
case 17:
YY_RULE_SETUP
#line 143 "lexer.ll"
return isc::eval::EvalParser::make_RBRACKET(loc);
return isc::eval::EvalParser::make_LBRACKET(loc);
YY_BREAK
case 18:
YY_RULE_SETUP
#line 144 "lexer.ll"
return isc::eval::EvalParser::make_COMA(loc);
return isc::eval::EvalParser::make_RBRACKET(loc);
YY_BREAK
case 19:
YY_RULE_SETUP
#line 146 "lexer.ll"
driver.error (loc, "Invalid character: " + std::string(yytext));
YY_BREAK
case YY_STATE_EOF(INITIAL):
#line 147 "lexer.ll"
return isc::eval::EvalParser::make_END(loc);
#line 145 "lexer.ll"
return isc::eval::EvalParser::make_COMA(loc);
YY_BREAK
case 20:
YY_RULE_SETUP
#line 147 "lexer.ll"
driver.error (loc, "Invalid character: " + std::string(yytext));
YY_BREAK
case YY_STATE_EOF(INITIAL):
#line 148 "lexer.ll"
return isc::eval::EvalParser::make_END(loc);
YY_BREAK
case 21:
YY_RULE_SETUP
#line 149 "lexer.ll"
ECHO;
YY_BREAK
#line 1248 "lexer.cc"
#line 1257 "lexer.cc"
case YY_END_OF_BUFFER:
{
@@ -1525,7 +1534,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 >= 57 )
if ( yy_current_state >= 60 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1553,11 +1562,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 >= 57 )
if ( yy_current_state >= 60 )
yy_c = yy_meta[(unsigned int) yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
yy_is_jam = (yy_current_state == 56);
yy_is_jam = (yy_current_state == 59);
if ( ! yy_is_jam )
*(yy_state_ptr)++ = yy_current_state;
@@ -2305,7 +2314,7 @@ void yyfree (void * ptr )
/* %ok-for-header */
#line 148 "lexer.ll"
#line 149 "lexer.ll"

View File

@@ -135,6 +135,7 @@ blank [ \t]
"text" return isc::eval::EvalParser::make_TEXT(loc);
"hex" return isc::eval::EvalParser::make_HEX(loc);
"substring" return isc::eval::EvalParser::make_SUBSTRING(loc);
"not" return isc::eval::EvalParser::make_NOT(loc);
"all" return isc::eval::EvalParser::make_ALL(loc);
"." return isc::eval::EvalParser::make_DOT(loc);
"(" return isc::eval::EvalParser::make_LPAREN(loc);

View File

@@ -251,19 +251,19 @@ namespace isc { namespace eval {
{
switch (that.type_get ())
{
case 25: // option_repr_type
case 26: // option_repr_type
value.move< TokenOption::RepresentationType > (that.value);
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.move< std::string > (that.value);
break;
case 24: // option_code
case 25: // option_code
value.move< uint16_t > (that.value);
break;
@@ -282,19 +282,19 @@ namespace isc { namespace eval {
state = that.state;
switch (that.type_get ())
{
case 25: // option_repr_type
case 26: // option_repr_type
value.copy< TokenOption::RepresentationType > (that.value);
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.copy< std::string > (that.value);
break;
case 24: // option_code
case 25: // option_code
value.copy< uint16_t > (that.value);
break;
@@ -334,51 +334,51 @@ namespace isc { namespace eval {
<< yysym.location << ": ";
switch (yytype)
{
case 15: // "constant string"
case 16: // "constant string"
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< std::string > (); }
#line 342 "parser.cc" // lalr1.cc:636
break;
case 16: // "integer"
case 17: // "integer"
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< std::string > (); }
#line 349 "parser.cc" // lalr1.cc:636
break;
case 17: // "constant hexstring"
case 18: // "constant hexstring"
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< std::string > (); }
#line 356 "parser.cc" // lalr1.cc:636
break;
case 18: // "option name"
case 19: // "option name"
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< std::string > (); }
#line 363 "parser.cc" // lalr1.cc:636
break;
case 19: // TOKEN
case 20: // TOKEN
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< std::string > (); }
#line 370 "parser.cc" // lalr1.cc:636
break;
case 24: // option_code
case 25: // option_code
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< uint16_t > (); }
#line 377 "parser.cc" // lalr1.cc:636
break;
case 25: // option_repr_type
case 26: // option_repr_type
#line 70 "parser.yy" // lalr1.cc:636
#line 71 "parser.yy" // lalr1.cc:636
{ yyoutput << yysym.value.template as< TokenOption::RepresentationType > (); }
#line 384 "parser.cc" // lalr1.cc:636
break;
@@ -580,19 +580,19 @@ namespace isc { namespace eval {
when using variants. */
switch (yyr1_[yyn])
{
case 25: // option_repr_type
case 26: // option_repr_type
yylhs.value.build< TokenOption::RepresentationType > ();
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
yylhs.value.build< std::string > ();
break;
case 24: // option_code
case 25: // option_code
yylhs.value.build< uint16_t > ();
break;
@@ -614,111 +614,120 @@ namespace isc { namespace eval {
switch (yyn)
{
case 4:
#line 84 "parser.yy" // lalr1.cc:859
#line 85 "parser.yy" // lalr1.cc:859
{
TokenPtr eq(new TokenEqual());
ctx.expression.push_back(eq);
TokenPtr neg(new TokenNot());
ctx.expression.push_back(neg);
}
#line 623 "parser.cc" // lalr1.cc:859
break;
case 5:
#line 91 "parser.yy" // lalr1.cc:859
#line 90 "parser.yy" // lalr1.cc:859
{
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
TokenPtr eq(new TokenEqual());
ctx.expression.push_back(eq);
}
#line 632 "parser.cc" // lalr1.cc:859
break;
case 6:
#line 96 "parser.yy" // lalr1.cc:859
#line 97 "parser.yy" // lalr1.cc:859
{
TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(hex);
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
#line 641 "parser.cc" // lalr1.cc:859
break;
case 7:
#line 101 "parser.yy" // lalr1.cc:859
#line 102 "parser.yy" // lalr1.cc:859
{
TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), yystack_[0].value.as< TokenOption::RepresentationType > ()));
ctx.expression.push_back(opt);
TokenPtr hex(new TokenHexString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(hex);
}
#line 650 "parser.cc" // lalr1.cc:859
break;
case 8:
#line 106 "parser.yy" // lalr1.cc:859
#line 107 "parser.yy" // lalr1.cc:859
{
TokenPtr sub(new TokenSubstring());
ctx.expression.push_back(sub);
TokenPtr opt(new TokenOption(yystack_[3].value.as< uint16_t > (), yystack_[0].value.as< TokenOption::RepresentationType > ()));
ctx.expression.push_back(opt);
}
#line 659 "parser.cc" // lalr1.cc:859
break;
case 10:
#line 115 "parser.yy" // lalr1.cc:859
case 9:
#line 112 "parser.yy" // lalr1.cc:859
{
yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location);
}
#line 667 "parser.cc" // lalr1.cc:859
TokenPtr sub(new TokenSubstring());
ctx.expression.push_back(sub);
}
#line 668 "parser.cc" // lalr1.cc:859
break;
case 11:
#line 119 "parser.yy" // lalr1.cc:859
#line 121 "parser.yy" // lalr1.cc:859
{
yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location);
yylhs.value.as< uint16_t > () = ctx.convertOptionCode(yystack_[0].value.as< std::string > (), yystack_[0].location);
}
#line 675 "parser.cc" // lalr1.cc:859
#line 676 "parser.cc" // lalr1.cc:859
break;
case 12:
#line 125 "parser.yy" // lalr1.cc:859
{
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
}
#line 683 "parser.cc" // lalr1.cc:859
yylhs.value.as< uint16_t > () = ctx.convertOptionName(yystack_[0].value.as< std::string > (), yystack_[0].location);
}
#line 684 "parser.cc" // lalr1.cc:859
break;
case 13:
#line 129 "parser.yy" // lalr1.cc:859
#line 131 "parser.yy" // lalr1.cc:859
{
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::TEXTUAL;
}
#line 691 "parser.cc" // lalr1.cc:859
#line 692 "parser.cc" // lalr1.cc:859
break;
case 14:
#line 135 "parser.yy" // lalr1.cc:859
{
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
yylhs.value.as< TokenOption::RepresentationType > () = TokenOption::HEXADECIMAL;
}
#line 700 "parser.cc" // lalr1.cc:859
break;
case 15:
#line 142 "parser.yy" // lalr1.cc:859
#line 141 "parser.yy" // lalr1.cc:859
{
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
#line 709 "parser.cc" // lalr1.cc:859
break;
case 16:
#line 147 "parser.yy" // lalr1.cc:859
#line 148 "parser.yy" // lalr1.cc:859
{
TokenPtr str(new TokenString(yystack_[0].value.as< std::string > ()));
ctx.expression.push_back(str);
}
#line 718 "parser.cc" // lalr1.cc:859
break;
case 17:
#line 153 "parser.yy" // lalr1.cc:859
{
TokenPtr str(new TokenString("all"));
ctx.expression.push_back(str);
}
#line 718 "parser.cc" // lalr1.cc:859
#line 727 "parser.cc" // lalr1.cc:859
break;
#line 722 "parser.cc" // lalr1.cc:859
#line 731 "parser.cc" // lalr1.cc:859
default:
break;
}
@@ -973,79 +982,79 @@ namespace isc { namespace eval {
}
const signed char EvalParser::yypact_ninf_ = -9;
const signed char EvalParser::yypact_ninf_ = -10;
const signed char EvalParser::yytable_ninf_ = -1;
const signed char
EvalParser::yypact_[] =
{
-4, -8, -3, -4, -9, -9, -9, 12, -9, 19,
1, -1, 11, -9, -1, -9, -9, 10, 15, -9,
-9, 17, 13, 14, -9, 18, -9, -9, -9, -6,
-9, -9, 20, -9
-4, -1, 3, -4, -4, -10, -10, -10, 18, -10,
17, -8, 1, -10, 13, -10, 1, -10, -10, 12,
19, -10, -10, 22, 11, 16, -10, 20, -10, -10,
-10, -7, -10, -10, 23, -10
};
const unsigned char
EvalParser::yydefact_[] =
{
0, 0, 0, 0, 5, 6, 9, 0, 2, 0,
0, 0, 0, 1, 0, 10, 11, 0, 0, 3,
4, 0, 0, 0, 14, 0, 12, 13, 7, 0,
16, 15, 0, 8
0, 0, 0, 0, 0, 6, 7, 10, 0, 2,
0, 0, 0, 4, 0, 1, 0, 11, 12, 0,
0, 3, 5, 0, 0, 0, 15, 0, 13, 14,
8, 0, 17, 16, 0, 9
};
const signed char
EvalParser::yypgoto_[] =
{
-9, -9, 24, -5, -9, -9, -9, -9
-10, -10, 21, -9, -10, -10, -10, -10
};
const signed char
EvalParser::yydefgoto_[] =
{
-1, 7, 8, 9, 17, 28, 25, 32
-1, 8, 9, 10, 19, 30, 27, 34
};
const unsigned char
EvalParser::yytable_[] =
{
1, 2, 30, 1, 2, 10, 18, 3, 11, 20,
31, 4, 13, 5, 4, 6, 5, 15, 6, 16,
26, 27, 14, 19, 21, 22, 23, 12, 29, 24,
0, 0, 33
1, 2, 32, 20, 3, 1, 2, 22, 4, 17,
33, 18, 5, 11, 6, 12, 7, 5, 15, 6,
16, 7, 28, 29, 13, 14, 21, 23, 26, 0,
24, 31, 25, 0, 0, 0, 35
};
const signed char
EvalParser::yycheck_[] =
{
4, 5, 8, 4, 5, 13, 11, 11, 11, 14,
16, 15, 0, 17, 15, 19, 17, 16, 19, 18,
6, 7, 3, 12, 14, 10, 9, 3, 10, 16,
-1, -1, 12
4, 5, 9, 12, 8, 4, 5, 16, 12, 17,
17, 19, 16, 14, 18, 12, 20, 16, 0, 18,
3, 20, 6, 7, 3, 4, 13, 15, 17, -1,
11, 11, 10, -1, -1, -1, 13
};
const unsigned char
EvalParser::yystos_[] =
{
0, 4, 5, 11, 15, 17, 19, 21, 22, 23,
13, 11, 22, 0, 3, 16, 18, 24, 23, 12,
23, 14, 10, 9, 16, 26, 6, 7, 25, 10,
8, 16, 27, 12
0, 4, 5, 8, 12, 16, 18, 20, 22, 23,
24, 14, 12, 23, 23, 0, 3, 17, 19, 25,
24, 13, 24, 15, 11, 10, 17, 27, 6, 7,
26, 11, 9, 17, 28, 13
};
const unsigned char
EvalParser::yyr1_[] =
{
0, 20, 21, 22, 22, 23, 23, 23, 23, 23,
24, 24, 25, 25, 26, 27, 27
0, 21, 22, 23, 23, 23, 24, 24, 24, 24,
24, 25, 25, 26, 26, 27, 28, 28
};
const unsigned char
EvalParser::yyr2_[] =
{
0, 2, 1, 3, 3, 1, 1, 6, 8, 1,
1, 1, 1, 1, 1, 1, 1
0, 2, 1, 3, 2, 3, 1, 1, 6, 8,
1, 1, 1, 1, 1, 1, 1, 1
};
@@ -1056,10 +1065,10 @@ namespace isc { namespace eval {
const EvalParser::yytname_[] =
{
"\"end of file\"", "error", "$undefined", "\"==\"", "\"option\"",
"\"substring\"", "\"text\"", "\"hex\"", "\"all\"", "\".\"", "\",\"",
"\"(\"", "\")\"", "\"[\"", "\"]\"", "\"constant string\"", "\"integer\"",
"\"constant hexstring\"", "\"option name\"", "TOKEN", "$accept",
"expression", "bool_expr", "string_expr", "option_code",
"\"substring\"", "\"text\"", "\"hex\"", "\"not\"", "\"all\"", "\".\"",
"\",\"", "\"(\"", "\")\"", "\"[\"", "\"]\"", "\"constant string\"",
"\"integer\"", "\"constant hexstring\"", "\"option name\"", "TOKEN",
"$accept", "expression", "bool_expr", "string_expr", "option_code",
"option_repr_type", "start_expr", "length_expr", YY_NULLPTR
};
@@ -1067,8 +1076,8 @@ namespace isc { namespace eval {
const unsigned char
EvalParser::yyrline_[] =
{
0, 79, 79, 82, 83, 90, 95, 100, 105, 110,
114, 118, 124, 128, 134, 141, 146
0, 80, 80, 83, 84, 89, 96, 101, 106, 111,
116, 120, 124, 130, 134, 140, 147, 152
};
// Print the state stack on the debug stream.
@@ -1103,8 +1112,8 @@ namespace isc { namespace eval {
#line 21 "parser.yy" // lalr1.cc:1167
} } // isc::eval
#line 1107 "parser.cc" // lalr1.cc:1167
#line 153 "parser.yy" // lalr1.cc:1168
#line 1116 "parser.cc" // lalr1.cc:1167
#line 159 "parser.yy" // lalr1.cc:1168
void
isc::eval::EvalParser::error(const location_type& loc,

View File

@@ -335,18 +335,19 @@ namespace isc { namespace eval {
TOKEN_SUBSTRING = 260,
TOKEN_TEXT = 261,
TOKEN_HEX = 262,
TOKEN_ALL = 263,
TOKEN_DOT = 264,
TOKEN_COMA = 265,
TOKEN_LPAREN = 266,
TOKEN_RPAREN = 267,
TOKEN_LBRACKET = 268,
TOKEN_RBRACKET = 269,
TOKEN_STRING = 270,
TOKEN_INTEGER = 271,
TOKEN_HEXSTRING = 272,
TOKEN_OPTION_NAME = 273,
TOKEN_TOKEN = 274
TOKEN_NOT = 263,
TOKEN_ALL = 264,
TOKEN_DOT = 265,
TOKEN_COMA = 266,
TOKEN_LPAREN = 267,
TOKEN_RPAREN = 268,
TOKEN_LBRACKET = 269,
TOKEN_RBRACKET = 270,
TOKEN_STRING = 271,
TOKEN_INTEGER = 272,
TOKEN_HEXSTRING = 273,
TOKEN_OPTION_NAME = 274,
TOKEN_TOKEN = 275
};
};
@@ -481,6 +482,10 @@ namespace isc { namespace eval {
symbol_type
make_HEX (const location_type& l);
static inline
symbol_type
make_NOT (const location_type& l);
static inline
symbol_type
make_ALL (const location_type& l);
@@ -734,12 +739,12 @@ namespace isc { namespace eval {
enum
{
yyeof_ = 0,
yylast_ = 32, ///< Last index in yytable_.
yylast_ = 36, ///< Last index in yytable_.
yynnts_ = 8, ///< Number of nonterminal symbols.
yyfinal_ = 13, ///< Termination state number.
yyfinal_ = 15, ///< Termination state number.
yyterror_ = 1,
yyerrcode_ = 256,
yyntokens_ = 20 ///< Number of tokens.
yyntokens_ = 21 ///< Number of tokens.
};
@@ -783,9 +788,9 @@ namespace isc { namespace eval {
2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19
15, 16, 17, 18, 19, 20
};
const unsigned int user_token_number_max_ = 274;
const unsigned int user_token_number_max_ = 275;
const token_number_type undef_token_ = 2;
if (static_cast<int>(t) <= yyeof_)
@@ -818,19 +823,19 @@ namespace isc { namespace eval {
{
switch (other.type_get ())
{
case 25: // option_repr_type
case 26: // option_repr_type
value.copy< TokenOption::RepresentationType > (other.value);
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.copy< std::string > (other.value);
break;
case 24: // option_code
case 25: // option_code
value.copy< uint16_t > (other.value);
break;
@@ -851,19 +856,19 @@ namespace isc { namespace eval {
(void) v;
switch (this->type_get ())
{
case 25: // option_repr_type
case 26: // option_repr_type
value.copy< TokenOption::RepresentationType > (v);
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.copy< std::string > (v);
break;
case 24: // option_code
case 25: // option_code
value.copy< uint16_t > (v);
break;
@@ -929,19 +934,19 @@ namespace isc { namespace eval {
// Type destructor.
switch (yytype)
{
case 25: // option_repr_type
case 26: // option_repr_type
value.template destroy< TokenOption::RepresentationType > ();
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.template destroy< std::string > ();
break;
case 24: // option_code
case 25: // option_code
value.template destroy< uint16_t > ();
break;
@@ -968,19 +973,19 @@ namespace isc { namespace eval {
super_type::move(s);
switch (this->type_get ())
{
case 25: // option_repr_type
case 26: // option_repr_type
value.move< TokenOption::RepresentationType > (s.value);
break;
case 15: // "constant string"
case 16: // "integer"
case 17: // "constant hexstring"
case 18: // "option name"
case 19: // TOKEN
case 16: // "constant string"
case 17: // "integer"
case 18: // "constant hexstring"
case 19: // "option name"
case 20: // TOKEN
value.move< std::string > (s.value);
break;
case 24: // option_code
case 25: // option_code
value.move< uint16_t > (s.value);
break;
@@ -1040,7 +1045,8 @@ namespace isc { namespace eval {
yytoken_number_[] =
{
0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
265, 266, 267, 268, 269, 270, 271, 272, 273, 274
265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
275
};
return static_cast<token_type> (yytoken_number_[type]);
}
@@ -1081,6 +1087,12 @@ namespace isc { namespace eval {
return symbol_type (token::TOKEN_HEX, l);
}
EvalParser::symbol_type
EvalParser::make_NOT (const location_type& l)
{
return symbol_type (token::TOKEN_NOT, l);
}
EvalParser::symbol_type
EvalParser::make_ALL (const location_type& l)
{
@@ -1156,7 +1168,7 @@ namespace isc { namespace eval {
#line 21 "parser.yy" // lalr1.cc:392
} } // isc::eval
#line 1160 "parser.h" // lalr1.cc:392
#line 1172 "parser.h" // lalr1.cc:392

View File

@@ -49,6 +49,7 @@ using namespace isc::eval;
SUBSTRING "substring"
TEXT "text"
HEX "hex"
NOT "not"
ALL "all"
DOT "."
COMA ","
@@ -80,6 +81,11 @@ expression : bool_expr
;
bool_expr : "(" bool_expr ")"
| NOT bool_expr
{
TokenPtr neg(new TokenNot());
ctx.expression.push_back(neg);
}
| string_expr EQUAL string_expr
{
TokenPtr eq(new TokenEqual());

View File

@@ -341,6 +341,14 @@ TEST_F(EvalContextTest, parseErrors) {
checkError("== 'ab'", "<string>:1.1-2: syntax error, unexpected ==");
checkError("'foo' ==",
"<string>:1.9: syntax error, unexpected end of file");
checkError("not 'foo'",
"<string>:1.10: syntax error, unexpected end of file, "
"expecting ==");
checkError("not()",
"<string>:1.5: syntax error, unexpected )");
checkError("(not('foo' 'bar')",
"<string>:1.12-16: syntax error, unexpected constant string, "
"expecting ==");
checkError("('foo' == 'bar'",
"<string>:1.16: syntax error, unexpected end of file, "
"expecting )");

View File

@@ -407,6 +407,39 @@ TEST_F(TokenTest, optionEqualTrue) {
EXPECT_EQ("true", values_.top());
}
// This test checks if a token representing a not is able to
// negate a boolean value (with incorrectly built stack).
TEST_F(TokenTest, optionNotInvalid) {
ASSERT_NO_THROW(t_.reset(new TokenNot()));
// CASE 1: The stack is empty.
EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalBadStack);
// CASE 2: The top value is not a boolean
values_.push("foo");
EXPECT_THROW(t_->evaluate(*pkt4_, values_), EvalTypeError);
}
// This test checks if a token representing a not operator is able to
// negate a boolean value.
TEST_F(TokenTest, optionNot) {
ASSERT_NO_THROW(t_.reset(new TokenNot()));
values_.push("true");
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
// After evaluation there should be the negation of the value.
ASSERT_EQ(1, values_.size());
EXPECT_EQ("false", values_.top());
// Double negation is identity.
EXPECT_NO_THROW(t_->evaluate(*pkt4_, values_));
ASSERT_EQ(1, values_.size());
EXPECT_EQ("true", values_.top());
}
};
// This test checks if an a token representing a substring request

View File

@@ -176,3 +176,23 @@ TokenSubstring::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
// and finally get the substring
values.push(string_str.substr(start_pos, length));
}
void
TokenNot::evaluate(const Pkt& /*pkt*/, ValueStack& values) {
if (values.size() == 0) {
isc_throw(EvalBadStack, "Incorrect empty stack.");
}
string op = values.top();
values.pop();
if (op == "true") {
values.push("false");
} else if (op == "false") {
values.push("true");
} else {
isc_throw(EvalTypeError, "Expected a logical value at top of stack. "
<< "Got '" << op << "'.");
}
}

View File

@@ -277,6 +277,31 @@ public:
void evaluate(const Pkt& pkt, ValueStack& values);
};
/// @brief Token that represents logical negation operator
///
/// For example in the expression "not(option[vendor-class].text == 'MSF')"
/// this token represents the leading "not"
class TokenNot : public Token {
public:
/// @brief Constructor (does nothing)
TokenNot() {}
/// @brief Logical negation.
///
/// Evaluation does not use packet information, but rather consumes the last
/// result. It does a simple string comparison and sets the value to
/// either "true" or "false". It requires at least one value to be
/// present on stack and to be either "true" or "false".
///
/// @throw EvalBadStack if there are less than 1 value on stack
/// @throw EvalTypeError if the top value on the stack is not either
/// "true" or "false"
///
/// @param pkt (unused)
/// @param values - stack of values (logical top value negated)
void evaluate(const Pkt& pkt, ValueStack& values);
};
}; // end of isc::dhcp namespace
}; // end of isc namespace