summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--grammar/grammar.y69
-rw-r--r--grammar/lexer.l9
-rw-r--r--grammar/rainerscript.c54
-rw-r--r--grammar/rainerscript.h23
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 */