%{ #include #include #include #include "lex.h" #define OVECCOUNT 3 int yylex (void); void yyerror (char const *); int regex_cmp(char* s, char* r); struct tree* tree_malloc(int type); struct tree { enum { ST_IF, ST_COND, ST_BLOCK, ST_ASS, ST_LEAF, ST_EMPTY } st; union { struct { struct tree* c; struct tree* i; struct tree* e; } tif; struct { int op; struct tree* left; struct tree* right; } cond; struct { struct tree* head; struct tree* tail; } block; struct { struct tree* left; struct tree* right; } ass; struct { enum { L_VAR, L_CONST, L_NUM } type; union { char* s; int n; } value; } leaf; } pt; }; %} %union { int n; char* str; struct tree* tr; } %token CONST %token NUM %token VAR %token KW_PIPE KW_MAIL KW_COPY %token '(' ')' '{' '}' ';' %left KW_ELSE %left KW_IF %left ARROW %left EQ NEQ GE LE '<' '>' RE NRE %left '+' '-' %left '*' '/' %left '|' %left '^' %left '&' %left '!' %left '=' %type input %type command %type next %type ass %type ass_right %type cif %type cond %type rop %% input: /* empty */ { $$ = NULL } | command input { $$ = tree_malloc(ST_BLOCK); $$->pt.block.head = $1; $$->pt.block.tail = $2; } ; command: ';' { $$ = tree_malloc(ST_EMPTY); } | '{' command next '}' { $$ = tree_malloc(ST_BLOCK); $$->pt.block.head = $2; $$->pt.block.tail = $3; } | '{' '}' { $$ = NULL } | cif { $$ = $1 } | ass ';' { $$ = $1} ; next: /* empty */ {$$ = NULL} | command ; cif: KW_IF cond command KW_ELSE command { $$ = tree_malloc(ST_IF); $$->pt.tif.c = $2; $$->pt.tif.i = $3; $$->pt.tif.e = $5; } | KW_IF cond command { $$ = tree_malloc(ST_IF); $$->pt.tif.c = $2; $$->pt.tif.i = $3; $$->pt.tif.e = NULL; } ; cond: '!' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $2; $$->pt.cond.right = NULL; $$->pt.cond.op = $1; } | cond '|' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; } | cond '&' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; } | cond '^' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; } | '(' cond ')' { $$ = $2; } | ass_right rop ass_right { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $1; $$->pt.cond.right = $3; $$->pt.cond.op = $2; } ; rop: '>' | '<' | EQ | NEQ | LE | GE | RE | NRE ; ass: VAR '=' ass_right { $$ = tree_malloc(ST_ASS); $$->pt.ass.left = tree_malloc(ST_LEAF); $$->pt.ass.left->pt.leaf.type = L_VAR; $$->pt.ass.left->pt.leaf.value.s = $1; $$->pt.ass.right = $3; } ; ass_right: NUM { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_NUM; $$->pt.leaf.value.n = $1; } | VAR { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_VAR; $$->pt.leaf.value.s = $1; } | CONST { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_CONST; $$->pt.leaf.value.s = $1; } ; %% struct tree* tree_malloc(int type) { struct tree* temp; temp = xmalloc(sizeof (struct tree)); temp->st=type; return temp; } int regex_cmp(char* s, char* r) { pcre *brum; int erroroffset; const char* error; int ovector[OVECCOUNT]; brum = pcre_compile(r,0,&error,&erroroffset,NULL); if (!brum) return -1; int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT); pcre_free(brum); return res; } void yyerror (char const *s) { fprintf (stderr, "%s\n", s); } int main(void) { // yydebug=1; return yyparse (); }