X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=cond.y;h=3b5d6239ba2bb78e439539a18041545b15e16f26;hb=HEAD;hp=8baaf2163306d7d1f58f2eae1a5061c15d1e20e1;hpb=24967a3dcde5a22b89e88abc4554735718fb4e08;p=umpf.git diff --git a/cond.y b/cond.y index 8baaf21..3b5d623 100644 --- a/cond.y +++ b/cond.y @@ -2,84 +2,14 @@ #include #include -#include +#include -#include "lex.h" +#include "umpf.h" -#define OVECCOUNT 3 - -int yylex (void); -void yyerror (char const *); - -int regex_cmp(char* s, char* r); -struct tree* tree_malloc(int type); -void print_tree(struct tree* t, int ind); - -struct tree { - enum { - ST_IF, - ST_COND, - ST_BLOCK, - ST_ASS, - ST_LEAF, - ST_EMPTY, - ST_ARROW, - ST_OP - } st; /* subtree type */ - union { - struct { - struct tree* c; /* condition */ - struct tree* i; /* if */ - struct tree* e; /* else */ - } tif; - - struct { - int op; - struct tree* left; - struct tree* right; - } cond; /* binary operator */ - - 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; - - struct { - char* kw_left; - char* kw_right; - struct tree* s; - } arrow; - - struct { - int op; - struct tree* left; - struct tree* right; - } op; - - } pt; -}; - -struct tree* input_tree; +static struct tree* tree_malloc(int type); +static enum var_type get_var_type(char* var); %} - %error-verbose %union { @@ -91,61 +21,59 @@ struct tree* input_tree; %token CONST %token NUM %token VAR -%token KW_PIPE KW_MAIL KW_COPY +%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 '=' +%left '.' +%left '+' '-' +%left '*' '/' %left '|' %left '^' %left '&' -%left '!' +%right '!' +%left NEG +%type input_init %type input %type command -%type next %type ass %type ass_right +%type ass_right_p %type cif %type arrow %type cond %type rop -%type left -%type right +%type left +%type right %type leaves %% -input: /* empty */ { $$ = input_tree = NULL; } +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; - - input_tree = $$; } ; command: ';' { $$ = tree_malloc(ST_EMPTY); } - | '{' command next '}' { + | '{' command input '}' { $$ = tree_malloc(ST_BLOCK); $$->pt.block.head = $2; $$->pt.block.tail = $3; } | '{' '}' { $$ = tree_malloc(ST_EMPTY); } | cif - | ass ';' { $$ = $1} - | arrow ';' { $$ = $1} + | ass ';' { $$ = $1; } + | arrow ';' { $$ = $1; } -; - -next: /* empty */ {$$ = NULL} - | command - - ; cif: KW_IF cond command KW_ELSE command { @@ -158,36 +86,37 @@ cif: KW_IF cond command KW_ELSE command { $$ = tree_malloc(ST_IF); $$->pt.tif.c = $2; $$->pt.tif.i = $3; - $$->pt.tif.e = NULL; + $$->pt.tif.e = tree_malloc(ST_EMPTY); } ; cond: '!' cond { $$ = tree_malloc(ST_COND); $$->pt.cond.left = $2; - $$->pt.cond.right = NULL; + $$->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; } @@ -196,7 +125,13 @@ cond: '!' 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: '>' @@ -210,59 +145,101 @@ rop: '>' ; ass: - VAR '=' ass_right { + 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.s = $1; - + $$->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: NUM { - $$ = tree_malloc(ST_LEAF); - $$->pt.leaf.type = L_NUM; - $$->pt.leaf.value.n = $1; - } - | VAR { +leaves: VAR { $$ = tree_malloc(ST_LEAF); $$->pt.leaf.type = L_VAR; - $$->pt.leaf.value.s = $1; + $$->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.s = $1; + $$->pt.leaf.value = $1; + $$->pt.leaf.n = store_const($1); } ; arrow: left ARROW right ass_right { $$ = tree_malloc(ST_ARROW); $$->pt.arrow.s = $4; - $$->pt.arrow.kw_left = $1; - $$->pt.arrow.kw_right = $3; + $$->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 */ {$$=NULL} - | KW_COPY { $$ = "copy" } +left: /* empty */ { $$ = K_EMPTY;} + | KW_COPY { $$ = K_COPY; } + +; +right: /* empty */ { $$ = K_EMPTY; } + | KW_PIPE { $$ = K_PIPE; } + | KW_MAIL { $$ = K_MAIL; } + | KW_FILTER { $$ = K_FILTER; } ; -right: /* empty */ {$$ = NULL} - | KW_PIPE { $$ = "pipe" } - | KW_MAIL { $$ = "mail" } +ass_right_p: '(' ass_right ')' {$$ = $2; } + | ass_right {$$ = $1; } ; ass_right: leaves | ass_right '.' ass_right { $$ = tree_malloc(ST_OP); - $$->pt.op.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; + } ; %% @@ -277,127 +254,32 @@ tree_malloc(int type) return temp; } -int -regex_cmp(char* s, char* r) +enum var_type +get_var_type(char* var) { - 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); + 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 res; + return VAR_INTERN; } void yyerror (char const *s) { - fprintf (stderr, "Line %d: %s\n", line, s); -} - -void -print_ind(int num, char c) -{ - int i; - - for (i = 0; i < num; i++){ - putchar(c); - } -} - -void -print_tree(struct tree* t, int ind) -{ - if (!t) - return; - - switch (t->st){ - case ST_IF: - print_ind(ind,' '); - puts("if"); - print_tree(t->pt.tif.c,ind+1); - print_ind(ind,' '); - puts("then"); - print_tree(t->pt.tif.i,ind+1); - print_ind(ind,' '); - puts("else"); - print_tree(t->pt.tif.e,ind+1); - break; - case ST_COND: -#define UPPER(a) ((a) >> 8) -#define LOWER(a) ((a) & 0xFF) - print_tree(t->pt.cond.left, ind+1); - print_ind(ind,' '); - - if (UPPER(t->pt.cond.op) > 0) - putchar(UPPER(t->pt.cond.op)); - putchar(LOWER(t->pt.cond.op)); - putchar('\n'); - print_tree(t->pt.cond.right, ind+1); - break; - case ST_BLOCK: - print_tree(t->pt.block.head,ind); - print_tree(t->pt.block.tail,ind); - break; - case ST_ASS: - print_tree(t->pt.ass.left, ind+1); - print_ind(ind,' '); - puts("="); - print_tree(t->pt.ass.right, ind+1); - break; - case ST_LEAF: - print_ind(ind, ' '); - switch (t->pt.leaf.type){ - case L_VAR: - putchar('$'); - case L_CONST: - puts(t->pt.leaf.value.s); - break; - case L_NUM: - printf("%d\n",t->pt.leaf.value.n); - break; - } - break; - case ST_ARROW: - if (t->pt.arrow.kw_left){ - print_ind(ind+1, ' '); - puts(t->pt.arrow.kw_left); - } - print_ind(ind, ' '); - printf("->\n"); - if (t->pt.arrow.kw_right){ - print_ind(ind+1, ' '); - puts(t->pt.arrow.kw_right); - } - print_tree(t->pt.arrow.s,ind+1); - break; - case ST_OP: - print_tree(t->pt.op.left, ind+1); - print_ind(ind,' '); - putchar(t->pt.op.op); - putchar('\n'); - print_tree(t->pt.op.right, ind+1); - break; - case ST_EMPTY: - break; - - - } -} - - -int -main(void) -{ -// yydebug=1; - yyparse (); - - print_tree(input_tree,0); - return 0; + fprintf (stderr, "Line %d: %s\n Saving your e-mail to default mailbox %s\n", + line, s, default_mailbox); + longjmp(env, 1); }