summaryrefslogtreecommitdiff
path: root/src/cparse/cparse.ypp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cparse/cparse.ypp')
-rw-r--r--src/cparse/cparse.ypp117
1 files changed, 95 insertions, 22 deletions
diff --git a/src/cparse/cparse.ypp b/src/cparse/cparse.ypp
index eb2ab12..193077a 100644
--- a/src/cparse/cparse.ypp
+++ b/src/cparse/cparse.ypp
@@ -1,9 +1,16 @@
%{
#include <cstdio>
+#include <vector>
+#include <string>
+#include <cstore/cstore.hpp>
+#include <cnode/cnode.hpp>
#include "cparse.hpp"
#include "cparse_def.h"
+using namespace std;
+using namespace cnode;
+
// stuff from lex
extern "C" {
extern int cparse_lineno;
@@ -19,33 +26,86 @@ cparse_error(const char *s)
s, cparse_lineno, cparse_text);
}
-int level = 0;
-int ndeact = 0;
-char *ncomment = NULL;
-char *nname = NULL;
-char *nval = NULL;
+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<CfgNode *> cur_path;
+static vector<string> pcomps;
+static vector<bool> pcomp_is_value;
static void
-print_node()
+print_path()
{
- int i = 0;
- if (ncomment) {
- for (i = 0; i <= level; i++) {
- printf(" ");
+ printf("[%p,%p] p[", cur_parent, cur_node);
+ for (size_t i = 0; i < pcomps.size(); i++) {
+ if (i > 0) {
+ printf(",");
}
- printf(" /*%s*/\n", ncomment);
- }
- printf("%s", ndeact ? "!" : " ");
- for (i = 0; i <= level; i++) {
- printf(" ");
+ printf("%s", pcomps[i].c_str());
}
- printf("%s", nname);
+ printf("] n[%s]", nname);
if (nval) {
- printf(" '%s'", 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
@@ -62,15 +122,27 @@ input: forest
;
forest: /* empty */
- | forest tree
+ | forest {
+ if (!cur_parent) {
+ // root node
+ cur_parent = new CfgNode(pcomps, nname, nval, ncomment,
+ ndeact, cstore);
+ }
+ } tree
;
tree: node {
- print_node();
+ add_node();
+ print_path();
}
| node {
- print_node();
- } LEFTB { ++level; } forest RIGHTB { --level; }
+ add_node();
+ print_path();
+ } LEFTB {
+ go_down();
+ } forest RIGHTB {
+ go_up();
+ }
;
node: nodec {
@@ -100,9 +172,10 @@ comment: COMMENT
%%
int
-cparse::parse_file(FILE *fin)
+cparse::parse_file(FILE *fin, Cstore& cs)
{
cparse_set_in(fin);
+ cstore = &cs;
return cparse_parse();
}