Clean up parser.c

This commit is contained in:
Max Brunsfeld 2016-04-02 20:58:19 -07:00
parent 956b3e68d7
commit d5c4dacb35

View file

@ -11,10 +11,6 @@
#include "runtime/language.h"
#include "runtime/alloc.h"
/*
* Debugging
*/
#define LOG(...) \
if (self->lexer.debugger.debug_fn) { \
snprintf(self->lexer.debug_buffer, TS_DEBUG_BUFFER_SIZE, __VA_ARGS__); \
@ -92,10 +88,6 @@ typedef enum {
BreakdownAborted,
} BreakdownResult;
/*
* Private
*/
static StackSlice ts_parser__pop_one(TSParser *self, int head_index, int count) {
StackPopResult pop = ts_stack_pop_count(self->stack, head_index, count);
if (pop.status != StackPopSucceeded)
@ -179,35 +171,8 @@ error:
return BreakdownFailed;
}
static void ts_parser__pop_reusable_subtree(ReusableNode *);
/*
* Replace the parser's reusable_subtree with its first non-fragile descendant.
* Return true if a suitable descendant is found, false otherwise.
*/
static void ts_parser__breakdown_reusable_subtree(ReusableNode *reusable_node) {
do {
if (reusable_node->tree->symbol == ts_builtin_sym_error) {
ts_parser__pop_reusable_subtree(reusable_node);
return;
}
if (reusable_node->tree->child_count == 0) {
ts_parser__pop_reusable_subtree(reusable_node);
return;
}
reusable_node->tree = reusable_node->tree->children[0];
} while (ts_tree_is_fragile(reusable_node->tree));
}
/*
* Replace the parser's reusable_subtree with its largest right neighbor, or
* NULL if no right neighbor exists.
*/
static void ts_parser__pop_reusable_subtree(ReusableNode *reusable_node) {
static void ts_parser__pop_reusable_node(ReusableNode *reusable_node) {
reusable_node->char_index += ts_tree_total_chars(reusable_node->tree);
while (reusable_node->tree) {
TSTree *parent = reusable_node->tree->context.parent;
size_t next_index = reusable_node->tree->context.index + 1;
@ -219,39 +184,49 @@ static void ts_parser__pop_reusable_subtree(ReusableNode *reusable_node) {
}
}
static bool ts_parser__can_reuse(TSParser *self, int head, TSTree *subtree) {
if (subtree->symbol == ts_builtin_sym_error)
static void ts_parser__breakdown_reusable_node(ReusableNode *reusable_node) {
do {
if (reusable_node->tree->symbol == ts_builtin_sym_error) {
ts_parser__pop_reusable_node(reusable_node);
return;
}
if (reusable_node->tree->child_count == 0) {
ts_parser__pop_reusable_node(reusable_node);
return;
}
reusable_node->tree = reusable_node->tree->children[0];
} while (ts_tree_is_fragile(reusable_node->tree));
}
static bool ts_parser__can_reuse(TSParser *self, int head, TSTree *tree) {
if (tree->symbol == ts_builtin_sym_error)
return false;
if (ts_tree_is_fragile(subtree)) {
if (subtree->parse_state != ts_stack_top_state(self->stack, head))
return false;
}
TSStateId state = ts_stack_top_state(self->stack, head);
if (ts_tree_is_fragile(tree) &&
tree->parse_state != ts_stack_top_state(self->stack, head))
return false;
if (subtree->lex_state != TS_TREE_STATE_INDEPENDENT) {
TSStateId lex_state = self->language->lex_states[state];
if (subtree->lex_state != lex_state)
return false;
}
TSStateId top_state = ts_stack_top_state(self->stack, head);
if (tree->lex_state != TS_TREE_STATE_INDEPENDENT &&
tree->lex_state != self->language->lex_states[top_state])
return false;
const TSParseAction action =
ts_language_last_action(self->language, state, subtree->symbol);
ts_language_last_action(self->language, top_state, tree->symbol);
if (action.type == TSParseActionTypeError || action.can_hide_split)
return false;
if (subtree->extra && !action.extra)
if (tree->extra && !action.extra)
return false;
return true;
}
/*
* Advance the parser's lookahead subtree. If there is a reusable subtree
* at the correct position in the parser's previous tree, use that. Otherwise,
* run the lexer.
*/
static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head, ReusableNode *reusable_node) {
static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head,
ReusableNode *reusable_node) {
TSLength position = ts_stack_top_position(self->stack, head);
while (reusable_node->tree) {
@ -261,7 +236,7 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head, ReusableN
if (reusable_node->char_index < position.chars) {
LOG("past_reusable sym:%s", SYM_NAME(reusable_node->tree->symbol));
ts_parser__pop_reusable_subtree(reusable_node);
ts_parser__pop_reusable_node(reusable_node);
continue;
}
@ -270,14 +245,13 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head, ReusableN
ts_parser__breakdown_top_of_stack(self, head);
LOG("breakdown_changed sym:%s", SYM_NAME(reusable_node->tree->symbol));
ts_parser__breakdown_reusable_subtree(reusable_node);
ts_parser__breakdown_reusable_node(reusable_node);
continue;
}
if (!ts_parser__can_reuse(self, head, reusable_node->tree)) {
LOG("breakdown_unreusable sym:%s",
SYM_NAME(reusable_node->tree->symbol));
ts_parser__breakdown_reusable_subtree(reusable_node);
LOG("breakdown_unreusable sym:%s", SYM_NAME(reusable_node->tree->symbol));
ts_parser__breakdown_reusable_node(reusable_node);
continue;
}
@ -285,7 +259,7 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head, ReusableN
TSLength size = ts_tree_total_size(result);
LOG("reuse sym:%s size:%lu extra:%d", SYM_NAME(result->symbol), size.chars,
result->extra);
ts_parser__pop_reusable_subtree(reusable_node);
ts_parser__pop_reusable_node(reusable_node);
ts_tree_retain(result);
return result;
}
@ -297,14 +271,6 @@ static TSTree *ts_parser__get_next_lookahead(TSParser *self, int head, ReusableN
return self->language->lex_fn(&self->lexer, lex_state, false);
}
static int ts_parser__split(TSParser *self, int head) {
return ts_stack_split(self->stack, head);
}
static void ts_parser__remove_head(TSParser *self, int head) {
ts_stack_remove_head(self->stack, head);
}
static int ts_parser__select_tree(void *data, TSTree *left, TSTree *right) {
if (!left || left->symbol == ts_builtin_sym_error)
return 1;
@ -327,16 +293,12 @@ static int ts_parser__select_tree(void *data, TSTree *left, TSTree *right) {
return comparison;
}
/*
* Parse Actions
*/
static ParseActionResult ts_parser__shift(TSParser *self, int head,
TSStateId parse_state,
TSTree *lookahead) {
bool is_verifying = lookahead->child_count > 0;
bool is_pending = lookahead->child_count > 0;
switch (
ts_stack_push(self->stack, head, lookahead, is_verifying, parse_state)) {
ts_stack_push(self->stack, head, lookahead, is_pending, parse_state)) {
case StackPushFailed:
return ParseActionFailed;
case StackPushMerged:
@ -638,7 +600,7 @@ static ParseActionResult ts_parser__accept(TSParser *self, int head) {
if (!trees.size)
array_delete(&trees);
ts_parser__remove_head(self, slice.head_index);
ts_stack_remove_head(self->stack, slice.head_index);
int comparison = ts_parser__select_tree(self, self->finished_tree, root);
if (comparison > 0) {
ts_tree_release(self->finished_tree);
@ -732,11 +694,6 @@ error:
return ParseActionFailed;
}
/*
* Continue performing parse actions for the given head until the current
* lookahead symbol is consumed.
*/
static ParseActionResult ts_parser__consume_lookahead(TSParser *self, int head,
TSTree *lookahead) {
for (;;) {
@ -768,7 +725,7 @@ static ParseActionResult ts_parser__consume_lookahead(TSParser *self, int head,
} else {
if (should_skip)
continue;
current_head = ts_parser__split(self, head);
current_head = ts_stack_split(self->stack, head);
LOG_ACTION("split_action from_head:%d, new_head:%d", head, current_head);
}
@ -790,7 +747,7 @@ static ParseActionResult ts_parser__consume_lookahead(TSParser *self, int head,
return ts_parser__handle_error(self, current_head, lookahead);
} else {
LOG_ACTION("bail current_head:%d", current_head);
ts_parser__remove_head(self, current_head);
ts_stack_remove_head(self->stack, current_head);
return ParseActionRemoved;
}
}
@ -848,7 +805,7 @@ static ParseActionResult ts_parser__consume_lookahead(TSParser *self, int head,
} else {
LOG_ACTION("bail head:%d, count:%d", current_head,
ts_stack_head_count(self->stack));
ts_parser__remove_head(self, current_head);
ts_stack_remove_head(self->stack, current_head);
if (current_head == head)
return ParseActionRemoved;
break;
@ -873,10 +830,6 @@ static ParseActionResult ts_parser__consume_lookahead(TSParser *self, int head,
}
}
/*
* Public
*/
bool ts_parser_init(TSParser *self) {
ts_lexer_init(&self->lexer);
self->finished_tree = NULL;
@ -920,7 +873,7 @@ void ts_parser_set_debugger(TSParser *self, TSDebugger debugger) {
TSTree *ts_parser_parse(TSParser *self, TSInput input, TSTree *previous_tree) {
ts_parser__start(self, input, previous_tree);
size_t max_position = 0;
ReusableNode current_reusable_node, next_reusable_node = {previous_tree, 0};
ReusableNode current_reusable_node, next_reusable_node = { previous_tree, 0 };
for (;;) {
current_reusable_node = next_reusable_node;