mirror of
https://github.com/yhirose/cpp-peglib.git
synced 2024-12-22 11:55:30 +00:00
Updated playground to show profiling result
This commit is contained in:
parent
ad74d9e8c0
commit
8f19894e32
@ -20,13 +20,21 @@
|
|||||||
<li><span id="code-validation" class="editor-validation">Valid</span></li>
|
<li><span id="code-validation" class="editor-validation">Valid</span></li>
|
||||||
</ul>
|
</ul>
|
||||||
<pre id="code-editor" class="editor-area">{{source}}</pre>
|
<pre id="code-editor" class="editor-area">{{source}}</pre>
|
||||||
|
<div id="code-info" class="editor-info"></div>
|
||||||
|
</div>
|
||||||
|
<div class="editor-container">
|
||||||
|
<ul class="editor-header">
|
||||||
|
<li><span>Output</span></li>
|
||||||
|
<li><span></span></li>
|
||||||
|
</ul>
|
||||||
<div class="editor-sub-header">AST</div>
|
<div class="editor-sub-header">AST</div>
|
||||||
<pre id="code-ast" class="editor-area"></pre>
|
<pre id="code-ast" class="editor-area"></pre>
|
||||||
<div class="editor-sub-header">Optimized AST
|
<div class="editor-sub-header">Optimized AST
|
||||||
mode: <select id="opt_mode" type="checkbox"><option value="all">All</option><option value="only">Only</option></select>
|
mode: <select id="opt_mode" type="checkbox"><option value="all">All</option><option value="only">Only</option></select>
|
||||||
</div>
|
</div>
|
||||||
<pre id="code-ast-optimized" class="editor-area"></pre>
|
<pre id="code-ast-optimized" class="editor-area"></pre>
|
||||||
<div id="code-info" class="editor-info"></div>
|
<div class="editor-sub-header">Profile</div>
|
||||||
|
<div id="profile" class="editor-area"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js"></script>
|
||||||
|
@ -1,34 +1,34 @@
|
|||||||
// Setup editros
|
// Setup editros
|
||||||
const grammar = ace.edit("grammar-editor");
|
function setupInfoArea(id) {
|
||||||
grammar.setShowPrintMargin(false);
|
const e = ace.edit(id);
|
||||||
grammar.setValue(localStorage.getItem('grammarText') || '');
|
e.setShowPrintMargin(false);
|
||||||
grammar.moveCursorTo(0, 0);
|
e.setOptions({
|
||||||
|
readOnly: true,
|
||||||
|
highlightActiveLine: false,
|
||||||
|
highlightGutterLine: false
|
||||||
|
})
|
||||||
|
e.renderer.$cursorLayer.element.style.opacity=0;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const code = ace.edit("code-editor");
|
function setupEditorArea(id, lsKey) {
|
||||||
code.setShowPrintMargin(false);
|
const e = ace.edit(id);
|
||||||
code.setValue(localStorage.getItem('codeText') || '');
|
e.setShowPrintMargin(false);
|
||||||
code.moveCursorTo(0, 0);
|
e.setValue(localStorage.getItem(lsKey) || '');
|
||||||
|
e.moveCursorTo(0, 0);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
const codeAst = ace.edit("code-ast");
|
const grammar = setupEditorArea("grammar-editor", "grammarText");
|
||||||
codeAst.setShowPrintMargin(false);
|
const code = setupEditorArea("code-editor", "codeText");
|
||||||
codeAst.setOptions({
|
|
||||||
readOnly: true,
|
|
||||||
highlightActiveLine: false,
|
|
||||||
highlightGutterLine: false
|
|
||||||
})
|
|
||||||
codeAst.renderer.$cursorLayer.element.style.opacity=0;
|
|
||||||
|
|
||||||
const codeAstOptimized = ace.edit("code-ast-optimized");
|
const codeAst = setupInfoArea("code-ast");
|
||||||
codeAstOptimized.setShowPrintMargin(false);
|
const codeAstOptimized = setupInfoArea("code-ast-optimized");
|
||||||
codeAstOptimized.setOptions({
|
const profile = setupInfoArea("profile");
|
||||||
readOnly: true,
|
|
||||||
highlightActiveLine: false,
|
|
||||||
highlightGutterLine: false
|
|
||||||
})
|
|
||||||
codeAstOptimized.renderer.$cursorLayer.element.style.opacity=0;
|
|
||||||
|
|
||||||
$('#opt_mode').val(localStorage.getItem('optimazationMode') || 'all');
|
$('#opt_mode').val(localStorage.getItem('optimazationMode') || 'all');
|
||||||
|
|
||||||
|
// Parse
|
||||||
function escapeHtml(unsafe) {
|
function escapeHtml(unsafe) {
|
||||||
return unsafe
|
return unsafe
|
||||||
.replace(/&/g, "&")
|
.replace(/&/g, "&")
|
||||||
@ -71,6 +71,7 @@ function parse() {
|
|||||||
$codeValidation.hide();
|
$codeValidation.hide();
|
||||||
codeAst.setValue('');
|
codeAst.setValue('');
|
||||||
codeAstOptimized.setValue('');
|
codeAstOptimized.setValue('');
|
||||||
|
profile.setValue('');
|
||||||
|
|
||||||
if (grammarText.length === 0) {
|
if (grammarText.length === 0) {
|
||||||
return;
|
return;
|
||||||
@ -84,6 +85,7 @@ function parse() {
|
|||||||
|
|
||||||
codeAst.insert(data.ast);
|
codeAst.insert(data.ast);
|
||||||
codeAstOptimized.insert(data.astOptimized);
|
codeAstOptimized.insert(data.astOptimized);
|
||||||
|
profile.insert(data.profile);
|
||||||
|
|
||||||
if (data.source_valid) {
|
if (data.source_valid) {
|
||||||
$codeValidation.removeClass('editor-validation-invalid').text('Valid').show();
|
$codeValidation.removeClass('editor-validation-invalid').text('Valid').show();
|
||||||
|
@ -59,14 +59,21 @@ std::string lint(const std::string &grammarText, const std::string &codeText, bo
|
|||||||
std::string codeResult;
|
std::string codeResult;
|
||||||
std::string astResult;
|
std::string astResult;
|
||||||
std::string astResultOptimized;
|
std::string astResultOptimized;
|
||||||
|
std::string profileResult;
|
||||||
|
|
||||||
peg::parser peg;
|
peg::parser peg;
|
||||||
auto is_grammar_valid = parse_grammar(grammarText, peg, grammarResult);
|
auto is_grammar_valid = parse_grammar(grammarText, peg, grammarResult);
|
||||||
auto is_source_valid = false;
|
auto is_source_valid = false;
|
||||||
|
|
||||||
if (is_grammar_valid && peg) {
|
if (is_grammar_valid && peg) {
|
||||||
|
std::stringstream ss;
|
||||||
|
peg::enable_profiling(peg, ss);
|
||||||
|
|
||||||
std::shared_ptr<peg::Ast> ast;
|
std::shared_ptr<peg::Ast> ast;
|
||||||
is_source_valid = parse_code(codeText, peg, codeResult, ast);
|
is_source_valid = parse_code(codeText, peg, codeResult, ast);
|
||||||
|
|
||||||
|
profileResult = escape_json(ss.str());
|
||||||
|
|
||||||
if (ast) {
|
if (ast) {
|
||||||
astResult = escape_json(peg::ast_to_s(ast));
|
astResult = escape_json(peg::ast_to_s(ast));
|
||||||
astResultOptimized = escape_json(
|
astResultOptimized = escape_json(
|
||||||
@ -83,6 +90,7 @@ std::string lint(const std::string &grammarText, const std::string &codeText, bo
|
|||||||
json += ",\"code\":" + codeResult;
|
json += ",\"code\":" + codeResult;
|
||||||
json += ",\"ast\":\"" + astResult + "\"";
|
json += ",\"ast\":\"" + astResult + "\"";
|
||||||
json += ",\"astOptimized\":\"" + astResultOptimized + "\"";
|
json += ",\"astOptimized\":\"" + astResultOptimized + "\"";
|
||||||
|
json += ",\"profile\":\"" + profileResult + "\"";
|
||||||
}
|
}
|
||||||
json += "}";
|
json += "}";
|
||||||
|
|
||||||
|
BIN
docs/native.wasm
BIN
docs/native.wasm
Binary file not shown.
@ -130,11 +130,11 @@ 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) {
|
||||||
enable_tracing(parser);
|
enable_tracing(parser, std::cout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt_profile) {
|
if (opt_profile) {
|
||||||
enable_profiling(parser);
|
enable_profiling(parser, std::cout);
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.set_verbose_trace(opt_verbose);
|
parser.set_verbose_trace(opt_verbose);
|
||||||
|
34
peglib.h
34
peglib.h
@ -4393,7 +4393,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void enable_trace(TracerEnter tracer_enter, TracerLeave tracer_leave,
|
void enable_trace(TracerEnter tracer_enter, TracerLeave tracer_leave,
|
||||||
TracerStartOrEnd tracer_start, TracerStartOrEnd tracer_end) {
|
TracerStartOrEnd tracer_start,
|
||||||
|
TracerStartOrEnd tracer_end) {
|
||||||
if (grammar_ != nullptr) {
|
if (grammar_ != nullptr) {
|
||||||
auto &rule = (*grammar_)[start_];
|
auto &rule = (*grammar_)[start_];
|
||||||
rule.tracer_enter = tracer_enter;
|
rule.tracer_enter = tracer_enter;
|
||||||
@ -4450,7 +4451,7 @@ private:
|
|||||||
* enable_tracing
|
* enable_tracing
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
inline void enable_tracing(parser &parser) {
|
inline void enable_tracing(parser &parser, std::ostream &os) {
|
||||||
size_t prev_pos = 0;
|
size_t prev_pos = 0;
|
||||||
parser.enable_trace(
|
parser.enable_trace(
|
||||||
[&](auto &ope, auto s, auto, auto &, auto &c, auto &, auto &) {
|
[&](auto &ope, auto s, auto, auto &, auto &c, auto &, auto &) {
|
||||||
@ -4468,8 +4469,8 @@ inline void enable_tracing(parser &parser) {
|
|||||||
auto lit = dynamic_cast<const peg::LiteralString *>(&ope);
|
auto lit = dynamic_cast<const peg::LiteralString *>(&ope);
|
||||||
if (lit) { name += " '" + peg::escape_characters(lit->lit_) + "'"; }
|
if (lit) { name += " '" + peg::escape_characters(lit->lit_) + "'"; }
|
||||||
}
|
}
|
||||||
std::cout << "E " << pos << backtrack << "\t" << indent << "┌" << name
|
os << "E " << pos << backtrack << "\t" << indent << "┌" << name << " #"
|
||||||
<< " #" << 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);
|
||||||
},
|
},
|
||||||
[&](auto &ope, auto s, auto, auto &sv, auto &c, auto &, auto len,
|
[&](auto &ope, auto s, auto, auto &sv, auto &c, auto &, auto len,
|
||||||
@ -4498,9 +4499,9 @@ inline void enable_tracing(parser &parser) {
|
|||||||
peg::TokenChecker::is_token(const_cast<peg::Ope &>(ope))) {
|
peg::TokenChecker::is_token(const_cast<peg::Ope &>(ope))) {
|
||||||
matched = ", match '" + peg::escape_characters(s, len) + "'";
|
matched = ", match '" + peg::escape_characters(s, len) + "'";
|
||||||
}
|
}
|
||||||
std::cout << "L " << pos << "\t" << indent << ret << name << " #"
|
os << "L " << pos << "\t" << indent << ret << name << " #"
|
||||||
<< c.trace_ids.back() << choice.str() << token << matched
|
<< c.trace_ids.back() << choice.str() << token << matched
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
},
|
},
|
||||||
[&](auto &) {}, [&](auto &) {});
|
[&](auto &) {}, [&](auto &) {});
|
||||||
}
|
}
|
||||||
@ -4509,7 +4510,7 @@ inline void enable_tracing(parser &parser) {
|
|||||||
* enable_profiling
|
* enable_profiling
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
inline void enable_profiling(parser &parser) {
|
inline void enable_profiling(parser &parser, std::ostream &os) {
|
||||||
struct Stats {
|
struct Stats {
|
||||||
struct Item {
|
struct Item {
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -4522,8 +4523,7 @@ inline void enable_profiling(parser &parser) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
parser.enable_trace(
|
parser.enable_trace(
|
||||||
[&](auto &ope, auto, auto, auto &, auto &, auto &,
|
[&](auto &ope, auto, auto, auto &, auto &, auto &, std::any &trace_data) {
|
||||||
std::any &trace_data) {
|
|
||||||
if (auto holder = dynamic_cast<const peg::Holder *>(&ope)) {
|
if (auto holder = dynamic_cast<const peg::Holder *>(&ope)) {
|
||||||
auto &stats = *std::any_cast<Stats *>(trace_data);
|
auto &stats = *std::any_cast<Stats *>(trace_data);
|
||||||
|
|
||||||
@ -4550,9 +4550,9 @@ inline void enable_profiling(parser &parser) {
|
|||||||
}
|
}
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
size_t id = 0;
|
size_t id = 0;
|
||||||
std::cout << " id total % success fail "
|
os << " id total % success fail "
|
||||||
"definition"
|
"definition"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
size_t total_total, total_success = 0, total_fail = 0;
|
size_t total_total, total_success = 0, total_fail = 0;
|
||||||
char buff[BUFSIZ];
|
char buff[BUFSIZ];
|
||||||
for (auto &[name, success, fail] : stats.items) {
|
for (auto &[name, success, fail] : stats.items) {
|
||||||
@ -4562,18 +4562,18 @@ inline void enable_profiling(parser &parser) {
|
|||||||
auto ratio = total * 100.0 / stats.total;
|
auto ratio = total * 100.0 / stats.total;
|
||||||
sprintf(buff, "%4zu %10lu %5.2f %10lu %10lu %s", id, total,
|
sprintf(buff, "%4zu %10lu %5.2f %10lu %10lu %s", id, total,
|
||||||
ratio, success, fail, name.c_str());
|
ratio, success, fail, name.c_str());
|
||||||
std::cout << buff << std::endl;
|
os << buff << std::endl;
|
||||||
id++;
|
id++;
|
||||||
}
|
}
|
||||||
std::cout << std::endl;
|
os << std::endl;
|
||||||
total_total = total_success + total_fail;
|
total_total = total_success + total_fail;
|
||||||
sprintf(buff, "%4s %10lu %5s %10lu %10lu %s", "", total_total,
|
sprintf(buff, "%4s %10lu %5s %10lu %10lu %s", "", total_total,
|
||||||
"", total_success, total_fail, "Total counters");
|
"", total_success, total_fail, "Total counters");
|
||||||
std::cout << buff << std::endl;
|
os << buff << std::endl;
|
||||||
sprintf(buff, "%4s %10s %5s %10.2f %10.2f %s", "", "", "",
|
sprintf(buff, "%4s %10s %5s %10.2f %10.2f %s", "", "", "",
|
||||||
total_success * 100.0 / total_total,
|
total_success * 100.0 / total_total,
|
||||||
total_fail * 100.0 / total_total, "% success/fail");
|
total_fail * 100.0 / total_total, "% success/fail");
|
||||||
std::cout << buff << std::endl;
|
os << buff << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user