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
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

View File

@ -751,33 +751,31 @@ public:
}
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;
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<T>();
}
return ret;
}
template <typename T>
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<void (size_t, size_t, const std::string&)> 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);
}
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) {