diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2010-10-25 18:24:55 -0700 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2010-10-25 18:24:55 -0700 |
commit | bd88dba48665c6002b2fad86866b0ec41e86b7ab (patch) | |
tree | 6ca3f4afa767069781d52349f366e66710a31de1 /src | |
parent | 4e89616719a7d4a84540ac7ed13933f2928e6257 (diff) | |
download | vyatta-cfg-bd88dba48665c6002b2fad86866b0ec41e86b7ab.tar.gz vyatta-cfg-bd88dba48665c6002b2fad86866b0ec41e86b7ab.zip |
initial lex/yacc config file parser
Diffstat (limited to 'src')
-rw-r--r-- | src/cparse/cparse.ypp | 100 | ||||
-rw-r--r-- | src/cparse/cparse_def.h | 12 | ||||
-rw-r--r-- | src/cparse/cparse_lex.l | 168 |
3 files changed, 280 insertions, 0 deletions
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp new file mode 100644 index 0000000..eef3d13 --- /dev/null +++ b/src/cparse/cparse.ypp @@ -0,0 +1,100 @@ +/* bison -v -t --defines=cparse.h -o cparse.cpp cparse.ypp */ +%{ +#include <stdio.h> +#include "cparse_def.h" + +extern "C" { +int yylex(); +} + +void +yyerror(const char *s) +{ + printf("%s\n", s); +} + +int level = 0; +int ndeact = 0; +char *ncomment = NULL; +char *nname = NULL; +char *nval = NULL; + +void +print_node() +{ + int i = 0; + if (ncomment) { + for (i = 0; i <= level; i++) { + printf(" "); + } + printf(" /*%s*/\n", ncomment); + } + printf("%s", ndeact ? "!" : " "); + for (i = 0; i <= level; i++) { + printf(" "); + } + printf("%s", nname); + if (nval) { + printf(" '%s'", nval); + } + printf("\n"); +} + +%} + +%token NODE +%token VALUE +%token COMMENT +%token LEFTB +%token RIGHTB + +%% + +input: forest + | forest comment +; + +forest: /* empty */ + | forest tree +; + +tree: node { + print_node(); + } + | node { + print_node(); + } LEFTB { ++level; } forest RIGHTB { --level; } +; + +node: nodec { + nval = NULL; + } + | nodec VALUE { + nval = $2.str; + } +; + +nodec: NODE { + ncomment = NULL; + nname = $1.str; + ndeact = $1.deactivated; + } + | COMMENT NODE { + ncomment = $1.str; + nname = $2.str; + ndeact = $2.deactivated; + } +; + +comment: COMMENT + | comment COMMENT +; + +%% + +int +main() +{ + return yyparse(); +} + diff --git a/src/cparse/cparse_def.h b/src/cparse/cparse_def.h new file mode 100644 index 0000000..877adb8 --- /dev/null +++ b/src/cparse/cparse_def.h @@ -0,0 +1,12 @@ +#ifndef _CPARSE_DEF_H_ +#define _CPARSE_DEF_H_ + +typedef struct { + char *str; + int deactivated; +} lex_ret_t; + +#define YYSTYPE lex_ret_t + +#endif /* _CPARSE_DEF_H_ */ + diff --git a/src/cparse/cparse_lex.l b/src/cparse/cparse_lex.l new file mode 100644 index 0000000..3bdb7f0 --- /dev/null +++ b/src/cparse/cparse_lex.l @@ -0,0 +1,168 @@ +/* flex -o cparse_lex.c cparse_lex.l */ +/* definitions */ +%x sComment +%x sID +%x sValue +%x sQStr +%option noyywrap + +ID ([-[:alnum:]_]+) +SPACE ([[:space:]]{-}[\n]) + +%{ +#include <string.h> +#include "cparse_def.h" +#include "cparse.h" + +#define STR_BUF_INC 4096 + +int line_number = 0; +int node_deactivated = 0; +char *str_buf = NULL; +char *out_buf = NULL; +char *str_ptr = NULL; +size_t str_buf_len = 0; + +void +append_str(char *text) +{ + size_t tlen = strlen(text); + size_t slen = str_ptr - str_buf; + if (!str_buf || (slen + tlen) >= str_buf_len) { + str_buf_len += STR_BUF_INC; + str_buf = realloc(str_buf, str_buf_len); + out_buf = realloc(out_buf, str_buf_len); + if (!str_buf || !out_buf) { + printf("realloc failed\n"); + exit(1); + } + str_ptr = str_buf + slen; + } + strcpy(str_ptr, text); + str_ptr += tlen; +} + +void +set_ret_str() +{ + *str_ptr = 0; + strcpy(out_buf, str_buf); + str_ptr = str_buf; +} + +%} + +%% + +<INITIAL>"/*" { + BEGIN(sComment); +} + +<sComment>[^*\n]* { + append_str(yytext); +} + +<sComment>\*[^/] { + append_str(yytext); +} + +<sComment>\n { + append_str(yytext); + ++line_number; +} + +<sComment>"*/" { + set_ret_str(); + yylval.str = strdup(out_buf); + BEGIN(INITIAL); + return COMMENT; +} + +<INITIAL>! { + node_deactivated = 1; +} + +<INITIAL>[[:space:]]+ { +} + +<INITIAL>\} { + node_deactivated = 0; + return RIGHTB; +} + +<INITIAL>{ID} { + yylval.str = strdup(yytext); + yylval.deactivated = node_deactivated; + node_deactivated = 0; + BEGIN(sID); + return NODE; +} + +<sID>:?{SPACE}+[^{\n] { + unput(yytext[yyleng - 1]); + BEGIN(sValue); +} + +<sID>{SPACE}+ { +} + +<sID>\{ { + BEGIN(INITIAL); + return LEFTB; +} + +<sID>\n { + ++line_number; + BEGIN(INITIAL); +} + +<sValue>{SPACE}+ { + /* ignore spaces */ +} + +<sValue>\" { + /* quoted string */ + BEGIN(sQStr); +} + +<sQStr>[^\"\\\n]+ { + append_str(yytext); +} + +<sQStr>\\. { + char tmp[2] = { yytext[1], 0 }; + append_str(tmp); +} + +<sQStr>\n { + append_str(yytext); + ++line_number; +} + +<sQStr>\" { + set_ret_str(); + yylval.str = strdup(out_buf); + BEGIN(sValue); + return VALUE; +} + +<sValue>[^{"[:space:]][^{[:space:]]+ { + /* unquoted string */ + yylval.str = strdup(yytext); + return VALUE; +} + +<sValue>\{ { + BEGIN(INITIAL); + return LEFTB; +} + +<sValue>\n { + ++line_number; + BEGIN(INITIAL); +} + +%% + +/* code */ + |