Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Sebastian Schrader
Kea
Commits
7917d94e
Commit
7917d94e
authored
Mar 18, 2016
by
Francis Dupont
Browse files
[master] Finished merge of trac4232a (IP address literal)
parents
2bc621d5
f9e7a274
Changes
14
Expand all
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
7917d94e
1090. [func] fdupont
Added support for IP address (IPv4 and IPv6) literals in
classification expressions.
(Trac #4232, git xxx)
1089. [func] fdupont
Added relay4[X].exists method in classifications that checks
whether a sub-option is present in theDHCPv4 RAI (Relay Agent
...
...
doc/guide/classify.xml
View file @
7917d94e
...
...
@@ -159,6 +159,7 @@
<tbody>
<row><entry>
String
</entry><entry>
'example'
</entry><entry>
A string
</entry></row>
<row><entry>
Hex String
</entry><entry>
0XABCD
</entry><entry>
A hexadecimal string
</entry></row>
<row><entry>
IP Address
</entry><entry>
10.0.0.1
</entry><entry>
An IP address
</entry></row>
<row><entry>
Integer
</entry><entry>
123
</entry><entry>
An integer value
</entry></row>
<!-- Text option not fully defined yet, leave it out
<row><entry>Option Text</entry><entry>option[code].text</entry><entry>The value of the option with code "code" from the packet as text</entry></row>
...
...
@@ -177,6 +178,11 @@ sub-option with code "code" from the DHCPv4 Relay Agent Information option
"
0
"
is prepended to it.
</para>
<para>
IP addresses are converted into strings of length 4 or 16. IPv4, IPv6,
and IPv4 embedded IPv6 (e.g., IPv4 mapped IPv6) addresses are supported.
</para>
<para>
Integers in the expression are converted to strings
when the expression is read into Kea.
...
...
src/lib/eval/lexer.cc
View file @
7917d94e
This diff is collapsed.
Click to expand it.
src/lib/eval/lexer.ll
View file @
7917d94e
...
...
@@ -11,6 +11,7 @@
#include
<
string
>
#include
<
eval/eval_context
.
h
>
#include
<
eval/parser
.
h
>
#include
<
asiolink/io_address
.
h
>
#include
<
boost/lexical_cast
.
hpp
>
//
Work
around
an
incompatibility
in
flex
(
at
least
versions
...
...
@@ -56,10 +57,13 @@ static isc::eval::location loc;
%option
yylineno
/
*
These
are
not
token
expressions
yet
,
just
convenience
expressions
that
can
be
used
during
actual
token
definitions
.
*
/
can
be
used
during
actual
token
definitions
.
Note
some
can
match
incorrect
inputs
(
e
.
g
.,
IP
addresses
)
which
must
be
checked
.
*
/
int
\-?
[
0-9
]
+
hex
[
0-9
a-fA-F
]
+
blank
[
\t
]
addr4
[
0-9
]
+\
.[
0-9
]
+\
.[
0-9
]
+\
.[
0-9
]
+
addr6
[
0-9
a-fA-F
]*
\:
[
0-9
a-fA-F
]*
\:
[
0
-9a-fA-F:
.]*
%
{
//
This
code
run
each
time
a
pattern
is
matched
.
It
updates
the
location
...
...
@@ -122,6 +126,20 @@ blank [ \t]
return
isc:
:
eval:
:
EvalParser:
:make_OPTION_NAME
(
yytext
,
loc
)
;
}
{
addr4
}
|
{
addr6
}
{
//
IPv4
or
IPv6
address
std:
:string
tmp
(
yytext
)
;
//
Some
incorrect
addresses
can
match
so
we
have
to
check
.
try
{
isc:
:
asiolink:
:IOAddress
ip
(
tmp
)
;
}
catch
(...)
{
driver
.
error
(
loc
,
"Failed to convert "
+
tmp
+
" to an IP address."
)
;
}
return
isc:
:
eval:
:
EvalParser:
:make_IP_ADDRESS
(
yytext
,
loc
)
;
}
"=="
return
isc:
:
eval:
:
EvalParser:
:make_EQUAL
(
loc
)
;
"option"
return
isc:
:
eval:
:
EvalParser:
:make_OPTION
(
loc
)
;
"relay4"
return
isc:
:
eval:
:
EvalParser:
:make_RELAY4
(
loc
)
;
...
...
src/lib/eval/location.hh
View file @
7917d94e
...
...
@@ -40,9 +40,9 @@
# include "position.hh"
#line 13 "parser.yy" // location.cc:
296
#line 13 "parser.yy" // location.cc:
337
namespace
isc
{
namespace
eval
{
#line 46 "location.hh" // location.cc:
296
#line 46 "location.hh" // location.cc:
337
/// Abstract a location.
class
location
{
...
...
@@ -186,7 +186,7 @@ namespace isc { namespace eval {
return
ostr
;
}
#line 13 "parser.yy" // location.cc:
296
#line 13 "parser.yy" // location.cc:
337
}
}
// isc::eval
#line 192 "location.hh" // location.cc:
296
#line 192 "location.hh" // location.cc:
337
#endif // !YY_YY_LOCATION_HH_INCLUDED
src/lib/eval/parser.cc
View file @
7917d94e
...
...
@@ -251,7 +251,7 @@ namespace isc { namespace eval {
{
switch
(
that
.
type_get
())
{
case
3
0
:
// option_repr_type
case
3
1
:
// option_repr_type
value
.
move
<
TokenOption
::
RepresentationType
>
(
that
.
value
);
break
;
...
...
@@ -259,10 +259,11 @@ namespace isc { namespace eval {
case
22
:
// "integer"
case
23
:
// "constant hexstring"
case
24
:
// "option name"
case
25
:
// "ip address"
value
.
move
<
std
::
string
>
(
that
.
value
);
break
;
case
29
:
// option_code
case
30
:
// option_code
value
.
move
<
uint16_t
>
(
that
.
value
);
break
;
...
...
@@ -281,7 +282,7 @@ namespace isc { namespace eval {
state
=
that
.
state
;
switch
(
that
.
type_get
())
{
case
3
0
:
// option_repr_type
case
3
1
:
// option_repr_type
value
.
copy
<
TokenOption
::
RepresentationType
>
(
that
.
value
);
break
;
...
...
@@ -289,10 +290,11 @@ namespace isc { namespace eval {
case
22
:
// "integer"
case
23
:
// "constant hexstring"
case
24
:
// "option name"
case
25
:
// "ip address"
value
.
copy
<
std
::
string
>
(
that
.
value
);
break
;
case
29
:
// option_code
case
30
:
// option_code
value
.
copy
<
uint16_t
>
(
that
.
value
);
break
;
...
...
@@ -334,44 +336,51 @@ namespace isc { namespace eval {
{
case
21
:
// "constant string"
#line 7
2
"parser.yy" // lalr1.cc:636
#line 7
3
"parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
std
::
string
>
();
}
#line 34
0
"parser.cc" // lalr1.cc:636
#line 34
2
"parser.cc" // lalr1.cc:636
break
;
case
22
:
// "integer"
#line 7
2
"parser.yy" // lalr1.cc:636
#line 7
3
"parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
std
::
string
>
();
}
#line 34
7
"parser.cc" // lalr1.cc:636
#line 34
9
"parser.cc" // lalr1.cc:636
break
;
case
23
:
// "constant hexstring"
#line 7
2
"parser.yy" // lalr1.cc:636
#line 7
3
"parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
std
::
string
>
();
}
#line 35
4
"parser.cc" // lalr1.cc:636
#line 35
6
"parser.cc" // lalr1.cc:636
break
;
case
24
:
// "option name"
#line 7
2
"parser.yy" // lalr1.cc:636
#line 7
3
"parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
std
::
string
>
();
}
#line 36
1
"parser.cc" // lalr1.cc:636
#line 36
3
"parser.cc" // lalr1.cc:636
break
;
case
2
9
:
//
option_code
case
2
5
:
//
"ip address"
#line 72 "parser.yy" // lalr1.cc:636
#line 73 "parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
std
::
string
>
();
}
#line 370 "parser.cc" // lalr1.cc:636
break
;
case
30
:
// option_code
#line 73 "parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
uint16_t
>
();
}
#line 3
68
"parser.cc" // lalr1.cc:636
#line 3
77
"parser.cc" // lalr1.cc:636
break
;
case
3
0
:
// option_repr_type
case
3
1
:
// option_repr_type
#line 7
2
"parser.yy" // lalr1.cc:636
#line 7
3
"parser.yy" // lalr1.cc:636
{
yyoutput
<<
yysym
.
value
.
template
as
<
TokenOption
::
RepresentationType
>
();
}
#line 3
75
"parser.cc" // lalr1.cc:636
#line 3
84
"parser.cc" // lalr1.cc:636
break
;
...
...
@@ -571,7 +580,7 @@ namespace isc { namespace eval {
when using variants. */
switch
(
yyr1_
[
yyn
])
{
case
3
0
:
// option_repr_type
case
3
1
:
// option_repr_type
yylhs
.
value
.
build
<
TokenOption
::
RepresentationType
>
();
break
;
...
...
@@ -579,10 +588,11 @@ namespace isc { namespace eval {
case
22
:
// "integer"
case
23
:
// "constant hexstring"
case
24
:
// "option name"
case
25
:
// "ip address"
yylhs
.
value
.
build
<
std
::
string
>
();
break
;
case
29
:
// option_code
case
30
:
// option_code
yylhs
.
value
.
build
<
uint16_t
>
();
break
;
...
...
@@ -604,52 +614,52 @@ namespace isc { namespace eval {
switch
(
yyn
)
{
case
4
:
#line 8
6
"parser.yy" // lalr1.cc:859
#line 8
7
"parser.yy" // lalr1.cc:859
{
TokenPtr
neg
(
new
TokenNot
());
ctx
.
expression
.
push_back
(
neg
);
}
#line 6
1
3 "parser.cc" // lalr1.cc:859
#line 6
2
3 "parser.cc" // lalr1.cc:859
break
;
case
5
:
#line 9
1
"parser.yy" // lalr1.cc:859
#line 9
2
"parser.yy" // lalr1.cc:859
{
TokenPtr
neg
(
new
TokenAnd
());
ctx
.
expression
.
push_back
(
neg
);
}
#line 6
2
2 "parser.cc" // lalr1.cc:859
#line 6
3
2 "parser.cc" // lalr1.cc:859
break
;
case
6
:
#line 9
6
"parser.yy" // lalr1.cc:859
#line 9
7
"parser.yy" // lalr1.cc:859
{
TokenPtr
neg
(
new
TokenOr
());
ctx
.
expression
.
push_back
(
neg
);
}
#line 6
3
1 "parser.cc" // lalr1.cc:859
#line 6
4
1 "parser.cc" // lalr1.cc:859
break
;
case
7
:
#line 10
1
"parser.yy" // lalr1.cc:859
#line 10
2
"parser.yy" // lalr1.cc:859
{
TokenPtr
eq
(
new
TokenEqual
());
ctx
.
expression
.
push_back
(
eq
);
}
#line 6
4
0 "parser.cc" // lalr1.cc:859
#line 6
5
0 "parser.cc" // lalr1.cc:859
break
;
case
8
:
#line 10
6
"parser.yy" // lalr1.cc:859
#line 10
7
"parser.yy" // lalr1.cc:859
{
TokenPtr
opt
(
new
TokenOption
(
yystack_
[
3
].
value
.
as
<
uint16_t
>
(),
TokenOption
::
EXISTS
));
ctx
.
expression
.
push_back
(
opt
);
}
#line 6
4
9 "parser.cc" // lalr1.cc:859
#line 6
5
9 "parser.cc" // lalr1.cc:859
break
;
case
9
:
#line 11
1
"parser.yy" // lalr1.cc:859
#line 11
2
"parser.yy" // lalr1.cc:859
{
switch
(
ctx
.
getUniverse
())
{
case
Option
::
V4
:
...
...
@@ -669,38 +679,47 @@ namespace isc { namespace eval {
error
(
yystack_
[
5
].
location
,
"relay4 can only be used in DHCPv4."
);
}
}
#line 6
7
3 "parser.cc" // lalr1.cc:859
#line 6
8
3 "parser.cc" // lalr1.cc:859
break
;
case
10
:
#line 13
3
"parser.yy" // lalr1.cc:859
#line 13
4
"parser.yy" // lalr1.cc:859
{
TokenPtr
str
(
new
TokenString
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
()));
ctx
.
expression
.
push_back
(
str
);
}
#line 6
8
2 "parser.cc" // lalr1.cc:859
#line 6
9
2 "parser.cc" // lalr1.cc:859
break
;
case
11
:
#line 13
8
"parser.yy" // lalr1.cc:859
#line 13
9
"parser.yy" // lalr1.cc:859
{
TokenPtr
hex
(
new
TokenHexString
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
()));
ctx
.
expression
.
push_back
(
hex
);
}
#line
69
1 "parser.cc" // lalr1.cc:859
#line
70
1 "parser.cc" // lalr1.cc:859
break
;
case
12
:
#line 143 "parser.yy" // lalr1.cc:859
#line 144 "parser.yy" // lalr1.cc:859
{
TokenPtr
ip
(
new
TokenIpAddress
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
()));
ctx
.
expression
.
push_back
(
ip
);
}
#line 710 "parser.cc" // lalr1.cc:859
break
;
case
13
:
#line 149 "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
);
}
#line 7
00
"parser.cc" // lalr1.cc:859
#line 7
19
"parser.cc" // lalr1.cc:859
break
;
case
1
3
:
#line 14
8
"parser.yy" // lalr1.cc:859
case
1
4
:
#line 1
5
4 "parser.yy" // lalr1.cc:859
{
switch
(
ctx
.
getUniverse
())
{
case
Option
::
V4
:
...
...
@@ -720,88 +739,88 @@ namespace isc { namespace eval {
error
(
yystack_
[
5
].
location
,
"relay4 can only be used in DHCPv4."
);
}
}
#line 7
2
4 "parser.cc" // lalr1.cc:859
#line 74
3
"parser.cc" // lalr1.cc:859
break
;
case
1
4
:
#line 1
68
"parser.yy" // lalr1.cc:859
case
1
5
:
#line 1
74
"parser.yy" // lalr1.cc:859
{
TokenPtr
sub
(
new
TokenSubstring
());
ctx
.
expression
.
push_back
(
sub
);
}
#line 7
33
"parser.cc" // lalr1.cc:859
#line 7
52
"parser.cc" // lalr1.cc:859
break
;
case
1
5
:
#line 17
3
"parser.yy" // lalr1.cc:859
case
1
6
:
#line 17
9
"parser.yy" // lalr1.cc:859
{
TokenPtr
conc
(
new
TokenConcat
());
ctx
.
expression
.
push_back
(
conc
);
}
#line 7
42
"parser.cc" // lalr1.cc:859
#line 7
61
"parser.cc" // lalr1.cc:859
break
;
case
1
6
:
#line 18
0
"parser.yy" // lalr1.cc:859
case
1
7
:
#line 18
6
"parser.yy" // lalr1.cc:859
{
yylhs
.
value
.
as
<
uint16_t
>
()
=
ctx
.
convertOptionCode
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
(),
yystack_
[
0
].
location
);
}
#line 7
50
"parser.cc" // lalr1.cc:859
#line 7
69
"parser.cc" // lalr1.cc:859
break
;
case
1
7
:
#line 1
84
"parser.yy" // lalr1.cc:859
case
1
8
:
#line 1
90
"parser.yy" // lalr1.cc:859
{
yylhs
.
value
.
as
<
uint16_t
>
()
=
ctx
.
convertOptionName
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
(),
yystack_
[
0
].
location
);
}
#line 7
58
"parser.cc" // lalr1.cc:859
#line 7
77
"parser.cc" // lalr1.cc:859
break
;
case
1
8
:
#line 19
0
"parser.yy" // lalr1.cc:859
case
1
9
:
#line 19
6
"parser.yy" // lalr1.cc:859
{
yylhs
.
value
.
as
<
TokenOption
::
RepresentationType
>
()
=
TokenOption
::
TEXTUAL
;
}
#line 7
66
"parser.cc" // lalr1.cc:859
#line 7
85
"parser.cc" // lalr1.cc:859
break
;
case
19
:
#line
194
"parser.yy" // lalr1.cc:859
case
20
:
#line
200
"parser.yy" // lalr1.cc:859
{
yylhs
.
value
.
as
<
TokenOption
::
RepresentationType
>
()
=
TokenOption
::
HEXADECIMAL
;
}
#line 7
74
"parser.cc" // lalr1.cc:859
#line 7
93
"parser.cc" // lalr1.cc:859
break
;
case
2
0
:
#line 20
0
"parser.yy" // lalr1.cc:859
case
2
1
:
#line 20
6
"parser.yy" // lalr1.cc:859
{
TokenPtr
str
(
new
TokenString
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
()));
ctx
.
expression
.
push_back
(
str
);
}
#line
783
"parser.cc" // lalr1.cc:859
#line
802
"parser.cc" // lalr1.cc:859
break
;
case
2
1
:
#line 2
07
"parser.yy" // lalr1.cc:859
case
2
2
:
#line 2
13
"parser.yy" // lalr1.cc:859
{
TokenPtr
str
(
new
TokenString
(
yystack_
[
0
].
value
.
as
<
std
::
string
>
()));
ctx
.
expression
.
push_back
(
str
);
}
#line
792
"parser.cc" // lalr1.cc:859
#line
811
"parser.cc" // lalr1.cc:859
break
;
case
2
2
:
#line 21
2
"parser.yy" // lalr1.cc:859
case
2
3
:
#line 21
8
"parser.yy" // lalr1.cc:859
{
TokenPtr
str
(
new
TokenString
(
"all"
));
ctx
.
expression
.
push_back
(
str
);
}
#line 80
1
"parser.cc" // lalr1.cc:859
#line 8
2
0 "parser.cc" // lalr1.cc:859
break
;
#line 8
05
"parser.cc" // lalr1.cc:859
#line 8
24
"parser.cc" // lalr1.cc:859
default:
break
;
}
...
...
@@ -1063,91 +1082,89 @@ namespace isc { namespace eval {
const
signed
char
EvalParser
::
yypact_
[]
=
{
-
1
,
-
1
,
-
1
,
1
,
10
,
2
8
,
3
6
,
-
29
,
-
29
,
32
,
0
,
4
1
,
29
,
-
29
,
-
7
,
-
7
,
1
7
,
1
7
,
-
29
,
-
1
,
-
1
,
17
,
-
29
,
-
29
,
-
29
,
38
,
3
9
,
4
2
,
43
,
37
,
40
,
-
29
,
46
,
-
29
,
4
4
,
4
5
,
-
7
,
-
7
,
47
,
17
,
27
,
3
0
,
48
,
49
,
-
29
,
51
,
58
,
-
29
,
-
29
,
-
29
,
-
29
,
-
29
,
-
29
,
5
0
,
5
2
,
-
4
,
-
29
,
3
3
,
3
3
,
-
29
,
-
29
,
60
,
-
29
-
1
,
-
1
,
-
1
,
24
,
27
,
1
8
,
3
7
,
-
29
,
-
29
,
-
29
,
50
,
6
,
4
3
,
11
,
-
29
,
10
,
10
,
1
6
,
1
6
,
-
29
,
-
1
,
-
1
,
16
,
-
29
,
-
29
,
-
29
,
40
,
4
1
,
4
4
,
45
,
35
,
38
,
-
29
,
52
,
-
29
,
4
6
,
47
,
10
,
10
,
39
,
16
,
28
,
3
1
,
51
,
53
,
-
29
,
48
,
58
,
-
29
,
-
29
,
-
29
,
-
29
,
-
29
,
-
29
,
5
5
,
5
6
,
-
15
,
-
29
,
3
4
,
3
4
,
-
29
,
-
29
,
60
,
-
29
};
const
unsigned
char
EvalParser
::
yydefact_
[]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
10
,
11
,
0
,
2
,
0
,
0
,
4
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
3
,
16
,
17
,
0
,
0
,
0
,
0
,
0
,
0
,
5
,
6
,
7
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
20
,
0
,
0
,
18
,
19
,
8
,
12
,
9
,
1
3
,
0
,
0
,
0
,
1
5
,
0
,
0
,
22
,
2
1
,
0
,
1
4
0
,
0
,
0
,
0
,
0
,
0
,
0
,
10
,
11
,
12
,
0
,
2
,
0
,
0
,
4
,
0
,
0
,
0
,
0
,
1
,
0
,
0
,
0
,
3
,
17
,
18
,
0
,
0
,
0
,
0
,
0
,
0
,
5
,
6
,
7
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
21
,
0
,
0
,
19
,
20
,
8
,
13
,
9
,
1
4
,
0
,
0
,
0
,
1
6
,
0
,
0
,
2
3
,
22
,
0
,
1
5
};
const
signed
char
EvalParser
::
yypgoto_
[]
=
{
-
29
,
-
29
,
9
,
-
1
6
,
-
1
2
,
-
28
,
-
29
,
-
29
-
29
,
-
29
,
9
,
-
1
7
,
-
1
0
,
-
28
,
-
29
,
-
29
};
const
signed
char
EvalParser
::
yydefgoto_
[]
=
{
-
1
,
9
,
10
,
11
,
2
5
,
5
0
,
4
5
,
6
1
-
1
,
10
,
11
,
12
,
2
6
,
5
1
,
4
6
,
6
2
};
const
unsigned
char
EvalParser
::
yytable_
[]
=
{
29
,
30
,
1
,
26
,
2
,
33
,
19
,
20
,
3
,
4
,
12
,
13
,
14
,
52
,
59
,
23
,
5
,
24
,
60
,
6
,
7
,
15
,
8
,
46
,
42
,
43
,
27
,
28
,
31
,
32
,
52
,
16
,
18
,
22
,
5
,
19
,
20
,
6
,
7
,
17
,
8
,
47
,
48
,
49
,
47
,
48
,
51
,
47
,
48
,
21
,
34
,
35
,
19
,
36
,
37
,
0
,
38
,
40
,
41
,
39
,
53
,
54
,
56
,
57
,
62
,
58
,
0
,
0
,
0
,
44
,
55
30
,
31
,
1
,
60
,
2
,
34
,
27
,
61
,
3
,
4
,
13
,
14
,
20
,
21
,
53
,
23
,
5
,
20
,
21
,
6
,
7
,
17
,
8
,
47
,
9
,
28
,
29
,
43
,
44
,
32
,
33
,
53
,
24
,
5
,
25
,
15
,
6
,
7
,
16
,
8
,
18
,
9
,
48
,
49
,
50
,
48
,
49
,
52
,
48
,
49
,
19
,
22
,
35
,
36
,
39
,
37
,
38
,
40
,
20
,
41
,
42
,
45
,
57
,
54
,
63
,
55
,
0
,
56
,
58
,
59
};
const
signed
char
EvalParser
::
yycheck_
[]
=
{
16
,
17
,
3
,
15
,
5
,
21
,
6
,
7
,
9
,
10
,
1
,
2
,
11
,
41
,
18
,
22
,
17
,
24
,
22
,
20
,
21
,
11
,
23
,
39
,
36
,
37
,
9
,
10
,
19
,
20
,
58
,
3
,
0
,
4
,
17
,
6
,
7
,
20
,
21
,
3
,
23
,
14
,
15
,
16
,
14
,
15
,
16
,
14
,
15
,
8
,
12
,
12
,
6
,
11
,
11
,
-
1
,
19
,
13
,
13
,
19
,
12
,
12
,
4
,
13
,
4
,
13
,
-
1
,
-
1
,
-
1
,
22
,
19
17
,
18
,
3
,
18
,
5
,
22
,
16
,
22
,
9
,
10
,
1
,
2
,
6
,
7
,
42
,
4
,
17
,
6
,
7
,
20
,
21
,
3
,
23
,
40
,
25
,
9
,
10
,
37
,
38
,
20
,
21
,
59
,
22
,
17
,
24
,
11
,
20
,
21
,
11
,
23
,
3
,
25
,
14
,
15
,
16
,
14
,
15
,
16
,
14
,
15
,
0
,
8
,
12
,
12
,
19
,
11
,
11
,
19
,
6
,
13
,
13
,
22
,
4
,
12
,
4
,
12
,
-
1
,
19
,
13
,
13
};
const
unsigned
char
EvalParser
::
yystos_
[]
=
{
0
,
3
,
5
,
9
,
10
,
17
,
20
,
21
,
23
,
2
6
,
27
,
28
,
2
7
,
2
7
,
11
,
11
,
3
,
3
,
0
,
6
,
7
,
8
,
4
,
22
,
24
,
29
,
29
,
9
,
10
,
28
,
2
8
,
2
7
,
2
7
,
28
,
12
,
12
,
11
,
11
,
19
,
19
,
13
,
13
,
29
,
29
,
22
,
3
1
,
2
8
,
14
,
15
,
16
,
30
,
16
,
3
0
,
12
,
12
,
19
,
4
,
13
,
13
,
18
,
22
,
3
2
,
4
0
,
3
,
5
,
9
,
10
,
17
,
20
,
21
,
23
,
2
5
,
27
,
28
,
2
9
,
28
,
2
8
,
11
,
11
,
3
,
3
,
0
,
6
,
7
,
8
,
4
,
22
,
24
,
30
,
30
,
9
,
10
,
2
9
,
2
9
,
2
8
,
28
,
29
,
12
,
12
,
11
,
11
,
19
,
19
,
13
,
13
,
30
,
30
,
22
,
3
2
,
2
9
,
14
,
15
,
16
,
31
,
16
,
3
1
,
12
,
12
,
19
,
4
,
13
,
13
,
18
,
22
,
3
3
,
4
};
const
unsigned
char
EvalParser
::
yyr1_
[]
=
{
0
,
2
5
,
2
6
,
2
7
,
2
7
,
2
7
,
2
7
,
2
7
,
2
7
,
2
7
,
2
8
,
2
8
,
2
8
,
2
8
,
2
8
,
28
,
29
,
29
,
30
,
30
,
31
,
32
,
3
2
0
,
2
6
,
2
7
,
2
8
,
2
8
,
2
8
,
2
8
,
2
8
,
2
8
,
2
8
,
2
9
,
2
9
,
2
9
,
2
9
,
2
9
,
29
,
29
,
30
,
30
,
31
,
31
,
32
,
3
3
,
33
};
const
unsigned
char
EvalParser
::
yyr2_
[]
=
{
0
,
2
,
1
,
3
,
2
,
3
,
3
,
3
,
6
,
6
,
1
,
1
,
6
,
6
,
8
,
6
,
1
,
1
,
1
,
1
,
1
,
1
,
1
1
,
1
,
1
,
6
,
6
,
8
,
6
,
1
,
1
,
1
,
1
,
1
,
1
,
1
};
...
...
@@ -1161,18 +1178,18 @@ namespace isc { namespace eval {
"
\"
and
\"
"
,
"
\"
or
\"
"
,
"
\"
==
\"
"
,
"
\"
option
\"
"
,
"
\"
relay4
\"
"
,
"
\"
[
\"
"
,
"