Handle goto actions after reductions in a more standard way

Rather than letting the reduced tree become the new lookahead symbol,
and re-adding it to the stack via a subsequent shift action, just
add it to the stack as part of the reduce action. This is more in
line with the way LR is described traditionally.
This commit is contained in:
Max Brunsfeld 2015-05-27 10:53:02 -07:00
parent 59fd190695
commit f7e4445358
3 changed files with 27 additions and 19 deletions

View file

@ -83,7 +83,8 @@ describe("Document", [&]() {
it("calls the debugger with a message for each parse action", [&]() {
ts_document_set_input_string(doc, "[1, 2]");
AssertThat(debugger->messages, Contains("shift state:1"));
AssertThat(debugger->messages, Contains("new_parse"));
AssertThat(debugger->messages, Contains("lookahead char:'['"));
AssertThat(debugger->messages, Contains("reduce sym:value, count:1"));
AssertThat(debugger->messages, Contains("accept"));
});

View file

@ -171,8 +171,7 @@ static void shift(TSParser *parser, TSStateId parse_state) {
parse_state = ts_stack_top_state(&parser->stack);
ts_stack_push(&parser->stack, parse_state, parser->lookahead);
parser->lookahead = parser->next_lookahead;
parser->next_lookahead = NULL;
parser->lookahead = NULL;
}
static void shift_extra(TSParser *parser) {
@ -180,15 +179,14 @@ static void shift_extra(TSParser *parser) {
shift(parser, 0);
}
static void reduce(TSParser *parser, TSSymbol symbol, size_t child_count) {
TSStack *stack = &parser->stack;
parser->next_lookahead = parser->lookahead;
static TSTree * reduce_helper(TSParser *parser, TSSymbol symbol, size_t child_count, bool extra) {
/*
* Walk down the stack to determine which symbols will be reduced.
* The child node count is known ahead of time, but some children
* may be ubiquitous tokens, which don't count.
*/
TSStack *stack = &parser->stack;
for (size_t i = 0; i < child_count; i++) {
if (child_count == stack->size)
break;
@ -203,19 +201,32 @@ static void reduce(TSParser *parser, TSSymbol symbol, size_t child_count) {
children[i] = stack->entries[start_index + i].node;
bool hidden = parser->language->hidden_symbol_flags[symbol];
parser->lookahead = ts_tree_make_node(symbol, child_count, children, hidden);
ts_stack_shrink(stack, stack->size - child_count);
TSTree *parent = ts_tree_make_node(symbol, child_count, children, hidden);
ts_stack_shrink(stack, start_index);
TSStateId top_state = ts_stack_top_state(stack), state;
if (extra)
state = top_state;
else
state = get_action(parser->language, top_state, symbol).data.to_state;
ts_stack_push(stack, state, parent);
return parent;
}
static void reduce(TSParser *parser, TSSymbol symbol, size_t child_count) {
reduce_helper(parser, symbol, child_count, false);
}
static void reduce_extra(TSParser *parser, TSSymbol symbol) {
reduce(parser, symbol, 1);
ts_tree_set_extra(parser->lookahead);
TSTree *reduced = reduce_helper(parser, symbol, 1, true);
ts_tree_set_extra(reduced);
}
static void reduce_fragile(TSParser *parser, TSSymbol symbol, size_t child_count) {
reduce(parser, symbol, child_count);
ts_tree_set_fragile_left(parser->lookahead);
ts_tree_set_fragile_right(parser->lookahead);
TSTree *reduced = reduce_helper(parser, symbol, child_count, false);
ts_tree_set_fragile_left(reduced);
ts_tree_set_fragile_right(reduced);
}
static int handle_error(TSParser *parser) {
@ -307,8 +318,6 @@ void ts_parser_destroy(TSParser *parser) {
if (parser->lookahead)
ts_tree_release(parser->lookahead);
if (parser->next_lookahead)
ts_tree_release(parser->next_lookahead);
if (parser->lexer.debugger.release_fn)
parser->lexer.debugger.release_fn(parser->lexer.debugger.data);
@ -327,7 +336,6 @@ void ts_parser_set_debugger(TSParser *parser, TSDebugger debugger) {
const TSTree *ts_parser_parse(TSParser *parser, TSInput input,
TSInputEdit *edit) {
parser->lookahead = NULL;
parser->next_lookahead = NULL;
TSLength position;
if (edit) {
@ -370,8 +378,8 @@ const TSTree *ts_parser_parse(TSParser *parser, TSInput input,
break;
case TSParseActionTypeReduce:
reduce(parser, action.data.symbol, action.data.child_count);
DEBUG("reduce sym:%s, count:%u", SYM_NAME(action.data.symbol), action.data.child_count);
reduce(parser, action.data.symbol, action.data.child_count);
break;
case TSParseActionTypeReduceExtra:
@ -380,8 +388,8 @@ const TSTree *ts_parser_parse(TSParser *parser, TSInput input,
break;
case TSParseActionTypeReduceFragile:
reduce_fragile(parser, action.data.symbol, action.data.child_count);
DEBUG("reduce_fragile sym:%s, count:%u", SYM_NAME(action.data.symbol), action.data.child_count);
reduce_fragile(parser, action.data.symbol, action.data.child_count);
break;
case TSParseActionTypeAccept:

View file

@ -13,7 +13,6 @@ typedef struct {
TSStack right_stack;
size_t total_chars;
TSTree *lookahead;
TSTree *next_lookahead;
const TSLanguage *language;
} TSParser;