# HG changeset patch # User vnorilo # Date 1590151208 -10800 # Fri May 22 15:40:08 2020 +0300 # Node ID d589b785a77125d9bf47985d7b95184ac3f46a7e # Parent 1aa74e6d37b2cf853cb27aa192403846ca9f9143 Kronos improvements: empty docstring no longer swallows following line, improved error messages in parsing stage diff --git a/ast.cpp b/ast.cpp --- a/ast.cpp +++ b/ast.cpp @@ -47,8 +47,8 @@ if (indent == 0) s << "Parse error: "; else { - if (children.size() > 1) s << "in "; - else s << "did not find "; + if (children.size() > 1) s << "- "; + else s << "Expected "; } auto er = (error_report*)strend; if (er) { er->write(s); s << "\n"; } diff --git a/grammar/kronos.cpp b/grammar/kronos.cpp --- a/grammar/kronos.cpp +++ b/grammar/kronos.cpp @@ -225,7 +225,9 @@ lithe::rule package_version() { using namespace grammar::common; auto space = I(grammar::common::whitespace()); - auto remote_version = identifier() | (digits(1) << O(T(".") << digits(1) << O(T(".") << digits(1)))); + auto remote_version = identifier() | L( + "Version tag", + (digits(1) << O(T(".") << digits(1) << O(T(".") << digits(1))))); return E(tag::package, I("[") << O(space) << identifier() << space << remote_version << O(space << identifier()) << O(space) << I("]")); } @@ -239,7 +241,9 @@ auto check_brace = bad("Unmatched parens/bracket/brace", characters("braces", ")]}")); - auto docstring = custom("docstring", I(T(";") << O(whitespace)) << upto_eol, [](const lithe::node& n) { + auto docstring = custom( + "docstring", I(T(";") << O(characters("space","\t "))) << (upto_eol | T("\n")), + [](const lithe::node& n) { if (docstrings().size()) { docstrings().top().children.emplace_back(n); } @@ -253,11 +257,11 @@ lithe::rule comment, space; if (keep_comments) { - comment = E(tag::comment, T(";") << (docstring | upto_eol)); - space = repeat(I(whitespace) | comment | I(","), 1); + comment = E(tag::comment, T(";") << (docstring | upto_eol | T("\n"))); + space = L("whitespace", repeat(I(whitespace) | comment | I(","), 1)); } else { - comment = IE(tag::comment, T(";") << (docstring | upto_eol)); - space = I(repeat(whitespace | comment | T(","), 1)); + comment = IE(tag::comment, T(";") << (docstring | upto_eol | T("\n"))); + space = L("whitespace", I(repeat(whitespace | comment | T(","), 1))); } auto opt_sp = O(space); diff --git a/grammar/kronos_tags.inc b/grammar/kronos_tags.inc --- a/grammar/kronos_tags.inc +++ b/grammar/kronos_tags.inc @@ -30,4 +30,4 @@ TAG(immediate, "immediate") TAG(free_var, "free variable") TAG(docstring, "documentation") -}; + }; diff --git a/lithe.cpp b/lithe.cpp --- a/lithe.cpp +++ b/lithe.cpp @@ -513,8 +513,9 @@ } void write(std::ostream& os) const override { - os << "optional "; + os << "(optional "; wrapper::write(os); + os << ")"; } }; @@ -591,12 +592,6 @@ if (tmp.is_error()) return tmp; return {}; } - - void write(std::ostream& s) const override { - s << "("; - wrapper::write(s); - s << ")"; - } }; struct indirect : public recursive { @@ -749,6 +744,10 @@ return r->ignore(r); } + rule L(const char* label, rule r) { + return make_shared(r, label); + } + rule O(rule r) { return make_shared(r); } diff --git a/lithe.h b/lithe.h --- a/lithe.h +++ b/lithe.h @@ -59,6 +59,7 @@ rule IE(const char *tag, rule content); rule T(const char *literal_text); rule I(rule ignore); + rule L(const char* label, rule content); static inline rule I(const char *ignore) { return I(T(ignore)); } rule O(rule r); rule repeat(rule element, int minimum = 1);