summaryrefslogtreecommitdiffstats
path: root/grammar
diff options
context:
space:
mode:
authorRainer Gerhards <rgerhards@adiscon.com>2011-07-03 18:13:23 +0200
committerRainer Gerhards <rgerhards@adiscon.com>2011-07-03 18:13:23 +0200
commit719962c1f0f1ee1a6d5b5389417fb68adcde431b (patch)
treecaef20ab6f3c5e0407a9e78e41980126e642c4e5 /grammar
parent65076e28dfed0765e51c69be81a7842331aae1d2 (diff)
downloadrsyslog-719962c1f0f1ee1a6d5b5389417fb68adcde431b.tar.gz
rsyslog-719962c1f0f1ee1a6d5b5389417fb68adcde431b.tar.xz
rsyslog-719962c1f0f1ee1a6d5b5389417fb68adcde431b.zip
milestone: added grammar for arithmetic expressions
Diffstat (limited to 'grammar')
-rw-r--r--grammar/makefile7
-rw-r--r--grammar/mini.samp2
-rw-r--r--grammar/rscript.l26
-rw-r--r--grammar/rscript.y28
-rw-r--r--grammar/utils.c73
-rw-r--r--grammar/utils.h28
6 files changed, 146 insertions, 18 deletions
diff --git a/grammar/makefile b/grammar/makefile
index 29aab217..eb6c9522 100644
--- a/grammar/makefile
+++ b/grammar/makefile
@@ -1,5 +1,5 @@
rscript: lex.yy.c utils.o rscript.tab.h utils.h
- gcc -o rscript lex.yy.c rscript.tab.c utils.o -lestr
+ gcc -g -o rscript lex.yy.c rscript.tab.c utils.o -lestr
lex.yy.c: rscript.l rscript.tab.h
flex rscript.l
@@ -8,4 +8,7 @@ rscript.tab.h: rscript.y
bison -d rscript.y
utils.o: utils.c utils.h
- gcc -c utils.c
+ gcc -g -Wall -c utils.c
+
+clean:
+ rm *.o
diff --git a/grammar/mini.samp b/grammar/mini.samp
index 54efacec..6aae758d 100644
--- a/grammar/mini.samp
+++ b/grammar/mini.samp
@@ -24,7 +24,7 @@ if 1 then { /var/log/log3
@@fwd
rger
}
-if 1/*pri("*.*")*/ then {
+if 2*4/5--(10-3)/*pri("*.*")*/ then {
action(type="omfile" taget="/var/log/log5")
action(type="omfile" taget="/var/log/log6")
action(type="omfwd" taget="10.0.0.1" port="514")
diff --git a/grammar/rscript.l b/grammar/rscript.l
index d6dab45b..f7e51e25 100644
--- a/grammar/rscript.l
+++ b/grammar/rscript.l
@@ -45,11 +45,16 @@ static int preCommentState;
/* keywords */
"if" { BEGIN EXPR; return IF; }
<EXPR>"then" { BEGIN INITIAL; return THEN; }
-<EXPR>"or" { printf("OR\n"); }
-<EXPR>"and" { printf("AND\n"); }
-<EXPR>"not" { printf("NOT\n"); }
-<EXPR>"(" { printf("LPAREN\n"); }
-<EXPR>")" { printf("RPAREN\n"); }
+<EXPR>"or" { return OR; }
+<EXPR>"and" { return AND; }
+<EXPR>"not" { return NOT; }
+<EXPR>"*" |
+<EXPR>"/" |
+<EXPR>"%" |
+<EXPR>"+" |
+<EXPR>"-" |
+<EXPR>"(" |
+<EXPR>")" { return yytext[0]; }
<EXPR>"==" { printf("==\n"); }
<EXPR>"<=" { printf("<=\n"); }
<EXPR>">=" { printf(">=\n"); }
@@ -61,11 +66,12 @@ static int preCommentState;
<EXPR>"contains_i" { printf("CONTAINS_I\n"); }
<EXPR>"startswith" { printf("STARTSWITH\n"); }
<EXPR>"startswith_i" { printf("STARTSWITH_I\n"); }
-<EXPR>-?0[0-7]+ { printf("NUMBER (oct) %s\n", yytext); }
-<EXPR>-?0x[0-7a-f] { printf("NUMBER (hex) %s\n", yytext); }
-<EXPR>-?([1-9][0-9]*|0) { printf("NUMBER (dec) %s\n", yytext); return NUMBER; }
-<EXPR>\$[$!]{0,1}[a-z][a-z0-9\-_\.]* { printf("VARNAME: '%s'\n", yytext); }
-<EXPR>\'([^'\\]|\\['])*\' { printf("EXPR string: -%s-\n", yytext); }
+<EXPR>0[0-7]+ { printf("NUMBER (oct) %s\n", yytext); }
+<EXPR>0x[0-7a-f] { printf("NUMBER (hex) %s\n", yytext); }
+<EXPR>([1-9][0-9]*|0) { printf("NUMBER (dec) %s\n", yytext);
+ yylval.n = atoll(yytext); return NUMBER; }
+<EXPR>\$[$!]{0,1}[a-z][a-z0-9\-_\.]* { printf("VARNAME: '%s'\n", yytext); return VAR; }
+<EXPR>\'([^'\\]|\\['])*\' { printf("EXPR string: -%s-\n", yytext); return STRING; }
<EXPR>[ \t\n]
<EXPR>. { printf("invalid char in expr: %s\n", yytext); }
"&" { return '&'; }
diff --git a/grammar/rscript.y b/grammar/rscript.y
index 7e9365c5..3b680990 100644
--- a/grammar/rscript.y
+++ b/grammar/rscript.y
@@ -8,11 +8,13 @@
%union {
char *s;
+ long long n;
es_str_t *estr;
enum cnfobjType objType;
struct cnfobj *obj;
struct nvlst *nvlst;
struct cnfactlst *actlst;
+ struct cnfexpr *expr;
}
%token <estr> NAME
@@ -26,7 +28,12 @@
%token <s> PROPFILT
%token IF
%token THEN
-%token NUMBER
+%token OR
+%token AND
+%token NOT
+%token VAR
+%token <estr> STRING
+%token <n> NUMBER
%type <nvlst> nv nvlst
%type <obj> obj
@@ -34,6 +41,12 @@
%type <actlst> act
%type <s> cfsysline
%type <actlst> block
+%type <expr> expr
+
+%left AND OR
+%left '+' '-'
+%left '*' '/' '%'
+%nonassoc UMINUS NOT
%expect 3
/* two shift/reduce conflicts are created by the CFSYSLINE construct, which we
@@ -72,7 +85,7 @@ rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1);
| PROPFILT actlst
| scriptfilt
-scriptfilt: IF NUMBER THEN actlst { printf("if filter detected\n"); }
+scriptfilt: IF expr THEN actlst { printf("if filter detected, expr:\n"); cnfexprPrint($2,0); }
/* note: we can do some limited block-structuring with the v6 engine. In that case,
* we must not support additonal filters inside the blocks, so they must consist of
@@ -94,6 +107,17 @@ act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); }
| LEGACY_ACTION { printf("legacy action: '%s'\n", $1);
$$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); }
+expr: expr '+' expr { $$ = cnfexprNew('+', $1, $3); }
+ | expr '-' expr { $$ = cnfexprNew('-', $1, $3); }
+ | expr '*' expr { $$ = cnfexprNew('*', $1, $3); }
+ | expr '/' expr { $$ = cnfexprNew('/', $1, $3); }
+ | expr '%' expr { $$ = cnfexprNew('%', $1, $3); }
+ | '(' expr ')' { $$ = $2; printf("( expr)\n"); }
+ | '-' expr %prec UMINUS { printf("uminus\n"); $$ = cnfexprNew('M', NULL, $2); }
+ | NUMBER { $$ = cnfnumvalNew($1); }
+ | STRING { $$ = cnfstringvalNew($1); }
+ | VAR { printf("variables not yet implemented!\n"); }
+
%%
int yyerror(char *s)
{
diff --git a/grammar/utils.c b/grammar/utils.c
index 28e1a04a..c26a856c 100644
--- a/grammar/utils.c
+++ b/grammar/utils.c
@@ -8,11 +8,9 @@
void
readConfFile(FILE *fp, es_str_t **str)
{
- int c;
char ln[10240];
int len, i;
int start; /* start index of to be submitted text */
- char *fgetsRet;
int bContLine = 0;
*str = es_newStr(4096);
@@ -177,7 +175,7 @@ cnfcfsyslinelstReverse(struct cnfcfsyslinelst *lst)
struct cnfcfsyslinelst *curr, *prev;
if(lst == NULL)
- return;
+ return NULL;
prev = lst;
lst = lst->next;
prev->next = NULL;
@@ -231,6 +229,75 @@ cnfactlstPrint(struct cnfactlst *actlst)
printf("----------\n");
}
+struct cnfexpr*
+cnfexprNew(int nodetype, struct cnfexpr *l, struct cnfexpr *r)
+{
+ struct cnfexpr *expr;
+ if((expr = malloc(sizeof(struct cnfexpr))) != NULL) {
+ expr->nodetype = nodetype;
+ expr->l = l;
+ expr->r = r;
+ }
+ return expr;
+}
+
+
+inline static void
+doIndent(indent)
+{
+ int i;
+ for(i = 0 ; i < indent ; ++i)
+ printf(" ");
+}
+void
+cnfexprPrint(struct cnfexpr *expr, int indent)
+{
+ //printf("expr %p, indent %d, type '%c'\n", expr, indent, expr->nodetype);
+ switch(expr->nodetype) {
+ case 'N':
+ doIndent(indent);
+ printf("%lld\n", ((struct cnfnumval*)expr)->val);
+ break;
+ case '+':
+ case '-':
+ case '*':
+ case '/':
+ case '%':
+ case 'M':
+ if(expr->l != NULL)
+ cnfexprPrint(expr->l, indent+1);
+ doIndent(indent);
+ printf("%c\n", (char) expr->nodetype);
+ cnfexprPrint(expr->r, indent+1);
+ break;
+ default:
+ printf("error: unknown nodetype\n");
+ break;
+ }
+}
+
+struct cnfnumval*
+cnfnumvalNew(long long val)
+{
+ struct cnfnumval *numval;
+ if((numval = malloc(sizeof(struct cnfnumval))) != NULL) {
+ numval->nodetype = 'N';
+ numval->val = val;
+ }
+ return numval;
+}
+
+struct cnfstringval*
+cnfstringvalNew(es_str_t *estr)
+{
+ struct cnfstringval *strval;
+ if((strval = malloc(sizeof(struct cnfstringval))) != NULL) {
+ strval->nodetype = 'S';
+ strval->estr = estr;
+ }
+ return strval;
+}
+
/* debug helper */
void
cstrPrint(char *text, es_str_t *estr)
diff --git a/grammar/utils.h b/grammar/utils.h
index 2a6ba10a..a402d4b2 100644
--- a/grammar/utils.h
+++ b/grammar/utils.h
@@ -58,6 +58,30 @@ struct cnfactlst {
} data;
};
+/* the following structures support expressions, and may (very much later
+ * be the sole foundation for the AST.
+ */
+struct cnfexpr {
+ int nodetype;
+ struct cnfexpr *l;
+ struct cnfexpr *r;
+};
+
+struct cnfnumval {
+ int nodetype;
+ long long val;
+};
+
+struct cnfstringval {
+ int nodetype;
+ es_str_t *estr;
+};
+
+/* future extensions
+struct x {
+ int nodetype;
+};
+*/
void readConfFile(FILE *fp, es_str_t **str);
struct nvlst* nvlstNew(es_str_t *name, es_str_t *value);
@@ -71,6 +95,10 @@ void cnfactlstDestruct(struct cnfactlst *actlst);
void cnfactlstPrint(struct cnfactlst *actlst);
struct cnfactlst* cnfactlstAddSysline(struct cnfactlst* actlst, char *line);
struct cnfactlst* cnfactlstReverse(struct cnfactlst *actlst);
+struct cnfexpr* cnfexprNew(int nodetype, struct cnfexpr *l, struct cnfexpr *r);
+void cnfexprPrint(struct cnfexpr *expr, int indent);
+struct cnfnumval* cnfnumvalNew(long long val);
+struct cnfstringval* cnfstringvalNew(es_str_t *estr);
/* debug helper */
void cstrPrint(char *text, es_str_t *estr);