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_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;
} pt;
};
+struct tree* input_tree;
+
%}
%union {
%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
%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 = $$;
}
;
$$->pt.block.head = $2;
$$->pt.block.tail = $3;
}
- | '{' '}' { $$ = NULL }
- | cif { $$ = $1 }
+ | '{' '}' { $$ = tree_malloc(ST_EMPTY); }
+ | cif
| ass ';' { $$ = $1}
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;
}
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);
}
case '>':
case '=':
case ';':
+ case '.':
+ yylval.n = c;
return c;
case '"':
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);
parse_err("Keyword too long");
}
buf[i] = 0;
+ ungetc(c,stdin);
n = (sizeof(k)/sizeof(struct keys));
for (i = 0; i < n; i++){