about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2015-10-27 14:38:57 -0700
committerKartik K. Agaram <vc@akkartik.com>2015-10-27 14:38:57 -0700
commita17f9186c17073e07eef6f046dcc1b15f08ed73c (patch)
treedec42cd5528b10c6a7cb6fb887342e5b526f62eb
parent79eef536f5fc2c427e3601e0dcca705aad1d7023 (diff)
downloadmu-a17f9186c17073e07eef6f046dcc1b15f08ed73c.tar.gz
2291 - parsing property trees
-rw-r--r--010vm.cc2
-rw-r--r--054dilated_reagent.cc10
-rw-r--r--055parse_tree.cc47
3 files changed, 50 insertions, 9 deletions
diff --git a/010vm.cc b/010vm.cc
index 23f9d9d6..5b4b9a16 100644
--- a/010vm.cc
+++ b/010vm.cc
@@ -366,7 +366,7 @@ void dump_property(const string_tree* property, ostringstream& out) {
   if (property->right)
     dump_property(property->right, out);
   else
-    out << " : <>";
+    out << "<>";
   out << ">";
 }
 
diff --git a/054dilated_reagent.cc b/054dilated_reagent.cc
index 7cfdafa9..21567a03 100644
--- a/054dilated_reagent.cc
+++ b/054dilated_reagent.cc
@@ -77,9 +77,9 @@ if (s.at(0) == '{') {
     string key = slurp_key(in);
     if (key.empty()) continue;
     if (key == "}") continue;
-    string value = next_word(in);
+    string_tree* value = new string_tree(next_word(in));
     // End Parsing Reagent Property(value)
-    properties.push_back(pair<string, string_tree*>(key, new string_tree(value)));
+    properties.push_back(pair<string, string_tree*>(key, value));
   }
   // structures for the first row of properties
   name = properties.at(0).first;
@@ -100,9 +100,3 @@ string slurp_key(istream& in) {
   }
   return result;
 }
-
-:(scenario dilated_reagent_with_nested_brackets)
-recipe main [
-  {1: number, foo: (bar (baz quux))} <- copy 34
-]
-+parse:   product: {"1": "number", "foo": "(bar (baz quux))"}
diff --git a/055parse_tree.cc b/055parse_tree.cc
new file mode 100644
index 00000000..3c6c2302
--- /dev/null
+++ b/055parse_tree.cc
@@ -0,0 +1,47 @@
+:(scenario dilated_reagent_with_nested_brackets)
+recipe main [
+  {1: number, foo: (bar (baz quux))} <- copy 34
+]
++parse:   product: {"1": "number", "foo": <"bar" : <<"baz" : <"quux" : <>>> : <>>>}
+
+:(before "End Parsing Reagent Property(value)")
+value = parse_string_tree(value);
+
+:(code)
+string_tree* parse_string_tree(string_tree* s) {
+  assert(!s->left && !s->right);
+  if (s->value.at(0) != '(') return s;
+  string_tree* result = parse_string_tree(s->value);
+  delete s;
+  return result;
+}
+
+string_tree* parse_string_tree(const string& s) {
+  istringstream in(s);
+  in >> std::noskipws;
+  return parse_string_tree(in);
+}
+
+string_tree* parse_string_tree(istream& in) {
+  skip_whitespace(in);
+  if (in.eof()) return NULL;
+  if (in.peek() == ')') {
+    in.get();
+    return NULL;
+  }
+  if (in.peek() != '(') {
+    return new string_tree(next_word(in));
+  }
+  in.get();  // skip '('
+  if (in.peek() == '(') {
+    string_tree* left = parse_string_tree(in);
+    string_tree* right = parse_string_tree(in);
+    return new string_tree(left, right);
+  }
+  else {
+    string value = next_word(in);
+    string_tree* right = parse_string_tree(in);
+    string_tree* rest = parse_string_tree(in);
+    return new string_tree(value, new string_tree(right, rest));
+  }
+}