#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#include "umpf.h"
static struct tree* tree_malloc(int type);
+static enum var_type get_var_type(char* var);
%}
%error-verbose
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 <n> KW_PIPE KW_MAIL KW_COPY KW_FILTER
%token '(' ')' '{' '}' ';'
%nonassoc KW_IF
%nonassoc KW_ELSE
%left <n> '|'
%left <n> '^'
%left <n> '&'
+%right <n> '!'
+%left <n> NEG
+%type <tr> input_init
%type <tr> input
%type <tr> command
-%type <tr> next
%type <tr> ass
%type <tr> ass_right
%type <tr> ass_right_p
%type <tr> leaves
%%
-input: /* empty */ { $$ = input_tree = tree_malloc(ST_EMPTY); }
+input_init: input {input_tree = $$}
+
+;
+input: /* empty */ { $$ = tree_malloc(ST_EMPTY); }
| command input { $$ = tree_malloc(ST_BLOCK);
$$->pt.block.head = $1;
$$->pt.block.tail = $2;
-
- input_tree = $$;
}
;
command: ';' { $$ = tree_malloc(ST_EMPTY); }
- | '{' command next '}' {
+ | '{' command input '}' {
$$ = tree_malloc(ST_BLOCK);
$$->pt.block.head = $2;
$$->pt.block.tail = $3;
| arrow ';' { $$ = $1; }
-;
-
-next: /* empty */ {$$ = tree_malloc(ST_EMPTY); }
- | command
-
-
;
cif: KW_IF cond command KW_ELSE command {
$$->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.left->pt.leaf.n = find_var($1, get_var_type($1), var_hash);
$$->pt.ass.right = $3;
}
;
$$ = tree_malloc(ST_LEAF);
$$->pt.leaf.type = L_VAR;
$$->pt.leaf.value = $1;
- $$->pt.leaf.n = find_var($1, var_hash);
+ $$->pt.leaf.n = find_var($1, get_var_type($1), var_hash);
}
| CONST {
$$ = tree_malloc(ST_LEAF);
right: /* empty */ { $$ = K_EMPTY; }
| KW_PIPE { $$ = K_PIPE; }
| KW_MAIL { $$ = K_MAIL; }
+ | KW_FILTER { $$ = K_FILTER; }
;
ass_right_p: '(' ass_right ')' {$$ = $2; }
$$->pt.op.left = $1;
$$->pt.op.right = $3;
}
+ | '-' ass_right %prec NEG {
+ $$ = tree_malloc(ST_OP);
+ $$->pt.op.op = $1;
+ $$->pt.op.left = tree_malloc(ST_LEAF);
+ $$->pt.op.left->pt.leaf.type = L_CONST;
+ $$->pt.op.left->pt.leaf.value = "0";
+ $$->pt.op.left->pt.leaf.n =
+ store_const("0");
+ $$->pt.op.right = $2;
+ }
;
%%
return temp;
}
+enum var_type
+get_var_type(char* var)
+{
+ int upper = 0;
+ int lower = 0;
+
+ if (islower(*var))
+ return VAR_USER;
+
+ while (*var) {
+ if (isupper(*var))
+ upper++;
+ if (islower(*var))
+ lower++;
+ var++;
+ }
+ if (upper && lower)
+ return VAR_HEADER;
+
+ return VAR_INTERN;
+}
+
void
yyerror (char const *s)
{
- fprintf (stderr, "Line %d: %s\n", line, s);
+ fprintf (stderr, "Line %d: %s\n Saving your e-mail to default mailbox %s\n",
+ line, s, default_mailbox);
+ longjmp(env, 1);
}