mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 20:05:31 +00:00
Added profile feature (Resolve #200)
This commit is contained in:
parent
26877dc456
commit
34a859a6a1
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
19
peglib.h
19
peglib.h
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user