diff options
-rw-r--r-- | grammar/grammar.y | 69 | ||||
-rw-r--r-- | grammar/lexer.l | 9 | ||||
-rw-r--r-- | grammar/rainerscript.c | 54 | ||||
-rw-r--r-- | grammar/rainerscript.h | 23 |
4 files changed, 130 insertions, 25 deletions
diff --git a/grammar/grammar.y b/grammar/grammar.y index 8371f854..6a5256d5 100644 --- a/grammar/grammar.y +++ b/grammar/grammar.y @@ -9,7 +9,7 @@ * cases. So while we hope that cfsysline support can be dropped some time in * the future, we will probably keep these useful constructs. * - * Copyright 2011 Rainer Gerhards and Adiscon GmbH. + * Copyright 2011-2012 Rainer Gerhards and Adiscon GmbH. * * This file is part of the rsyslog runtime library. * @@ -48,11 +48,12 @@ extern int yyerror(char*); es_str_t *estr; enum cnfobjType objType; struct cnfobj *obj; + struct cnfstmt *stmt; struct nvlst *nvlst; struct objlst *objlst; struct cnfactlst *actlst; struct cnfexpr *expr; - struct cnfrule *rule; + /*struct cnfrule *rule;*/ struct cnffunc *func; struct cnffparamlst *fparams; } @@ -75,6 +76,7 @@ extern int yyerror(char*); %token <s> BSD_HOST_SELECTOR %token IF %token THEN +%token ELSE %token OR %token AND %token NOT @@ -95,13 +97,16 @@ extern int yyerror(char*); %type <nvlst> nv nvlst %type <obj> obj property constant %type <objlst> propconst -%type <actlst> actlst +/*%type <actlst> actlst %type <actlst> act -%type <s> cfsysline %type <actlst> block +*/ %type <expr> expr +%type <stmt> stmt s_act actlst block script +/* %type <rule> rule %type <rule> scriptfilt +*/ %type <fparams> fparams %left AND OR @@ -110,15 +115,9 @@ extern int yyerror(char*); %left '*' '/' '%' %nonassoc UMINUS NOT -%expect 3 -/* these shift/reduce conflicts are created by the CFSYSLINE construct, which we - * unfortunately can not avoid. The problem is that CFSYSLINE can occur both in - * global context as well as within an action. It's not permitted somewhere else, - * but this is suficient for conflicts. The "dangling else" built-in resolution - * works well to solve this issue, so we accept it (it's a wonder that our - * old style grammar doesn't work at all, so we better do not complain...). - * Use "bison -v rscript.y" if more conflicts arise and check rscript.out for - * were exactly these conflicts exits. +%expect 1 /* dangling else */ +/* If more erors show up, Use "bison -v grammar.y" if more conflicts arise and + * check grammar.output for were exactly these conflicts exits. */ %% /* note: we use left recursion below, because that saves stack space AND @@ -127,12 +126,11 @@ extern int yyerror(char*); */ conf: /* empty (to end recursion) */ | conf obj { cnfDoObj($2); } - | conf rule { cnfDoRule($2); } - | conf cfsysline { cnfDoCfsysline($2); } + | conf stmt { dbgprintf("RRRR: top-level stmt:\n"); + cnfstmtPrint($2, 0); } | conf BSD_TAG_SELECTOR { cnfDoBSDTag($2); } | conf BSD_HOST_SELECTOR { cnfDoBSDHost($2); } obj: BEGINOBJ nvlst ENDOBJ { $$ = cnfobjNew($1, $2); } - | BEGIN_ACTION nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_ACTION, $2); } | BEGIN_TPL nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_TPL, $2); } | BEGIN_TPL nvlst ENDOBJ '{' propconst '}' { $$ = cnfobjNew(CNFOBJ_TPL, $2); @@ -143,10 +141,40 @@ propconst: { $$ = NULL; } | propconst constant { $$ = objlstAdd($1, $2); } property: BEGIN_PROPERTY nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_PROPERTY, $2); } constant: BEGIN_CONSTANT nvlst ENDOBJ { $$ = cnfobjNew(CNFOBJ_CONSTANT, $2); } -cfsysline: CFSYSLINE { $$ = $1; } nvlst: { $$ = NULL; } | nvlst nv { $2->next = $1; $$ = $2; } nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); } +script: stmt { $$ = $1; dbgprintf("RRRR: root stmt\n"); } + | script stmt { $2->next = $1; $$ = $2; dbgprintf("RRRR: stmt in list\n"); } +stmt: actlst { $$ = $1; dbgprintf("RRRR: have stmt:actlst\n"); } + | STOP { $$ = cnfstmtNew(S_STOP); + dbgprintf("RRRR: have STOP\n"); } + | IF expr THEN block { $$ = cnfstmtNew(S_IF); + $$->d.cond.expr = $2; + $$->d.cond.t_then = $4; + $$->d.cond.t_else = NULL; + dbgprintf("RRRR: have s_if \n"); } + | IF expr THEN block ELSE block { $$ = cnfstmtNew(S_IF); + $$->d.cond.expr = $2; + $$->d.cond.t_then = $4; + $$->d.cond.t_else = $6; + dbgprintf("RRRR: have s_if \n"); } + | PRIFILT block { $$ = cnfstmtNew(S_PRIFILT); + $$->d.cond.printable = $1; + $$->d.cond.expr = $1; + $$->d.cond.t_then = $2; + dbgprintf("RRRR: have s_prifilt\n"); } + | PROPFILT block { $$ = cnfstmtNew(S_PROPFILT); + $$->d.cond.expr = $1; + $$->d.cond.t_then = $2; + dbgprintf("RRRR: have s_propfilt\n"); } +block: stmt { $$ = $1; dbgprintf("RRRR: have block:stmt\n"); } + | '{' script '}' { $$ = $2; dbgprintf("RRRR: have block:script\n"); } +actlst: s_act { $$ = $1; dbgprintf("RRRR: have s_act\n"); } + | actlst '&' s_act { $3->next = $1; $$ = $3; dbgprintf("RRRR: have actlst actlst:s_act\n"); } +s_act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfstmtNew(S_ACT); dbgprintf("RRRR: action object\n"); } + | LEGACY_ACTION { $$ = cnfstmtNew(S_ACT); dbgprintf("RRRR: legacy action\n"); } +/* rule: PRIFILT actlst { $$ = cnfruleNew(CNFFILT_PRI, $2); $$->filt.s = $1; } | PROPFILT actlst { $$ = cnfruleNew(CNFFILT_PROP, $2); $$->filt.s = $1; } | scriptfilt { $$ = $1; } @@ -155,14 +183,13 @@ scriptfilt: IF expr THEN actlst { $$ = cnfruleNew(CNFFILT_SCRIPT, $4); $$->filt.expr = $2; } block: actlst { $$ = $1; } | block actlst { $2->next = $1; $$ = $2; } - /* v7: | actlst - v7: | block rule */ /* v7 extensions require new rule engine capabilities! */ + / * v7: | actlst + v7: | block rule v7 extensions require new rule engine capabilities! * / actlst: act { $$=$1; } | actlst '&' act { $3->next = $1; $$ = $3; } | actlst cfsysline { $$ = cnfactlstAddSysline($1, $2); } | '{' block '}' { $$ = $2; } -act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); } - | LEGACY_ACTION { $$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); } +*/ expr: expr AND expr { $$ = cnfexprNew(AND, $1, $3); } | expr OR expr { $$ = cnfexprNew(OR, $1, $3); } | NOT expr { $$ = cnfexprNew(NOT, NULL, $2); } diff --git a/grammar/lexer.l b/grammar/lexer.l index c5e7bf7d..d603c449 100644 --- a/grammar/lexer.l +++ b/grammar/lexer.l @@ -138,6 +138,7 @@ int fileno(FILE *stream); * to tell us the real source line. */ "stop" { dbgprintf("STOP\n"); return STOP; } +"else" { dbgprintf("STOP\n"); return ELSE; } "preprocfilelinenumber(" { BEGIN LINENO; } <LINENO>[0-9]+ { yylineno = atoi(yytext) - 1; } <LINENO>")" { BEGIN INITIAL; } @@ -161,7 +162,7 @@ int fileno(FILE *stream); BEGIN INOBJ; return BEGINOBJ; } "module"[ \n\t]*"(" { yylval.objType = CNFOBJ_MODULE; BEGIN INOBJ; return BEGINOBJ; } -"action"[ \n\t]*"(" { BEGIN INOBJ; return BEGIN_ACTION; } +"action"[ \n\t]*"(" { dbgprintf("RRRR: lexer: %s\n", yytext); BEGIN INOBJ; return BEGIN_ACTION; } ^[ \t]*:\$?[a-z\-]+[ ]*,[ ]*!?[a-z]+[ ]*,[ ]*\".*\" { yylval.s = strdup(yytext); return PROPFILT; } ^[ \t]*[\*a-z][,\*a-z]*[0-7]*\.[,!=;\.\*a-z0-7]+ { yylval.s = strdup(yytext); return PRIFILT; } @@ -193,8 +194,10 @@ int fileno(FILE *stream); yyless(14); BEGIN INCL; } else { - yylval.s = strdup(yytext); - return CFSYSLINE; + /*yylval.s = strdup(yytext); + return CFSYSLINE;*/ + dbgprintf("RRRR: have CFSYSLINE/lexer: %s\n", yytext); + cnfDoCfsysline(strdup(yytext)); } } ![^ \t\n]+[ \t]*$ { yylval.s = strdup(yytext); return BSD_TAG_SELECTOR; } diff --git a/grammar/rainerscript.c b/grammar/rainerscript.c index 56a6376d..2d5bbd9b 100644 --- a/grammar/rainerscript.c +++ b/grammar/rainerscript.c @@ -107,7 +107,6 @@ objlstNew(struct cnfobj *o) lst->next = NULL; lst->obj = o; } -dbgprintf("AAAA: creating new objlst\n"); cnfobjPrint(o); return lst; @@ -1498,6 +1497,48 @@ cnfexprPrint(struct cnfexpr *expr, int indent) break; } } +void +cnfstmtPrint(struct cnfstmt *stmt, int indent) +{ + //dbgprintf("stmt %p, indent %d, type '%c'\n", expr, indent, expr->nodetype); + switch(stmt->nodetype) { + case S_STOP: + doIndent(indent); dbgprintf("STOP\n"); + break; + case S_ACT: + doIndent(indent); dbgprintf("ACTION %p\n", stmt->d.act); + break; + case S_IF: + doIndent(indent); dbgprintf("IF\n"); + cnfexprPrint(stmt->d.cond.expr, indent+1); + doIndent(indent); dbgprintf("THEN\n"); + cnfstmtPrint(stmt->d.cond.t_then, indent+1); + if(stmt->d.cond.t_else != NULL) { + doIndent(indent); dbgprintf("ELSE\n"); + cnfstmtPrint(stmt->d.cond.t_else, indent+1); + } + doIndent(indent); dbgprintf("END IF\n"); + break; + case S_PRIFILT: + doIndent(indent); dbgprintf("PRIFILT '%s'\n", stmt->d.cond.printable); + //cnfexprPrint(stmt->d.cond.expr, indent+1); + doIndent(indent); dbgprintf("THEN\n"); + cnfstmtPrint(stmt->d.cond.t_then, indent+1); + doIndent(indent); dbgprintf("END PRIFILT\n"); + break; + case S_PROPFILT: + doIndent(indent); dbgprintf("PROPFILT\n"); + cnfexprPrint(stmt->d.cond.expr, indent+1); + doIndent(indent); dbgprintf("THEN\n"); + cnfstmtPrint(stmt->d.cond.t_then, indent+1); + doIndent(indent); dbgprintf("END PROPFILT\n"); + break; + default: + dbgprintf("error: unknown stmt type %u\n", + (unsigned) stmt->nodetype); + break; + } +} struct cnfnumval* cnfnumvalNew(long long val) @@ -1532,6 +1573,17 @@ cnfvarNew(char *name) return var; } +struct cnfstmt * +cnfstmtNew(unsigned s_type) +{ + struct cnfstmt* cnfstmt; + if((cnfstmt = malloc(sizeof(struct cnfstmt))) != NULL) { + cnfstmt->nodetype = s_type; + cnfstmt->next = NULL; + } + return cnfstmt; +} + struct cnfrule * cnfruleNew(enum cnfFiltType filttype, struct cnfactlst *actlst) { diff --git a/grammar/rainerscript.h b/grammar/rainerscript.h index 4c625cd8..1fe7f1b9 100644 --- a/grammar/rainerscript.h +++ b/grammar/rainerscript.h @@ -118,7 +118,14 @@ struct cnfactlst { * R - rule * S - string * V - var + * ... plus the S_* #define's below: */ +#define S_STOP 4000 +#define S_PRIFILT 4001 +#define S_PROPFILT 4002 +#define S_IF 4003 +#define S_ACT 4004 + enum cnfFiltType { CNFFILT_NONE, CNFFILT_PRI, CNFFILT_PROP, CNFFILT_SCRIPT }; static inline char* cnfFiltType2str(enum cnfFiltType filttype) @@ -147,6 +154,20 @@ struct cnfrule { struct cnfactlst *actlst; }; +struct cnfstmt { /* base statement, for simple types */ + unsigned nodetype; + struct cnfstmt *next; + union { + struct { + struct cnfexpr *expr; + uchar *printable; /* printable expr for debugging */ + struct cnfstmt *t_then; + struct cnfstmt *t_else; + } cond; + struct action_s *act; + } d; +}; + struct cnfexpr { unsigned nodetype; struct cnfexpr *l; @@ -273,6 +294,8 @@ void cnfparamsPrint(struct cnfparamblk *params, struct cnfparamvals *vals); void varDelete(struct var *v); void cnfparamvalsDestruct(struct cnfparamvals *paramvals, struct cnfparamblk *blk); void cnfcfsyslinelstDestruct(struct cnfcfsyslinelst *cfslst); +struct cnfstmt * cnfstmtNew(unsigned s_type); +void cnfstmtPrint(struct cnfstmt *stmt, int indent); rsRetVal initRainerscript(void); /* debug helper */ |