diff options
Diffstat (limited to '')
-rw-r--r-- | tc/emp_ematch.y | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/tc/emp_ematch.y b/tc/emp_ematch.y new file mode 100644 index 0000000..4da3dae --- /dev/null +++ b/tc/emp_ematch.y @@ -0,0 +1,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); + } |