From fa9f360626f91ca9fd6945aace8c90c9ec4bf077 Mon Sep 17 00:00:00 2001 From: Anicka Bernathova Date: Fri, 4 Jul 2008 20:42:19 +0200 Subject: [PATCH] parsing conditions --- cond.y | 217 +++++++++++++++++++++++++++++++++++++++++++++++++-------- lex.c | 10 +-- 2 files changed, 192 insertions(+), 35 deletions(-) diff --git a/cond.y b/cond.y index 6473557..34af263 100644 --- a/cond.y +++ b/cond.y @@ -4,64 +4,226 @@ #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); + +struct tree { + enum { + ST_IF, + ST_COND, + ST_BLOCK, + ST_ASS, + ST_LEAF, + ST_EMPTY + } st; + union { + struct { + struct tree* c; + struct tree* i; + struct tree* e; + } tif; + + struct { + int op; + struct tree* left; + struct tree* right; + } cond; + + 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; +}; %} %union { - int b; int n; char* str; + struct tree* tr; } %token CONST %token NUM %token VAR -%token KW_IF KW_ELSE KW_PIPE KW_MAIL KW_COPY -%token '(' ')' '{' '}' +%token KW_PIPE KW_MAIL KW_COPY +%token '(' ')' '{' '}' ';' +%left KW_ELSE +%left KW_IF %left ARROW -%left EQ NEQ GE LE '<' '>' RE NRE +%left EQ NEQ GE LE '<' '>' RE NRE %left '+' '-' %left '*' '/' -%left '|' '&' '^' -%left '!' -%left '=' -%type boo +%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 */ { $$ = NULL } + | command input { $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $1; + $$->pt.block.tail = $2; + } +; + +command: ';' { $$ = tree_malloc(ST_EMPTY); } + | '{' command next '}' { + $$ = tree_malloc(ST_BLOCK); + $$->pt.block.head = $2; + $$->pt.block.tail = $3; + } + | '{' '}' { $$ = NULL } + | cif { $$ = $1 } + | ass ';' { $$ = $1} + + +; + +next: /* empty */ {$$ = NULL} + | command + + +; + +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; + } ; -line: '\n' - | boo '\n' { printf("%s\n",$1?"true":"false"); } - | error '\n' { yyerrok; } +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; + } ; -boo: CONST EQ CONST { $$ = ! strcmp($1, $3); } - | CONST NEQ CONST { $$ = !! strcmp($1, $3); } - | CONST RE CONST { $$ = regex_cmp($1,$3) >= 0 } - | CONST NRE CONST { $$ = regex_cmp($1,$3) < 0 } - | NUM EQ NUM { $$ = $1 == $3 } - | NUM NEQ NUM { $$ = $1 != $3 } - | NUM GE NUM { $$ = $1 >= $3 } - | NUM LE NUM { $$ = $1 <= $3 } - | NUM '>' NUM { $$ = $1 > $3 } - | NUM '<' NUM { $$ = $1 < $3 } - | boo '|' boo { $$ = $1 || $3 } - | boo '&' boo { $$ = $1 && $3 } - | boo '^' boo { $$ = ($1 || $3) && !($1 && $3) } - | '!' boo { $$ = ! $2 } +rop: '>' + | '<' + | EQ + | NEQ + | LE + | GE + | RE + | NRE ; +ass: + VAR '=' ass_right { + $$ = tree_malloc(ST_ASS); + + $$->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; + + return temp; +} + int regex_cmp(char* s, char* r) { @@ -75,7 +237,6 @@ regex_cmp(char* s, char* r) return -1; int res = pcre_exec(brum,NULL,s,strlen(s),0,0,ovector,OVECCOUNT); - pcre_free(brum); return res; diff --git a/lex.c b/lex.c index 4ee876d..ba892db 100644 --- a/lex.c +++ b/lex.c @@ -115,18 +115,13 @@ is_alpha(int c) int yylex(void) { - int c, nl = 0; + int c; while ((c = getchar ()) == ' ' || c == '\t' || c =='\n'){ - if (c == '\n'){ - nl = 1; + if (c == '\n') line++; - } } - if (nl) - return '\n'; - if (c == EOF) return 0; @@ -158,6 +153,7 @@ yylex(void) case '<': case '>': case '=': + case ';': return c; case '"': -- 2.39.5