https://github.com/akkartik/mu1/blob/master/017parse_tree.cc
1
2
3
4
5
6
7
8
9
10
11
12
13 :(scenarios load)
14 :(scenario dilated_reagent_with_nested_brackets)
15 def main [
16 {1: number, foo: (bar (baz quux))} <- copy 34
17 ]
18 +parse: product: {1: "number", "foo": ("bar" ("baz" "quux"))}
19
20 :(before "End Parsing Dilated Reagent Property(value)")
21 value = parse_string_tree(value);
22 :(before "End Parsing Dilated Reagent Type Property(type_names)")
23 type_names = parse_string_tree(type_names);
24
25 :(code)
26 string_tree* parse_string_tree(string_tree* s) {
27 assert(s->atom);
28 if (!starts_with(s->value, "(")) return s;
29 string_tree* result = parse_string_tree(s->value);
30 delete s;
31 return result;
32 }
33
34 string_tree* parse_string_tree(const string& s) {
35 istringstream in(s);
36 in >> std::noskipws;
37 return parse_string_tree(in);
38 }
39
40 string_tree* parse_string_tree(istream& in) {
41 skip_whitespace_but_not_newline(in);
42 if (!has_data(in)) return NULL;
43 if (in.peek() == ')') {
44 in.get();
45 return NULL;
46 }
47 if (in.peek() != '(') {
48 string s = next_word(in);
49 if (s.empty()) {
50 assert(!has_data(in));
51 raise << "incomplete string tree at end of file (0)\n" << end();
52 return NULL;
53 }
54 string_tree* result = new string_tree(s);
55 return result;
56 }
57 in.get();
58 string_tree* result = NULL;
59 string_tree** curr = &result;
60 while (true) {
61 skip_whitespace_but_not_newline(in);
62 assert(has_data(in));
63 if (in.peek() == ')') break;
64 *curr = new string_tree(NULL, NULL);
65 if (in.peek() == '(') {
66 (*curr)->left = parse_string_tree(in);
67 }
68 else {
69 string s = next_word(in);
70 if (s.empty()) {
71 assert(!has_data(in));
72 raise << "incomplete string tree at end of file (1)\n" << end();
73 return NULL;
74 }
75 (*curr)->left = new string_tree(s);
76 }
77 curr = &(*curr)->right;
78 }
79 in.get();
80 assert(*curr == NULL);
81 return result;
82 }
83
84 :(scenario dilated_reagent_with_type_tree)
85 % Hide_errors = true; // 'map' isn't defined yet
86 def main [
87 {1: (foo (address array character) (bar number))} <- copy 34
88 ]
89
90 container foo [
91 ]
92 container bar [
93 ]
94 +parse: product: {1: ("foo" ("address" "array" "character") ("bar" "number"))}
95
96 :(scenario dilated_empty_tree)
97 def main [
98 {1: number, foo: ()} <- copy 34
99 ]
100 +parse: product: {1: "number", "foo": ()}
101
102 :(scenario dilated_singleton_tree)
103 def main [
104 {1: number, foo: (bar)} <- copy 34
105 ]
106 +parse: product: {1: "number", "foo": ("bar")}