Skip to content

Commit

Permalink
Now I've got closer to a good parse tree dump
Browse files Browse the repository at this point in the history
  • Loading branch information
mingodad committed Jul 16, 2023
1 parent 02178b9 commit eb7ff4c
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 57 deletions.
9 changes: 7 additions & 2 deletions playground/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<option>Gringo/Clingo non grounded parser</option>
<option>Ada parser</option>
<option>Ada parser case insensitive</option>
<option>XML parser</option>
<option>C++ parser (bug)</option>
<option>Bison parser (not working)</option>
<option>DParser parser (not working)</option>
Expand All @@ -52,14 +53,14 @@
<li class="editor-options">
<ul class="editor-header-options">
<li class="option"><label><input id="gen-ebnf" type="checkbox">Gen. EBNF</label></li>
<li class="option"><label><input id="auto-refresh" type="checkbox">Auto Refresh</label></li>
<!--<li class="option"><label><input id="auto-refresh" type="checkbox">Auto Refresh</label></li>-->
<li class="option"><button id="parse" class="parse">Parse</button></li>
</ul>
</li>
</ul>
<pre id="code-editor" class="editor-area">{{source}}</pre>
<div class="editor-sub-header"><label><input id="show-ast" class="show-toggle" type="checkbox">AST</label>&nbsp;&nbsp;&nbsp;&nbsp;
mode:&nbsp;<select id="opt-mode" type="checkbox"><option value="0">Raw parse tree</option><option value="1">Unwrap</option><option value="2">Simplify</option></select>
mode:&nbsp;<select id="ast-mode" type="checkbox"><option value="1">Parse tree</option><option value="2">Debug parse tree</option></select>
</div>
<pre id="code-ast" class="editor-area"></pre>
<div class="editor-sub-header"><label><input id="show-lexer" class="show-toggle" type="checkbox">Lexer</label></div>
Expand All @@ -71,6 +72,10 @@
<div id="overlay"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--
<script src="ajax/libs/ace/1.4.2/ace.js"></script>
<script src="ajax/libs/jquery/3.3.1/jquery.min.js"></script>
-->
<script src="index.js"></script>
<script src="lalr_playground.js"></script>
</body>
Expand Down
23 changes: 17 additions & 6 deletions playground/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ function loadLalr_sample(self) {
$.get(base_url + "javascript.g", function( data ) {
grammarEditor.setValue( data );
});
$.get(base_url + "test.js", function( data ) {
$.get(base_url + "test.js.txt", function( data ) {
codeEditor.setValue( data );
codeEditor.getSession().setMode("ace/mode/javascript");
});
Expand All @@ -141,7 +141,7 @@ function loadLalr_sample(self) {
$.get(base_url + "javascript-core.g", function( data ) {
grammarEditor.setValue( data );
});
$.get(base_url + "test.js", function( data ) {
$.get(base_url + "test.js.txt", function( data ) {
codeEditor.setValue( data );
codeEditor.getSession().setMode("ace/mode/javascript");
});
Expand Down Expand Up @@ -227,10 +227,19 @@ function loadLalr_sample(self) {
codeEditor.getSession().setMode("ace/mode/ada");
});
break;
case "XML parser":
$.get(base_url + "xml.g", function( data ) {
grammarEditor.setValue( data );
});
$.get(base_url + "test.xml.txt", function( data ) {
codeEditor.setValue( data );
codeEditor.getSession().setMode("ace/mode/xml");
});
break;
}
}

$('#opt-mode').val(localStorage.getItem('optimizationMode') || '2');
//$('#ast-mode').val(localStorage.getItem('optimizationMode') || '2');
$('#gen-ebnf').prop('checked', localStorage.getItem('gen-ebnf') === 'true');
$('#auto-refresh').prop('checked', localStorage.getItem('autoRefresh') === 'true');
$('#parse').prop('disabled', $('#auto-refresh').prop('checked'));
Expand Down Expand Up @@ -284,7 +293,7 @@ function generateErrorListHTML(errors) {
function updateLocalStorage() {
localStorage.setItem('grammarText', grammarEditor.getValue());
localStorage.setItem('codeText', codeEditor.getValue());
localStorage.setItem('optimizationMode', $('#opt-mode').val());
//localStorage.setItem('optimizationMode', $('#opt-mode').val());
localStorage.setItem('gen-ebnf', $('#gen-ebnf').prop('checked'));
localStorage.setItem('autoRefresh', $('#auto-refresh').prop('checked'));
}
Expand All @@ -300,10 +309,12 @@ function parse() {
const $codeInfo = $('#code-info');
const codeText = codeEditor.getValue();

const optimizationMode = $('#opt-mode').val();
const astMode = $('#ast-mode').val();
const generate_ebnf = $('#gen-ebnf').prop('checked');
const lexer = $('#show-lexer').prop('checked');
const generate_ast = $('#show-ast').prop('checked');
let generate_ast = $('#show-ast').prop('checked');
if(generate_ast && astMode == 2)
generate_ast = 2;

$grammarInfo.html('');
$grammarValidation.hide();
Expand Down
167 changes: 118 additions & 49 deletions playground/lalr_playground.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,41 @@ struct C_MultLineCommentLexer
}
};


struct ParseTreeUserDataDbg {
int index;
int stack_index;
static int next_index;
static int total;
ParseTreeUserDataDbg():index(total++), stack_index(next_index++) {};
};
int ParseTreeUserDataDbg::next_index = 0;
int ParseTreeUserDataDbg::total = 0;


static bool parseTreeMakerDbg( ParseTreeUserDataDbg& result, const ParseTreeUserDataDbg* start, const lalr::ParserNode<mychar_t>* nodes, size_t length )
{
switch_output("ast");
// //printf("astMaker: %s\n", nodes[0].lexeme().c_str());
// const char *lexstr = (length > 0 ? (const char *)nodes[0].lexeme().c_str() : "::lnull");
// const char *idstr = (length > 0 ? nodes[0].symbol()->identifier : "::inull");
// int line = (length > 0 ? nodes[0].line() : 0);
// int column = (length > 0 ? nodes[0].column() : 0);
// //const char *stateLabel = (length > 0 ? nodes[0].state()->label : "::inull");
// printf("astMaker: %p\t%zd:%d:%d\t%p\t%zd\t->\t%s : %s :%d:%d\n", start, length,
// length ? start->index : -1, length ? start->stack_index : -1,
// nodes, length, idstr, lexstr, line, column);
printf("----\n");
for(size_t i=0; i< length; ++i)
printf("%zd:%d\t%p\t%d:%d\t%p <:> %s <:> %s <:> %s <:> %d:%d\n", i, nodes[i].symbol()->type,
start+i, start[i].index, start[i].stack_index, nodes+i,
nodes[i].symbol()->identifier, nodes[i].symbol()->lexeme,
nodes[i].lexeme().c_str(), nodes[i].line(), nodes[i].column());
switch_output("parse_status");
return true;
}


struct ParseTreeUserData {
std::vector<ParseTreeUserData> children;
const lalr::ParserSymbol *symbol;
Expand All @@ -69,48 +104,48 @@ struct ParseTreeUserData {

static bool parsetreeMaker( ParseTreeUserData& result, const ParseTreeUserData* start, const lalr::ParserNode<mychar_t>* nodes, size_t length )
{
if(length == 2 && nodes[0].symbol()->type == lalr::SymbolType::SYMBOL_NON_TERMINAL && nodes[1].symbol()->type == lalr::SymbolType::SYMBOL_NON_TERMINAL)
{
if(start[0].symbol == nodes[0].symbol())
{
result = start[0];
}
else
{
result.symbol = nodes[0].symbol();
}
ParseTreeUserData& udt = result.children.emplace_back();
udt.symbol = nodes[1].symbol();
udt.children.push_back(start[1]);
}
else
if(length == 0) return false;
result.symbol = nodes[length-1].state()->transitions->reduced_symbol;
for(size_t i_node = 0; i_node < length; ++i_node)
{
for(size_t i_node = 0; i_node < length; ++i_node)
const lalr::ParserNode<mychar_t>& the_node = nodes[i_node];
switch(the_node.symbol()->type)
{
const lalr::ParserNode<mychar_t>& the_node = nodes[i_node];
switch(the_node.symbol()->type)
case lalr::SymbolType::SYMBOL_TERMINAL:
{
ParseTreeUserData& udt = result.children.emplace_back();
udt.symbol = the_node.symbol();
udt.lexeme = the_node.lexeme();
//printf("TERMINAL: %s : %s\n", udt.symbol->identifier, udt.lexeme.c_str());
}
break;
case lalr::SymbolType::SYMBOL_NON_TERMINAL:
{
case lalr::SymbolType::SYMBOL_TERMINAL:
if(the_node.symbol() == result.symbol)
{
ParseTreeUserData& udt = (length == 1) ? result : result.children.emplace_back();
udt.symbol = the_node.symbol();
udt.symbol = the_node.symbol();
udt.lexeme = the_node.lexeme();
//printf("TERMINAL: %s : %s\n", udt.symbol->identifier, udt.lexeme.c_str());
const ParseTreeUserData& startx = start[i_node];
for (std::vector<ParseTreeUserData>::const_iterator child = startx.children.begin(); child != startx.children.end(); ++child)
{
result.children.push_back( std::move(*child) );
}
}
break;
case lalr::SymbolType::SYMBOL_NON_TERMINAL:
else
{
ParseTreeUserData& udt = (length == 1) ? result : result.children.emplace_back();
ParseTreeUserData& udt = result.children.emplace_back();
udt.symbol = the_node.symbol();
udt.children.push_back(start[i_node]);
//printf("NON_TERMINAL: %s\n", result.symbol->identifier);
if(udt.symbol == start[i_node].symbol)
{
udt.children = start[i_node].children;
}
else
udt.children.push_back(std::move(start[i_node]));
}
break;
default:
//LALR_ASSERT( ?? );
printf("Unexpected symbol %p\n", the_node.symbol());
//printf("NON_TERMINAL: %s\n", result.symbol->identifier);
}
break;
default:
//LALR_ASSERT( ?? );
printf("Unexpected symbol %p\n", the_node.symbol());
}
}
return true;
Expand Down Expand Up @@ -205,30 +240,64 @@ extern "C" int parse(const char *grammar, const unsigned char *input, int dumpLe

if(input) {
lalr::ErrorPolicy error_policy_input;
//lalr::Parser<const mychar_t*, int> parser( compiler.parser_state_machine(), &error_policy_input );
lalr::Parser<const mychar_t*, ParseTreeUserData> parser( compiler.parser_state_machine(), &error_policy_input );
parser.set_default_action_handler(parsetreeMaker);
parser.lexer_action_handlers()
( "C_MultilineComment", &C_MultLineCommentLexer::string_lexer )
;
if(dumpLexer) {
switch_output("lexer");
parser.dumpLex( input, input + strlen((const char*)input) );
if(generate_parsetree == 1)
{
lalr::Parser<const mychar_t*, ParseTreeUserData> parser( compiler.parser_state_machine(), &error_policy_input );
parser.set_default_action_handler(parsetreeMaker);
parser.lexer_action_handlers()
( "C_MultilineComment", &C_MultLineCommentLexer::string_lexer )
;
if(dumpLexer) {
switch_output("lexer");
parser.dumpLex( input, input + strlen((const char*)input) );
}
else parser.parse( input, input + strlen((const char*)input) );

parse_result = parser.accepted() == 1 && parser.full() == 1;
if(generate_parsetree && parse_result)
{
showDiffTime("Parse input");
switch_output("ast");
print_parsetree( parser.user_data(), 0 );
switch_output("parse_status");
showDiffTime("Print parse tree");
}
}
else parser.parse( input, input + strlen((const char*)input) );
if(generate_parsetree > 1)
{
lalr::Parser<const mychar_t*, ParseTreeUserDataDbg> parser( compiler.parser_state_machine(), &error_policy_input );
parser.set_default_action_handler(parseTreeMakerDbg);
parser.lexer_action_handlers()
( "C_MultilineComment", &C_MultLineCommentLexer::string_lexer )
;
if(dumpLexer) {
switch_output("lexer");
parser.dumpLex( input, input + strlen((const char*)input) );
}
else parser.parse( input, input + strlen((const char*)input) );

parse_result = parser.accepted() == 1 && parser.full() == 1;
if(generate_parsetree && parse_result)
parse_result = parser.accepted() == 1 && parser.full() == 1;
}
else
{
switch_output("ast");
print_parsetree( parser.user_data(), 0 );
switch_output("parse_status");
lalr::Parser<const mychar_t*, int> parser( compiler.parser_state_machine(), &error_policy_input );
parser.lexer_action_handlers()
( "C_MultilineComment", &C_MultLineCommentLexer::string_lexer )
;
if(dumpLexer) {
switch_output("lexer");
parser.dumpLex( input, input + strlen((const char*)input) );
}
else parser.parse( input, input + strlen((const char*)input) );

parse_result = parser.accepted() == 1 && parser.full() == 1;
}
if (parse_result) {
if (parse_verbose) {
fprintf(stderr, "Parse successful.\n");
}
showDiffTime("Parse input");
if(generate_parsetree != 1)
showDiffTime("Parse input");
}
else {
err = -2;
Expand Down

0 comments on commit eb7ff4c

Please sign in to comment.