update: parser/src/parser a bit more normed

This commit is contained in:
maix0 2024-09-19 22:19:22 +02:00
parent e4a11d298e
commit 0862cd35c4
23 changed files with 448 additions and 311 deletions

View file

@ -31,6 +31,7 @@ node/node_iterator \
node/node_relevent \
parser/parser_accept \
parser/parser_advance \
parser/parser_advance_bis \
parser/parser_breakdown_top_of_stack \
parser/parser_condense_stack \
parser/parser_do_reduction \

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/10 13:56:47 by maiboyer #+# #+# */
/* Updated: 2024/09/19 16:44:59 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 22:10:08 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -79,6 +79,33 @@ struct s_string_input
t_u32 length;
};
struct s_parser_advance_state
{
TSParseAction action;
TableEntry table_entry;
bool end_of_non_terminal_extra;
bool is_fragile;
bool needs_lex;
t_stack_version last_reduction_version;
t_stack_version reduction_version;
t_state_id next_state;
t_state_id state;
t_subtree lookahead;
t_subtree mutable_lookahead;
t_u32 i;
};
struct s_parser_parse_state
{
t_tree *result;
t_u32 position;
t_u32 last_position;
t_u32 version_count;
t_stack_version version;
t_u32 min_error_cost;
bool first;
};
t_parser *ts_parser_new(t_language *language);
t_tree *ts_parser_parse(t_parser *self, t_input input);
t_tree *ts_parser_parse_string(t_parser *self, t_const_str string, t_u32 length);

View file

@ -6,28 +6,72 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 14:02:35 by maiboyer #+# #+# */
/* Updated: 2024/09/19 17:23:29 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 21:37:04 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "me/types.h"
#include "parser/inner/parser_inner.h"
void ts_parser__accept(t_parser *self, t_stack_version version,
t_subtree lookahead)
void _parser_accept_endloop(t_parser *self, t_subtree root, t_u32 *i)
{
self->accept_count++;
if (self->finished_tree)
{
if (ts_parser__select_tree(self, self->finished_tree, root))
{
ts_subtree_release(self->finished_tree);
self->finished_tree = root;
}
else
ts_subtree_release(root);
}
else
self->finished_tree = root;
(*i)++;
}
bool parser_select_root(\
t_parser *self, t_vec_subtree *trees, t_subtree *root, t_u32 *j)
{
t_u32 k;
t_u32 n;
const t_subtree *childs;
t_subtree tree;
tree = trees->buffer[*j];
if (!ts_subtree_extra(tree))
{
n = ts_subtree_child_count(tree);
childs = ts_subtree_children(tree);
k = 0;
while (k < n)
{
childs[k]->ref_count++;
k++;
}
vec_subtree_splice(trees, vec_subtree_splice_args(*j, 1, n, childs));
*root = ts_subtree_new_node(ts_subtree_symbol(tree), trees, \
tree->production_id, self->language);
ts_subtree_release(tree);
return (true);
}
return ((*j)--, false);
}
void ts_parser__accept(\
t_parser *self, t_stack_version v, t_subtree lookahead)
{
t_u32 child_count;
const t_subtree *children;
t_stack_slice_array pop;
t_vec_subtree trees;
t_subtree root;
t_u32 i;
t_u32 j;
t_u32 k;
t_subtree tree;
assert(ts_subtree_is_eof(lookahead));
ts_stack_push(self->stack, (struct s_stack_push_arg){version, lookahead, false, 1});
pop = ts_stack_pop_all(self->stack, version);
if (!ts_subtree_is_eof(lookahead))
me_abort("failed assertion: lookahead isn't eof tree");
ts_stack_push(self->stack, (struct s_stack_push_arg){v, lookahead, 0, 1});
pop = ts_stack_pop_all(self->stack, v);
i = 0;
while (i < pop.size)
{
@ -35,42 +79,10 @@ void ts_parser__accept(t_parser *self, t_stack_version version,
root = NULL;
j = trees.len - 1;
while (j + 1 > 0)
{
tree = trees.buffer[j];
if (!ts_subtree_extra(tree))
{
child_count = ts_subtree_child_count(tree);
children = ts_subtree_children(tree);
k = 0;
while (k < child_count)
{
children[k]->ref_count++;
k++;
}
vec_subtree_splice(&trees, vec_subtree_splice_args(j, 1,
child_count, children));
root = (ts_subtree_new_node(ts_subtree_symbol(tree), &trees,
tree->production_id, self->language));
ts_subtree_release(tree);
if (parser_select_root(self, &trees, &root, &j))
break ;
}
j--;
}
self->accept_count++;
if (self->finished_tree)
{
if (ts_parser__select_tree(self, self->finished_tree, root))
{
ts_subtree_release(self->finished_tree);
self->finished_tree = root;
}
else
ts_subtree_release(root);
}
else
self->finished_tree = root;
i++;
_parser_accept_endloop(self, root, &i);
}
ts_stack_remove_version(self->stack, pop.contents[0].version);
ts_stack_halt(self->stack, version);
ts_stack_halt(self->stack, v);
}

View file

@ -6,131 +6,131 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 14:01:20 by maiboyer #+# #+# */
/* Updated: 2024/09/19 17:24:14 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 22:17:53 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser/inner/parser_inner.h"
bool ts_parser__advance(t_parser *self, t_stack_version version)
{
t_state_id state;
t_subtree mutable_lookahead;
t_subtree lookahead;
TableEntry table_entry;
bool needs_lex;
t_u32 i;
t_stack_version last_reduction_version;
TSParseAction action;
t_state_id next_state;
bool is_fragile;
bool end_of_non_terminal_extra;
t_stack_version reduction_version;
bool _parser_advance_do_lex(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state);
bool _parser_advance_shift(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state);
lookahead = NULL;
table_entry = (TableEntry){.action_count = 0};
state = ts_stack_state(self->stack, version);
needs_lex = true;
while (true)
bool _process_single_action(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
state->action = state->table_entry.actions[state->i];
if (state->action.type == TSParseActionTypeShift)
{
if (needs_lex)
{
needs_lex = false;
lookahead = ts_parser__lex(self, version, state);
if (self->has_scanner_error)
return (false);
if (lookahead)
ts_language_table_entry(self->language, state,
ts_subtree_symbol(lookahead), &table_entry);
else
ts_language_table_entry(self->language, state,
ts_builtin_sym_end, &table_entry);
}
last_reduction_version = STACK_VERSION_NONE;
i = 0;
while (i < table_entry.action_count)
{
action = table_entry.actions[i];
if (action.type == TSParseActionTypeShift)
{
if (action.shift.repetition)
{
i++;
continue ;
}
if (action.shift.extra)
next_state = state;
else
next_state = action.shift.state;
if (ts_subtree_child_count(lookahead) > 0)
next_state = ts_language_next_state(self->language, state,
ts_subtree_symbol(lookahead));
ts_parser__shift(self, version, next_state, lookahead,
action.shift.extra);
return (true);
}
if (action.type == TSParseActionTypeReduce)
{
is_fragile = table_entry.action_count > 1;
end_of_non_terminal_extra = lookahead == NULL;
reduction_version = ts_parser__reduce(self, version,
action.reduce.symbol, action.reduce.child_count,
action.reduce.dynamic_precedence,
action.reduce.production_id, is_fragile,
end_of_non_terminal_extra);
if (reduction_version != (t_stack_version)STACK_VERSION_NONE)
last_reduction_version = reduction_version;
i++;
}
if (action.type == TSParseActionTypeAccept)
return (ts_parser__accept(self, version, lookahead), true);
if (action.type == TSParseActionTypeRecover)
return (ts_parser__recover(self, version, lookahead), true);
}
if (last_reduction_version != (t_stack_version)STACK_VERSION_NONE)
{
ts_stack_renumber_version(self->stack, last_reduction_version,
version);
state = ts_stack_state(self->stack, version);
if (!lookahead)
needs_lex = true;
else
ts_language_table_entry(self->language, state,
ts_subtree_leaf_symbol(lookahead), &table_entry);
continue ;
}
if (!lookahead)
{
ts_stack_halt(self->stack, version);
if (_parser_advance_shift(self, version, state))
return (true);
}
if (ts_subtree_is_keyword(lookahead)
&& ts_subtree_symbol(lookahead) != self->language->keyword_capture_token)
{
ts_language_table_entry(self->language, state,
self->language->keyword_capture_token, &table_entry);
if (table_entry.action_count > 0)
{
mutable_lookahead = ts_subtree_ensure_owner(lookahead);
ts_subtree_set_symbol(&mutable_lookahead,
self->language->keyword_capture_token, self->language);
lookahead = mutable_lookahead;
continue ;
}
}
if (state == ERROR_STATE)
{
ts_parser__recover(self, version, lookahead);
return (true);
}
if (ts_parser__breakdown_top_of_stack(self, version))
{
state = ts_stack_state(self->stack, version);
ts_subtree_release(lookahead);
needs_lex = true;
continue ;
}
ts_stack_pause(self->stack, version, lookahead);
return (false);
}
if (state->action.type == TSParseActionTypeReduce)
{
state->is_fragile = state->table_entry.action_count > 1;
state->end_of_non_terminal_extra = state->lookahead == NULL;
state->reduction_version = ts_parser__reduce(self, version,
state->action.reduce.symbol, state->action.reduce.child_count,
state->action.reduce.dynamic_precedence,
state->action.reduce.production_id, state->is_fragile,
state->end_of_non_terminal_extra);
if (state->reduction_version != (t_stack_version)STACK_VERSION_NONE)
state->last_reduction_version = state->reduction_version;
state->i++;
}
if (state->action.type == TSParseActionTypeAccept)
return (ts_parser__accept(self, version, state->lookahead), true);
if (state->action.type == TSParseActionTypeRecover)
return (ts_parser__recover(self, version, state->lookahead), true);
return (false);
}
bool _parser_handle_first_reduction(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
if (state->last_reduction_version != (t_stack_version)STACK_VERSION_NONE)
{
ts_stack_renumber_version(self->stack, state->last_reduction_version,
version);
state->state = ts_stack_state(self->stack, version);
if (!state->lookahead)
state->needs_lex = true;
else
ts_language_table_entry(self->language, state->state,
ts_subtree_leaf_symbol(state->lookahead), &state->table_entry);
return (true);
}
return (false);
}
bool _parser_handle_keyword(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
(void)(version);
if (ts_subtree_is_keyword(state->lookahead)
&& ts_subtree_symbol(state->lookahead) \
!= self->language->keyword_capture_token)
{
ts_language_table_entry(self->language, state->state,
self->language->keyword_capture_token, &state->table_entry);
if (state->table_entry.action_count > 0)
{
state->mutable_lookahead = ts_subtree_ensure_owner(\
state->lookahead);
ts_subtree_set_symbol(&state->mutable_lookahead,
self->language->keyword_capture_token, self->language);
state->lookahead = state->mutable_lookahead;
return (true);
}
}
return (false);
}
bool _parser_loop_inner(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
while (state->i < state->table_entry.action_count)
if (_process_single_action(self, version, state))
return (true);
if (_parser_handle_first_reduction(self, version, state))
return (false);
if (!state->lookahead)
return (ts_stack_halt(self->stack, version), true);
if (_parser_handle_keyword(self, version, state))
return (false);
if (state->state == ERROR_STATE)
return (ts_parser__recover(self, version, state->lookahead), true);
if (ts_parser__breakdown_top_of_stack(self, version))
{
state->state = ts_stack_state(self->stack, version);
ts_subtree_release(state->lookahead);
state->needs_lex = true;
return (false);
}
return (ts_stack_pause(self->stack, version, state->lookahead), true);
}
bool ts_parser__advance(t_parser *self, t_stack_version version)
{
struct s_parser_advance_state state;
state.lookahead = NULL;
state.table_entry = (TableEntry){.action_count = 0};
state.state = ts_stack_state(self->stack, version);
state.needs_lex = true;
while (true)
{
if (_parser_advance_do_lex(self, version, &state))
return (false);
if (_parser_loop_inner(self, version, &state))
return (true);
}
}

View file

@ -0,0 +1,56 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* parser_advance_bis.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 14:01:20 by maiboyer #+# #+# */
/* Updated: 2024/09/19 22:00:08 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser/inner/parser_inner.h"
bool _parser_advance_do_lex(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
if (state->needs_lex)
{
state->needs_lex = false;
state->lookahead = ts_parser__lex(self, version, state->state);
if (self->has_scanner_error)
return (true);
if (state->lookahead)
ts_language_table_entry(self->language, state->state,
ts_subtree_symbol(state->lookahead), &state->table_entry);
else
ts_language_table_entry(self->language, state->state,
ts_builtin_sym_end, &state->table_entry);
}
state->last_reduction_version = (t_stack_version)STACK_VERSION_NONE;
state->i = 0;
return (false);
}
bool _parser_advance_shift(\
t_parser *self, t_stack_version version, \
struct s_parser_advance_state *state)
{
if (state->action.shift.repetition)
{
state->i++;
return (false);
}
if (state->action.shift.extra)
state->next_state = state->state;
else
state->next_state = state->action.shift.state;
if (ts_subtree_child_count(state->lookahead) > 0)
state->next_state = ts_language_next_state(self->language, state->state,
ts_subtree_symbol(state->lookahead));
ts_parser__shift(self, version, state->next_state, state->lookahead,
state->action.shift.extra);
return (true);
}

View file

@ -57,15 +57,18 @@ bool ts_parser__breakdown_top_of_stack(t_parser *self,
state = ts_language_next_state(self->language, state,
ts_subtree_symbol(child));
child->ref_count++;
ts_stack_push(self->stack, \
(struct s_stack_push_arg){slice.version, child, pending, state});
ts_stack_push(self->stack,
(struct s_stack_push_arg){slice.version, child, pending,
state});
j++;
}
j = 1;
while (j < slice.subtrees.len)
{
tree = slice.subtrees.buffer[j];
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version, tree, false, state});
ts_stack_push(self->stack,
(struct s_stack_push_arg){slice.version, tree, false,
state});
j++;
}
ts_subtree_release(parent);

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/11 16:44:11 by maiboyer #+# #+# */
/* Updated: 2024/09/19 17:23:41 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 21:38:35 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -22,7 +22,7 @@ void ts_parser__external_scanner_destroy(t_parser *self)
if (self->external_scanner_payload != NULL)
{
self->language->external_scanner.destroy(\
self->external_scanner_payload);
self->external_scanner_payload);
self->external_scanner_payload = NULL;
}
}
@ -32,14 +32,14 @@ t_u32 ts_parser__external_scanner_serialize(t_parser *self)
t_u32 length;
length = self->language->external_scanner.serialize(\
self->external_scanner_payload, self->lexer.debug_buffer);
self->external_scanner_payload, self->lexer.debug_buffer);
if (length > TREE_SITTER_SERIALIZATION_BUFFER_SIZE)
me_abort("assertion failed in " __FILE__ " `length > " \
"TREE_SITTER_SERIALIZATION_BUFFER_SIZE`");
return (length);
}
void ts_parser__external_scanner_deserialize(t_parser *self,
void ts_parser__external_scanner_deserialize(t_parser *self, \
t_subtree external_token)
{
const t_u8 *data;
@ -50,12 +50,12 @@ void ts_parser__external_scanner_deserialize(t_parser *self,
if (external_token)
{
data = ts_external_scanner_state_data(\
&external_token->external_scanner_state);
&external_token->external_scanner_state);
length = external_token->external_scanner_state.length;
printf("HERE\n");
}
self->language->external_scanner.deserialize(self->external_scanner_payload,
data, length);
self->language->external_scanner.deserialize(\
self->external_scanner_payload, data, length);
}
bool ts_parser__external_scanner_scan(t_parser *self,
@ -63,8 +63,8 @@ bool ts_parser__external_scanner_scan(t_parser *self,
{
const bool *valid_external_tokens;
valid_external_tokens = ts_language_enabled_external_tokens(self->language,
external_lex_state);
valid_external_tokens = ts_language_enabled_external_tokens(\
self->language, external_lex_state);
return (self->language->external_scanner.scan(\
self->external_scanner_payload, &self->lexer, valid_external_tokens));
self->external_scanner_payload, &self->lexer, valid_external_tokens));
}

View file

@ -17,8 +17,8 @@ void ts_lexer__mark_end(t_lexer *_self);
void ts_parser__handle_error(t_parser *self, t_stack_version version,
t_subtree lookahead)
{
t_length padding;
t_length position;
t_length padding;
t_length position;
t_state_id state;
t_state_id state_after_missing_symbol;
t_symbol missing_symbol;
@ -67,7 +67,8 @@ void ts_parser__handle_error(t_parser *self, t_stack_version version,
v);
missing_tree = ts_subtree_new_missing_leaf(missing_symbol,
padding, lookahead_bytes, self->language);
ts_stack_push(self->stack, (struct s_stack_push_arg){version_with_missing_tree,
ts_stack_push(self->stack,
(struct s_stack_push_arg){version_with_missing_tree,
missing_tree, false, state_after_missing_symbol});
if (ts_parser__do_all_potential_reductions(self,
version_with_missing_tree,
@ -80,7 +81,8 @@ void ts_parser__handle_error(t_parser *self, t_stack_version version,
missing_symbol++;
}
}
ts_stack_push(self->stack, (struct s_stack_push_arg){v, NULL, false, ERROR_STATE});
ts_stack_push(self->stack, (struct s_stack_push_arg){v, NULL, false,
ERROR_STATE});
if (v == version)
v = previous_version_count;
else

View file

@ -15,12 +15,12 @@
t_subtree ts_parser__lex(t_parser *self, t_stack_version version,
t_state_id parse_state)
{
t_length current_position;
t_length error_end_position;
t_length error_start_position;
t_length padding;
t_length size;
t_length start_position;
t_length current_position;
t_length error_end_position;
t_length error_start_position;
t_length padding;
t_length size;
t_length start_position;
TSLexMode lex_mode;
t_symbol symbol;
bool called_get_column;
@ -87,8 +87,7 @@ t_subtree ts_parser__lex(t_parser *self, t_stack_version version,
ts_lexer_reset(&self->lexer, current_position);
}
ts_lexer_start(&self->lexer);
found_token = self->language->lex_fn(&self->lexer,
lex_mode.lex_state);
found_token = self->language->lex_fn(&self->lexer, lex_mode.lex_state);
ts_lexer_finish(&self->lexer, &lookahead_end_byte);
if (found_token)
break ;
@ -122,8 +121,8 @@ t_subtree ts_parser__lex(t_parser *self, t_stack_version version,
padding = length_sub(error_start_position, start_position);
size = length_sub(error_end_position, error_start_position);
lookahead_bytes = lookahead_end_byte - error_end_position.bytes;
result = ts_subtree_new_error((t_st_newerr_args){first_error_character, padding, size,
lookahead_bytes, parse_state, self->language});
result = ts_subtree_new_error((t_st_newerr_args){first_error_character,
padding, size, lookahead_bytes, parse_state, self->language});
}
else
{
@ -151,9 +150,9 @@ t_subtree ts_parser__lex(t_parser *self, t_stack_version version,
symbol = self->lexer.funcs.result_symbol;
}
}
result = ts_subtree_new_leaf((t_st_newleaf_args){symbol, padding, size, lookahead_bytes,
parse_state, found_external_token, called_get_column,
is_keyword, self->language});
result = ts_subtree_new_leaf((t_st_newleaf_args){symbol, padding, size,
lookahead_bytes, parse_state, found_external_token,
called_get_column, is_keyword, self->language});
if (found_external_token)
{
ts_external_scanner_state_init(&result->external_scanner_state,

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 13:56:28 by maiboyer #+# #+# */
/* Updated: 2024/09/13 13:56:36 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 22:18:23 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -19,70 +19,88 @@ bool _parse_condition(t_parser *self, t_u32 *version_count,
return (*version < *version_count);
}
t_tree *ts_parser_parse(t_parser *self, t_input input)
t_error _parser_parse_init_state(\
t_parser *self, t_input input, struct s_parser_parse_state *state)
{
t_tree *result;
t_u32 position;
t_u32 last_position;
t_u32 version_count;
t_stack_version version;
t_u32 min_error_cost;
bool first;
result = NULL;
self->operation_count = 0;
state->first = true;
state->last_position = 0;
state->position = 0;
state->result = NULL;
state->version = 0;
state->version_count = 0;
if (!self->language || !input.read)
return (NULL);
return (ERROR);
ts_lexer_set_input(&self->lexer, input);
if (!ts_parser_has_outstanding_parse(self))
{
ts_parser__external_scanner_create(self);
if (self->has_scanner_error)
return (ts_parser_reset(self), result);
return (ts_parser_reset(self), ERROR);
}
self->operation_count = 0;
position = 0;
last_position = 0;
version_count = 0;
version = 0;
first = true;
while (first || version_count != 0)
return (NO_ERROR);
}
t_tree *_parser_parse_end(\
t_parser *self, t_input input, struct s_parser_parse_state state)
{
(void)(input);
if (self->finished_tree == NULL)
me_abort("self->finished_tree == NULL");
ts_subtree_balance(self->finished_tree, self->language);
state.result = ts_tree_new(self->finished_tree, self->language);
self->finished_tree = NULL;
ts_parser_reset(self);
return (state.result);
}
t_error _parser_parse_mainloop(\
t_parser *self, t_input input, struct s_parser_parse_state *state)
{
(void)(input);
state->first = false;
state->version = 0;
while (_parse_condition(self, &state->version_count, &state->version))
{
first = false;
version = 0;
while (_parse_condition(self, &version_count, &version))
while (ts_stack_is_active(self->stack, state->version))
{
while (ts_stack_is_active(self->stack, version))
if (!ts_parser__advance(self, state->version))
{
if (!ts_parser__advance(self, version))
{
if (self->has_scanner_error)
return (ts_parser_reset(self), result);
return (NULL);
}
position = ts_stack_position(self->stack, version).bytes;
if (position > last_position || (version > 0
&& position == last_position))
{
last_position = position;
break ;
}
if (self->has_scanner_error)
return (ts_parser_reset(self), ERROR);
return (ERROR);
}
state->position = \
ts_stack_position(self->stack, state->version).bytes;
if (state->position > state->last_position \
|| (state->version > 0 && state->position == state->last_position))
{
state->last_position = state->position;
break ;
}
version++;
}
min_error_cost = ts_parser__condense_stack(self);
if (self->finished_tree
&& ts_subtree_error_cost(self->finished_tree) < min_error_cost)
state->version++;
}
return (NO_ERROR);
}
t_tree *ts_parser_parse(t_parser *self, t_input input)
{
struct s_parser_parse_state state;
if (_parser_parse_init_state(self, input, &state))
return (NULL);
while (state.first || state.version_count != 0)
{
if (_parser_parse_mainloop(self, input, &state))
return (NULL);
state.min_error_cost = ts_parser__condense_stack(self);
if (self->finished_tree \
&& ts_subtree_error_cost(self->finished_tree) < state.min_error_cost)
{
ts_stack_clear(self->stack);
break ;
}
}
if (self->finished_tree == NULL)
me_abort("self->finished_tree == NULL");
ts_subtree_balance(self->finished_tree, self->language);
result = ts_tree_new(self->finished_tree, self->language);
self->finished_tree = NULL;
ts_parser_reset(self);
return (result);
return (_parser_parse_end(self, input, state));
}

View file

@ -37,6 +37,5 @@ t_tree *ts_parser_parse_string(t_parser *self, t_const_str string,
t_string_input input;
input = (t_string_input){(const t_u8 *)string, length};
return (ts_parser_parse(self, \
(t_input){&input, ts_string_input_read}));
return (ts_parser_parse(self, (t_input){&input, ts_string_input_read}));
}

View file

@ -15,7 +15,7 @@
void ts_parser__recover(t_parser *self, t_stack_version version,
t_subtree lookahead)
{
t_length position;
t_length position;
bool did_recover;
bool would_merge;
t_stack_slice_array pop;
@ -123,8 +123,8 @@ void ts_parser__recover(t_parser *self, t_stack_version version,
{
children = vec_subtree_new(16, NULL);
parent = ts_subtree_new_error_node(&children, false, self->language);
ts_stack_push(self->stack, \
(struct s_stack_push_arg){version, parent, false, 1});
ts_stack_push(self->stack, (struct s_stack_push_arg){version, parent,
false, 1});
ts_parser__accept(self, version, lookahead);
return ;
}
@ -140,7 +140,7 @@ void ts_parser__recover(t_parser *self, t_stack_version version,
}
actions = ts_language_actions(self->language, 1,
ts_subtree_symbol(lookahead), &n);
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n \
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n
- 1].shift.extra)
{
mutable_lookahead = ts_subtree_ensure_owner(lookahead);
@ -170,8 +170,8 @@ void ts_parser__recover(t_parser *self, t_stack_version version,
error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat,
&pop.contents[0].subtrees, 0, self->language);
}
ts_stack_push(self->stack, \
(struct s_stack_push_arg){version, (error_repeat), false, ERROR_STATE});
ts_stack_push(self->stack, (struct s_stack_push_arg){version,
(error_repeat), false, ERROR_STATE});
if (ts_subtree_has_external_tokens(lookahead))
ts_stack_set_last_external_token(self->stack, version,
ts_subtree_last_external_token(lookahead));

View file

@ -71,7 +71,8 @@ bool ts_parser__recover_to_state(t_parser *self, t_stack_version version,
{
error = ts_subtree_new_error_node(&slice.subtrees, true,
self->language);
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version, error, false, goal_state});
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version,
error, false, goal_state});
}
else
{
@ -81,7 +82,8 @@ bool ts_parser__recover_to_state(t_parser *self, t_stack_version version,
while (j < self->trailing_extras.len)
{
tree = self->trailing_extras.buffer[j];
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version, tree, false, goal_state});
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version,
tree, false, goal_state});
j++;
}
previous_version = slice.version;

View file

@ -97,7 +97,8 @@ t_stack_version ts_parser__reduce(t_parser *self, t_stack_version version,
else
parent->parse_state = state;
parent->dynamic_precedence += dynamic_precedence;
ts_stack_push(self->stack, (struct s_stack_push_arg){slice_version, (parent), false, next_state});
ts_stack_push(self->stack, (struct s_stack_push_arg){slice_version,
(parent), false, next_state});
j = 0;
while (j < self->trailing_extras.len)
{

View file

@ -6,7 +6,7 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 13:55:07 by maiboyer #+# #+# */
/* Updated: 2024/09/13 14:09:10 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 21:38:54 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
@ -31,11 +31,11 @@ bool ts_parser__select_tree(t_parser *self, t_subtree left, t_subtree right)
return (true);
if (ts_subtree_error_cost(left) < ts_subtree_error_cost(right))
return (false);
if (ts_subtree_dynamic_precedence(right) > \
ts_subtree_dynamic_precedence(left))
if (ts_subtree_dynamic_precedence(right) \
> ts_subtree_dynamic_precedence(left))
return (true);
if (ts_subtree_dynamic_precedence(left) > \
ts_subtree_dynamic_precedence(right))
if (ts_subtree_dynamic_precedence(left) \
> ts_subtree_dynamic_precedence(right))
return (false);
if (ts_subtree_error_cost(left) > 0)
return (true);

View file

@ -27,7 +27,8 @@ void ts_parser__shift(t_parser *self, t_stack_version version,
ts_subtree_set_extra(&result, extra);
subtree_to_push = (result);
}
ts_stack_push(self->stack,(struct s_stack_push_arg){ version, subtree_to_push, !is_leaf, state});
ts_stack_push(self->stack, (struct s_stack_push_arg){version,
subtree_to_push, !is_leaf, state});
if (ts_subtree_has_external_tokens(subtree_to_push))
ts_stack_set_last_external_token(self->stack, version,
ts_subtree_last_external_token(subtree_to_push));

View file

@ -6,37 +6,47 @@
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/09/13 13:42:50 by maiboyer #+# #+# */
/* Updated: 2024/09/13 13:42:58 by maiboyer ### ########.fr */
/* Updated: 2024/09/19 22:17:04 by maiboyer ### ########.fr */
/* */
/* ************************************************************************** */
#include "parser/inner/parser_inner.h"
t_error_comparison ts_parser__compare_versions(t_parser *self,
t_error_status a, t_error_status b)
bool _parser_compare_inner(t_parser *self, \
t_error_status a, t_error_status b, t_error_comparison *ret)
{
(void)self;
(void)(self);
if (!a.is_in_error && b.is_in_error)
{
if (a.cost < b.cost)
return (ECTakeLeft);
return (*ret = ECTakeLeft, true);
else
return (ECPreferLeft);
return (*ret = ECPreferLeft, true);
}
if (a.is_in_error && !b.is_in_error)
{
if (b.cost < a.cost)
return (ECTakeRight);
return (*ret = ECTakeRight, true);
else
return (ECPreferRight);
return (*ret = ECPreferRight, true);
}
if (a.cost < b.cost)
{
if ((b.cost - a.cost) * (1 + a.node_count) > MAX_COST_DIFFERENCE)
return (ECTakeLeft);
return (*ret = ECTakeLeft, true);
else
return (ECPreferLeft);
return (*ret = ECPreferLeft, true);
}
return (false);
}
t_error_comparison ts_parser__compare_versions(t_parser *self,
t_error_status a, t_error_status b)
{
t_error_comparison ret;
if (_parser_compare_inner(self, a, b, &ret))
return (ret);
if (b.cost < a.cost)
{
if ((a.cost - b.cost) * (1 + b.node_count) > MAX_COST_DIFFERENCE)
@ -68,26 +78,15 @@ t_error_status ts_parser__version_status(t_parser *self,
version) == ERROR_STATE});
}
bool ts_parser__better_version_exists(t_parser *self,
t_stack_version version, bool is_in_error, t_u32 cost)
bool _better_version_end(\
t_parser *self, t_stack_version version, \
t_length position, t_error_status status)
{
t_error_status status_i;
t_length position;
t_error_status status;
t_stack_version i;
t_stack_version n;
t_error_comparison cmp;
t_error_status status_i;
if (self->finished_tree
&& ts_subtree_error_cost(self->finished_tree) <= cost)
return (true);
position = ts_stack_position(self->stack, version);
status = (t_error_status){
.cost = cost,
.is_in_error = is_in_error,
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
.node_count = ts_stack_node_count_since_error(self->stack, version),
};
i = 0;
n = ts_stack_version_count(self->stack);
while (i < n)
@ -101,12 +100,29 @@ bool ts_parser__better_version_exists(t_parser *self,
status_i = ts_parser__version_status(self, i);
cmp = ts_parser__compare_versions(self, status, status_i);
if (cmp == ECTakeRight)
{
return (true);
}
if (cmp == ECPreferRight && ts_stack_can_merge(self->stack, i, version))
return (true);
i++;
}
return (false);
}
bool ts_parser__better_version_exists(t_parser *self,
t_stack_version version, bool is_in_error, t_u32 cost)
{
t_length position;
t_error_status status;
if (self->finished_tree
&& ts_subtree_error_cost(self->finished_tree) <= cost)
return (true);
position = ts_stack_position(self->stack, version);
status = (t_error_status){
.cost = cost,
.is_in_error = is_in_error,
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
.node_count = ts_stack_node_count_since_error(self->stack, version),
};
return (_better_version_end(self, version, position, status));
}