From 4282498f6c9ea35fd19220d048bc28e478f1f093 Mon Sep 17 00:00:00 2001 From: yhirose Date: Thu, 12 Feb 2015 22:14:28 -0500 Subject: [PATCH] Fixed problems with peglint. --- lint/peglint.cc | 28 +++++++++++----------------- peglib.h | 43 +++++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/lint/peglint.cc b/lint/peglint.cc index cc674b9..901e42c 100644 --- a/lint/peglint.cc +++ b/lint/peglint.cc @@ -20,22 +20,19 @@ int main(int argc, const char** argv) } // Check PEG grammar - cerr << "checking grammar file..." << endl; + auto syntax_path = argv[1]; - MemoryMappedFile syntax(argv[1]); + MemoryMappedFile syntax(syntax_path); if (!syntax.is_open()) { cerr << "can't open the grammar file." << endl; return -1; } - auto parser = make_parser(syntax.data(), syntax.size(), [](size_t ln, size_t col, const string& msg) { - cerr << ln << ":" << col << ": " << msg << endl; + auto parser = make_parser(syntax.data(), syntax.size(), [&](size_t ln, size_t col, const string& msg) { + cerr << syntax_path << ":" << ln << ":" << col << ": " << msg << endl; }); - if (parser) { - cerr << "success" << endl; - } else { - cerr << "invalid grammar file." << endl; + if (!parser) { return -1; } @@ -44,22 +41,19 @@ int main(int argc, const char** argv) } // Check source - cerr << "checking source file..." << endl; + auto source_path = argv[2]; - MemoryMappedFile source(argv[2]); + MemoryMappedFile source(source_path); if (!source.is_open()) { cerr << "can't open the source file." << endl; return -1; } - auto m = parser.lint(source.data(), source.size()); + auto ret = parser.lint(source.data(), source.size(), true, [&](size_t ln, size_t col, const string& msg) { + cerr << source_path << ":" << ln << ":" << col << ": " << msg << endl; + }); - if (m.ret) { - cerr << "success" << endl; - } else { - auto info = line_info(source.data(), m.ptr); - cerr << info.first << ":" << info.second << ": syntax error" << endl; - } + return ret ? 0 : -1; } // vim: et ts=4 sw=4 cin cino={1s ff=unix diff --git a/peglib.h b/peglib.h index 3c3989e..fd4eca2 100644 --- a/peglib.h +++ b/peglib.h @@ -751,33 +751,31 @@ public: } template - bool parse(const char* s, size_t l, T& val) const { + bool parse(const char* s, size_t l, T& val, bool exact = true) const { Values v; - - const auto& rule = *holder_; - auto m = rule.parse(s, l, v); - auto ret = m.ret && m.len == l; - + auto m = holder_->parse(s, l, v); + auto ret = m.ret && (!exact || m.len == l); if (ret && !v.values.empty() && !v.values.front().is_undefined()) { val = v.values[0].get(); } - return ret; } template - bool parse(const char* s, T& val) const { - return parse(s, strlen(s), val); + bool parse(const char* s, T& val, bool exact = true) const { + auto l = strlen(s); + return parse(s, l, val, exact); } - bool parse(const char* s, size_t l) const { + bool parse(const char* s, size_t l, bool exact = true) const { Values v; auto m = holder_->parse(s, l, v); - return m.ret && m.len == l; + return m.ret && (!exact || m.len == l); } - bool parse(const char* s) const { - return parse(s, strlen(s)); + bool parse(const char* s, bool exact = true) const { + auto l = strlen(s); + return parse(s, l, exact); } Definition& operator=(Action ac) { @@ -1250,12 +1248,25 @@ public: return parse(s, l); } - Match lint(const char* s, size_t l) const { + bool lint(const char* s, size_t l, bool exact, + std::function log = nullptr) { + + assert(grammar_); if (grammar_ != nullptr) { const auto& rule = (*grammar_)[start_]; - return rule.parse_with_match(s, l); + auto m = rule.parse_with_match(s, l); + if (!m.ret) { + if (log) { + auto line = line_info(s, m.ptr); + log(line.first, line.second, m.msg.empty() ? "syntax error" : m.msg); + } + } else if (exact && m.len != l) { + auto line = line_info(s, s + m.len); + log(line.first, line.second, "garbage string at the end"); + } + return m.ret && (!exact || m.len == l); } - return Match{ false, 0, (size_t)-1, s, "invalid grammar" }; + return false; } Definition& operator[](const char* s) {