%{ #include #include #include #include #include #include "cparse.hpp" #include "cparse_def.h" using namespace std; using namespace cnode; // stuff from lex extern "C" { extern int cparse_lineno; extern char *cparse_text; int cparse_lex(); void cparse_set_in(FILE *fin); } static void cparse_error(const char *s) { printf("Invalid config file (%s): error at line %d, text [%s]\n", s, cparse_lineno, cparse_text); } static int ndeact = 0; static char *ncomment = NULL; static char *nname = NULL; static char *nval = NULL; static Cstore *cstore = NULL; static CfgNode *cur_node = NULL; static CfgNode *cur_parent = NULL; static CfgNode *prev_sibling = NULL; static vector cur_path; static vector pcomps; static vector pcomp_is_value; static void print_path() { printf("[%p,%p] p[", cur_parent, cur_node); for (size_t i = 0; i < pcomps.size(); i++) { if (i > 0) { printf(","); } printf("%s", pcomps[i].c_str()); } printf("] n[%s]", nname); if (nval) { printf(" v[%s]", nval); } if (ncomment) { printf(" c[%s]", ncomment); } if (ndeact) { printf(" D"); } printf("\n"); } static void add_node() { if (prev_sibling && nval && prev_sibling->isValue() && prev_sibling->isMulti() && prev_sibling->getName() == nname) { prev_sibling->addMultiValue(nval); } else { cur_node = new CfgNode(pcomps, nname, nval, ncomment, ndeact, cstore); cur_parent->addChildNode(cur_node); prev_sibling = cur_node; } } static void go_down() { cur_path.push_back(cur_parent); cur_parent = cur_node; prev_sibling = NULL; pcomps.push_back(nname); pcomp_is_value.push_back(false); if (nval) { pcomps.push_back(nval); pcomp_is_value.push_back(true); } } static void go_up() { cur_parent = cur_path.back(); cur_path.pop_back(); prev_sibling = NULL; if (pcomp_is_value.back()) { pcomps.pop_back(); pcomp_is_value.pop_back(); } pcomps.pop_back(); pcomp_is_value.pop_back(); } %} %token NODE %token VALUE %token COMMENT %token LEFTB %token RIGHTB %token SYNTAX_ERROR %% input: forest | forest comment ; forest: /* empty */ | forest { if (!cur_parent) { // root node cur_parent = new CfgNode(pcomps, nname, nval, ncomment, ndeact, cstore); } } tree ; tree: node { add_node(); print_path(); } | node { add_node(); print_path(); } LEFTB { go_down(); } forest RIGHTB { go_up(); } ; 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 cparse::parse_file(FILE *fin, Cstore& cs) { cparse_set_in(fin); cstore = &cs; return cparse_parse(); }