summaryrefslogtreecommitdiff
path: root/src/wasm-s-parser.h
diff options
context:
space:
mode:
authorMichael Bebenita <mbebenita@gmail.com>2016-03-15 03:24:55 -0700
committerMichael Bebenita <mbebenita@gmail.com>2016-03-15 03:24:55 -0700
commitac2a4a62dd903e11be089018bcd11d7a7584a973 (patch)
tree96192efd793285172cec4c5dd1ca24a3c03171b0 /src/wasm-s-parser.h
parentf04dd1bb5b06d64ebfdd347a852a55322743b363 (diff)
downloadbinaryen-ac2a4a62dd903e11be089018bcd11d7a7584a973.tar.gz
binaryen-ac2a4a62dd903e11be089018bcd11d7a7584a973.tar.bz2
binaryen-ac2a4a62dd903e11be089018bcd11d7a7584a973.zip
Remove recursion from s-expr parsing.
Diffstat (limited to 'src/wasm-s-parser.h')
-rw-r--r--src/wasm-s-parser.h54
1 files changed, 22 insertions, 32 deletions
diff --git a/src/wasm-s-parser.h b/src/wasm-s-parser.h
index db57dda9f..2f2eeb937 100644
--- a/src/wasm-s-parser.h
+++ b/src/wasm-s-parser.h
@@ -125,47 +125,37 @@ public:
SExpressionParser(char* input) : input(input) {
root = nullptr;
while (!root) { // keep parsing until we pass an initial comment
- root = parseInnerList();
+ root = parse();
}
}
Element* root;
private:
- // parses the internal part of a list, inside the parens.
- Element* parseInnerList() {
- if (input[0] == ';') {
- // comment
- input++;
- if (input[0] == ';') {
- while (input[0] != '\n') input++;
- return nullptr;
- }
- input = strstr(input, ";)");
- assert(input);
- return nullptr;
- }
- auto ret = allocator.alloc<Element>();
- while (1) {
- Element* curr = parse();
- if (!curr) return ret;
- ret->list().push_back(curr);
- }
- }
-
Element* parse() {
- skipWhitespace();
- if (input[0] == 0 || input[0] == ')') return nullptr;
- if (input[0] == '(') {
- // a list
- input++;
- auto ret = parseInnerList();
+ std::vector<Element *> stack;
+ Element *curr = allocator.alloc<Element>();
+ while (1) {
skipWhitespace();
- assert(input[0] == ')');
- input++;
- return ret;
+ if (input[0] == 0)
+ break;
+ if (input[0] == '(') {
+ input++;
+ stack.push_back(curr);
+ curr = allocator.alloc<Element>();
+ } else if (input[0] == ')') {
+ input++;
+ auto last = curr;
+ curr = stack.back();
+ assert(stack.size());
+ stack.pop_back();
+ curr->list().push_back(last);
+ } else {
+ curr->list().push_back(parseString());
+ }
}
- return parseString();
+ assert(stack.size() == 0);
+ return curr;
}
void skipWhitespace() {