Fixed problems with peglint.

This commit is contained in:
yhirose 2015-02-12 22:14:28 -05:00
parent 05fa8c4424
commit 4282498f6c
2 changed files with 38 additions and 33 deletions

View File

@ -20,22 +20,19 @@ int main(int argc, const char** argv)
} }
// Check PEG grammar // 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()) { if (!syntax.is_open()) {
cerr << "can't open the grammar file." << endl; cerr << "can't open the grammar file." << endl;
return -1; return -1;
} }
auto parser = make_parser(syntax.data(), syntax.size(), [](size_t ln, size_t col, const string& msg) { auto parser = make_parser(syntax.data(), syntax.size(), [&](size_t ln, size_t col, const string& msg) {
cerr << ln << ":" << col << ": " << msg << endl; cerr << syntax_path << ":" << ln << ":" << col << ": " << msg << endl;
}); });
if (parser) { if (!parser) {
cerr << "success" << endl;
} else {
cerr << "invalid grammar file." << endl;
return -1; return -1;
} }
@ -44,22 +41,19 @@ int main(int argc, const char** argv)
} }
// Check source // Check source
cerr << "checking source file..." << endl; auto source_path = argv[2];
MemoryMappedFile source(argv[2]); MemoryMappedFile source(source_path);
if (!source.is_open()) { if (!source.is_open()) {
cerr << "can't open the source file." << endl; cerr << "can't open the source file." << endl;
return -1; 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) { return ret ? 0 : -1;
cerr << "success" << endl;
} else {
auto info = line_info(source.data(), m.ptr);
cerr << info.first << ":" << info.second << ": syntax error" << endl;
}
} }
// vim: et ts=4 sw=4 cin cino={1s ff=unix // vim: et ts=4 sw=4 cin cino={1s ff=unix

View File

@ -751,33 +751,31 @@ public:
} }
template <typename T> template <typename T>
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; Values v;
auto m = holder_->parse(s, l, v);
const auto& rule = *holder_; auto ret = m.ret && (!exact || m.len == l);
auto m = rule.parse(s, l, v);
auto ret = m.ret && m.len == l;
if (ret && !v.values.empty() && !v.values.front().is_undefined()) { if (ret && !v.values.empty() && !v.values.front().is_undefined()) {
val = v.values[0].get<T>(); val = v.values[0].get<T>();
} }
return ret; return ret;
} }
template <typename T> template <typename T>
bool parse(const char* s, T& val) const { bool parse(const char* s, T& val, bool exact = true) const {
return parse(s, strlen(s), val); 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; Values v;
auto m = holder_->parse(s, l, 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 { bool parse(const char* s, bool exact = true) const {
return parse(s, strlen(s)); auto l = strlen(s);
return parse(s, l, exact);
} }
Definition& operator=(Action ac) { Definition& operator=(Action ac) {
@ -1250,12 +1248,25 @@ public:
return parse(s, l); 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<void (size_t, size_t, const std::string&)> log = nullptr) {
assert(grammar_);
if (grammar_ != nullptr) { if (grammar_ != nullptr) {
const auto& rule = (*grammar_)[start_]; 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);
} }
return Match{ false, 0, (size_t)-1, s, "invalid grammar" }; } 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 false;
} }
Definition& operator[](const char* s) { Definition& operator[](const char* s) {