From 1cdab4d2b548a0db54b5a2c5404f3f78e012113e Mon Sep 17 00:00:00 2001 From: Rainer Gerhards Date: Sun, 3 Jul 2011 13:10:37 +0200 Subject: milestone: support for action list added to grammar --- grammar/rscript.l | 4 +- grammar/rscript.y | 33 +++++++++++---- grammar/utils.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- grammar/utils.h | 22 ++++++++++ 4 files changed, 163 insertions(+), 13 deletions(-) diff --git a/grammar/rscript.l b/grammar/rscript.l index ccc39a2f..750a3e81 100644 --- a/grammar/rscript.l +++ b/grammar/rscript.l @@ -105,8 +105,8 @@ static int preCommentState; . { printf("INOBJ: invalid char '%s'\n", yytext); } /* CFSYSLINE is valid in all modes */ -\$[a-z]+.*$ { yylval.s = yytext; return CFSYSLINE; } -\$[a-z]+.*$ { yylval.s = yytext; return CFSYSLINE; } +\$[a-z]+.*$ { yylval.s = strdup(yytext); return CFSYSLINE; } +\$[a-z]+.*$ { yylval.s = strdup(yytext); return CFSYSLINE; } \#.*\n /* skip comments in input */ [\n\t ] /* drop whitespace */ diff --git a/grammar/rscript.y b/grammar/rscript.y index 5bd8f0f9..15348e4d 100644 --- a/grammar/rscript.y +++ b/grammar/rscript.y @@ -12,6 +12,7 @@ enum cnfobjType objType; struct cnfobj *obj; struct nvlst *nvlst; + struct cnfactlst *actlst; } %token NAME @@ -26,9 +27,20 @@ %type nv nvlst %type obj -%type actlst -%type act +%type actlst +%type act + +%expect 2 +/* 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 @@ -50,15 +62,20 @@ nvlst: { $$ = NULL; } | nvlst nv { $2->next = $1; $$ = $2; } nv: NAME '=' VALUE { $$ = nvlstNew($1, $3); } -rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1); } +rule: PRIFILT actlst { printf("PRIFILT: %s\n", $1); free($1); + $2 = cnfactlstReverse($2); + cnfactlstPrint($2); } | PROPFILT actlst -actlst: act { printf("action (end actlst) %s\n", $1);$$=$1; } - | actlst '&' act { printf("in actionlist %s\n", $3); } -act: BEGIN_ACTION nvlst ENDOBJ { $$ = "obj"; } +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); } + +act: BEGIN_ACTION nvlst ENDOBJ { $$ = cnfactlstNew(CNFACT_V2, $2, NULL); } | LEGACY_ACTION { printf("legacy action: '%s'\n", $1); - /*free($1);*/ - $$ = $1;} + $$ = cnfactlstNew(CNFACT_LEGACY, NULL, $1); } %% int yyerror(char *s) diff --git a/grammar/utils.c b/grammar/utils.c index a505704f..28e1a04a 100644 --- a/grammar/utils.c +++ b/grammar/utils.c @@ -74,7 +74,6 @@ nvlstDestruct(struct nvlst *lst) } } - void nvlstPrint(struct nvlst *lst) { @@ -119,14 +118,126 @@ cnfobjPrint(struct cnfobj *o) nvlstPrint(o->nvlst); } + +struct cnfactlst* +cnfactlstNew(enum cnfactType actType, struct nvlst *lst, char *actLine) +{ + struct cnfactlst *actlst; + + if((actlst = malloc(sizeof(struct cnfactlst))) != NULL) { + actlst->next = NULL; + actlst->syslines = NULL; + actlst->actType = actType; + if(actType == CNFACT_V2) + actlst->data.lst = lst; + else + actlst->data.legActLine = actLine; + } + return actlst; +} + +struct cnfactlst* +cnfactlstAddSysline(struct cnfactlst* actlst, char *line) +{ + struct cnfcfsyslinelst *cflst; + + if((cflst = malloc(sizeof(struct cnfcfsyslinelst))) != NULL) { + cflst->next = NULL; + cflst->line = line; + if(actlst->syslines == NULL) { + actlst->syslines = cflst; + } else { + cflst->next = actlst->syslines; + actlst->syslines = cflst; + } + } + return actlst; +} + +void +cnfactlstDestruct(struct cnfactlst *actlst) +{ + struct cnfactlst *toDel; + + while(actlst != NULL) { + toDel = actlst; + actlst = actlst->next; + if(toDel->actType == CNFACT_V2) + nvlstDestruct(toDel->data.lst); + else + free(toDel->data.legActLine); + free(toDel); + } + +} + +static inline struct cnfcfsyslinelst* +cnfcfsyslinelstReverse(struct cnfcfsyslinelst *lst) +{ + struct cnfcfsyslinelst *curr, *prev; + + if(lst == NULL) + return; + prev = lst; + lst = lst->next; + prev->next = NULL; + while(lst != NULL) { + curr = lst; + lst = lst->next; + curr->next = prev; + prev = curr; + } + return prev; +} + +struct cnfactlst* +cnfactlstReverse(struct cnfactlst *actlst) +{ + struct cnfactlst *curr, *prev; + + prev = actlst; + actlst = actlst->next; + prev->next = NULL; + while(actlst != NULL) { + curr = actlst; + actlst = actlst->next; + curr->syslines = cnfcfsyslinelstReverse(curr->syslines); + curr->next = prev; + prev = curr; + } + return prev; +} + +void +cnfactlstPrint(struct cnfactlst *actlst) +{ + struct cnfcfsyslinelst *cflst; + + printf("---------- cnfactlst %p:\n", actlst); + while(actlst != NULL) { + if(actlst->actType == CNFACT_V2) { + printf("V2 action type: "); + nvlstPrint(actlst->data.lst); + } else { + printf("legacy action line: '%s'\n", + actlst->data.legActLine); + } + for( cflst = actlst->syslines + ; cflst != NULL ; cflst = cflst->next) { + printf("cfsysline: '%s'\n", cflst->line); + } + actlst = actlst->next; + } + printf("----------\n"); +} + /* debug helper */ void cstrPrint(char *text, es_str_t *estr) { char *str; - printf("in cstrPrint, estr %p\n", estr); str = es_str2cstr(estr, NULL); - printf("2: in cstrPrint, estr %p\n", estr); printf("%s%s", text, str); free(str); } + diff --git a/grammar/utils.h b/grammar/utils.h index 66b05647..2a6ba10a 100644 --- a/grammar/utils.h +++ b/grammar/utils.h @@ -30,6 +30,8 @@ cnfobjType2str(enum cnfobjType ot) } } +enum cnfactType { CNFACT_V2, CNFACT_LEGACY }; + struct cnfobj { enum cnfobjType objType; struct nvlst *nvlst; @@ -41,6 +43,21 @@ struct nvlst { es_str_t *value; }; +struct cnfcfsyslinelst { + struct cnfcfsyslinelst *next; + char *line; +}; + +struct cnfactlst { + struct cnfactlst *next; + struct cnfcfsyslinelst *syslines; + enum cnfactType actType; + union { + struct nvlst *lst; + char *legActLine; + } data; +}; + void readConfFile(FILE *fp, es_str_t **str); struct nvlst* nvlstNew(es_str_t *name, es_str_t *value); @@ -49,6 +66,11 @@ void nvlstPrint(struct nvlst *lst); struct cnfobj* cnfobjNew(enum cnfobjType objType, struct nvlst *lst); void cnfobjDestruct(struct cnfobj *o); void cnfobjPrint(struct cnfobj *o); +struct cnfactlst* cnfactlstNew(enum cnfactType actType, struct nvlst *lst, char *actLine); +void cnfactlstDestruct(struct cnfactlst *actlst); +void cnfactlstPrint(struct cnfactlst *actlst); +struct cnfactlst* cnfactlstAddSysline(struct cnfactlst* actlst, char *line); +struct cnfactlst* cnfactlstReverse(struct cnfactlst *actlst); /* debug helper */ void cstrPrint(char *text, es_str_t *estr); -- cgit