]> mj.ucw.cz Git - umpf.git/commitdiff
print parse tree
authorAnicka Bernathova <anicka@anicka.net>
Mon, 7 Jul 2008 15:09:56 +0000 (17:09 +0200)
committerAnicka Bernathova <anicka@anicka.net>
Mon, 7 Jul 2008 15:09:56 +0000 (17:09 +0200)
cond.y
lex.c
lex.h [new file with mode: 0644]

diff --git a/cond.y b/cond.y
index 34af26373f77b43e4ff1553811ff5997e183fc45..e69668b30b7fc2a94264b545b21c3e4bf1cfe781 100644 (file)
--- a/cond.y
+++ b/cond.y
@@ -13,6 +13,7 @@ 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 {
@@ -22,19 +23,19 @@ struct tree {
                ST_ASS,
                ST_LEAF,
                ST_EMPTY
-       } st;
+       } st;   /* subtree type */
        union {
                struct {
-                       struct tree* c;
-                       struct tree* i;
-                       struct tree* e; 
+                       struct tree* c; /* condition */
+                       struct tree* i; /* if */
+                       struct tree* e; /* else */
                } tif;
 
                struct {
-                       int op; 
+                       int op;
                        struct tree* left;
                        struct tree* right;
-               } cond;
+               } cond; /* binary operator */
 
                struct {
                        struct tree* head;
@@ -61,6 +62,8 @@ struct tree {
        } pt;
 };
 
+struct tree* input_tree;
+
 %}
 
 %union {
@@ -74,17 +77,18 @@ struct tree {
 %token <str> VAR
 %token KW_PIPE KW_MAIL KW_COPY
 %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 '+' '-' 
 %left '*' '/'
 %left <n> '|'
 %left <n> '^'
 %left <n> '&'
 %left <n> '!'
-%left '='
 %type <tr> input 
 %type <tr> command 
 %type <tr> next 
@@ -95,10 +99,12 @@ struct tree {
 %type <n> rop 
 
 %%
-input: /* empty */     { $$ = NULL }
+input: /* empty */     { $$ = input_tree = NULL; }
        | command input {       $$ = tree_malloc(ST_BLOCK); 
                                $$->pt.block.head = $1;
-                               $$->pt.block.tail = $2; 
+                               $$->pt.block.tail = $2;
+
+                               input_tree = $$;
                        } 
 ;
 
@@ -108,8 +114,8 @@ command:     ';' { $$ = tree_malloc(ST_EMPTY); }
                                                $$->pt.block.head = $2;
                                                $$->pt.block.tail = $3; 
                                        }
-               | '{' '}' { $$ = NULL }
-               | cif { $$ = $1 }
+               | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
+               | cif
                | ass ';' { $$ = $1}
                
        
@@ -248,9 +254,83 @@ yyerror (char const *s)
        fprintf (stderr, "%s\n", 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_EMPTY:
+                       break;  
+
+
+       }
+}
+
+
 int
 main(void)
 {
-//     yydebug=1;
-       return yyparse ();
+       yydebug=1;
+       yyparse ();
+
+       print_tree(input_tree,0);
+       return 0;
 }
diff --git a/lex.c b/lex.c
index ba892dbdf29789b18e073cd936e85a415c279a11..35b5b00f67073f012ad45ad9f68e72fb75610a88 100644 (file)
--- a/lex.c
+++ b/lex.c
@@ -129,13 +129,13 @@ yylex(void)
        int d = getchar();
        if (d >= 0) {
                switch (CC(c,d)) {
-               case CC('!','='): return NEQ;
-               case CC('!','~'): return NRE;
-               case CC('<','='): return LE;
-               case CC('>','='): return GE;
-               case CC('=','='): return EQ;
-               case CC('~','~'): return RE;
-               case CC('-','>'): return ARROW;
+               case CC('!','='): yylval.n = CC('!','='); return NEQ;
+               case CC('!','~'): yylval.n = CC('!','='); return NRE;
+               case CC('<','='): yylval.n = CC('<','='); return LE;
+               case CC('>','='): yylval.n = CC('>','='); return GE;
+               case CC('=','='): yylval.n = CC('=','='); return EQ;
+               case CC('~','~'): yylval.n = CC('~','~'); return RE;
+               case CC('-','>'): yylval.n = CC('-','>'); return ARROW;
                }
                ungetc(d,stdin);
        }
@@ -154,6 +154,8 @@ yylex(void)
                case '>':
                case '=':
                case ';':
+               case '.':
+                       yylval.n = c;
                        return c;
                
                case '"':
@@ -178,6 +180,7 @@ yylex(void)
                        if (i >= BUFSIZE-1)
                                parse_err("Too long identifier, max allowed length is %d",BUFSIZE-1);   
                }
+               ungetc(c,stdin);
                buf[i] = 0;
                yylval.str = xstrdup(buf);
 
@@ -195,6 +198,7 @@ yylex(void)
                                parse_err("Keyword too long");
                }
                buf[i] = 0;
+               ungetc(c,stdin);
 
                n = (sizeof(k)/sizeof(struct keys));
                for (i = 0; i < n; i++){
diff --git a/lex.h b/lex.h
new file mode 100644 (file)
index 0000000..71799df
--- /dev/null
+++ b/lex.h
@@ -0,0 +1 @@
+void* xmalloc(size_t size);