-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathffilter_gram.y
More file actions
126 lines (99 loc) · 3.94 KB
/
ffilter_gram.y
File metadata and controls
126 lines (99 loc) · 3.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
Copyright (c) 2013-2017, Tomas Podermanski, Imrich Štoffa
This file is part of libnf.net project.
Libnf is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Libnf is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with libnf. If not, see <http://www.gnu.org/licenses/>.
*/
%defines
%pure-parser
%lex-param { yyscan_t scanner }
%lex-param { ff_t *filter }
%parse-param { yyscan_t scanner }
%parse-param { ff_t *filter }
%name-prefix = "ff2_"
%{
#include <stdio.h>
#include <string.h>
#include "ffilter.h"
#include "ffilter_internal.h"
#include "ffilter_gram.h"
#define YY_EXTRA_TYPE ff_t
void yyerror(yyscan_t scanner, ff_t *filter, char *msg)
{
ff_set_error(filter, msg);
}
%}
%union {
uint64_t t_uint;
double t_double;
char string[FF_MAX_STRING];
void *node;
};
%token AND OR NOT
%token ANY EXIST
%token EQ LT GT ISSET
%token IN
%token <string> IDENT STRING QUOTED DIR DIR_2 PAIR_AND PAIR_OR
%token <string> BAD_TOKEN
%type <t_uint> cmp
%type <string> field value string consistent_val
%type <node> expr filter
%type <node> list
%left OR
%left AND
%left NOT
%%
filter:
expr { filter->root = $1; }
| { filter->root = NULL; }
;
field:
IDENT { strncpy($$, $1, FF_MAX_STRING - 1); }
| DIR IDENT { snprintf($$, FF_MAX_STRING - 1, "%s%s", $1, $2); }
| DIR_2 IDENT { snprintf($$, FF_MAX_STRING - 1, "%s%s", $1, $2); }
| DIR_2 DIR IDENT { snprintf($$, FF_MAX_STRING - 1, "%s%s%s", $1,$2,$3); }
| PAIR_OR IDENT { snprintf($$, FF_MAX_STRING - 1, "%c%s", '|', $2); }
| PAIR_AND IDENT { snprintf($$, FF_MAX_STRING - 1, "%c%s", '&', $2); }
;
string:
IDENT { strncpy($$, $1, FF_MAX_STRING - 1); /*TRY not to copy, only pass pointer*/ }
| STRING { strncpy($$, $1, FF_MAX_STRING - 1); }
value:
consistent_val { strncpy($$, $1, FF_MAX_STRING - 1); }
| string string { snprintf($$, FF_MAX_STRING - 1, "%s %s", $1, $2); }
consistent_val:
string { strncpy($$, $1, FF_MAX_STRING - 1); }
| QUOTED { $1[strlen($1)-1] = 0; snprintf($$, FF_MAX_STRING - 1, "%s", &$1[1]); /*Dequote*/}
;
expr:
ANY { $$ = ff_new_node(scanner, filter, NULL, FF_OP_YES, NULL); if ($$ == NULL) { YYABORT; }; }
| NOT expr { $$ = ff_new_node(scanner, filter, NULL, FF_OP_NOT, $2); if ($$ == NULL) { YYABORT; }; }
| expr AND expr { $$ = ff_new_node(scanner, filter, $1, FF_OP_AND, $3); if ($$ == NULL) { YYABORT; }; }
| expr OR expr { $$ = ff_new_node(scanner, filter, $1, FF_OP_OR, $3); if ($$ == NULL) { YYABORT; }; }
| '(' expr ')' { $$ = $2; }
| EXIST field { $$ = ff_new_leaf(scanner, filter, $2, FF_OP_EXIST, ""); if ($$ == NULL) { YYABORT; } }
| field cmp value { $$ = ff_new_leaf(scanner, filter, $1, $2, $3); if ($$ == NULL) { YYABORT; } }
| field IN list { $$ = ff_new_leaf(scanner, filter, $1, FF_OP_IN, $3); if ($$ == NULL) { YYABORT; } }
| IDENT { $$ = ff_new_leaf(scanner, filter, $1, FF_OP_NOOP, ""); if ($$ == NULL) { YYABORT; } }
;
list:
consistent_val ',' list { $$ = ff_new_mval(scanner, filter, $1, FF_OP_EQ, $3); if ($$ == NULL) { YYABORT; } }
| consistent_val list { $$ = ff_new_mval(scanner, filter, $1, FF_OP_EQ, $2); if ($$ == NULL) { YYABORT; } }
| consistent_val ']' { $$ = ff_new_mval(scanner, filter, $1, FF_OP_EQ, NULL); if ($$ == NULL) { YYABORT; } }
;
cmp:
ISSET { $$ = FF_OP_ISSET; }
| EQ { $$ = FF_OP_EQ; }
| LT { $$ = FF_OP_LT; }
| GT { $$ = FF_OP_GT; }
| { $$ = FF_OP_NOOP; }
;
%%