]> mj.ucw.cz Git - umpf.git/blobdiff - cond.y
fix many little bugs, release 0.1
[umpf.git] / cond.y
diff --git a/cond.y b/cond.y
index 34af26373f77b43e4ff1553811ff5997e183fc45..3b5d6239ba2bb78e439539a18041545b15e16f26 100644 (file)
--- a/cond.y
+++ b/cond.y
@@ -2,66 +2,15 @@
 
 #include <stdio.h>
 #include <string.h>
-#include <pcre.h>
+#include <ctype.h>
 
-#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);
-
-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;
-};
+static struct tree* tree_malloc(int type);
+static enum var_type get_var_type(char* var);
 
 %}
+%error-verbose
 
 %union {
        int n;
@@ -72,53 +21,59 @@ struct tree {
 %token <str> CONST
 %token <n> NUM
 %token <str> VAR
-%token KW_PIPE KW_MAIL KW_COPY
+%token <n> KW_DISCARD
+%token <n> KW_PIPE KW_MAIL KW_COPY KW_FILTER
 %token '(' ')' '{' '}' ';'
-%left KW_ELSE
-%left KW_IF
+%nonassoc KW_IF
+%nonassoc KW_ELSE
 %left ARROW
 %left <n> EQ NEQ GE LE '<' '>' RE NRE
-%left '+' '-' 
-%left '*' '/'
+%left <n> '='
+%left <n> '.'
+%left <n> '+' '-' 
+%left <n> '*' '/'
 %left <n> '|'
 %left <n> '^'
 %left <n> '&'
-%left <n> '!'
-%left '='
+%right <n> '!'
+%left <n> NEG
+%type <tr> input_init 
 %type <tr> input 
 %type <tr> command 
-%type <tr> next 
 %type <tr> ass 
 %type <tr> ass_right 
+%type <tr> ass_right_p
 %type <tr> cif
+%type <tr> arrow 
 %type <tr> cond
 %type <n> rop 
+%type <n> left
+%type <n> right 
+%type <tr> leaves 
 
 %%
-input: /* empty */     { $$ = 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; 
+                               $$->pt.block.tail = $2;
                        } 
 ;
 
 command:        ';' { $$ = tree_malloc(ST_EMPTY); }
-               | '{' command next '}'  {
+               | '{' command input '}'         {
                                                $$ = tree_malloc(ST_BLOCK); 
                                                $$->pt.block.head = $2;
                                                $$->pt.block.tail = $3; 
                                        }
-               | '{' '}' { $$ = NULL }
-               | cif { $$ = $1 }
-               | ass ';' { $$ = $1}
+               | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
+               | cif
+               | ass ';' { $$ = $1; }
+               | arrow ';' { $$ = $1; }
                
        
-;
-
-next:  /* empty */ {$$ = NULL}
-       | command
-       
-
 ;
 
 cif:   KW_IF cond command KW_ELSE command      { 
@@ -131,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; }
@@ -169,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:   '>'
@@ -183,33 +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;
                                }
 ;
 
-ass_right:     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 {
+               | 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.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;   
+                       }
 ;
 
 %%
@@ -224,33 +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);
-
-       return res;
+       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;
 }
 
 void
 yyerror (char const *s)
 {
-       fprintf (stderr, "%s\n", s);
-}
-
-int
-main(void)
-{
-//     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);
 }