summaryrefslogtreecommitdiff
path: root/src/cparse
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2010-10-25 18:24:55 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2010-10-25 18:24:55 -0700
commitbd88dba48665c6002b2fad86866b0ec41e86b7ab (patch)
tree6ca3f4afa767069781d52349f366e66710a31de1 /src/cparse
parent4e89616719a7d4a84540ac7ed13933f2928e6257 (diff)
downloadvyatta-cfg-bd88dba48665c6002b2fad86866b0ec41e86b7ab.tar.gz
vyatta-cfg-bd88dba48665c6002b2fad86866b0ec41e86b7ab.zip
initial lex/yacc config file parser
Diffstat (limited to 'src/cparse')
-rw-r--r--src/cparse/cparse.ypp100
-rw-r--r--src/cparse/cparse_def.h12
-rw-r--r--src/cparse/cparse_lex.l168
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 */
+