From: Anicka Bernathova Date: Mon, 7 Jul 2008 15:09:56 +0000 (+0200) Subject: print parse tree X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=57679925e1533fb05f03bf73f47ac85fe6570a1c;p=umpf.git print parse tree --- diff --git a/cond.y b/cond.y index 34af263..e69668b 100644 --- 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 VAR %token KW_PIPE KW_MAIL KW_COPY %token '(' ')' '{' '}' ';' -%left KW_ELSE -%left KW_IF +%nonassoc KW_IF +%nonassoc KW_ELSE %left ARROW %left EQ NEQ GE LE '<' '>' RE NRE +%left '=' +%left '.' %left '+' '-' %left '*' '/' %left '|' %left '^' %left '&' %left '!' -%left '=' %type input %type command %type next @@ -95,10 +99,12 @@ struct tree { %type 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 ba892db..35b5b00 100644 --- 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 index 0000000..71799df --- /dev/null +++ b/lex.h @@ -0,0 +1 @@ +void* xmalloc(size_t size);