blob: 4da3daed095c54a7a98a9c2d540f601c265eba6e (
plain)
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
|
%{
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
#include "m_ematch.h"
%}
%union {
unsigned int i;
struct bstr *b;
struct ematch *e;
}
%{
extern int ematch_lex(void);
extern void yyerror(const char *s);
extern struct ematch *ematch_root;
extern char *ematch_err;
%}
%token <i> ERROR
%token <b> ATTRIBUTE
%token <i> AND OR NOT
%type <i> invert relation
%type <e> match expr
%type <b> args
%right AND OR
%start input
%%
input:
/* empty */
| expr
{ ematch_root = $1; }
| expr error
{
ematch_root = $1;
YYACCEPT;
}
;
expr:
match
{ $$ = $1; }
| match relation expr
{
$1->relation = $2;
$1->next = $3;
$$ = $1;
}
;
match:
invert ATTRIBUTE '(' args ')'
{
$2->next = $4;
$$ = new_ematch($2, $1);
if ($$ == NULL)
YYABORT;
}
| invert '(' expr ')'
{
$$ = new_ematch(NULL, $1);
if ($$ == NULL)
YYABORT;
$$->child = $3;
}
;
args:
ATTRIBUTE
{ $$ = $1; }
| ATTRIBUTE args
{ $1->next = $2; }
;
relation:
AND
{ $$ = TCF_EM_REL_AND; }
| OR
{ $$ = TCF_EM_REL_OR; }
;
invert:
/* empty */
{ $$ = 0; }
| NOT
{ $$ = 1; }
;
%%
void yyerror(const char *s)
{
ematch_err = strdup(s);
}
|