Updated playground to show profiling result

This commit is contained in:
yhirose 2022-06-03 19:25:49 -04:00
parent ad74d9e8c0
commit 8f19894e32
6 changed files with 62 additions and 44 deletions

View File

@ -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&nbsp;&nbsp;&nbsp;&nbsp; <div class="editor-sub-header">Optimized AST&nbsp;&nbsp;&nbsp;&nbsp;
mode:&nbsp;<select id="opt_mode" type="checkbox"><option value="all">All</option><option value="only">Only</option></select> mode:&nbsp;<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>

View File

@ -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, "&amp;") .replace(/&/g, "&amp;")
@ -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();

View File

@ -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 += "}";

Binary file not shown.

View File

@ -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);

View File

@ -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;
} }
} }
}, },