diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2015-12-02 17:11:58 -0800 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2015-12-02 17:11:58 -0800 |
commit | 1f7e3c056ce0ea71e1337579b24e8fd1ad26abac (patch) | |
tree | cebdec305552bdf180f3f0db5518a69c2a086857 | |
parent | f8997ec06c0cdda1a16c5d99f96c447ce6809185 (diff) | |
download | mu-1f7e3c056ce0ea71e1337579b24e8fd1ad26abac.tar.gz |
2614 - still fixing bugs with missing '['
When skipping past some text (usually whitespace, but also commas and comments) I need to always be aware of whether it's ok to switch to the next line or not.
-rw-r--r-- | 010vm.cc | 15 | ||||
-rw-r--r-- | 011load.cc | 36 | ||||
-rw-r--r-- | 014literal_string.cc | 3 | ||||
-rw-r--r-- | 030container.cc | 2 | ||||
-rw-r--r-- | 054dilated_reagent.cc | 2 | ||||
-rw-r--r-- | 055parse_tree.cc | 5 | ||||
-rw-r--r-- | 056recipe_header.cc | 27 |
7 files changed, 49 insertions, 41 deletions
diff --git a/010vm.cc b/010vm.cc index 53e40b0a..59229ad6 100644 --- a/010vm.cc +++ b/010vm.cc @@ -261,7 +261,7 @@ reagent::reagent(string s) :original_string(s), value(0), initialized(false), ty } string_tree* parse_property_list(istream& in) { - skip_whitespace(in); + skip_whitespace_but_not_newline(in); if (!has_data(in)) return NULL; string_tree* result = new string_tree(slurp_until(in, ':')); result->right = parse_property_list(in); @@ -523,9 +523,16 @@ void dump(const string_tree* x, ostream& out) { out << ')'; } -void skip_whitespace(istream& in) { - while (in && isspace(in.peek()) && in.peek() != '\n') { - in.get(); +:(before "End Globals") +const string Ignore(","); // commas are ignored in mu except within [] strings +:(code) +void skip_whitespace_but_not_newline(istream& in) { + while (true) { + if (!has_data(in)) break; + else if (in.peek() == '\n') break; + else if (isspace(in.peek())) in.get(); + else if (Ignore.find(in.peek()) != string::npos) in.get(); + else break; } } diff --git a/011load.cc b/011load.cc index 578e2b46..14811e38 100644 --- a/011load.cc +++ b/011load.cc @@ -43,7 +43,7 @@ vector<recipe_ordinal> load(istream& in) { long long int slurp_recipe(istream& in) { recipe result; result.name = next_word(in); - skip_whitespace_and_comments(in); + skip_whitespace_and_comments_but_not_newline(in); // End recipe Refinements if (result.name.empty()) raise_error << "empty result.name\n" << end(); @@ -82,31 +82,22 @@ void slurp_body(istream& in, recipe& result) { bool next_instruction(istream& in, instruction* curr) { curr->clear(); - if (!has_data(in)) { - raise_error << "0: unbalanced '[' for recipe\n" << end(); - return false; - } - skip_whitespace(in); - if (!has_data(in)) { - raise_error << "1: unbalanced '[' for recipe\n" << end(); - return false; - } skip_whitespace_and_comments(in); if (!has_data(in)) { - raise_error << "2: unbalanced '[' for recipe\n" << end(); + raise_error << "0: unbalanced '[' for recipe\n" << end(); return false; } vector<string> words; while (has_data(in) && in.peek() != '\n') { - skip_whitespace(in); + skip_whitespace_but_not_newline(in); if (!has_data(in)) { - raise_error << "3: unbalanced '[' for recipe\n" << end(); + raise_error << "1: unbalanced '[' for recipe\n" << end(); return false; } string word = next_word(in); words.push_back(word); - skip_whitespace(in); + skip_whitespace_but_not_newline(in); } skip_whitespace_and_comments(in); if (SIZE(words) == 1 && words.at(0) == "]") { @@ -159,20 +150,17 @@ bool next_instruction(istream& in, instruction* curr) { } string next_word(istream& in) { - skip_whitespace(in); - skip_ignored_characters(in); + skip_whitespace_and_comments_but_not_newline(in); // End next_word Special-cases ostringstream out; slurp_word(in, out); - skip_whitespace(in); - skip_comment(in); + skip_whitespace_and_comments_but_not_newline(in); return out.str(); } :(before "End Globals") // word boundaries -string Terminators("(){}"); -string Ignore(","); // meaningless except within [] strings +const string Terminators("(){}"); :(code) void slurp_word(istream& in, ostream& out) { char c; @@ -190,17 +178,11 @@ void slurp_word(istream& in, ostream& out) { } } -void skip_ignored_characters(istream& in) { - while (isspace(in.peek()) || Ignore.find(in.peek()) != string::npos) { - in.get(); - } -} - void skip_whitespace_and_comments(istream& in) { while (true) { if (!has_data(in)) break; if (isspace(in.peek())) in.get(); - else if (in.peek() == ',') in.get(); + else if (Ignore.find(in.peek()) != string::npos) in.get(); else if (in.peek() == '#') skip_comment(in); else break; } diff --git a/014literal_string.cc b/014literal_string.cc index 34655aa9..209a6428 100644 --- a/014literal_string.cc +++ b/014literal_string.cc @@ -24,8 +24,7 @@ put(Type_ordinal, "literal-string", 0); :(before "End next_word Special-cases") if (in.peek() == '[') { string result = slurp_quoted(in); - skip_whitespace(in); - skip_comment(in); + skip_whitespace_and_comments_but_not_newline(in); return result; } diff --git a/030container.cc b/030container.cc index 04be418c..afe08952 100644 --- a/030container.cc +++ b/030container.cc @@ -404,7 +404,7 @@ else if (command == "container") { :(code) void insert_container(const string& command, kind_of_type kind, istream& in) { - skip_whitespace(in); + skip_whitespace_but_not_newline(in); string name = next_word(in); // End container Name Refinements trace(9991, "parse") << "--- defining " << command << ' ' << name << end(); diff --git a/054dilated_reagent.cc b/054dilated_reagent.cc index ac40f049..6788becc 100644 --- a/054dilated_reagent.cc +++ b/054dilated_reagent.cc @@ -32,7 +32,7 @@ bool start_of_dilated_reagent(istream& in) { if (in.peek() != '{') return false; long long int pos = in.tellg(); in.get(); // slurp '{' - skip_whitespace(in); + skip_whitespace_but_not_newline(in); char next = in.peek(); in.seekg(pos); return next != '\n'; diff --git a/055parse_tree.cc b/055parse_tree.cc index ef9cf4e1..33537344 100644 --- a/055parse_tree.cc +++ b/055parse_tree.cc @@ -28,7 +28,7 @@ string_tree* parse_string_tree(const string& s) { } string_tree* parse_string_tree(istream& in) { - skip_whitespace(in); + skip_whitespace_but_not_newline(in); if (!has_data(in)) return NULL; if (in.peek() == ')') { in.get(); @@ -44,8 +44,7 @@ string_tree* parse_string_tree(istream& in) { while (in.peek() != ')') { assert(has_data(in)); *curr = new string_tree(""); - skip_whitespace(in); - skip_ignored_characters(in); + skip_whitespace_but_not_newline(in); if (in.peek() == '(') (*curr)->left = parse_string_tree(in); else diff --git a/056recipe_header.cc b/056recipe_header.cc index f0d448b2..2ca02af7 100644 --- a/056recipe_header.cc +++ b/056recipe_header.cc @@ -23,7 +23,6 @@ vector<reagent> products; has_header = false; :(before "End recipe Refinements") -skip_whitespace(in); if (in.peek() != '[') { trace(9999, "parse") << "recipe has a header; parsing" << end(); load_recipe_header(in, result); @@ -37,17 +36,28 @@ void load_recipe_header(istream& in, recipe& result) { if (s == "->") break; result.ingredients.push_back(reagent(s)); trace(9999, "parse") << "header ingredient: " << result.ingredients.back().original_string << end(); - skip_whitespace_and_comments(in); + skip_whitespace_and_comments_but_not_newline(in); } while (has_data(in) && in.peek() != '[' && in.peek() != '\n') { string s = next_word(in); result.products.push_back(reagent(s)); trace(9999, "parse") << "header product: " << result.products.back().original_string << end(); - skip_whitespace_and_comments(in); + skip_whitespace_and_comments_but_not_newline(in); } // End Load Recipe Header(result) } +void skip_whitespace_and_comments_but_not_newline(istream& in) { + while (true) { + if (!has_data(in)) break; + if (in.peek() == '\n') break; + if (isspace(in.peek())) in.get(); + else if (Ignore.find(in.peek()) != string::npos) in.get(); + else if (in.peek() == '#') skip_comment(in); + else break; + } +} + :(scenario recipe_handles_stray_comma) recipe main [ 1:number/raw <- add2 3, 5 @@ -78,6 +88,17 @@ recipe main ] +error: recipe body must begin with '[' +:(scenario recipe_handles_missing_bracket_2) +% Hide_errors = true; +recipe main + local-scope + { + } +] +# doesn't overflow line when reading header +-parse: header ingredient: local-scope ++error: recipe body must begin with '[' + :(after "Begin debug_string(recipe x)") out << "ingredients:\n"; for (long long int i = 0; i < SIZE(x.ingredients); ++i) |