1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
%{
#include <stdio.h>
#include <libestr.h>
#include "utils.h"
#define YYDEBUG 1
%}
%union {
char *s;
es_str_t *estr;
enum cnfobjType objType;
struct cnfobj *obj;
struct nvlst *nvlst;
struct cnfactlst *actlst;
}
%token <estr> NAME
%token <estr> VALUE
%token <objType> BEGINOBJ
%token ENDOBJ
%token <s> CFSYSLINE
%token BEGIN_ACTION
%token <s> LEGACY_ACTION
%token <s> PRIFILT
%token <s> PROPFILT
%token IF
%token THEN
%token NUMBER
%type <nvlst> nv nvlst
%type <obj> obj
%type <actlst> actlst
%type <actlst> act
%type <s> cfsysline
%type <actlst> block
%expect 3
/* two 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.
*/
%%
conf: /* empty (to end recursion) */
| obj conf
| cfsysline conf
| rule conf
obj: BEGINOBJ nvlst ENDOBJ { $$ = cnfobjNew($1, $2);
cnfobjPrint($$);
cnfobjDestruct($$);
}
| BEGIN_ACTION nvlst ENDOBJ { struct cnfobj *t = cnfobjNew(CNFOBJ_ACTION, $2);
cnfobjPrint(t);
cnfobjDestruct(t);
printf("XXXX: this is an new-style action!\n");
}
cfsysline: CFSYSLINE { printf("XXXX: processing CFSYSLINE: %s\n", $1); }
nvlst: { $$ = NULL; }
| nvlst nv { $2->next = $1; $$ = $2; }
nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); }
rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1);
$2 = cnfactlstReverse($2);
cnfactlstPrint($2); }
| PROPFILT actlst
| scriptfilt
scriptfilt: IF NUMBER THEN actlst { printf("if filter detected\n"); }
/* 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
* "act", only. We can implement that via the "&" actlist logic.
*/
block: actlst
| block actlst
/* v7: | actlst
v7: | block rule */
actlst: act { printf("action (end actlst)\n");$$=$1; }
| actlst '&' act { printf("in actionlist \n");
$3->next = $1; $$ = $3; }
| actlst cfsysline { printf("in actionlist/CFSYSLINE: %s\n", $2);
$$ = cnfactlstAddSysline($1, $2); }
| '{' block '}' { $$ = $2; }
act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); }
| LEGACY_ACTION { printf("legacy action: '%s'\n", $1);
$$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); }
%%
int yyerror(char *s)
{
printf("yyerror called: %s\n", s);
}
int main()
{
yydebug = 0;
return yyparse();
}
|