summaryrefslogtreecommitdiffstats
path: root/grammar/rscript.y
blob: 7e9365c5aba7c29435c38bd8ea96a8c2cb03950f (plain)
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();
}