]> mj.ucw.cz Git - umpf.git/blobdiff - cond.y
started interpreting
[umpf.git] / cond.y
diff --git a/cond.y b/cond.y
index a199ed98463496506a485d4453d8bf3459a94be9..5410156de9db8915290caf5550d866641268f55f 100644 (file)
--- a/cond.y
+++ b/cond.y
 %{
 
 #include <stdio.h>
+#include <string.h>
+
+#include "umpf.h"
 
-int yylex (void);
-void yyerror (char const *);
+static struct tree* tree_malloc(int type);
 
 %}
+%error-verbose
 
-%token CONST
-%left EQ
-%left '|' '&' '^'
-%left '!'
+%union {
+       int n;
+       char* str;
+       struct tree* tr;        
+}
+
+%right <n> '!'
+%token <str> CONST
+%token <n> NUM
+%token <str> VAR
+%token <n> KW_DISCARD
+%token <n> KW_PIPE KW_MAIL KW_COPY
+%token '(' ')' '{' '}' ';'
+%nonassoc KW_IF
+%nonassoc KW_ELSE
+%left ARROW
+%left <n> EQ NEQ GE LE '<' '>' RE NRE
+%left <n> '='
+%left <n> '.'
+%left <n> '+' '-' 
+%left <n> '*' '/'
+%left <n> '|'
+%left <n> '^'
+%left <n> '&'
+%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 */
-       | input line
+input: /* empty */     { $$ = input_tree = tree_malloc(ST_EMPTY); }
+       | command input {       $$ = tree_malloc(ST_BLOCK); 
+                               $$->pt.block.head = $1;
+                               $$->pt.block.tail = $2;
+
+                               input_tree = $$;
+                       } 
 ;
 
-line:  '\n'
-       | boo '\n'      { printf("%s\n",$1?"true":"false"); }
-       | boo EQ boo    { $$ = $1 == $2 } 
-       | boo '|' boo   { $$ = $1 || $2 }
-       | boo '&' boo   { $$ = $1 && $2 }
-       | boo '^' boo   { $$ = ($1 || $2) && !($1 && $2) }
-       | '!' boo       { $$ = ! $1 }
+command:        ';' { $$ = tree_malloc(ST_EMPTY); }
+               | '{' command next '}'  {
+                                               $$ = tree_malloc(ST_BLOCK); 
+                                               $$->pt.block.head = $2;
+                                               $$->pt.block.tail = $3; 
+                                       }
+               | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
+               | cif
+               | ass ';' { $$ = $1; }
+               | arrow ';' { $$ = $1; }
+               
+       
 ;
 
-boo:
+next:  /* empty */ {$$ = tree_malloc(ST_EMPTY); }
+       | command
+       
 
 ;
-%%
 
-#include <ctype.h>
-#include <string.h>
+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;     
 
-#define BUFSIZE 4096
+                       }
+       | '(' 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
+;
+
+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, 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, var_hash);
+                       }
+               | CONST { 
+                               $$ = tree_malloc(ST_LEAF);
+                               $$->pt.leaf.type = L_CONST;
+                               $$->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;
+                               }
+;
 
-int
-yylex(void)
+left:  /* empty */ { $$ = K_EMPTY;}
+       | KW_COPY { $$ = K_COPY; }
+
+;
+
+right: /* empty */ { $$ = K_EMPTY; }
+       | KW_PIPE { $$ = K_PIPE; }
+       | KW_MAIL { $$ = K_MAIL; }
+;
+
+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;   
+                               }
+;
+
+%%
+
+struct tree* 
+tree_malloc(int type)
 {
+       struct tree* temp;
+       temp = xmalloc(sizeof (struct tree));
+       temp->st=type;
 
-       int c, last;
-       char temp[BUFSIZE];
-       char* p=temp;
-       
-       while ((c = getchar ()) == ' ' || c == '\t');
-       
-       if (c == '"'){
-               last = '"';
-               while ((c = getchar()) != '"' || last == '\\'){
-                       *p = c;
-                       last = c;
-                       p++;
-                       if (p-temp >= BUFSIZE-1)
-                               break;
-               }       
-               *p = '\0';
-       
-               strcpy(&yylval,temp);
-               return CONST;   
-       }
-
-       if (c == '='){
-               if ((c = getchar ()) == '=')
-                       return EQ;
-       }
-       
-       if (c == EOF)
-               return 0;
-       
-       return c;
+       return temp;
 }
 
 void
 yyerror (char const *s)
 {
-       fprintf (stderr, "%s\n", s);
-}
-
-int
-main(void)
-{
-       return yyparse ();
+       fprintf (stderr, "Line %d: %s\n", line, s);
 }