ST_BLOCK,
ST_ASS,
ST_LEAF,
- ST_EMPTY
+ ST_EMPTY,
+ ST_ARROW,
+ ST_OP
} st; /* subtree type */
union {
struct {
} value;
} leaf;
+ struct {
+ char* kw_left;
+ char* kw_right;
+ struct tree* s;
+ } arrow;
+
+ struct {
+ int op;
+ struct tree* left;
+ struct tree* right;
+ } op;
+
} pt;
};
%}
+%error-verbose
+
%union {
int n;
char* str;
%token <str> CONST
%token <n> NUM
%token <str> VAR
-%token KW_PIPE KW_MAIL KW_COPY
+%token <str> KW_PIPE KW_MAIL KW_COPY
%token '(' ')' '{' '}' ';'
%nonassoc KW_IF
%nonassoc KW_ELSE
%type <tr> ass
%type <tr> ass_right
%type <tr> cif
+%type <tr> arrow
%type <tr> cond
%type <n> rop
+%type <str> left
+%type <str> right
+%type <tr> leaves
%%
input: /* empty */ { $$ = input_tree = NULL; }
| '{' '}' { $$ = tree_malloc(ST_EMPTY); }
| cif
| ass ';' { $$ = $1}
+ | arrow ';' { $$ = $1}
;
}
;
-ass_right: NUM {
+leaves: NUM {
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_NUM;
$$->pt.leaf.value.n = $1;
$$->pt.leaf.type = L_VAR;
$$->pt.leaf.value.s = $1;
}
- | CONST {
+ | CONST {
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_CONST;
$$->pt.leaf.value.s = $1;
}
+;
+
+arrow: left ARROW right ass_right {
+ $$ = tree_malloc(ST_ARROW);
+ $$->pt.arrow.s = $4;
+ $$->pt.arrow.kw_left = $1;
+ $$->pt.arrow.kw_right = $3;
+ }
+;
+left: /* empty */ {$$=NULL}
+ | KW_COPY { $$ = "copy" }
+
+;
+
+right: /* empty */ {$$ = NULL}
+ | KW_PIPE { $$ = "pipe" }
+ | KW_MAIL { $$ = "mail" }
+;
+
+ass_right: leaves
+ | ass_right '.' ass_right {
+ $$ = tree_malloc(ST_OP);
+ $$->pt.op.op = '.';
+ $$->pt.op.left = $1;
+ $$->pt.op.right = $3;
+ }
;
%%
void
yyerror (char const *s)
{
- fprintf (stderr, "%s\n", s);
+ fprintf (stderr, "Line %d: %s\n", line, s);
}
void
break;
}
break;
+ case ST_ARROW:
+ if (t->pt.arrow.kw_left){
+ print_ind(ind+1, ' ');
+ puts(t->pt.arrow.kw_left);
+ }
+ print_ind(ind, ' ');
+ printf("->\n");
+ if (t->pt.arrow.kw_right){
+ print_ind(ind+1, ' ');
+ puts(t->pt.arrow.kw_right);
+ }
+ print_tree(t->pt.arrow.s,ind+1);
+ break;
+ case ST_OP:
+ print_tree(t->pt.op.left, ind+1);
+ print_ind(ind,' ');
+ putchar(t->pt.op.op);
+ putchar('\n');
+ print_tree(t->pt.op.right, ind+1);
+ break;
case ST_EMPTY:
break;
int
main(void)
{
- yydebug=1;
+// yydebug=1;
yyparse ();
print_tree(input_tree,0);