mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Fixed problems with peglint.
This commit is contained in:
parent
05fa8c4424
commit
4282498f6c
@ -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
|
||||||
|
43
peglib.h
43
peglib.h
@ -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);
|
||||||
|
}
|
||||||
|
} 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) {
|
Definition& operator[](const char* s) {
|
||||||
|
Loading…
Reference in New Issue
Block a user