X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=cond.y;h=e69668b30b7fc2a94264b545b21c3e4bf1cfe781;hb=57679925e1533fb05f03bf73f47ac85fe6570a1c;hp=a199ed98463496506a485d4453d8bf3459a94be9;hpb=83a5c325a43c8cec2d0b59ba39a4b3267081a4fc;p=umpf.git diff --git a/cond.y b/cond.y index a199ed9..e69668b 100644 --- a/cond.y +++ b/cond.y @@ -1,75 +1,251 @@ %{ #include +#include +#include + +#include "lex.h" + +#define OVECCOUNT 3 int yylex (void); 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 { + ST_IF, + ST_COND, + ST_BLOCK, + ST_ASS, + ST_LEAF, + ST_EMPTY + } st; /* subtree type */ + union { + struct { + struct tree* c; /* condition */ + struct tree* i; /* if */ + struct tree* e; /* else */ + } tif; + + struct { + int op; + struct tree* left; + struct tree* right; + } cond; /* binary operator */ + + struct { + struct tree* head; + struct tree* tail; + } block; + + struct { + struct tree* left; + struct tree* right; + } ass; + + struct { + enum { + L_VAR, + L_CONST, + L_NUM + } type; + union { + char* s; + int n; + } value; + } leaf; + + } pt; +}; + +struct tree* input_tree; + %} -%token CONST -%left EQ -%left '|' '&' '^' -%left '!' +%union { + int n; + char* str; + struct tree* tr; +} + +%token CONST +%token NUM +%token VAR +%token KW_PIPE KW_MAIL KW_COPY +%token '(' ')' '{' '}' ';' +%nonassoc KW_IF +%nonassoc KW_ELSE +%left ARROW +%left EQ NEQ GE LE '<' '>' RE NRE +%left '=' +%left '.' +%left '+' '-' +%left '*' '/' +%left '|' +%left '^' +%left '&' +%left '!' +%type input +%type command +%type next +%type ass +%type ass_right +%type cif +%type cond +%type rop %% -input: /* empty */ - | input line +input: /* empty */ { $$ = input_tree = NULL; } + | command input { $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $1; + $$->pt.block.tail = $2; + + input_tree = $$; + } +; + +command: ';' { $$ = tree_malloc(ST_EMPTY); } + | '{' command next '}' { + $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $2; + $$->pt.block.tail = $3; + } + | '{' '}' { $$ = tree_malloc(ST_EMPTY); } + | cif + | ass ';' { $$ = $1} + + +; + +next: /* empty */ {$$ = NULL} + | command + + ; -line: '\n' - | boo '\n' { printf("%s\n",$1?"true":"false"); } - | boo EQ boo { $$ = $1 == $2 } - | boo '|' boo { $$ = $1 || $2 } - | boo '&' boo { $$ = $1 && $2 } - | boo '^' boo { $$ = ($1 || $2) && !($1 && $2) } - | '!' boo { $$ = ! $1 } +cif: KW_IF cond command KW_ELSE command { + $$ = tree_malloc(ST_IF); + $$->pt.tif.c = $2; + $$->pt.tif.i = $3; + $$->pt.tif.e = $5; + } + | KW_IF cond command { + $$ = tree_malloc(ST_IF); + $$->pt.tif.c = $2; + $$->pt.tif.i = $3; + $$->pt.tif.e = NULL; + } ; -boo: +cond: '!' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $2; + $$->pt.cond.right = NULL; + $$->pt.cond.op = $1; + + } + | cond '|' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + + } + | cond '&' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + + } + | cond '^' cond { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + } + | '(' cond ')' { $$ = $2; } + | ass_right rop ass_right { + $$ = tree_malloc(ST_COND); + $$->pt.cond.left = $1; + $$->pt.cond.right = $3; + $$->pt.cond.op = $2; + } ; -%% -#include -#include +rop: '>' + | '<' + | EQ + | NEQ + | LE + | GE + | RE + | NRE +; -#define BUFSIZE 4096 +ass: + VAR '=' ass_right { + $$ = tree_malloc(ST_ASS); -int -yylex(void) + $$->pt.ass.left = tree_malloc(ST_LEAF); + $$->pt.ass.left->pt.leaf.type = L_VAR; + $$->pt.ass.left->pt.leaf.value.s = $1; + + $$->pt.ass.right = $3; + } +; + +ass_right: NUM { + $$ = tree_malloc(ST_LEAF); + $$->pt.leaf.type = L_NUM; + $$->pt.leaf.value.n = $1; + } + | VAR { + $$ = tree_malloc(ST_LEAF); + $$->pt.leaf.type = L_VAR; + $$->pt.leaf.value.s = $1; + } + | CONST { + $$ = tree_malloc(ST_LEAF); + $$->pt.leaf.type = L_CONST; + $$->pt.leaf.value.s = $1; + } + +; + +%% + +struct tree* +tree_malloc(int type) { + struct tree* temp; + temp = xmalloc(sizeof (struct tree)); + temp->st=type; - int c, last; - char temp[BUFSIZE]; - char* p=temp; - - while ((c = getchar ()) == ' ' || c == '\t'); - - if (c == '"'){ - last = '"'; - while ((c = getchar()) != '"' || last == '\\'){ - *p = c; - last = c; - p++; - if (p-temp >= BUFSIZE-1) - break; - } - *p = '\0'; - - strcpy(&yylval,temp); - return CONST; - } + return temp; +} - if (c == '='){ - if ((c = getchar ()) == '=') - return EQ; - } +int +regex_cmp(char* s, char* r) +{ + pcre *brum; + int erroroffset; + const char* error; + int ovector[OVECCOUNT]; - if (c == EOF) - return 0; + brum = pcre_compile(r,0,&error,&erroroffset,NULL); + if (!brum) + return -1; - return c; + int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT); + pcre_free(brum); + + return res; } void @@ -78,8 +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) { - return yyparse (); + yydebug=1; + yyparse (); + + print_tree(input_tree,0); + return 0; }