Added profile feature (Resolve #200)

This commit is contained in:
yhirose 2022-06-02 22:15:09 -04:00
parent 26877dc456
commit 34a859a6a1
4 changed files with 75 additions and 18 deletions

View File

@ -609,6 +609,7 @@ usage: grammar_file_path [source_file_path]
--opt-only: optimize only AST nodes selected with `no_ast_opt` instruction --opt-only: optimize only AST nodes selected with `no_ast_opt` instruction
--trace: show concise trace messages --trace: show concise trace messages
--trace-verbose: show verbose trace messages --trace-verbose: show verbose trace messages
--profile: show profile report
``` ```
### Grammar check ### Grammar check

View File

@ -14,6 +14,7 @@ usage: grammar_file_path [source_file_path]
--source: source text --source: source text
--trace: show concise trace messages --trace: show concise trace messages
--trace-verbose: show verbose trace messages --trace-verbose: show verbose trace messages
--profile: show profile report
``` ```
### Build peglint ### Build peglint

View File

@ -41,7 +41,8 @@ int main(int argc, const char **argv) {
auto opt_source = false; auto opt_source = false;
vector<char> source; vector<char> source;
auto opt_trace = false; auto opt_trace = false;
auto opt_verbose = false; auto opt_trace_verbose = false;
auto opt_profile = false;
vector<const char *> path_list; vector<const char *> path_list;
auto argi = 1; auto argi = 1;
@ -68,8 +69,9 @@ int main(int argc, const char **argv) {
} else if (string("--trace") == arg) { } else if (string("--trace") == arg) {
opt_trace = true; opt_trace = true;
} else if (string("--trace-verbose") == arg) { } else if (string("--trace-verbose") == arg) {
opt_trace = true; opt_trace_verbose = true;
opt_verbose = true; } else if (string("--profile") == arg) {
opt_profile = true;
} else { } else {
path_list.push_back(arg); path_list.push_back(arg);
} }
@ -86,6 +88,7 @@ int main(int argc, const char **argv) {
--opt-only: optimize only AST nodes selected with `no_ast_opt` instruction --opt-only: optimize only AST nodes selected with `no_ast_opt` instruction
--trace: show concise trace messages --trace: show concise trace messages
--trace-verbose: show verbose trace messages --trace-verbose: show verbose trace messages
--profile: show profile report
)"; )";
return 1; return 1;
@ -126,12 +129,10 @@ int main(int argc, const char **argv) {
if (opt_packrat) { parser.enable_packrat_parsing(); } if (opt_packrat) { parser.enable_packrat_parsing(); }
if (opt_trace) { if (opt_trace || opt_trace_verbose) {
size_t prev_pos = 0; size_t prev_pos = 0;
parser.enable_trace( parser.enable_trace(
[&](const peg::Ope &ope, const char *s, size_t /*n*/, [&](auto &ope, auto s, auto, auto &, auto &c, auto &) {
const peg::SemanticValues & /*sv*/, const peg::Context &c,
const std::any & /*dt*/) {
auto pos = static_cast<size_t>(s - c.s); auto pos = static_cast<size_t>(s - c.s);
auto backtrack = (pos < prev_pos ? "*" : ""); auto backtrack = (pos < prev_pos ? "*" : "");
string indent; string indent;
@ -150,9 +151,7 @@ int main(int argc, const char **argv) {
<< " #" << c.trace_ids.back() << std::endl; << " #" << c.trace_ids.back() << std::endl;
prev_pos = static_cast<size_t>(pos); prev_pos = static_cast<size_t>(pos);
}, },
[&](const peg::Ope &ope, const char *s, size_t /*n*/, [&](auto &ope, auto s, auto, auto &sv, auto &c, auto &, auto len) {
const peg::SemanticValues &sv, const peg::Context &c,
const std::any & /*dt*/, size_t len) {
auto pos = static_cast<size_t>(s - c.s); auto pos = static_cast<size_t>(s - c.s);
if (len != static_cast<size_t>(-1)) { pos += len; } if (len != static_cast<size_t>(-1)) { pos += len; }
string indent; string indent;
@ -181,7 +180,58 @@ int main(int argc, const char **argv) {
<< c.trace_ids.back() << choice.str() << token << matched << c.trace_ids.back() << choice.str() << token << matched
<< std::endl; << std::endl;
}, },
opt_verbose); opt_trace_verbose);
}
struct StatsItem {
std::string name;
size_t success;
size_t fail;
};
std::vector<StatsItem> stats;
std::map<std::string, size_t> stats_index;
size_t stats_item_total = false;
if (opt_profile) {
parser.enable_trace(
[&](auto &ope, auto, auto, auto &, auto &, auto &) {
if (peg::IsOpeType<peg::Holder>::check(ope)) {
auto &name = dynamic_cast<const peg::Holder &>(ope).name();
if (stats_index.find(name) == stats_index.end()) {
stats_index[name] = stats_index.size();
stats.push_back({name, 0, 0});
}
stats_item_total++;
}
},
[&](auto &ope, auto, auto, auto &, auto &, auto &, auto len) {
if (peg::IsOpeType<peg::Holder>::check(ope)) {
auto &name = dynamic_cast<const peg::Holder &>(ope).name();
auto index = stats_index[name];
auto &stat = stats[index];
if (len != static_cast<size_t>(-1)) {
stat.success++;
} else {
stat.fail++;
}
if (index == 0) {
size_t id = 0;
std::cout << " id total % success fail "
"definition"
<< std::endl;
for (auto &[name, success, fail] : stats) {
char buff[BUFSIZ];
auto total = success + fail;
auto ratio = total * 100.0 / stats_item_total;
sprintf(buff, "%4zu %10lu %5.2f %10lu %10lu %s", id, total,
ratio, success, fail, name.c_str());
std::cout << buff << std::endl;
id++;
}
}
}
},
true);
} }
if (opt_ast) { if (opt_ast) {

View File

@ -1467,7 +1467,8 @@ public:
std::any reduce(SemanticValues &vs, std::any &dt) const; std::any reduce(SemanticValues &vs, std::any &dt) const;
const char *trace_name() const; const std::string &name() const;
const std::string &trace_name() const;
std::shared_ptr<Ope> ope_; std::shared_ptr<Ope> ope_;
Definition *outer_; Definition *outer_;
@ -1825,7 +1826,7 @@ struct TraceOpeName : public Ope::Visitor {
void visit(Ignore &) override { name_ = "Ignore"; } void visit(Ignore &) override { name_ = "Ignore"; }
void visit(User &) override { name_ = "User"; } void visit(User &) override { name_ = "User"; }
void visit(WeakHolder &) override { name_ = "WeakHolder"; } void visit(WeakHolder &) override { name_ = "WeakHolder"; }
void visit(Holder &ope) override { name_ = ope.trace_name(); } void visit(Holder &ope) override { name_ = ope.trace_name().data(); }
void visit(Reference &) override { name_ = "Reference"; } void visit(Reference &) override { name_ = "Reference"; }
void visit(Whitespace &) override { name_ = "Whitespace"; } void visit(Whitespace &) override { name_ = "Whitespace"; }
void visit(BackReference &) override { name_ = "BackReference"; } void visit(BackReference &) override { name_ = "BackReference"; }
@ -1929,7 +1930,7 @@ private:
}; };
struct FindLiteralToken : public Ope::Visitor { struct FindLiteralToken : public Ope::Visitor {
void visit(LiteralString &ope) override { token_ = ope.lit_.c_str(); } void visit(LiteralString &ope) override { token_ = ope.lit_.data(); }
void visit(TokenBoundary &ope) override { ope.ope_->accept(*this); } void visit(TokenBoundary &ope) override { ope.ope_->accept(*this); }
void visit(Ignore &ope) override { ope.ope_->accept(*this); } void visit(Ignore &ope) override { ope.ope_->accept(*this); }
void visit(Reference &ope) override; void visit(Reference &ope) override;
@ -2491,7 +2492,7 @@ inline size_t parse_literal(const char *s, size_t n, SemanticValues &vs,
for (; i < lit.size(); i++) { for (; i < lit.size(); i++) {
if (i >= n || (ignore_case ? (std::tolower(s[i]) != std::tolower(lit[i])) if (i >= n || (ignore_case ? (std::tolower(s[i]) != std::tolower(lit[i]))
: (s[i] != lit[i]))) { : (s[i] != lit[i]))) {
c.set_error_pos(s, lit.c_str()); c.set_error_pos(s, lit.data());
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
} }
@ -2574,7 +2575,7 @@ inline void Context::set_error_pos(const char *a_s, const char *literal) {
token && token[0] != '\0') { token && token[0] != '\0') {
error_info.add(token, true); error_info.add(token, true);
} else { } else {
error_info.add(rule->name.c_str(), false); error_info.add(rule->name.data(), false);
} }
} }
} }
@ -2735,9 +2736,13 @@ inline std::any Holder::reduce(SemanticValues &vs, std::any &dt) const {
} }
} }
inline const char *Holder::trace_name() const { inline const std::string &Holder::name() const {
return outer_->name;
}
inline const std::string &Holder::trace_name() const {
if (trace_name_.empty()) { trace_name_ = "[" + outer_->name + "]"; } if (trace_name_.empty()) { trace_name_ = "[" + outer_->name + "]"; }
return trace_name_.data(); return trace_name_;
} }
inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &vs, inline size_t Reference::parse_core(const char *s, size_t n, SemanticValues &vs,