X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=cond.y;h=3b5d6239ba2bb78e439539a18041545b15e16f26;hb=HEAD;hp=6473557660d944e472b17612517f7440092b6a4c;hpb=dca5a9e58bee396d155b7c34aff5758e40c4c3d5;p=umpf.git diff --git a/cond.y b/cond.y index 6473557..3b5d623 100644 --- a/cond.y +++ b/cond.y @@ -2,94 +2,284 @@ #include #include -#include +#include -#define OVECCOUNT 3 +#include "umpf.h" -int yylex (void); -void yyerror (char const *); - -int regex_cmp(char* s, char* r); +static struct tree* tree_malloc(int type); +static enum var_type get_var_type(char* var); %} +%error-verbose %union { - int b; int n; char* str; + struct tree* tr; } %token CONST %token NUM %token VAR -%token KW_IF KW_ELSE KW_PIPE KW_MAIL KW_COPY -%token '(' ')' '{' '}' +%token KW_DISCARD +%token KW_PIPE KW_MAIL KW_COPY KW_FILTER +%token '(' ')' '{' '}' ';' +%nonassoc KW_IF +%nonassoc KW_ELSE %left ARROW -%left EQ NEQ GE LE '<' '>' RE NRE -%left '+' '-' -%left '*' '/' -%left '|' '&' '^' -%left '!' -%left '=' -%type boo +%left EQ NEQ GE LE '<' '>' RE NRE +%left '=' +%left '.' +%left '+' '-' +%left '*' '/' +%left '|' +%left '^' +%left '&' +%right '!' +%left NEG +%type input_init +%type input +%type command +%type ass +%type ass_right +%type ass_right_p +%type cif +%type arrow +%type cond +%type rop +%type left +%type right +%type leaves %% -input: /* empty */ - | input line +input_init: input {input_tree = $$} + +; +input: /* empty */ { $$ = tree_malloc(ST_EMPTY); } + | command input { $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $1; + $$->pt.block.tail = $2; + } +; + +command: ';' { $$ = tree_malloc(ST_EMPTY); } + | '{' command input '}' { + $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $2; + $$->pt.block.tail = $3; + } + | '{' '}' { $$ = tree_malloc(ST_EMPTY); } + | cif + | ass ';' { $$ = $1; } + | arrow ';' { $$ = $1; } + + +; + +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 = tree_malloc(ST_EMPTY); + } +; + +cond: '!' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $2; + $$->pt.cond.right = NULL; + $$->pt.cond.op = $1; + $$->pt.cond.type = OP_BOOL; + } + | cond '|' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + $$->pt.cond.type = OP_BOOL; + } + | cond '&' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + $$->pt.cond.type = OP_BOOL; + } + | cond '^' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + $$->pt.cond.type = OP_BOOL; + + } + | '(' cond ')' { $$ = $2; } + | ass_right rop ass_right { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + $$->pt.cond.type = OP_REL; + } + | ass_right { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.type = JUST_BOOL; + } +; + +rop: '>' + | '<' + | EQ + | NEQ + | LE + | GE + | RE + | NRE ; -line: '\n' - | boo '\n' { printf("%s\n",$1?"true":"false"); } - | error '\n' { yyerrok; } +ass: + VAR '=' ass_right_p { + $$ = 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 = $1; + $$->pt.ass.left->pt.leaf.n = find_var($1, get_var_type($1), var_hash); + $$->pt.ass.right = $3; + } +; + +leaves: VAR { + $$ = tree_malloc(ST_LEAF); + $$->pt.leaf.type = L_VAR; + $$->pt.leaf.value = $1; + $$->pt.leaf.n = find_var($1, get_var_type($1), var_hash); + } + | CONST { + $$ = tree_malloc(ST_LEAF); + $$->pt.leaf.type = L_CONST; + $$->pt.leaf.value = $1; + $$->pt.leaf.n = store_const($1); + } ; -boo: CONST EQ CONST { $$ = ! strcmp($1, $3); } - | CONST NEQ CONST { $$ = !! strcmp($1, $3); } - | CONST RE CONST { $$ = regex_cmp($1,$3) >= 0 } - | CONST NRE CONST { $$ = regex_cmp($1,$3) < 0 } - | NUM EQ NUM { $$ = $1 == $3 } - | NUM NEQ NUM { $$ = $1 != $3 } - | NUM GE NUM { $$ = $1 >= $3 } - | NUM LE NUM { $$ = $1 <= $3 } - | NUM '>' NUM { $$ = $1 > $3 } - | NUM '<' NUM { $$ = $1 < $3 } - | boo '|' boo { $$ = $1 || $3 } - | boo '&' boo { $$ = $1 && $3 } - | boo '^' boo { $$ = ($1 || $3) && !($1 && $3) } - | '!' boo { $$ = ! $2 } +arrow: left ARROW right ass_right { + $$ = tree_malloc(ST_ARROW); + $$->pt.arrow.s = $4; + $$->pt.arrow.left = $1; + $$->pt.arrow.right = $3; + } + | left ARROW KW_DISCARD { //FIXME: actually left does not make sense here + $$ = tree_malloc(ST_ARROW); + $$->pt.arrow.s = NULL; + $$->pt.arrow.left = K_EMPTY; + $$->pt.arrow.right = K_DISCARD; + } ; +left: /* empty */ { $$ = K_EMPTY;} + | KW_COPY { $$ = K_COPY; } + ; + +right: /* empty */ { $$ = K_EMPTY; } + | KW_PIPE { $$ = K_PIPE; } + | KW_MAIL { $$ = K_MAIL; } + | KW_FILTER { $$ = K_FILTER; } +; + +ass_right_p: '(' ass_right ')' {$$ = $2; } + | ass_right {$$ = $1; } +; + +ass_right: leaves + | ass_right '.' ass_right { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $2; + $$->pt.op.left = $1; + $$->pt.op.right = $3; + } + | ass_right '+' ass_right { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $2; + $$->pt.op.left = $1; + $$->pt.op.right = $3; + } + | ass_right '-' ass_right { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $2; + $$->pt.op.left = $1; + $$->pt.op.right = $3; + } + | ass_right '*' ass_right { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $2; + $$->pt.op.left = $1; + $$->pt.op.right = $3; + } + | ass_right '/' ass_right { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $2; + $$->pt.op.left = $1; + $$->pt.op.right = $3; + } + | '-' ass_right %prec NEG { + $$ = tree_malloc(ST_OP); + $$->pt.op.op = $1; + $$->pt.op.left = tree_malloc(ST_LEAF); + $$->pt.op.left->pt.leaf.type = L_CONST; + $$->pt.op.left->pt.leaf.value = "0"; + $$->pt.op.left->pt.leaf.n = + store_const("0"); + $$->pt.op.right = $2; + } +; + %% -int -regex_cmp(char* s, char* r) +struct tree* +tree_malloc(int type) { - 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; + struct tree* temp; + temp = xmalloc(sizeof (struct tree)); + temp->st=type; + + return temp; } -void -yyerror (char const *s) +enum var_type +get_var_type(char* var) { - fprintf (stderr, "%s\n", s); + int upper = 0; + int lower = 0; + + if (islower(*var)) + return VAR_USER; + + while (*var) { + if (isupper(*var)) + upper++; + if (islower(*var)) + lower++; + var++; + } + if (upper && lower) + return VAR_HEADER; + + return VAR_INTERN; } -int -main(void) +void +yyerror (char const *s) { -// yydebug=1; - return yyparse (); + fprintf (stderr, "Line %d: %s\n Saving your e-mail to default mailbox %s\n", + line, s, default_mailbox); + longjmp(env, 1); }