fix: fixed the script kiddy
This commit is contained in:
parent
cd87c06903
commit
9f55be8a7c
286 changed files with 0 additions and 37434 deletions
|
|
@ -1,62 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_field.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:47:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:10:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/str/str.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
t_const_str ts_language_field_name_for_id(const t_language *self, t_field_id id)
|
||||
{
|
||||
t_u32 count;
|
||||
|
||||
count = ts_language_field_count(self);
|
||||
if (count && id <= count)
|
||||
return (self->field_names[id]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_field_id ts_language_field_id_for_name(const t_language *self,
|
||||
t_const_str name, t_u32 name_length)
|
||||
{
|
||||
t_u16 count;
|
||||
t_symbol i;
|
||||
|
||||
count = (t_u16)ts_language_field_count(self);
|
||||
i = 1;
|
||||
while (i < count + 1)
|
||||
{
|
||||
if (str_n_compare(name, self->field_names[i], name_length)
|
||||
&& self->field_names[i][name_length] == 0)
|
||||
return (i);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ts_language_field_map(const t_language *self, t_u32 production_id,
|
||||
const TSFieldMapEntry **start, const TSFieldMapEntry **end)
|
||||
{
|
||||
TSFieldMapSlice slice;
|
||||
|
||||
if (self->field_count == 0)
|
||||
{
|
||||
*start = NULL;
|
||||
*end = NULL;
|
||||
return ;
|
||||
}
|
||||
slice = self->field_map_slices[production_id];
|
||||
*start = &self->field_map_entries[slice.index];
|
||||
*end = &self->field_map_entries[slice.index] + slice.length;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_getters.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:42:37 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:43:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
t_u32 ts_language_symbol_count(const t_language *self)
|
||||
{
|
||||
return (self->symbol_count + self->alias_count);
|
||||
}
|
||||
|
||||
t_u32 ts_language_state_count(const t_language *self)
|
||||
{
|
||||
return (self->state_count);
|
||||
}
|
||||
|
||||
t_u32 ts_language_version(const t_language *self)
|
||||
{
|
||||
return (self->version);
|
||||
}
|
||||
|
||||
t_u32 ts_language_field_count(const t_language *self)
|
||||
{
|
||||
return (self->field_count);
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_getters2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:50:29 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:54:52 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
bool ts_language_has_actions(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
return (ts_language_lookup(self, state, symbol) != 0);
|
||||
}
|
||||
|
||||
const bool *ts_language_enabled_external_tokens(const t_language *self,
|
||||
t_u32 external_scanner_state)
|
||||
{
|
||||
if (external_scanner_state == 0)
|
||||
return (NULL);
|
||||
else
|
||||
return (self->external_scanner.states \
|
||||
+ self->external_token_count * external_scanner_state);
|
||||
}
|
||||
|
||||
const t_symbol *ts_language_alias_sequence(const t_language *self,
|
||||
t_u32 production_id)
|
||||
{
|
||||
if (production_id)
|
||||
return (&self->alias_sequences[production_id \
|
||||
* self->max_alias_sequence_length]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_symbol ts_language_alias_at(const t_language *self, t_u32 production_id,
|
||||
t_u32 child_index)
|
||||
{
|
||||
if (production_id)
|
||||
return (self->alias_sequences[production_id \
|
||||
* self->max_alias_sequence_length + child_index]);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_misc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:51:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:55:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
void ts_language_table_entry(const t_language *self, t_state_id state,
|
||||
t_symbol symbol, TableEntry *result)
|
||||
{
|
||||
t_u32 action_index;
|
||||
const TSParseActionEntry *entry;
|
||||
|
||||
if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat)
|
||||
{
|
||||
result->action_count = 0;
|
||||
result->is_reusable = false;
|
||||
result->actions = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
action_index = ts_language_lookup(self, state, symbol);
|
||||
entry = &self->parse_actions[action_index];
|
||||
result->action_count = entry->entry.count;
|
||||
result->is_reusable = entry->entry.reusable;
|
||||
result->actions = (const TSParseAction *)(entry + 1);
|
||||
}
|
||||
}
|
||||
|
||||
t_state_id ts_language_next_state(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
t_u32 count;
|
||||
const TSParseAction *actions;
|
||||
TSParseAction action;
|
||||
|
||||
if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
else if (symbol < self->token_count)
|
||||
{
|
||||
actions = ts_language_actions(self, state, symbol, &count);
|
||||
if (count > 0)
|
||||
{
|
||||
action = actions[count - 1];
|
||||
if (action.type == TSParseActionTypeShift)
|
||||
{
|
||||
if (action.shift.extra)
|
||||
return (state);
|
||||
return (action.shift.state);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (ts_language_lookup(self, state, symbol));
|
||||
}
|
||||
|
||||
const TSParseAction *ts_language_actions(const t_language *self,
|
||||
t_state_id state, t_symbol symbol, t_u32 *count)
|
||||
{
|
||||
TableEntry entry;
|
||||
|
||||
ts_language_table_entry(self, state, symbol, &entry);
|
||||
*count = entry.action_count;
|
||||
return (entry.actions);
|
||||
}
|
||||
|
||||
bool ts_language_has_reduce_action(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
TableEntry entry;
|
||||
|
||||
ts_language_table_entry(self, state, symbol, &entry);
|
||||
return (entry.action_count > 0
|
||||
&& entry.actions[0].type == TSParseActionTypeReduce);
|
||||
}
|
||||
|
||||
// Lookup the table value for a given symbol and state.
|
||||
//
|
||||
// For non-terminal symbols, the table value represents a successor state.
|
||||
// For terminal symbols, it represents an index in the actions table.
|
||||
// For 'large' parse states, this is a direct lookup. For 'small' parse
|
||||
// states, this requires searching through the symbol groups to find
|
||||
// the given symbol.
|
||||
t_u16 ts_language_lookup(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
if (state >= self->large_state_count)
|
||||
return (me_abort("we got a small parse table, which isn't supported"),
|
||||
-1);
|
||||
return (self->parse_table[state * self->symbol_count + symbol]);
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_symbol.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:43:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:51:19 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/str/str.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
t_symbol_metadata ts_language_symbol_metadata(const t_language *self,
|
||||
t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return ((t_symbol_metadata){.visible = true, .named = true});
|
||||
else if (symbol == ts_builtin_sym_error_repeat)
|
||||
return ((t_symbol_metadata){.visible = false, .named = false});
|
||||
else
|
||||
return (self->symbol_metadata[symbol]);
|
||||
}
|
||||
|
||||
t_symbol ts_language_public_symbol(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return (symbol);
|
||||
return (self->public_symbol_map[symbol]);
|
||||
}
|
||||
|
||||
t_const_str ts_language_symbol_name(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return ("ERROR");
|
||||
else if (symbol == ts_builtin_sym_error_repeat)
|
||||
return ("_ERROR");
|
||||
else if (symbol < ts_language_symbol_count(self))
|
||||
return (self->symbol_names[symbol]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_symbol ts_language_symbol_for_name(const t_language *self,
|
||||
t_const_str string, t_u32 length, bool is_named)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
t_u16 count;
|
||||
t_symbol i;
|
||||
t_const_str symbol_name;
|
||||
|
||||
if (str_n_compare(string, "ERROR", length))
|
||||
return (ts_builtin_sym_error);
|
||||
count = (t_u16)ts_language_symbol_count(self);
|
||||
i = 0;
|
||||
while (i < count)
|
||||
{
|
||||
metadata = ts_language_symbol_metadata(self, i);
|
||||
if ((!metadata.visible && !metadata.supertype)
|
||||
|| metadata.named != is_named)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
symbol_name = self->symbol_names[i];
|
||||
if (str_n_compare(symbol_name, string, length) && !symbol_name[length])
|
||||
return (self->public_symbol_map[i]);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_symbol_type ts_language_symbol_type(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
|
||||
metadata = ts_language_symbol_metadata(self, symbol);
|
||||
if (metadata.named && metadata.visible)
|
||||
return (t_symbol_typeRegular);
|
||||
else if (metadata.visible)
|
||||
return (t_symbol_typeAnonymous);
|
||||
else
|
||||
return (t_symbol_typeAuxiliary);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_symbol2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:46:08 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:46:44 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
void ts_language_aliases_for_symbol(const t_language *self,
|
||||
t_symbol original_symbol, const t_symbol **start, const t_symbol **end)
|
||||
{
|
||||
t_u32 idx;
|
||||
t_symbol symbol;
|
||||
t_u16 count;
|
||||
|
||||
*start = &self->public_symbol_map[original_symbol];
|
||||
*end = *start + 1;
|
||||
idx = 0;
|
||||
while (true)
|
||||
{
|
||||
symbol = self->alias_map[idx++];
|
||||
if (symbol == 0 || symbol > original_symbol)
|
||||
break ;
|
||||
count = self->alias_map[idx++];
|
||||
if (symbol == original_symbol)
|
||||
{
|
||||
*start = &self->alias_map[idx];
|
||||
*end = &self->alias_map[idx + count];
|
||||
break ;
|
||||
}
|
||||
idx += count;
|
||||
}
|
||||
}
|
||||
|
||||
bool ts_language_is_symbol_external(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
return (0 < symbol && symbol < self->external_token_count + 1);
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:38:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:53:22 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/length.h"
|
||||
#include "parser/point.h"
|
||||
|
||||
bool length_is_undefined(t_length length)
|
||||
{
|
||||
return (length.bytes == 0 && length.extent.column != 0);
|
||||
}
|
||||
|
||||
t_length length_min(t_length len1, t_length len2)
|
||||
{
|
||||
if (len1.bytes < len2.bytes)
|
||||
return (len1);
|
||||
return (len2);
|
||||
}
|
||||
|
||||
t_length length_add(t_length len1, t_length len2)
|
||||
{
|
||||
t_length result;
|
||||
|
||||
result.bytes = len1.bytes + len2.bytes;
|
||||
result.extent = point_add(len1.extent, len2.extent);
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_length length_sub(t_length len1, t_length len2)
|
||||
{
|
||||
t_length result;
|
||||
|
||||
result.bytes = len1.bytes - len2.bytes;
|
||||
result.extent = point_sub(len1.extent, len2.extent);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:38:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:39:17 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/length.h"
|
||||
#include "parser/point.h"
|
||||
|
||||
t_length length_zero(void)
|
||||
{
|
||||
return ((t_length){0, {0, 0}});
|
||||
}
|
||||
|
||||
t_length length_saturating_sub(t_length len1, t_length len2)
|
||||
{
|
||||
if (len1.bytes > len2.bytes)
|
||||
return (length_sub(len1, len2));
|
||||
else
|
||||
return (length_zero());
|
||||
}
|
||||
2436
parser/src/lex.c
2436
parser/src/lex.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,105 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_advance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:06:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:58:25 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
bool ts_lexer__do_advance_loop(t_lexer *self, const t_range **current_range);
|
||||
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||
const t_range *cur);
|
||||
|
||||
// Intended to be called only from functions that control logging.
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip)
|
||||
{
|
||||
const t_range *cur = \
|
||||
&self->included_ranges[self->current_included_range_index];
|
||||
|
||||
if (self->lookahead_size)
|
||||
{
|
||||
self->current_position.bytes += self->lookahead_size;
|
||||
if (self->funcs.lookahead == '\n')
|
||||
{
|
||||
self->current_position.extent.row++;
|
||||
self->current_position.extent.column = 0;
|
||||
}
|
||||
else
|
||||
self->current_position.extent.column += self->lookahead_size;
|
||||
}
|
||||
while (self->current_position.bytes >= cur->end_byte
|
||||
|| cur->end_byte == cur->start_byte)
|
||||
if (ts_lexer__do_advance_loop(self, &cur))
|
||||
break ;
|
||||
ts_lexer__do_advance_after_loop(self, skip, cur);
|
||||
}
|
||||
|
||||
// Advance to the next character in the source code, retrieving a new
|
||||
// chunk of source code if needed.
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip)
|
||||
{
|
||||
t_lexer *self;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
if (!self->chunk)
|
||||
return ;
|
||||
ts_lexer__do_advance(self, skip);
|
||||
}
|
||||
|
||||
bool ts_lexer__do_advance_loop(t_lexer *self, const t_range **current_range)
|
||||
{
|
||||
if (self->current_included_range_index < self->included_range_count)
|
||||
self->current_included_range_index++;
|
||||
if (self->current_included_range_index < self->included_range_count)
|
||||
{
|
||||
(*current_range)++;
|
||||
self->current_position = (t_length){
|
||||
(*current_range)->start_byte,
|
||||
(*current_range)->start_point,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
(*current_range) = NULL;
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||
const t_range *cur)
|
||||
{
|
||||
if (skip)
|
||||
self->token_start_position = self->current_position;
|
||||
if (cur)
|
||||
{
|
||||
if (self->current_position.bytes < self->chunk_start
|
||||
|| self->current_position.bytes >= self->chunk_start
|
||||
+ self->chunk_size)
|
||||
ts_lexer__get_chunk(self);
|
||||
ts_lexer__get_lookahead(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->funcs.lookahead = '\0';
|
||||
self->lookahead_size = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_chunk.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:07:46 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:07:52 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
// Clear the currently stored chunk of source code, because the lexer's
|
||||
// position has changed.
|
||||
void ts_lexer__clear_chunk(t_lexer *self)
|
||||
{
|
||||
self->chunk = NULL;
|
||||
self->chunk_size = 0;
|
||||
self->chunk_start = 0;
|
||||
}
|
||||
|
||||
// Call the lexer's input callback to obtain a new chunk of source code
|
||||
// for the current position.
|
||||
void ts_lexer__get_chunk(t_lexer *self)
|
||||
{
|
||||
self->chunk_start = self->current_position.bytes;
|
||||
self->chunk = self->input.read(self->input.payload,
|
||||
self->current_position.bytes, self->current_position.extent,
|
||||
&self->chunk_size);
|
||||
if (!self->chunk_size)
|
||||
{
|
||||
self->current_included_range_index = self->included_range_count;
|
||||
self->chunk = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_end.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:07:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:58:53 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
// Check if the lexer has reached EOF. This state is stored
|
||||
// by setting the lexer's `current_included_range_index` such that
|
||||
// it has consumed all of its available ranges.
|
||||
bool ts_lexer__eof(const t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
return (self->current_included_range_index == self->included_range_count);
|
||||
}
|
||||
|
||||
// Mark that a token match has completed. This can be called multiple
|
||||
// times if a longer match is found later.
|
||||
void ts_lexer__mark_end(t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
t_range *current_included_range;
|
||||
t_range *previous_included_range;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
if (!ts_lexer__eof(self))
|
||||
{
|
||||
current_included_range = \
|
||||
&self->included_ranges[self->current_included_range_index];
|
||||
if (self->current_included_range_index > 0 \
|
||||
&& self->current_position.bytes == current_included_range->start_byte)
|
||||
{
|
||||
previous_included_range = current_included_range - 1;
|
||||
self->token_end_position = (t_length){
|
||||
previous_included_range->end_byte,
|
||||
previous_included_range->end_point,
|
||||
};
|
||||
return ;
|
||||
}
|
||||
}
|
||||
self->token_end_position = self->current_position;
|
||||
}
|
||||
|
||||
void ts_lexer_advance_to_end(t_lexer *self)
|
||||
{
|
||||
while (self->chunk)
|
||||
ts_lexer__advance(self, false);
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_get_column.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:04:55 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:18:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
t_u32 goal_byte;
|
||||
t_u32 result;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
goal_byte = self->current_position.bytes;
|
||||
self->did_get_column = true;
|
||||
self->current_position.bytes -= self->current_position.extent.column;
|
||||
self->current_position.extent.column = 0;
|
||||
if (self->current_position.bytes < self->chunk_start)
|
||||
ts_lexer__get_chunk(self);
|
||||
result = 0;
|
||||
if (!ts_lexer__eof(_self))
|
||||
{
|
||||
ts_lexer__get_lookahead(self);
|
||||
while (self->current_position.bytes < goal_byte && self->chunk)
|
||||
{
|
||||
result++;
|
||||
ts_lexer__do_advance(self, false);
|
||||
if (ts_lexer__eof(_self))
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_goto.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:08:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:59:09 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||
t_range *included_range, t_usize i);
|
||||
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range);
|
||||
|
||||
void ts_lexer_goto(t_lexer *self, t_length position)
|
||||
{
|
||||
bool found_included_range;
|
||||
t_range *included_range;
|
||||
t_u32 i;
|
||||
|
||||
included_range = NULL;
|
||||
found_included_range = false;
|
||||
self->current_position = position;
|
||||
i = 0;
|
||||
while (i < self->included_range_count)
|
||||
{
|
||||
included_range = &self->included_ranges[i];
|
||||
if (included_range->end_byte > self->current_position.bytes
|
||||
&& included_range->end_byte > included_range->start_byte)
|
||||
{
|
||||
ts_lexer_goto_inside_loop(self, &found_included_range,
|
||||
included_range, i);
|
||||
break ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ts_lexer_goto_after_loop(self, found_included_range);
|
||||
}
|
||||
|
||||
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||
t_range *included_range, t_usize i)
|
||||
{
|
||||
if (included_range->start_byte >= self->current_position.bytes)
|
||||
{
|
||||
self->current_position = (t_length){
|
||||
.bytes = included_range->start_byte,
|
||||
.extent = included_range->start_point,
|
||||
};
|
||||
}
|
||||
self->current_included_range_index = i;
|
||||
*found_included_range = true;
|
||||
}
|
||||
|
||||
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range)
|
||||
{
|
||||
t_range *last_included_range;
|
||||
|
||||
if (found_included_range)
|
||||
{
|
||||
if (self->chunk && (self->current_position.bytes < self->chunk_start
|
||||
|| self->current_position.bytes >= self->chunk_start
|
||||
+ self->chunk_size))
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->lookahead_size = 0;
|
||||
self->funcs.lookahead = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
self->current_included_range_index = self->included_range_count;
|
||||
last_included_range = &self->included_ranges[self->included_range_count
|
||||
- 1];
|
||||
self->current_position = (t_length){
|
||||
.bytes = last_included_range->end_byte,
|
||||
.extent = last_included_range->end_point,
|
||||
};
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->lookahead_size = 1;
|
||||
self->funcs.lookahead = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:58:01 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:59:58 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
#define BYTE_ORDER_MARK 0xFEFF
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer_init(t_lexer *self)
|
||||
{
|
||||
static t_range default_range = {.start_point = {\
|
||||
.row = 0, .column = 0, }, .end_point = {.row = UINT32_MAX, \
|
||||
.column = UINT32_MAX, }, .start_byte = 0, .end_byte = UINT32_MAX};
|
||||
|
||||
*self = (t_lexer){
|
||||
.funcs = {
|
||||
.advance = ts_lexer__advance,
|
||||
.mark_end = ts_lexer__mark_end,
|
||||
.get_column = NULL, //ts_lexer__get_column,
|
||||
.eof = ts_lexer__eof,
|
||||
.lookahead = 0,
|
||||
.result_symbol = 0, },
|
||||
.chunk = NULL,
|
||||
.chunk_size = 0,
|
||||
.chunk_start = 0,
|
||||
.current_position = {0, {0, 0}},
|
||||
.included_ranges = (void *)&default_range,
|
||||
.included_range_count = 1,
|
||||
.current_included_range_index = 0,
|
||||
};
|
||||
}
|
||||
|
||||
void ts_lexer_set_input(t_lexer *self, t_input input)
|
||||
{
|
||||
self->input = input;
|
||||
ts_lexer__clear_chunk(self);
|
||||
ts_lexer_goto(self, self->current_position);
|
||||
}
|
||||
|
||||
void ts_lexer_reset(t_lexer *self, t_length position)
|
||||
{
|
||||
if (position.bytes != self->current_position.bytes)
|
||||
ts_lexer_goto(self, position);
|
||||
}
|
||||
|
||||
void ts_lexer_start(t_lexer *self)
|
||||
{
|
||||
self->token_start_position = self->current_position;
|
||||
self->token_end_position = LENGTH_UNDEFINED;
|
||||
self->funcs.result_symbol = 0;
|
||||
self->did_get_column = false;
|
||||
if (!ts_lexer__eof(self))
|
||||
{
|
||||
if (!self->chunk_size)
|
||||
ts_lexer__get_chunk(self);
|
||||
if (!self->lookahead_size)
|
||||
ts_lexer__get_lookahead(self);
|
||||
if (self->current_position.bytes == 0
|
||||
&& self->funcs.lookahead == BYTE_ORDER_MARK)
|
||||
ts_lexer__advance(self, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ts_lexer_finish(t_lexer *self, t_u32 *lookahead_end_byte)
|
||||
{
|
||||
if (length_is_undefined(self->token_end_position))
|
||||
ts_lexer__mark_end(self);
|
||||
(void)(lookahead_end_byte);
|
||||
if (self->token_end_position.bytes < self->token_start_position.bytes)
|
||||
self->token_start_position = self->token_end_position;
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_lookahead.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:09:03 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:00:15 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/input.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer__get_lookahead(t_lexer *self)
|
||||
{
|
||||
t_u32 position_in_chunk;
|
||||
t_u32 size;
|
||||
const t_u8 *chunk;
|
||||
|
||||
position_in_chunk = self->current_position.bytes - self->chunk_start;
|
||||
size = self->chunk_size - position_in_chunk;
|
||||
if (size == 0)
|
||||
{
|
||||
self->lookahead_size = 1;
|
||||
self->funcs.lookahead = '\0';
|
||||
return ;
|
||||
}
|
||||
chunk = (const t_u8 *)self->chunk + position_in_chunk;
|
||||
self->lookahead_size = ts_decode_ascii(chunk, size, &self->funcs.lookahead);
|
||||
if (self->funcs.lookahead == TS_DECODE_ERROR)
|
||||
self->lookahead_size = 1;
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* create_language.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/25 16:13:52 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:36:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../static/headers/constants.h"
|
||||
#include "../static/headers/symbols.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
// bool lex_keywords_main(t_lexer *lexer, t_state_id state);
|
||||
// bool lex_normal_main(t_lexer *lexer, t_state_id state);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *ctx, t_lexer *lexer, \
|
||||
const bool *ret);
|
||||
void *create_external_scanner_states(void);
|
||||
void *create_field_names(void);
|
||||
void *create_symbols_names(void);
|
||||
void *create_field_map_entries(void);
|
||||
void *create_field_map_slices(void);
|
||||
void *create_lex_modes(void);
|
||||
void *create_parse_actions_entries(void);
|
||||
void *create_primary_state_ids(void);
|
||||
void *create_alias_sequences(void);
|
||||
void *create_external_scanner_symbol_map(void);
|
||||
void *create_non_terminal_alias_map(void);
|
||||
void *create_unique_symbols_map(void);
|
||||
void *create_symbols_metadata(void);
|
||||
void *create_parse_table(void);
|
||||
bool ts_lex_keywords(t_lexer *lexer, t_state_id state);
|
||||
bool ts_lex(t_lexer *lexer, t_state_id state);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *ctx, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *ctx, \
|
||||
const t_u8 *state, t_u32 val);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *ctx);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
|
||||
static struct ExternalScannerDefinition init_scanner(void)
|
||||
{
|
||||
return ((struct ExternalScannerDefinition){
|
||||
create_external_scanner_states(),
|
||||
create_external_scanner_symbol_map(),
|
||||
tree_sitter_sh_external_scanner_create,
|
||||
tree_sitter_sh_external_scanner_destroy,
|
||||
tree_sitter_sh_external_scanner_scan,
|
||||
tree_sitter_sh_external_scanner_serialize,
|
||||
tree_sitter_sh_external_scanner_deserialize,
|
||||
});
|
||||
}
|
||||
|
||||
static void init_language(t_language *language)
|
||||
{
|
||||
static uint32_t empty_map[] = {0, 0, 0};
|
||||
|
||||
language->parse_table = create_parse_table();
|
||||
language->small_parse_table = (void *)empty_map;
|
||||
language->small_parse_table_map = (void *)empty_map;
|
||||
language->parse_actions = create_parse_actions_entries();
|
||||
language->symbol_names = create_symbols_names();
|
||||
language->field_names = create_field_names();
|
||||
language->field_map_slices = create_field_map_slices();
|
||||
language->field_map_entries = create_field_map_entries();
|
||||
language->symbol_metadata = create_symbols_metadata();
|
||||
language->public_symbol_map = create_unique_symbols_map();
|
||||
language->alias_map = create_non_terminal_alias_map();
|
||||
language->alias_sequences = create_alias_sequences();
|
||||
language->lex_modes = create_lex_modes();
|
||||
language->primary_state_ids = create_primary_state_ids();
|
||||
language->lex_fn = ts_lex;
|
||||
language->keyword_lex_fn = ts_lex_keywords;
|
||||
language->keyword_capture_token = sym_word;
|
||||
language->external_scanner = init_scanner();
|
||||
}
|
||||
|
||||
const t_language *tree_sitter_sh(void)
|
||||
{
|
||||
static bool init = false;
|
||||
static t_language language = {
|
||||
.version = LANGUAGE_VERSION,
|
||||
.symbol_count = SYMBOL_COUNT,
|
||||
.alias_count = ALIAS_COUNT,
|
||||
.token_count = TOKEN_COUNT,
|
||||
.external_token_count = EXTERNAL_TOKEN_COUNT,
|
||||
.state_count = STATE_COUNT,
|
||||
.large_state_count = LARGE_STATE_COUNT,
|
||||
.production_id_count = PRODUCTION_ID_COUNT,
|
||||
.field_count = FIELD_COUNT,
|
||||
.max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH,
|
||||
};
|
||||
|
||||
if (!init)
|
||||
{
|
||||
init_language(&language);
|
||||
init = true;
|
||||
}
|
||||
return ((t_language *)&language);
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* external_scanner_state.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/24 13:55:33 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:05:53 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void ts_external_scanner_state_init(t_external_scanner_state *self,
|
||||
const t_u8 *data, t_u32 length)
|
||||
{
|
||||
self->length = length;
|
||||
self->long_data = mem_alloc(length);
|
||||
mem_copy(self->long_data, data, length);
|
||||
}
|
||||
|
||||
t_external_scanner_state ts_external_scanner_state_copy(\
|
||||
const t_external_scanner_state *self)
|
||||
{
|
||||
t_external_scanner_state result;
|
||||
|
||||
result = *self;
|
||||
result.long_data = mem_alloc(self->length);
|
||||
mem_copy(result.long_data, self->long_data, self->length);
|
||||
return (result);
|
||||
}
|
||||
|
||||
void ts_external_scanner_state_delete(t_external_scanner_state *self)
|
||||
{
|
||||
mem_free(self->long_data);
|
||||
}
|
||||
|
||||
const t_u8 *ts_external_scanner_state_data(\
|
||||
const t_external_scanner_state *self)
|
||||
{
|
||||
return ((const t_u8 *)self->long_data);
|
||||
}
|
||||
|
||||
bool ts_external_scanner_state_eq(const t_external_scanner_state *self,
|
||||
const t_u8 *buffer, t_u32 length)
|
||||
{
|
||||
return (self->length == length
|
||||
&& mem_compare(ts_external_scanner_state_data(self), buffer, length));
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* external_scanner_state2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:37:45 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:06:09 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
const t_external_scanner_state *ts_subtree_external_scanner_state(\
|
||||
t_subtree self)
|
||||
{
|
||||
static const t_external_scanner_state empty_state = {NULL, .length = 0};
|
||||
|
||||
if (self && self->has_external_tokens && self->child_count == 0)
|
||||
return (&self->external_scanner_state);
|
||||
else
|
||||
return (&empty_state);
|
||||
}
|
||||
|
||||
bool ts_subtree_external_scanner_state_eq(t_subtree self, t_subtree other)
|
||||
{
|
||||
const t_external_scanner_state *state_self = \
|
||||
ts_subtree_external_scanner_state(self);
|
||||
const t_external_scanner_state *state_other = \
|
||||
ts_subtree_external_scanner_state(other);
|
||||
|
||||
return (ts_external_scanner_state_eq(state_self,
|
||||
ts_external_scanner_state_data(state_other), state_other->length));
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* input.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:33:08 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:33:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/input.h"
|
||||
#include "me/types.h"
|
||||
|
||||
t_u32 ts_decode_ascii(const t_u8 *string, t_u32 length, t_i32 *code_point)
|
||||
{
|
||||
if (string == NULL || length == 0 || code_point == 0)
|
||||
return (0);
|
||||
*code_point = 0;
|
||||
*(t_u8 *)code_point = *string;
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* reduce_action.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:33:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 12:55:11 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/reduce_action.h"
|
||||
#include "me/vec/vec_reduce_action.h"
|
||||
|
||||
void ts_reduce_action_set_add(\
|
||||
t_vec_reduce_action *self, t_reduce_action new_action)
|
||||
{
|
||||
t_reduce_action action;
|
||||
t_u32 i;
|
||||
|
||||
i = 0;
|
||||
while (i < self->len)
|
||||
{
|
||||
action = self->buffer[i];
|
||||
if (action.symbol == new_action.symbol \
|
||||
&& action.count == new_action.count)
|
||||
return ;
|
||||
i++;
|
||||
}
|
||||
vec_reduce_action_push(self, new_action);
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_child.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:14:40 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:21:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
|
||||
t_u32 ts_node_child_count(t_node self)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
return (tree->visible_child_count);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_u32 ts_node_named_child_count(t_node self)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
return (tree->named_child_count);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_field_id ts_node_field_id_for_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
t_node result;
|
||||
bool did_descend;
|
||||
t_field_id inherited_field_id;
|
||||
t_node child;
|
||||
t_u32 index;
|
||||
NodeChildIterator iterator;
|
||||
t_u32 grandchild_index;
|
||||
t_u32 grandchild_count;
|
||||
t_field_id field_id;
|
||||
|
||||
result = self;
|
||||
did_descend = true;
|
||||
inherited_field_id = 0;
|
||||
while (did_descend)
|
||||
{
|
||||
did_descend = false;
|
||||
index = 0;
|
||||
iterator = ts_node_iterate_children(&result);
|
||||
while (ts_node_child_iterator_next(&iterator, &child))
|
||||
{
|
||||
if (ts_node__is_relevant(child, true))
|
||||
{
|
||||
if (index == child_index)
|
||||
{
|
||||
if (ts_node_is_extra(child))
|
||||
return (0);
|
||||
field_id = ts_node__field_id_from_language(result,
|
||||
iterator.structural_child_index - 1);
|
||||
if (field_id)
|
||||
return (field_id);
|
||||
return (inherited_field_id);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandchild_index = child_index - index;
|
||||
grandchild_count = ts_node__relevant_child_count(child, true);
|
||||
if (grandchild_index < grandchild_count)
|
||||
{
|
||||
field_id = ts_node__field_id_from_language(result,
|
||||
iterator.structural_child_index - 1);
|
||||
if (field_id)
|
||||
inherited_field_id = field_id;
|
||||
did_descend = true;
|
||||
result = child;
|
||||
child_index = grandchild_index;
|
||||
break ;
|
||||
}
|
||||
index += grandchild_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_childinner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:16:18 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:23:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
|
||||
t_node ts_node__child(t_node self, t_u32 child_index, bool include_anonymous)
|
||||
{
|
||||
t_node result;
|
||||
bool did_descend;
|
||||
t_node child;
|
||||
t_u32 index;
|
||||
NodeChildIterator iterator;
|
||||
t_u32 grandchild_index;
|
||||
t_u32 grandchild_count;
|
||||
|
||||
result = self;
|
||||
did_descend = true;
|
||||
while (did_descend)
|
||||
{
|
||||
did_descend = false;
|
||||
index = 0;
|
||||
iterator = ts_node_iterate_children(&result);
|
||||
while (ts_node_child_iterator_next(&iterator, &child))
|
||||
{
|
||||
if (ts_node__is_relevant(child, include_anonymous))
|
||||
{
|
||||
if (index == child_index)
|
||||
return (child);
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandchild_index = child_index - index;
|
||||
grandchild_count = ts_node__relevant_child_count(child,
|
||||
include_anonymous);
|
||||
if (grandchild_index < grandchild_count)
|
||||
{
|
||||
did_descend = true;
|
||||
result = child;
|
||||
child_index = grandchild_index;
|
||||
break ;
|
||||
}
|
||||
index += grandchild_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ts_node__null());
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_constructor.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:10:57 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:24:15 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/length.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
t_node ts_node_new(const t_tree *tree, const t_subtree *subtree, \
|
||||
t_length position, t_symbol alias)
|
||||
{
|
||||
return ((t_node){
|
||||
position.bytes, position.extent.row, position.extent.column, \
|
||||
alias, subtree, tree,
|
||||
});
|
||||
}
|
||||
|
||||
t_node ts_node__null(void)
|
||||
{
|
||||
return (ts_node_new(NULL, NULL, length_zero(), 0));
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_fields.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:15:23 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:25:26 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_const_str ts_node__field_name_from_language(t_node self,
|
||||
t_u32 structural_child_index)
|
||||
{
|
||||
const TSFieldMapEntry *field_map;
|
||||
const TSFieldMapEntry *field_map_end;
|
||||
|
||||
ts_language_field_map(self.tree->language,
|
||||
ts_node__subtree(self)->production_id, &field_map, &field_map_end);
|
||||
while (field_map != field_map_end)
|
||||
{
|
||||
if (!field_map->inherited
|
||||
&& field_map->child_index == structural_child_index)
|
||||
return (self.tree->language->field_names[field_map->field_id]);
|
||||
field_map++;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_field_id ts_node__field_id_from_language(t_node self,
|
||||
t_u32 structural_child_index)
|
||||
{
|
||||
const TSFieldMapEntry *field_map;
|
||||
const TSFieldMapEntry *field_map_end;
|
||||
|
||||
ts_language_field_map(self.tree->language,
|
||||
ts_node__subtree(self)->production_id, &field_map, &field_map_end);
|
||||
while (field_map != field_map_end)
|
||||
{
|
||||
if (!field_map->inherited
|
||||
&& field_map->child_index == structural_child_index)
|
||||
return (field_map->field_id);
|
||||
field_map++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:04:21 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
bool ts_node_is_extra(t_node self)
|
||||
{
|
||||
return (ts_subtree_extra(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
bool ts_node_is_named(t_node self)
|
||||
{
|
||||
t_symbol alias;
|
||||
|
||||
alias = ts_node__alias(&self);
|
||||
if (alias)
|
||||
return (ts_language_symbol_metadata(self.tree->language, alias).named);
|
||||
return (ts_subtree_named(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
t_node ts_node_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
return (ts_node__child(self, child_index, true));
|
||||
}
|
||||
|
||||
t_node ts_node_named_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
return (ts_node__child(self, child_index, false));
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:29:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:25 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_u32 ts_node_start_byte(t_node self)
|
||||
{
|
||||
return (self.start_byte);
|
||||
}
|
||||
|
||||
const t_language *ts_node_language(t_node self)
|
||||
{
|
||||
return (self.tree->language);
|
||||
}
|
||||
|
||||
t_point ts_node_start_point(t_node self)
|
||||
{
|
||||
return ((t_point){self.start_row, self.start_col});
|
||||
}
|
||||
|
||||
t_u32 ts_node__alias(const t_node *self)
|
||||
{
|
||||
return (self->alias);
|
||||
}
|
||||
|
||||
t_subtree ts_node__subtree(t_node self)
|
||||
{
|
||||
return (*(const t_subtree *)self.id);
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:29:34 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_u32 ts_node_end_byte(t_node self)
|
||||
{
|
||||
return (ts_node_start_byte(self)
|
||||
+ ts_subtree_size(ts_node__subtree(self)).bytes);
|
||||
}
|
||||
|
||||
t_symbol ts_node_symbol(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_node__alias(&self);
|
||||
if (!symbol)
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_public_symbol(self.tree->language, symbol));
|
||||
}
|
||||
|
||||
t_const_str ts_node_type(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_node__alias(&self);
|
||||
if (!symbol)
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_symbol_name(self.tree->language, symbol));
|
||||
}
|
||||
|
||||
t_symbol ts_node_grammar_symbol(t_node self)
|
||||
{
|
||||
return (ts_subtree_symbol(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
t_const_str ts_node_grammar_type(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_symbol_name(self.tree->language, symbol));
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_iterator.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:14:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:07:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
NodeChildIterator ts_node_iterate_children(const t_node *node)
|
||||
{
|
||||
t_subtree subtree;
|
||||
const t_symbol *alias_sequence;
|
||||
|
||||
subtree = ts_node__subtree(*node);
|
||||
if (ts_subtree_child_count(subtree) == 0)
|
||||
return ((NodeChildIterator){NULL, node->tree, length_zero(), 0, 0,
|
||||
NULL});
|
||||
alias_sequence = ts_language_alias_sequence(node->tree->language,
|
||||
subtree->production_id);
|
||||
return ((NodeChildIterator){
|
||||
.tree = node->tree,
|
||||
.parent = subtree,
|
||||
.position = {ts_node_start_byte(*node), ts_node_start_point(*node)},
|
||||
.child_index = 0,
|
||||
.structural_child_index = 0,
|
||||
.alias_sequence = alias_sequence,
|
||||
});
|
||||
}
|
||||
|
||||
bool ts_node_child_iterator_done(NodeChildIterator *self)
|
||||
{
|
||||
return (self->child_index == self->parent->child_count);
|
||||
}
|
||||
|
||||
bool ts_node_child_iterator_next(NodeChildIterator *self, t_node *result)
|
||||
{
|
||||
const t_subtree *child;
|
||||
t_symbol alias_symbol;
|
||||
|
||||
if (!self->parent || ts_node_child_iterator_done(self))
|
||||
return (false);
|
||||
alias_symbol = 0;
|
||||
child = &ts_subtree_children(self->parent)[self->child_index];
|
||||
if (!ts_subtree_extra(*child))
|
||||
{
|
||||
if (self->alias_sequence)
|
||||
alias_symbol = self->alias_sequence[self->structural_child_index];
|
||||
self->structural_child_index++;
|
||||
}
|
||||
if (self->child_index > 0)
|
||||
self->position = length_add(self->position, ts_subtree_padding(*child));
|
||||
*result = ts_node_new(self->tree, child, self->position, alias_symbol);
|
||||
self->position = length_add(self->position, ts_subtree_size(*child));
|
||||
self->child_index++;
|
||||
return (true);
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_relevent.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:16:53 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:07:16 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
bool ts_node__is_relevant(t_node self, bool include_anonymous)
|
||||
{
|
||||
t_symbol alias;
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (include_anonymous)
|
||||
return (ts_subtree_visible(tree) || ts_node__alias(&self));
|
||||
alias = ts_node__alias(&self);
|
||||
if (alias)
|
||||
return (ts_language_symbol_metadata(self.tree->language, alias).named);
|
||||
else
|
||||
return (ts_subtree_visible(tree) && ts_subtree_named(tree));
|
||||
}
|
||||
|
||||
t_u32 ts_node__relevant_child_count(t_node self, bool include_anonymous)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
{
|
||||
if (include_anonymous)
|
||||
return (tree->visible_child_count);
|
||||
else
|
||||
return (tree->named_child_count);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_accept.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:02:35 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:37:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
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_stack_slice_array pop;
|
||||
t_vec_subtree trees;
|
||||
t_subtree root;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
|
||||
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)
|
||||
{
|
||||
trees = pop.contents[i].subtrees;
|
||||
root = NULL;
|
||||
j = trees.len - 1;
|
||||
while (j + 1 > 0)
|
||||
if (parser_select_root(self, &trees, &root, &j))
|
||||
break ;
|
||||
_parser_accept_endloop(self, root, &i);
|
||||
}
|
||||
ts_stack_remove_version(self->stack, pop.contents[0].version);
|
||||
ts_stack_halt(self->stack, v);
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_advance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:01:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:17:53 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);
|
||||
bool _parser_advance_shift(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state);
|
||||
|
||||
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 (_parser_advance_shift(self, version, state))
|
||||
return (true);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* 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);
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_breakdown_top_of_stack.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:36:06 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:19:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__breakdown_top_of_stack(t_parser *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_state_id state;
|
||||
bool did_break_down;
|
||||
bool pending;
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_subtree child;
|
||||
t_subtree parent;
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_u32 n;
|
||||
bool first;
|
||||
|
||||
first = true;
|
||||
did_break_down = false;
|
||||
pending = false;
|
||||
while (pending || first)
|
||||
{
|
||||
first = false;
|
||||
pop = ts_stack_pop_pending(self->stack, version);
|
||||
if (!pop.size)
|
||||
break ;
|
||||
did_break_down = true;
|
||||
pending = false;
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
state = ts_stack_state(self->stack, slice.version);
|
||||
parent = *slice.subtrees.buffer;
|
||||
j = 0;
|
||||
n = ts_subtree_child_count(parent);
|
||||
while (j < n)
|
||||
{
|
||||
child = ts_subtree_children(parent)[j];
|
||||
pending = ts_subtree_child_count(child) > 0;
|
||||
if (ts_subtree_is_error(child))
|
||||
state = ERROR_STATE;
|
||||
else if (!ts_subtree_extra(child))
|
||||
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});
|
||||
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});
|
||||
j++;
|
||||
}
|
||||
ts_subtree_release(parent);
|
||||
array_delete(&slice.subtrees);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return (did_break_down);
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_condense_stack.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:57:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 13:57:41 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_u32 ts_parser__condense_stack(t_parser *self)
|
||||
{
|
||||
bool has_unpaused_version;
|
||||
t_error_comparison cmp;
|
||||
t_error_status status_i;
|
||||
t_error_status status_j;
|
||||
t_stack_version i;
|
||||
t_stack_version j;
|
||||
t_stack_version n;
|
||||
t_subtree lookahead;
|
||||
t_u32 min_error_cost;
|
||||
|
||||
min_error_cost = UINT_MAX;
|
||||
i = 0;
|
||||
while (i < ts_stack_version_count(self->stack))
|
||||
{
|
||||
if (ts_stack_is_halted(self->stack, i))
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
continue ;
|
||||
}
|
||||
status_i = ts_parser__version_status(self, i);
|
||||
if (!status_i.is_in_error && status_i.cost < min_error_cost)
|
||||
min_error_cost = status_i.cost;
|
||||
j = 0;
|
||||
while (j < i)
|
||||
{
|
||||
status_j = ts_parser__version_status(self, j);
|
||||
cmp = ts_parser__compare_versions(self, status_j, status_i);
|
||||
if (cmp == ECTakeLeft)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
if ((cmp == ECPreferLeft || cmp == ECNone)
|
||||
&& ts_stack_merge(self->stack, j, i))
|
||||
{
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
if (cmp == ECPreferRight)
|
||||
{
|
||||
if (ts_stack_merge(self->stack, j, i))
|
||||
{
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
else
|
||||
ts_stack_swap_versions(self->stack, i, j);
|
||||
}
|
||||
if (cmp == ECTakeRight)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, j);
|
||||
i--;
|
||||
j--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (ts_stack_version_count(self->stack) > MAX_VERSION_COUNT)
|
||||
ts_stack_remove_version(self->stack, MAX_VERSION_COUNT);
|
||||
if (ts_stack_version_count(self->stack) > 0)
|
||||
{
|
||||
has_unpaused_version = false;
|
||||
i = 0;
|
||||
n = ts_stack_version_count(self->stack);
|
||||
while (i < n)
|
||||
{
|
||||
if (ts_stack_is_paused(self->stack, i))
|
||||
{
|
||||
if (!has_unpaused_version
|
||||
&& self->accept_count < MAX_VERSION_COUNT)
|
||||
{
|
||||
min_error_cost = ts_stack_error_cost(self->stack, i);
|
||||
lookahead = ts_stack_resume(self->stack, i);
|
||||
ts_parser__handle_error(self, i, lookahead);
|
||||
has_unpaused_version = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
i--;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
else
|
||||
has_unpaused_version = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return (min_error_cost);
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_do_reduction.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:04:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:21:23 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__do_all_potential_reductions(t_parser *self,
|
||||
t_stack_version starting_version, t_symbol lookahead_symbol)
|
||||
{
|
||||
t_u32 initial_version_count;
|
||||
bool can_shift_lookahead_symbol;
|
||||
t_stack_version version;
|
||||
t_u32 i;
|
||||
t_u32 version_count;
|
||||
bool merged;
|
||||
t_stack_version j;
|
||||
t_state_id state;
|
||||
bool has_shift_action;
|
||||
t_symbol first_symbol;
|
||||
t_symbol end_symbol;
|
||||
t_stack_version reduction_version;
|
||||
t_reduce_action reduce_action;
|
||||
t_u32 k;
|
||||
t_symbol symbol;
|
||||
TableEntry entry;
|
||||
TSParseAction action;
|
||||
|
||||
initial_version_count = ts_stack_version_count(self->stack);
|
||||
can_shift_lookahead_symbol = false;
|
||||
version = starting_version;
|
||||
i = 0;
|
||||
while (true)
|
||||
{
|
||||
version_count = ts_stack_version_count(self->stack);
|
||||
if (version >= version_count)
|
||||
break ;
|
||||
merged = false;
|
||||
j = initial_version_count;
|
||||
while (j < version)
|
||||
{
|
||||
if (ts_stack_merge(self->stack, j, version))
|
||||
{
|
||||
merged = true;
|
||||
break ;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (merged)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
state = ts_stack_state(self->stack, version);
|
||||
has_shift_action = false;
|
||||
self->reduce_actions.len = 0;
|
||||
if (lookahead_symbol != 0)
|
||||
{
|
||||
first_symbol = lookahead_symbol;
|
||||
end_symbol = lookahead_symbol + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_symbol = 1;
|
||||
end_symbol = self->language->token_count;
|
||||
}
|
||||
symbol = first_symbol;
|
||||
while (symbol < end_symbol)
|
||||
{
|
||||
ts_language_table_entry(self->language, state, symbol, &entry);
|
||||
k = 0;
|
||||
while (k < entry.action_count)
|
||||
{
|
||||
action = entry.actions[k];
|
||||
if ((action.type == TSParseActionTypeShift
|
||||
|| action.type == TSParseActionTypeRecover)
|
||||
&& (!action.shift.extra && !action.shift.repetition))
|
||||
has_shift_action = true;
|
||||
if ((action.type == TSParseActionTypeReduce)
|
||||
&& (action.reduce.child_count > 0))
|
||||
ts_reduce_action_set_add(&self->reduce_actions,
|
||||
(t_reduce_action){
|
||||
.symbol = action.reduce.symbol,
|
||||
.count = action.reduce.child_count,
|
||||
.dynamic_precedence = action.reduce.dynamic_precedence,
|
||||
.production_id = action.reduce.production_id,
|
||||
});
|
||||
k++;
|
||||
}
|
||||
symbol++;
|
||||
}
|
||||
reduction_version = STACK_VERSION_NONE;
|
||||
k = 0;
|
||||
while (k < self->reduce_actions.len)
|
||||
{
|
||||
reduce_action = self->reduce_actions.buffer[k];
|
||||
reduction_version = ts_parser__reduce(self, version,
|
||||
reduce_action.symbol, reduce_action.count,
|
||||
reduce_action.dynamic_precedence,
|
||||
reduce_action.production_id, true, false);
|
||||
k++;
|
||||
}
|
||||
if (has_shift_action)
|
||||
can_shift_lookahead_symbol = true;
|
||||
else if (reduction_version != (t_stack_version)STACK_VERSION_NONE
|
||||
&& i < MAX_VERSION_COUNT)
|
||||
{
|
||||
ts_stack_renumber_version(self->stack, reduction_version, version);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
else if (lookahead_symbol != 0)
|
||||
ts_stack_remove_version(self->stack, version);
|
||||
if (version == starting_version)
|
||||
version = version_count;
|
||||
else
|
||||
version++;
|
||||
i++;
|
||||
}
|
||||
return (can_shift_lookahead_symbol);
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_external_scanner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/11 16:44:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:38:35 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__external_scanner_create(t_parser *self)
|
||||
{
|
||||
self->external_scanner_payload = self->language->external_scanner.create();
|
||||
}
|
||||
|
||||
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 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
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, \
|
||||
t_subtree external_token)
|
||||
{
|
||||
const t_u8 *data;
|
||||
t_u32 length;
|
||||
|
||||
data = NULL;
|
||||
length = 0;
|
||||
if (external_token)
|
||||
{
|
||||
data = ts_external_scanner_state_data(\
|
||||
&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);
|
||||
}
|
||||
|
||||
bool ts_parser__external_scanner_scan(t_parser *self,
|
||||
t_state_id external_lex_state)
|
||||
{
|
||||
const bool *valid_external_tokens;
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_handle_error.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:04:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:50 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
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_state_id state;
|
||||
t_state_id state_after_missing_symbol;
|
||||
t_symbol missing_symbol;
|
||||
bool did_insert_missing_token;
|
||||
t_stack_version v;
|
||||
t_stack_version version_with_missing_tree;
|
||||
t_subtree missing_tree;
|
||||
t_u32 i;
|
||||
t_u32 lookahead_bytes;
|
||||
t_u32 previous_version_count;
|
||||
t_u32 version_count;
|
||||
|
||||
previous_version_count = ts_stack_version_count(self->stack);
|
||||
ts_parser__do_all_potential_reductions(self, version, 0);
|
||||
version_count = ts_stack_version_count(self->stack);
|
||||
position = ts_stack_position(self->stack, version);
|
||||
did_insert_missing_token = false;
|
||||
v = version;
|
||||
while (v < version_count)
|
||||
{
|
||||
if (!did_insert_missing_token)
|
||||
{
|
||||
state = ts_stack_state(self->stack, v);
|
||||
missing_symbol = 1;
|
||||
while (missing_symbol < (t_u16)self->language->token_count)
|
||||
{
|
||||
state_after_missing_symbol = ts_language_next_state(self->language,
|
||||
state, missing_symbol);
|
||||
if (state_after_missing_symbol == 0
|
||||
|| state_after_missing_symbol == state)
|
||||
{
|
||||
missing_symbol++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_language_has_reduce_action(self->language,
|
||||
state_after_missing_symbol,
|
||||
ts_subtree_leaf_symbol(lookahead)))
|
||||
{
|
||||
ts_lexer_reset(&self->lexer, position);
|
||||
ts_lexer__mark_end((void *)&self->lexer);
|
||||
padding = length_sub(self->lexer.token_end_position,
|
||||
position);
|
||||
lookahead_bytes = ts_subtree_total_bytes(lookahead)
|
||||
+ ts_subtree_lookahead_bytes(lookahead);
|
||||
version_with_missing_tree = ts_stack_copy_version(self->stack,
|
||||
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,
|
||||
missing_tree, false, state_after_missing_symbol});
|
||||
if (ts_parser__do_all_potential_reductions(self,
|
||||
version_with_missing_tree,
|
||||
ts_subtree_leaf_symbol(lookahead)))
|
||||
{
|
||||
did_insert_missing_token = true;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
missing_symbol++;
|
||||
}
|
||||
}
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){v, NULL, false,
|
||||
ERROR_STATE});
|
||||
if (v == version)
|
||||
v = previous_version_count;
|
||||
else
|
||||
v += 1;
|
||||
}
|
||||
i = previous_version_count;
|
||||
while (i < version_count)
|
||||
{
|
||||
ts_stack_merge(self->stack, version, previous_version_count);
|
||||
i++;
|
||||
}
|
||||
ts_stack_record_summary(self->stack, version, MAX_SUMMARY_DEPTH);
|
||||
ts_parser__recover(self, version, lookahead);
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_lex.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:54:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:22:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
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;
|
||||
TSLexMode lex_mode;
|
||||
t_symbol symbol;
|
||||
bool called_get_column;
|
||||
bool error_mode;
|
||||
bool external_scanner_state_changed;
|
||||
bool found_external_token;
|
||||
bool found_token;
|
||||
bool is_keyword;
|
||||
bool skipped_error;
|
||||
t_i32 first_error_character;
|
||||
t_subtree external_token;
|
||||
t_subtree result;
|
||||
t_u32 end_byte;
|
||||
t_u32 external_scanner_state_len;
|
||||
t_u32 lookahead_bytes;
|
||||
t_u32 lookahead_end_byte;
|
||||
|
||||
lex_mode = self->language->lex_modes[parse_state];
|
||||
if (lex_mode.lex_state == (t_u16)-1)
|
||||
return (NULL);
|
||||
start_position = ts_stack_position(self->stack, version);
|
||||
external_token = ts_stack_last_external_token(self->stack, version);
|
||||
found_external_token = false;
|
||||
error_mode = parse_state == ERROR_STATE;
|
||||
skipped_error = false;
|
||||
called_get_column = false;
|
||||
first_error_character = 0;
|
||||
error_start_position = length_zero();
|
||||
error_end_position = length_zero();
|
||||
lookahead_end_byte = 0;
|
||||
external_scanner_state_len = 0;
|
||||
external_scanner_state_changed = false;
|
||||
ts_lexer_reset(&self->lexer, start_position);
|
||||
while (true)
|
||||
{
|
||||
found_token = false;
|
||||
current_position = self->lexer.current_position;
|
||||
if (lex_mode.external_lex_state != 0)
|
||||
{
|
||||
ts_lexer_start(&self->lexer);
|
||||
ts_parser__external_scanner_deserialize(self, external_token);
|
||||
found_token = ts_parser__external_scanner_scan(self,
|
||||
lex_mode.external_lex_state);
|
||||
if (self->has_scanner_error)
|
||||
return (NULL);
|
||||
ts_lexer_finish(&self->lexer, &lookahead_end_byte);
|
||||
if (found_token)
|
||||
{
|
||||
external_scanner_state_len = ts_parser__external_scanner_serialize(self);
|
||||
external_scanner_state_changed = !ts_external_scanner_state_eq(ts_subtree_external_scanner_state(external_token),
|
||||
self->lexer.debug_buffer, external_scanner_state_len);
|
||||
if (self->lexer.token_end_position.bytes <= current_position.bytes
|
||||
&& (error_mode
|
||||
|| !ts_stack_has_advanced_since_error(self->stack,
|
||||
version)) && !external_scanner_state_changed)
|
||||
found_token = false;
|
||||
}
|
||||
if (found_token)
|
||||
{
|
||||
found_external_token = true;
|
||||
called_get_column = self->lexer.did_get_column;
|
||||
break ;
|
||||
}
|
||||
ts_lexer_reset(&self->lexer, current_position);
|
||||
}
|
||||
ts_lexer_start(&self->lexer);
|
||||
found_token = self->language->lex_fn(&self->lexer, lex_mode.lex_state);
|
||||
ts_lexer_finish(&self->lexer, &lookahead_end_byte);
|
||||
if (found_token)
|
||||
break ;
|
||||
if (!error_mode)
|
||||
{
|
||||
error_mode = true;
|
||||
lex_mode = self->language->lex_modes[ERROR_STATE];
|
||||
ts_lexer_reset(&self->lexer, start_position);
|
||||
continue ;
|
||||
}
|
||||
if (!skipped_error)
|
||||
{
|
||||
skipped_error = true;
|
||||
error_start_position = self->lexer.token_start_position;
|
||||
error_end_position = self->lexer.token_start_position;
|
||||
first_error_character = self->lexer.funcs.lookahead;
|
||||
}
|
||||
if (self->lexer.current_position.bytes == error_end_position.bytes)
|
||||
{
|
||||
if (self->lexer.funcs.eof(&self->lexer))
|
||||
{
|
||||
self->lexer.funcs.result_symbol = ts_builtin_sym_error;
|
||||
break ;
|
||||
}
|
||||
self->lexer.funcs.advance(&self->lexer, false);
|
||||
}
|
||||
error_end_position = self->lexer.current_position;
|
||||
}
|
||||
if (skipped_error)
|
||||
{
|
||||
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});
|
||||
}
|
||||
else
|
||||
{
|
||||
is_keyword = false;
|
||||
symbol = self->lexer.funcs.result_symbol;
|
||||
padding = length_sub(self->lexer.token_start_position, start_position);
|
||||
size = length_sub(self->lexer.token_end_position,
|
||||
self->lexer.token_start_position);
|
||||
lookahead_bytes = lookahead_end_byte
|
||||
- self->lexer.token_end_position.bytes;
|
||||
if (found_external_token)
|
||||
{
|
||||
symbol = self->language->external_scanner.symbol_map[symbol];
|
||||
}
|
||||
else if (symbol == self->language->keyword_capture_token && symbol != 0)
|
||||
{
|
||||
end_byte = self->lexer.token_end_position.bytes;
|
||||
ts_lexer_reset(&self->lexer, self->lexer.token_start_position);
|
||||
ts_lexer_start(&self->lexer);
|
||||
is_keyword = self->language->keyword_lex_fn(&self->lexer, 0);
|
||||
if (is_keyword && self->lexer.token_end_position.bytes == end_byte
|
||||
&& ts_language_has_actions(self->language, parse_state,
|
||||
self->lexer.funcs.result_symbol))
|
||||
{
|
||||
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});
|
||||
if (found_external_token)
|
||||
{
|
||||
ts_external_scanner_state_init(&result->external_scanner_state,
|
||||
self->lexer.debug_buffer, external_scanner_state_len);
|
||||
result->has_external_scanner_state_change = external_scanner_state_changed;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 13:56:13 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 14:12:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_parser *ts_parser_new(t_language *language)
|
||||
{
|
||||
t_parser *self;
|
||||
|
||||
self = mem_alloc(sizeof(*self));
|
||||
ts_lexer_init(&self->lexer);
|
||||
self->reduce_actions = vec_reduce_action_new(4, NULL);
|
||||
self->stack = ts_stack_new();
|
||||
self->finished_tree = NULL;
|
||||
self->language = language;
|
||||
self->has_scanner_error = false;
|
||||
self->external_scanner_payload = NULL;
|
||||
self->operation_count = 0;
|
||||
return (self);
|
||||
}
|
||||
|
||||
void ts_parser_delete(t_parser *self)
|
||||
{
|
||||
if (!self)
|
||||
return ;
|
||||
ts_parser_reset(self);
|
||||
self->language = NULL;
|
||||
ts_stack_delete(self->stack);
|
||||
vec_reduce_action_free(self->reduce_actions);
|
||||
array_delete(&self->trailing_extras);
|
||||
array_delete(&self->trailing_extras2);
|
||||
array_delete(&self->scratch_trees);
|
||||
mem_free(self);
|
||||
}
|
||||
|
||||
void ts_parser_reset(t_parser *self)
|
||||
{
|
||||
ts_parser__external_scanner_destroy(self);
|
||||
ts_lexer_reset(&self->lexer, length_zero());
|
||||
ts_stack_clear(self->stack);
|
||||
if (self->finished_tree)
|
||||
{
|
||||
ts_subtree_release(self->finished_tree);
|
||||
self->finished_tree = NULL;
|
||||
}
|
||||
self->accept_count = 0;
|
||||
self->has_scanner_error = false;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_outstanding_parse.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:56:59 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 13:57:06 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser_has_outstanding_parse(t_parser *self)
|
||||
{
|
||||
return (self->external_scanner_payload || ts_stack_state(self->stack,
|
||||
0) != 1 || ts_stack_node_count_since_error(self->stack, 0) != 0);
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_parse.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:56:28 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:18:23 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parse_condition(t_parser *self, t_u32 *version_count,
|
||||
t_stack_version *version)
|
||||
{
|
||||
*version_count = ts_stack_version_count(self->stack);
|
||||
return (*version < *version_count);
|
||||
}
|
||||
|
||||
t_error _parser_parse_init_state(\
|
||||
t_parser *self, t_input input, struct s_parser_parse_state *state)
|
||||
{
|
||||
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 (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), ERROR);
|
||||
}
|
||||
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))
|
||||
{
|
||||
while (ts_stack_is_active(self->stack, state->version))
|
||||
{
|
||||
if (!ts_parser__advance(self, state->version))
|
||||
{
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
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 ;
|
||||
}
|
||||
}
|
||||
return (_parser_parse_end(self, input, state));
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_parse_str.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:49:37 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 14:19:20 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
const t_u8 *ts_string_input_read(void *_self, t_u32 byte, t_point point,
|
||||
t_u32 *length)
|
||||
{
|
||||
t_string_input *self;
|
||||
|
||||
(void)point;
|
||||
self = (t_string_input *)_self;
|
||||
if (byte >= self->length)
|
||||
{
|
||||
*length = 0;
|
||||
return ((const t_u8 *)"");
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = self->length - byte;
|
||||
return (self->string + byte);
|
||||
}
|
||||
}
|
||||
|
||||
t_tree *ts_parser_parse_string(t_parser *self, t_const_str string,
|
||||
t_u32 length)
|
||||
{
|
||||
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}));
|
||||
}
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_recover.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:46:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:18:36 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__recover(t_parser *self, t_stack_version version,
|
||||
t_subtree lookahead)
|
||||
{
|
||||
t_length position;
|
||||
bool did_recover;
|
||||
bool would_merge;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_summary *summary;
|
||||
t_stack_summary_entry entry;
|
||||
t_subtree parent;
|
||||
t_u32 current_error_cost;
|
||||
t_u32 depth;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_u32 new_cost;
|
||||
t_u32 node_count_since_error;
|
||||
t_u32 previous_version_count;
|
||||
t_vec_subtree children;
|
||||
t_u32 n;
|
||||
const TSParseAction *actions;
|
||||
t_subtree error_repeat;
|
||||
t_subtree mutable_lookahead;
|
||||
|
||||
did_recover = false;
|
||||
previous_version_count = ts_stack_version_count(self->stack);
|
||||
position = ts_stack_position(self->stack, version);
|
||||
summary = ts_stack_get_summary(self->stack, version);
|
||||
node_count_since_error = ts_stack_node_count_since_error(self->stack,
|
||||
version);
|
||||
current_error_cost = ts_stack_error_cost(self->stack, version);
|
||||
if (summary && !ts_subtree_is_error(lookahead))
|
||||
{
|
||||
i = 0;
|
||||
while (i < summary->size)
|
||||
{
|
||||
entry = summary->contents[i];
|
||||
if (entry.state == ERROR_STATE)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
if (entry.position.bytes == position.bytes)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
depth = entry.depth;
|
||||
if (node_count_since_error > 0)
|
||||
depth++;
|
||||
would_merge = false;
|
||||
j = 0;
|
||||
while (j < previous_version_count)
|
||||
{
|
||||
if (ts_stack_state(self->stack, j) == entry.state
|
||||
&& ts_stack_position(self->stack,
|
||||
j).bytes == position.bytes)
|
||||
{
|
||||
would_merge = true;
|
||||
break ;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (would_merge)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
new_cost = current_error_cost + entry.depth
|
||||
* ERROR_COST_PER_SKIPPED_TREE + (position.bytes
|
||||
- entry.position.bytes) * ERROR_COST_PER_SKIPPED_CHAR
|
||||
+ (position.extent.row - entry.position.extent.row)
|
||||
* ERROR_COST_PER_SKIPPED_LINE;
|
||||
if (ts_parser__better_version_exists(self, version, false,
|
||||
new_cost))
|
||||
break ;
|
||||
if (ts_language_has_actions(self->language, entry.state,
|
||||
ts_subtree_symbol(lookahead)))
|
||||
{
|
||||
if (ts_parser__recover_to_state(self, version, depth,
|
||||
entry.state))
|
||||
{
|
||||
did_recover = true;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = previous_version_count;
|
||||
while (i < ts_stack_version_count(self->stack))
|
||||
{
|
||||
if (!ts_stack_is_active(self->stack, i))
|
||||
ts_stack_remove_version(self->stack, i--);
|
||||
i++;
|
||||
}
|
||||
if (did_recover && ts_stack_version_count(self->stack) > MAX_VERSION_COUNT)
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
if (did_recover && ts_subtree_has_external_scanner_state_change(lookahead))
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
if (ts_subtree_is_eof(lookahead))
|
||||
{
|
||||
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_parser__accept(self, version, lookahead);
|
||||
return ;
|
||||
}
|
||||
new_cost = current_error_cost + ERROR_COST_PER_SKIPPED_TREE
|
||||
+ ts_subtree_total_bytes(lookahead) * ERROR_COST_PER_SKIPPED_CHAR
|
||||
+ ts_subtree_total_size(lookahead).extent.row
|
||||
* ERROR_COST_PER_SKIPPED_LINE;
|
||||
if (ts_parser__better_version_exists(self, version, false, new_cost))
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
actions = ts_language_actions(self->language, 1,
|
||||
ts_subtree_symbol(lookahead), &n);
|
||||
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n
|
||||
- 1].shift.extra)
|
||||
{
|
||||
mutable_lookahead = ts_subtree_ensure_owner(lookahead);
|
||||
ts_subtree_set_extra(&mutable_lookahead, true);
|
||||
lookahead = (mutable_lookahead);
|
||||
}
|
||||
children = vec_subtree_new(1, NULL);
|
||||
vec_subtree_push(&children, lookahead);
|
||||
error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children,
|
||||
0, self->language);
|
||||
if (node_count_since_error > 0)
|
||||
{
|
||||
pop = ts_stack_pop_count(self->stack, version, 1);
|
||||
if (pop.size > 1)
|
||||
{
|
||||
i = 1;
|
||||
while (i < pop.size)
|
||||
ts_subtree_array_delete(&pop.contents[i++].subtrees);
|
||||
while (ts_stack_version_count(self->stack) > pop.contents[0].version
|
||||
+ 1)
|
||||
ts_stack_remove_version(self->stack, pop.contents[0].version
|
||||
+ 1);
|
||||
}
|
||||
ts_stack_renumber_version(self->stack, pop.contents[0].version,
|
||||
version);
|
||||
vec_subtree_push(&pop.contents[0].subtrees, (error_repeat));
|
||||
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});
|
||||
if (ts_subtree_has_external_tokens(lookahead))
|
||||
ts_stack_set_last_external_token(self->stack, version,
|
||||
ts_subtree_last_external_token(lookahead));
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_recover_to_tree.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:48:22 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:23:55 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__recover_to_state(t_parser *self, t_stack_version version,
|
||||
t_u32 depth, t_state_id goal_state)
|
||||
{
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_version previous_version;
|
||||
t_subtree error;
|
||||
t_subtree error_tree;
|
||||
t_subtree tree;
|
||||
t_u32 error_child_count;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_vec_subtree error_trees;
|
||||
|
||||
previous_version = STACK_VERSION_NONE;
|
||||
pop = ts_stack_pop_count(self->stack, version, depth);
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
if (slice.version == previous_version)
|
||||
{
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
array_erase(&pop, i--);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_stack_state(self->stack, slice.version) != goal_state)
|
||||
{
|
||||
ts_stack_halt(self->stack, slice.version);
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
array_erase(&pop, i--);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
error_trees = ts_stack_pop_error(self->stack, slice.version);
|
||||
if (error_trees.len > 0)
|
||||
{
|
||||
error_tree = error_trees.buffer[0];
|
||||
error_child_count = ts_subtree_child_count(error_tree);
|
||||
if (error_child_count > 0)
|
||||
{
|
||||
vec_subtree_splice(&slice.subtrees, vec_subtree_splice_args(0,
|
||||
0, error_child_count, ts_subtree_children(error_tree)));
|
||||
j = 0;
|
||||
while (j < error_child_count)
|
||||
{
|
||||
slice.subtrees.buffer[j]->ref_count++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ts_subtree_array_delete(&error_trees);
|
||||
}
|
||||
ts_subtree_array_remove_trailing_extras(&slice.subtrees,
|
||||
&self->trailing_extras);
|
||||
if (slice.subtrees.len > 0)
|
||||
{
|
||||
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});
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_subtree_free(slice.subtrees);
|
||||
}
|
||||
j = 0;
|
||||
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});
|
||||
j++;
|
||||
}
|
||||
previous_version = slice.version;
|
||||
i++;
|
||||
}
|
||||
return (previous_version != (t_stack_version)STACK_VERSION_NONE);
|
||||
}
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_reduce.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:03:09 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:24 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_stack_version ts_parser__reduce(t_parser *self, t_stack_version version,
|
||||
t_symbol symbol, t_u32 count, int dynamic_precedence,
|
||||
t_u16 production_id, bool is_fragile, bool end_of_non_terminal_extra)
|
||||
{
|
||||
t_state_id next_state;
|
||||
t_state_id state;
|
||||
t_stack_slice next_slice;
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_version k;
|
||||
t_stack_version slice_version;
|
||||
t_subtree parent;
|
||||
t_u32 i;
|
||||
t_u32 initial_version_count;
|
||||
t_u32 j;
|
||||
t_u32 removed_version_count;
|
||||
t_vec_subtree children;
|
||||
t_vec_subtree next_slice_children;
|
||||
|
||||
initial_version_count = ts_stack_version_count(self->stack);
|
||||
pop = ts_stack_pop_count(self->stack, version, count);
|
||||
removed_version_count = 0;
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
slice_version = slice.version - removed_version_count;
|
||||
if (slice_version > MAX_VERSION_COUNT + MAX_VERSION_COUNT_OVERFLOW)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, slice_version);
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
removed_version_count++;
|
||||
while (i + 1 < pop.size)
|
||||
{
|
||||
next_slice = pop.contents[i + 1];
|
||||
if (next_slice.version != slice.version)
|
||||
break ;
|
||||
ts_subtree_array_delete(&next_slice.subtrees);
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
children = slice.subtrees;
|
||||
ts_subtree_array_remove_trailing_extras(&children,
|
||||
&self->trailing_extras);
|
||||
parent = ts_subtree_new_node(symbol, &children, production_id,
|
||||
self->language);
|
||||
while (i + 1 < pop.size)
|
||||
{
|
||||
next_slice = pop.contents[i + 1];
|
||||
if (next_slice.version != slice.version)
|
||||
break ;
|
||||
i++;
|
||||
next_slice_children = next_slice.subtrees;
|
||||
ts_subtree_array_remove_trailing_extras(&next_slice_children,
|
||||
&self->trailing_extras2);
|
||||
if (ts_parser__select_children(self, (parent),
|
||||
&next_slice_children))
|
||||
{
|
||||
ts_subtree_array_clear(&self->trailing_extras);
|
||||
ts_subtree_release(parent);
|
||||
array_swap(&self->trailing_extras, &self->trailing_extras2);
|
||||
parent = ts_subtree_new_node(symbol, &next_slice_children,
|
||||
production_id, self->language);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->trailing_extras2.len = 0;
|
||||
ts_subtree_array_delete(&next_slice.subtrees);
|
||||
}
|
||||
}
|
||||
state = ts_stack_state(self->stack, slice_version);
|
||||
next_state = ts_language_next_state(self->language, state, symbol);
|
||||
if (end_of_non_terminal_extra && next_state == state)
|
||||
parent->extra = true;
|
||||
if (is_fragile || pop.size > 1 || initial_version_count > 1)
|
||||
{
|
||||
parent->fragile_left = true;
|
||||
parent->fragile_right = true;
|
||||
parent->parse_state = TS_TREE_STATE_NONE;
|
||||
}
|
||||
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});
|
||||
j = 0;
|
||||
while (j < self->trailing_extras.len)
|
||||
{
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){slice_version,
|
||||
self->trailing_extras.buffer[j], false, next_state});
|
||||
j++;
|
||||
}
|
||||
k = 0;
|
||||
while (k < slice_version)
|
||||
{
|
||||
if (k == version)
|
||||
{
|
||||
k++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_stack_merge(self->stack, k, slice_version))
|
||||
{
|
||||
removed_version_count++;
|
||||
break ;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (ts_stack_version_count(self->stack) > initial_version_count)
|
||||
return (initial_version_count);
|
||||
return (STACK_VERSION_NONE);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_select.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:55:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:38:54 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
// Determine if a given tree should be replaced by an
|
||||
// alternative tree.
|
||||
//
|
||||
// The decision is based on the trees' error costs (if any),
|
||||
// their dynamic precedence, and finally, as a default, by a
|
||||
// recursive comparison of the trees' symbols.
|
||||
bool ts_parser__select_tree(t_parser *self, t_subtree left, t_subtree right)
|
||||
{
|
||||
int comparison;
|
||||
|
||||
(void)(self);
|
||||
if (!left)
|
||||
return (true);
|
||||
if (!right)
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(right) < ts_subtree_error_cost(left))
|
||||
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))
|
||||
return (true);
|
||||
if (ts_subtree_dynamic_precedence(left) \
|
||||
> ts_subtree_dynamic_precedence(right))
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(left) > 0)
|
||||
return (true);
|
||||
comparison = ts_subtree_compare(left, right);
|
||||
return (comparison == 1);
|
||||
}
|
||||
|
||||
// Determine if a given tree's children should be replaced
|
||||
// by an alternative array of children.
|
||||
bool ts_parser__select_children(t_parser *self, t_subtree left,
|
||||
const t_vec_subtree *children)
|
||||
{
|
||||
t_subtree scratch_tree;
|
||||
|
||||
vec_subtree_copy_into(&self->scratch_trees, (void *)children);
|
||||
scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left),
|
||||
&self->scratch_trees, 0, self->language);
|
||||
return (ts_parser__select_tree(self, left, (scratch_tree)));
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_shift.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:55:29 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__shift(t_parser *self, t_stack_version version,
|
||||
t_state_id state, t_subtree lookahead, bool extra)
|
||||
{
|
||||
bool is_leaf;
|
||||
t_subtree result;
|
||||
t_subtree subtree_to_push;
|
||||
|
||||
is_leaf = ts_subtree_child_count(lookahead) == 0;
|
||||
subtree_to_push = lookahead;
|
||||
if (extra != ts_subtree_extra(lookahead) && is_leaf)
|
||||
{
|
||||
result = ts_subtree_ensure_owner(lookahead);
|
||||
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});
|
||||
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));
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_versions.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:42:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:17:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parser_compare_inner(t_parser *self, \
|
||||
t_error_status a, t_error_status b, t_error_comparison *ret)
|
||||
{
|
||||
(void)(self);
|
||||
if (!a.is_in_error && b.is_in_error)
|
||||
{
|
||||
if (a.cost < b.cost)
|
||||
return (*ret = ECTakeLeft, true);
|
||||
else
|
||||
return (*ret = ECPreferLeft, true);
|
||||
}
|
||||
if (a.is_in_error && !b.is_in_error)
|
||||
{
|
||||
if (b.cost < a.cost)
|
||||
return (*ret = ECTakeRight, true);
|
||||
else
|
||||
return (*ret = ECPreferRight, true);
|
||||
}
|
||||
if (a.cost < b.cost)
|
||||
{
|
||||
if ((b.cost - a.cost) * (1 + a.node_count) > MAX_COST_DIFFERENCE)
|
||||
return (*ret = ECTakeLeft, true);
|
||||
else
|
||||
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)
|
||||
return (ECTakeRight);
|
||||
else
|
||||
return (ECPreferRight);
|
||||
}
|
||||
if (a.dynamic_precedence > b.dynamic_precedence)
|
||||
return (ECPreferLeft);
|
||||
if (b.dynamic_precedence > a.dynamic_precedence)
|
||||
return (ECPreferRight);
|
||||
return (ECNone);
|
||||
}
|
||||
|
||||
t_error_status ts_parser__version_status(t_parser *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_u32 cost;
|
||||
bool is_paused;
|
||||
|
||||
cost = ts_stack_error_cost(self->stack, version);
|
||||
is_paused = ts_stack_is_paused(self->stack, version);
|
||||
if (is_paused)
|
||||
cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
return ((t_error_status){.cost = cost,
|
||||
.node_count = ts_stack_node_count_since_error(self->stack, version),
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
|
||||
.is_in_error = is_paused || ts_stack_state(self->stack,
|
||||
version) == ERROR_STATE});
|
||||
}
|
||||
|
||||
bool _better_version_end(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
t_length position, t_error_status status)
|
||||
{
|
||||
t_stack_version i;
|
||||
t_stack_version n;
|
||||
t_error_comparison cmp;
|
||||
t_error_status status_i;
|
||||
|
||||
i = 0;
|
||||
n = ts_stack_version_count(self->stack);
|
||||
while (i < n)
|
||||
{
|
||||
if (i == version || !ts_stack_is_active(self->stack, i)
|
||||
|| ts_stack_position(self->stack, i).bytes < position.bytes)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:31:13 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:31:33 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/point.h"
|
||||
|
||||
t_point point__new(t_u32 row, t_u32 column)
|
||||
{
|
||||
return ((t_point){row, column});
|
||||
}
|
||||
|
||||
t_point point_add(t_point a, t_point b)
|
||||
{
|
||||
if (b.row > 0)
|
||||
return (point__new(a.row + b.row, b.column));
|
||||
else
|
||||
return (point__new(a.row, a.column + b.column));
|
||||
}
|
||||
|
||||
t_point point_sub(t_point a, t_point b)
|
||||
{
|
||||
if (a.row > b.row)
|
||||
return (point__new(a.row - b.row, a.column));
|
||||
else
|
||||
return (point__new(0, a.column - b.column));
|
||||
}
|
||||
|
||||
bool point_lte(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row < b.row) || (a.row == b.row && a.column <= b.column));
|
||||
}
|
||||
|
||||
bool point_lt(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row < b.row) || (a.row == b.row && a.column < b.column));
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:31:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:31:57 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/point.h"
|
||||
|
||||
bool point_gt(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row > b.row) || (a.row == b.row && a.column > b.column));
|
||||
}
|
||||
|
||||
bool point_gte(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row > b.row) || (a.row == b.row && a.column >= b.column));
|
||||
}
|
||||
|
||||
bool point_eq(t_point a, t_point b)
|
||||
{
|
||||
return (a.row == b.row && a.column == b.column);
|
||||
}
|
||||
|
||||
t_point point_min(t_point a, t_point b)
|
||||
{
|
||||
if (a.row < b.row || (a.row == b.row && a.column < b.column))
|
||||
return (a);
|
||||
else
|
||||
return (b);
|
||||
}
|
||||
|
||||
t_point point_max(t_point a, t_point b)
|
||||
{
|
||||
if (a.row > b.row || (a.row == b.row && a.column > b.column))
|
||||
return (a);
|
||||
else
|
||||
return (b);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:12:41 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:47:19 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_heredoc_start(t_heredoc *heredoc, t_lexer *lexer);
|
||||
bool scan_heredoc_end_identifier(t_heredoc *heredoc, t_lexer *lexer);
|
||||
bool scan_heredoc_content(t_scanner *scanner, t_lexer *lexer, \
|
||||
enum e_token_type middle_type, enum e_token_type end_type);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols)
|
||||
{
|
||||
return (valid_symbols[ERROR_RECOVERY]);
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scan.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:09:30 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:48:40 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool scan_bare_dollar(t_lexer *lexer)
|
||||
{
|
||||
while (me_isspace(lexer->funcs.lookahead) && lexer->funcs.lookahead != '\n'
|
||||
&& !lexer->funcs.eof((void *)lexer))
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.result_symbol = BARE_DOLLAR;
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
return (me_isspace(lexer->funcs.lookahead) \
|
||||
|| lexer->funcs.eof((void *)lexer) || lexer->funcs.lookahead == '\"');
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
if (valid_symbols[IMMEDIATE_DOUBLE_HASH]
|
||||
&& !(valid_symbols[ERROR_RECOVERY]))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '#')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '#')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead != '}')
|
||||
{
|
||||
lexer->funcs.result_symbol = IMMEDIATE_DOUBLE_HASH;
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scanner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 15:41:11 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:51:57 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
/**
|
||||
* Consume a "word" in POSIX parlance, and returns it unquoted.
|
||||
*
|
||||
* This is an approximate implementation that doesn't deal with any
|
||||
* POSIX-mandated substitution, and assumes the default value for
|
||||
* IFS.
|
||||
*/
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
lexer->funcs.result_symbol = CONCAT;
|
||||
if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '"' || lexer->funcs.lookahead == '\''
|
||||
|| lexer->funcs.lookahead == '\\')
|
||||
return (true);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
bool advanced_once;
|
||||
bool advance_once_space;
|
||||
|
||||
advanced_once = false;
|
||||
advance_once_space = false;
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
while (true)
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\"')
|
||||
return (false);
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '{' || lexer->funcs.lookahead == '('
|
||||
|| lexer->funcs.lookahead == '\''
|
||||
|| me_isalnum(lexer->funcs.lookahead))
|
||||
{
|
||||
lexer->funcs.result_symbol = EXPANSION_WORD;
|
||||
return (advanced_once);
|
||||
}
|
||||
advanced_once = true;
|
||||
}
|
||||
if (lexer->funcs.lookahead == '}')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = EXPANSION_WORD;
|
||||
return (advanced_once || advance_once_space);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '(' && !(advanced_once
|
||||
|| advance_once_space))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
while (lexer->funcs.lookahead != ')'
|
||||
&& !lexer->funcs.eof((void *)lexer))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '{'
|
||||
|| lexer->funcs.lookahead == '('
|
||||
|| lexer->funcs.lookahead == '\''
|
||||
|| me_isalnum(lexer->funcs.lookahead))
|
||||
return (lexer->funcs.result_symbol = EXPANSION_WORD,
|
||||
advanced_once);
|
||||
advanced_once = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
advanced_once = advanced_once
|
||||
|| !me_isspace(lexer->funcs.lookahead);
|
||||
advance_once_space = advance_once_space
|
||||
|| me_isspace(lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
}
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
if (lexer->funcs.lookahead == ')')
|
||||
{
|
||||
advanced_once = true;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
if (lexer->funcs.lookahead == '}')
|
||||
return (false);
|
||||
}
|
||||
else
|
||||
return (false);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '\'')
|
||||
return (false);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
return (false);
|
||||
advanced_once = advanced_once || !me_isspace(lexer->funcs.lookahead);
|
||||
advance_once_space = advance_once_space
|
||||
|| me_isspace(lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
bool is_number;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((lexer->funcs.lookahead == ' ' || lexer->funcs.lookahead == '\t'
|
||||
|| lexer->funcs.lookahead == '\r'
|
||||
|| (lexer->funcs.lookahead == '\n' && !valid_symbols[NEWLINE]))
|
||||
&& !valid_symbols[EXPANSION_WORD])
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
else if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (true);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '\r')
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.lookahead == '\n')
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
else
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\\'
|
||||
&& valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
else
|
||||
break ;
|
||||
}
|
||||
if (!valid_symbols[EXPANSION_WORD] && (lexer->funcs.lookahead == '*'
|
||||
|| lexer->funcs.lookahead == '@' || lexer->funcs.lookahead == '?'
|
||||
|| lexer->funcs.lookahead == '-' || lexer->funcs.lookahead == '0'
|
||||
|| lexer->funcs.lookahead == '_'))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == '['
|
||||
|| lexer->funcs.lookahead == ':' || lexer->funcs.lookahead == '-'
|
||||
|| lexer->funcs.lookahead == '%' || lexer->funcs.lookahead == '#'
|
||||
|| lexer->funcs.lookahead == '/')
|
||||
return (false);
|
||||
if (valid_symbols[EXTGLOB_PATTERN] && \
|
||||
me_isspace(lexer->funcs.lookahead))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = EXTGLOB_PATTERN;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
is_number = true;
|
||||
if (me_isdigit(lexer->funcs.lookahead))
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
else if (me_isalpha(lexer->funcs.lookahead) || \
|
||||
lexer->funcs.lookahead == '_')
|
||||
{
|
||||
is_number = false;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lexer->funcs.lookahead == '{')
|
||||
return (false);
|
||||
if (valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
if (me_isdigit(lexer->funcs.lookahead))
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
else if (me_isalpha(lexer->funcs.lookahead)
|
||||
|| lexer->funcs.lookahead == '_')
|
||||
{
|
||||
is_number = false;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
else
|
||||
break ;
|
||||
}
|
||||
if (is_number && valid_symbols[FILE_DESCRIPTOR]
|
||||
&& (lexer->funcs.lookahead == '>' || lexer->funcs.lookahead == '<'))
|
||||
return (lexer->funcs.result_symbol = FILE_DESCRIPTOR, true);
|
||||
if (valid_symbols[VARIABLE_NAME])
|
||||
{
|
||||
if (lexer->funcs.lookahead == '+')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == ':')
|
||||
return (lexer->funcs.result_symbol = VARIABLE_NAME, true);
|
||||
return (false);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '/')
|
||||
return (false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == '['
|
||||
|| (lexer->funcs.lookahead == ':' && !valid_symbols[OPENING_PAREN])
|
||||
|| lexer->funcs.lookahead == '%' || (lexer->funcs.lookahead == '#'
|
||||
&& !is_number) || lexer->funcs.lookahead == '@'
|
||||
|| (lexer->funcs.lookahead == '-'))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (true);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '?')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (me_isalpha(lexer->funcs.lookahead));
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||
{
|
||||
if (valid_symbols[CONCAT] && !(valid_symbols[ERROR_RECOVERY])
|
||||
&& (!(lexer->funcs.lookahead == 0 || me_isspace(lexer->funcs.lookahead) \
|
||||
|| lexer->funcs.lookahead == '>' || lexer->funcs.lookahead == '<' \
|
||||
|| lexer->funcs.lookahead == ')' || lexer->funcs.lookahead == '(' \
|
||||
|| lexer->funcs.lookahead == ';' || lexer->funcs.lookahead == '&' \
|
||||
|| lexer->funcs.lookahead == '|' || lexer->funcs.lookahead == '{' \
|
||||
|| lexer->funcs.lookahead == '}')))
|
||||
return (scan_concat(scanner, lexer, valid_symbols));
|
||||
if (scan_double_hash(scanner, lexer, valid_symbols))
|
||||
return (true);
|
||||
if (valid_symbols[EMPTY_VALUE] && (me_isspace(lexer->funcs.lookahead)
|
||||
|| lexer->funcs.eof((void *)lexer) || lexer->funcs.lookahead == ';'
|
||||
|| lexer->funcs.lookahead == '&'))
|
||||
return (lexer->funcs.result_symbol = EMPTY_VALUE, true);
|
||||
if ((valid_symbols[VARIABLE_NAME] || valid_symbols[FILE_DESCRIPTOR])
|
||||
&& !(valid_symbols[ERROR_RECOVERY]))
|
||||
return (scan_literals(scanner, lexer, valid_symbols));
|
||||
if (valid_symbols[BARE_DOLLAR] && !(valid_symbols[ERROR_RECOVERY])
|
||||
&& scan_bare_dollar(lexer))
|
||||
return (true);
|
||||
if (valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* serialize.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:08:04 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:53:51 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem.h"
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word)
|
||||
{
|
||||
bool empty;
|
||||
t_i32 quote;
|
||||
|
||||
empty = true;
|
||||
quote = 0;
|
||||
if (lexer->funcs.lookahead == '\'' || lexer->funcs.lookahead == '"')
|
||||
{
|
||||
quote = lexer->funcs.lookahead;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
while (lexer->funcs.lookahead && !((quote && \
|
||||
(lexer->funcs.lookahead == quote \
|
||||
|| lexer->funcs.lookahead == '\r' \
|
||||
|| lexer->funcs.lookahead == '\n')) || (!quote \
|
||||
&& me_isspace(lexer->funcs.lookahead))))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (!lexer->funcs.lookahead)
|
||||
return (false);
|
||||
}
|
||||
empty = false;
|
||||
string_push_char(unquoted_word, lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
string_push_char(unquoted_word, '\0');
|
||||
if (quote && lexer->funcs.lookahead == quote)
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
return (!empty);
|
||||
}
|
||||
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer)
|
||||
{
|
||||
t_u32 size;
|
||||
|
||||
size = 0;
|
||||
buffer[size++] = (char)scanner->last_glob_paren_depth;
|
||||
buffer[size++] = (char)scanner->ext_was_in_double_quote;
|
||||
buffer[size++] = (char)scanner->ext_saw_outside_quote;
|
||||
return (size);
|
||||
}
|
||||
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length)
|
||||
{
|
||||
t_u32 size;
|
||||
|
||||
if (length == 0)
|
||||
mem_set_zero(scanner, sizeof(*scanner));
|
||||
else
|
||||
{
|
||||
size = 0;
|
||||
scanner->last_glob_paren_depth = buffer[size++];
|
||||
scanner->ext_was_in_double_quote = buffer[size++];
|
||||
scanner->ext_saw_outside_quote = buffer[size++];
|
||||
if (!(size == length))
|
||||
me_abort("assertion failed: size == length");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree_sitter.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:10:31 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:54:39 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
void *tree_sitter_sh_external_scanner_create(void)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = mem_alloc(sizeof(*scanner));
|
||||
return (scanner);
|
||||
}
|
||||
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
return (scan(scanner, lexer, valid_symbols));
|
||||
}
|
||||
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
return (serialize(scanner, state));
|
||||
}
|
||||
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload,
|
||||
const t_u8 *state, t_u32 length)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
deserialize(scanner, state, length);
|
||||
}
|
||||
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
mem_free(scanner);
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_add_link.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:52:46 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:49:32 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void _add_link_tail(t_stack_node *self, t_stack_link link)
|
||||
{
|
||||
t_i32 dynamic_precedence;
|
||||
t_u32 node_count;
|
||||
|
||||
if (self->link_count == MAX_LINK_COUNT)
|
||||
return ;
|
||||
stack_node_retain(link.node);
|
||||
node_count = link.node->node_count;
|
||||
dynamic_precedence = link.node->dynamic_precedence;
|
||||
self->links[self->link_count++] = link;
|
||||
if (link.subtree)
|
||||
{
|
||||
(link.subtree->ref_count++);
|
||||
node_count += stack__subtree_node_count(link.subtree);
|
||||
dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
|
||||
}
|
||||
if (node_count > self->node_count)
|
||||
self->node_count = node_count;
|
||||
if (dynamic_precedence > self->dynamic_precedence)
|
||||
self->dynamic_precedence = dynamic_precedence;
|
||||
}
|
||||
|
||||
bool _is_link_node_similar(\
|
||||
t_stack_node *self, t_stack_link link, \
|
||||
t_stack_link *ext_link)
|
||||
{
|
||||
t_usize j;
|
||||
t_i32 dynamic_precedence;
|
||||
|
||||
if (ext_link->node->state == link.node->state \
|
||||
&& ext_link->node->position.bytes == link.node->position.bytes
|
||||
&& ext_link->node->error_cost == link.node->error_cost)
|
||||
{
|
||||
j = 0;
|
||||
while (j < link.node->link_count)
|
||||
stack_node_add_link(ext_link->node,
|
||||
link.node->links[j++]);
|
||||
dynamic_precedence = link.node->dynamic_precedence;
|
||||
if (link.subtree)
|
||||
dynamic_precedence
|
||||
+= ts_subtree_dynamic_precedence(link.subtree);
|
||||
if (dynamic_precedence > self->dynamic_precedence)
|
||||
self->dynamic_precedence = dynamic_precedence;
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _is_link_same_node(\
|
||||
t_stack_node *self, t_stack_link link, \
|
||||
t_stack_link *ext_link)
|
||||
{
|
||||
if (ext_link->node == link.node)
|
||||
{
|
||||
if (ts_subtree_dynamic_precedence(\
|
||||
link.subtree) > ts_subtree_dynamic_precedence(ext_link->subtree))
|
||||
{
|
||||
link.subtree->ref_count++;
|
||||
ts_subtree_release(ext_link->subtree);
|
||||
ext_link->subtree = link.subtree;
|
||||
self->dynamic_precedence = link.node->dynamic_precedence
|
||||
+ ts_subtree_dynamic_precedence(link.subtree);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
// In general,
|
||||
// we preserve ambiguities until they are removed from the stack
|
||||
// during a pop operation where multiple paths lead to the same node. But in
|
||||
// the special case where two links directly connect the same pair of nodes,
|
||||
// we can safely remove the ambiguity ahead of time without changing behavior.
|
||||
void stack_node_add_link(t_stack_node *self, t_stack_link link)
|
||||
{
|
||||
t_stack_link *ext_link;
|
||||
t_usize i;
|
||||
|
||||
if (link.node == self)
|
||||
return ;
|
||||
i = 0;
|
||||
while (i < self->link_count)
|
||||
{
|
||||
ext_link = &self->links[i];
|
||||
if (stack__subtree_is_equivalent(ext_link->subtree, link.subtree))
|
||||
{
|
||||
if (_is_link_same_node(self, link, ext_link) \
|
||||
|| _is_link_node_similar(self, link, ext_link))
|
||||
return ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_add_link_tail(self, link);
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:52:03 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:06:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool ts_stack_is_active(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusActive);
|
||||
}
|
||||
|
||||
bool ts_stack_is_halted(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusHalted);
|
||||
}
|
||||
|
||||
bool ts_stack_is_paused(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusPaused);
|
||||
}
|
||||
|
||||
t_subtree ts_stack_resume(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_subtree result;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
assert(head->status == SStatusPaused);
|
||||
result = head->lookahead_when_paused;
|
||||
head->status = SStatusActive;
|
||||
head->lookahead_when_paused = NULL;
|
||||
return (result);
|
||||
}
|
||||
|
||||
void ts_stack_clear(t_stack *self)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
stack_node_retain(self->base_node);
|
||||
i = 0;
|
||||
while (i < self->heads.size)
|
||||
stack_head_delete(&self->heads.contents[i++]);
|
||||
array_clear(&self->heads);
|
||||
array_push(&self->heads, ((t_stack_head){.node = self->base_node, \
|
||||
.status = SStatusActive, .last_external_token = NULL, \
|
||||
.lookahead_when_paused = NULL, }));
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:55:52 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:38:38 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_u32 ts_stack_error_cost(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_u32 result;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
result = head->node->error_cost;
|
||||
if (head->status == SStatusPaused || (head->node->state == ERROR_STATE
|
||||
&& !head->node->links[0].subtree))
|
||||
{
|
||||
result += ERROR_COST_PER_RECOVERY;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_u32 ts_stack_node_count_since_error(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
if (head->node->node_count < head->node_count_at_last_error)
|
||||
{
|
||||
head->node_count_at_last_error = head->node->node_count;
|
||||
}
|
||||
return (head->node->node_count - head->node_count_at_last_error);
|
||||
}
|
||||
|
||||
int ts_stack_dynamic_precedence(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->dynamic_precedence);
|
||||
}
|
||||
|
||||
bool ts_stack_has_advanced_since_error(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
const t_stack_head *head = array_get(&self->heads, version);
|
||||
const t_stack_node *node = head->node;
|
||||
t_subtree subtree;
|
||||
|
||||
if (node->error_cost == 0)
|
||||
return (true);
|
||||
while (node)
|
||||
{
|
||||
if (node->link_count == 0)
|
||||
break ;
|
||||
subtree = node->links[0].subtree;
|
||||
if (subtree)
|
||||
{
|
||||
if (ts_subtree_total_bytes(subtree) > 0)
|
||||
return (true);
|
||||
else if (node->node_count > head->node_count_at_last_error
|
||||
&& ts_subtree_error_cost(subtree) == 0)
|
||||
{
|
||||
node = node->links[0].node;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:56:40 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:56:49 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool stack__subtree_is_equivalent(t_subtree left, t_subtree right)
|
||||
{
|
||||
if (left == right)
|
||||
return (true);
|
||||
if (!left || !right)
|
||||
return (false);
|
||||
if (ts_subtree_symbol(left) != ts_subtree_symbol(right))
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0)
|
||||
return (true);
|
||||
return (ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes
|
||||
&& ts_subtree_size(left).bytes == ts_subtree_size(right).bytes
|
||||
&& ts_subtree_child_count(left) == ts_subtree_child_count(right)
|
||||
&& ts_subtree_extra(left) == ts_subtree_extra(right)
|
||||
&& ts_subtree_external_scanner_state_eq(left, right));
|
||||
}
|
||||
|
||||
void stack_head_delete(t_stack_head *self)
|
||||
{
|
||||
if (self->node)
|
||||
{
|
||||
if (self->last_external_token)
|
||||
{
|
||||
ts_subtree_release(self->last_external_token);
|
||||
}
|
||||
if (self->lookahead_when_paused)
|
||||
{
|
||||
ts_subtree_release(self->lookahead_when_paused);
|
||||
}
|
||||
if (self->summary)
|
||||
{
|
||||
array_delete(self->summary);
|
||||
mem_free(self->summary);
|
||||
}
|
||||
stack_node_release(self->node);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_version ts_stack__add_version(t_stack *self,
|
||||
t_stack_version original_version, t_stack_node *node)
|
||||
{
|
||||
t_stack_head head;
|
||||
|
||||
head = (t_stack_head){
|
||||
.node = node,
|
||||
.node_count_at_last_error = \
|
||||
self->heads.contents[original_version].node_count_at_last_error,
|
||||
.last_external_token = \
|
||||
self->heads.contents[original_version].last_external_token,
|
||||
.status = SStatusActive,
|
||||
.lookahead_when_paused = NULL,
|
||||
};
|
||||
array_push(&self->heads, head);
|
||||
stack_node_retain(node);
|
||||
if (head.last_external_token)
|
||||
(head.last_external_token->ref_count++);
|
||||
return ((t_stack_version)(self->heads.size - 1));
|
||||
}
|
||||
|
||||
void ts_stack__add_slice(t_stack *self, \
|
||||
t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees)
|
||||
{
|
||||
t_u32 i;
|
||||
t_stack_version version;
|
||||
t_stack_slice slice;
|
||||
|
||||
i = self->slices.size - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
version = self->slices.contents[i].version;
|
||||
if (self->heads.contents[version].node == node)
|
||||
{
|
||||
slice = (t_stack_slice){.subtrees = *subtrees, .version = version};
|
||||
array_insert(&self->slices, i + 1, slice);
|
||||
return ;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
version = ts_stack__add_version(self, original_version, node);
|
||||
slice = (t_stack_slice){.subtrees = *subtrees, .version = version};
|
||||
array_push(&self->slices, slice);
|
||||
}
|
||||
|
||||
void ts_stack_set_last_external_token(t_stack *self, t_stack_version version,
|
||||
t_subtree token)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
if (token)
|
||||
(token->ref_count++);
|
||||
if (head->last_external_token)
|
||||
ts_subtree_release(head->last_external_token);
|
||||
head->last_external_token = token;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs4.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:58:39 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:37:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
t_u32 ts_stack_version_count(const t_stack *self)
|
||||
{
|
||||
return (self->heads.size);
|
||||
}
|
||||
|
||||
t_state_id ts_stack_state(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->state);
|
||||
}
|
||||
|
||||
t_length ts_stack_position(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->position);
|
||||
}
|
||||
|
||||
t_subtree ts_stack_last_external_token(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->last_external_token);
|
||||
}
|
||||
|
||||
/// Get the number of nodes in the subtree, for the purpose of measuring
|
||||
/// how much progress has been made by a given version of the stack.
|
||||
//
|
||||
// Count intermediate error nodes even though they are not visible,
|
||||
// because a stack version's node count is used to check whether it
|
||||
// has made any progress since the last time it encountered an error.
|
||||
t_u32 stack__subtree_node_count(t_subtree subtree)
|
||||
{
|
||||
t_u32 count;
|
||||
|
||||
count = ts_subtree_visible_descendant_count(subtree);
|
||||
if (ts_subtree_visible(subtree))
|
||||
count++;
|
||||
if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat)
|
||||
count++;
|
||||
return (count);
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_iter.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:46:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:57:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void _set_stack_iter_vars(\
|
||||
t_stack *self, struct s_stack_iter_args *args)
|
||||
{
|
||||
t_stack_iterator new_iterator;
|
||||
t_stack_head *head;
|
||||
|
||||
array_clear(&self->slices);
|
||||
array_clear(&self->iterators);
|
||||
head = array_get(&self->heads, args->version);
|
||||
new_iterator = (t_stack_iterator){
|
||||
.node = head->node,
|
||||
.subtrees = vec_subtree_new(16, NULL),
|
||||
.subtree_count = 0,
|
||||
.is_pending = true,
|
||||
};
|
||||
if (args->goal_subtree_count >= 0)
|
||||
vec_subtree_reserve(&new_iterator.subtrees, \
|
||||
ts_subtree_alloc_size(args->goal_subtree_count) / sizeof(t_subtree));
|
||||
array_push(&self->iterators, new_iterator);
|
||||
}
|
||||
|
||||
bool _handle_pop_stop(\
|
||||
t_stack *self, struct s_stack_iter_args *args, \
|
||||
struct s_stack_iter_indexes *idx, t_stack_node **node)
|
||||
{
|
||||
t_stack_action action;
|
||||
t_stack_iterator *iterator;
|
||||
t_vec_subtree subtrees;
|
||||
|
||||
iterator = &self->iterators.contents[idx->i];
|
||||
*node = iterator->node;
|
||||
action = args->callback(args->payload, iterator);
|
||||
if (action & SActionPop)
|
||||
{
|
||||
subtrees = iterator->subtrees;
|
||||
if (action & SActionStop || (*node)->link_count == 0)
|
||||
ts_subtree_array_copy(subtrees, &subtrees);
|
||||
vec_subtree_reverse(&subtrees);
|
||||
ts_stack__add_slice(self, args->version, *node, &subtrees);
|
||||
}
|
||||
if (action & SActionStop || (*node)->link_count == 0)
|
||||
{
|
||||
if (!(action & SActionPop))
|
||||
ts_subtree_array_delete(&iterator->subtrees);
|
||||
(array_erase(&self->iterators, idx->i), idx->size--);
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void _stack_iter_misc(t_stack_link *link, t_stack_iterator **next_iterator, \
|
||||
struct s_stack_iter_args *args)
|
||||
{
|
||||
(*next_iterator)->node = link->node;
|
||||
if (link->subtree)
|
||||
{
|
||||
if (args->goal_subtree_count >= 0)
|
||||
{
|
||||
vec_subtree_push(&(*next_iterator)->subtrees, link->subtree);
|
||||
link->subtree->ref_count++;
|
||||
}
|
||||
if (!ts_subtree_extra(link->subtree))
|
||||
{
|
||||
(*next_iterator)->subtree_count++;
|
||||
if (!link->is_pending)
|
||||
(*next_iterator)->is_pending = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*next_iterator)->subtree_count++;
|
||||
(*next_iterator)->is_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _func(t_stack *self, \
|
||||
t_stack_link *link, \
|
||||
t_stack_iterator **next_iterator, \
|
||||
struct s_stack_iter_args *args, \
|
||||
t_stack_node **node, \
|
||||
struct s_stack_iter_indexes *idx)
|
||||
{
|
||||
t_stack_iterator current_iterator;
|
||||
|
||||
if (idx->j == (*node)->link_count)
|
||||
{
|
||||
*link = (*node)->links[0];
|
||||
*next_iterator = &self->iterators.contents[idx->i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->iterators.size >= MAX_ITERATOR_COUNT)
|
||||
{
|
||||
idx->j++;
|
||||
return ;
|
||||
}
|
||||
*link = (*node)->links[idx->j];
|
||||
current_iterator = self->iterators.contents[idx->i];
|
||||
array_push(&self->iterators, current_iterator);
|
||||
*next_iterator = array_back(&self->iterators);
|
||||
ts_subtree_array_copy((*next_iterator)->subtrees,
|
||||
&(*next_iterator)->subtrees);
|
||||
}
|
||||
_stack_iter_misc(link, next_iterator, args);
|
||||
idx->j++;
|
||||
}
|
||||
|
||||
t_stack_slice_array stack__iter(t_stack *self, struct s_stack_iter_args args)
|
||||
{
|
||||
t_stack_iterator *next_iterator;
|
||||
t_stack_link link;
|
||||
t_stack_node *node;
|
||||
struct s_stack_iter_indexes idx;
|
||||
|
||||
_set_stack_iter_vars(self, &args);
|
||||
while (self->iterators.size > 0)
|
||||
{
|
||||
idx.i = 0;
|
||||
idx.size = self->iterators.size;
|
||||
while (idx.i < idx.size)
|
||||
{
|
||||
if (_handle_pop_stop(self, &args, &idx, &node))
|
||||
continue ;
|
||||
idx.j = 1;
|
||||
while (idx.j <= node->link_count)
|
||||
_func(self, &link, &next_iterator, &args, &node, &idx);
|
||||
idx.i++;
|
||||
}
|
||||
}
|
||||
return (self->slices);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:47:47 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:48:13 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack *ts_stack_new(void)
|
||||
{
|
||||
t_stack *self;
|
||||
|
||||
self = mem_alloc(sizeof(*self));
|
||||
array_init(&self->heads);
|
||||
array_init(&self->slices);
|
||||
array_init(&self->iterators);
|
||||
array_reserve(&self->heads, 4);
|
||||
array_reserve(&self->slices, 4);
|
||||
array_reserve(&self->iterators, 4);
|
||||
self->base_node = stack_node_new(NULL, NULL, false, 1);
|
||||
ts_stack_clear(self);
|
||||
return (self);
|
||||
}
|
||||
|
||||
void ts_stack_delete(t_stack *self)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
i = 0;
|
||||
if (self->slices.contents)
|
||||
array_delete(&self->slices);
|
||||
if (self->iterators.contents)
|
||||
array_delete(&self->iterators);
|
||||
stack_node_release(self->base_node);
|
||||
while (i < self->heads.size)
|
||||
stack_head_delete(&self->heads.contents[i++]);
|
||||
array_clear(&self->heads);
|
||||
array_delete(&self->heads);
|
||||
mem_free(self);
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:50:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:57:27 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
void ts_stack_push(t_stack *self, struct s_stack_push_arg args)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_stack_node *new_node;
|
||||
|
||||
head = array_get(&self->heads, args.version);
|
||||
new_node = stack_node_new(\
|
||||
head->node, args.subtree, args.pending, args.state);
|
||||
if (!args.subtree)
|
||||
head->node_count_at_last_error = new_node->node_count;
|
||||
head->node = new_node;
|
||||
}
|
||||
|
||||
t_stack_action pop_count_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
t_u32 *goal_subtree_count;
|
||||
|
||||
goal_subtree_count = payload;
|
||||
if (iterator->subtree_count == *goal_subtree_count)
|
||||
{
|
||||
return (SActionPop | SActionStop);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SActionNone);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_count(t_stack *self, t_stack_version version,
|
||||
t_u32 count)
|
||||
{
|
||||
return (stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_count_callback, \
|
||||
&count, (int)count}));
|
||||
}
|
||||
|
||||
t_stack_action pop_pending_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
(void)payload;
|
||||
if (iterator->subtree_count >= 1)
|
||||
{
|
||||
if (iterator->is_pending)
|
||||
return (SActionPop | SActionStop);
|
||||
else
|
||||
return (SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_pending(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_slice_array pop;
|
||||
|
||||
pop = stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_pending_callback, NULL, 0});
|
||||
if (pop.size > 0)
|
||||
{
|
||||
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
||||
pop.contents[0].version = version;
|
||||
}
|
||||
return (pop);
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:54:26 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:59:43 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool ts_stack_merge(t_stack *self, t_stack_version version1,
|
||||
t_stack_version version2)
|
||||
{
|
||||
t_stack_head *head1;
|
||||
t_stack_head *head2;
|
||||
t_usize i;
|
||||
|
||||
if (!ts_stack_can_merge(self, version1, version2))
|
||||
return (false);
|
||||
head1 = &self->heads.contents[version1];
|
||||
head2 = &self->heads.contents[version2];
|
||||
i = 0;
|
||||
while (i < head2->node->link_count)
|
||||
stack_node_add_link(head1->node, head2->node->links[i++]);
|
||||
if (head1->node->state == ERROR_STATE)
|
||||
head1->node_count_at_last_error = head1->node->node_count;
|
||||
ts_stack_remove_version(self, version2);
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool ts_stack_can_merge(t_stack *self, t_stack_version version1,
|
||||
t_stack_version version2)
|
||||
{
|
||||
t_stack_head *head1;
|
||||
t_stack_head *head2;
|
||||
|
||||
head1 = &self->heads.contents[version1];
|
||||
head2 = &self->heads.contents[version2];
|
||||
return (head1->status == SStatusActive && head2->status == SStatusActive
|
||||
&& head1->node->state == head2->node->state
|
||||
&& head1->node->position.bytes == head2->node->position.bytes
|
||||
&& head1->node->error_cost == head2->node->error_cost
|
||||
&& ts_subtree_external_scanner_state_eq(head1->last_external_token,
|
||||
head2->last_external_token));
|
||||
}
|
||||
|
||||
void ts_stack_halt(t_stack *self, t_stack_version version)
|
||||
{
|
||||
array_get(&self->heads, version)->status = SStatusHalted;
|
||||
}
|
||||
|
||||
void ts_stack_pause(t_stack *self, t_stack_version version,
|
||||
t_subtree lookahead)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
head->status = SStatusPaused;
|
||||
head->lookahead_when_paused = lookahead;
|
||||
head->node_count_at_last_error = head->node->node_count;
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:00:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:26:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack_action pop_error_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
bool *found_error;
|
||||
|
||||
if (iterator->subtrees.len > 0)
|
||||
{
|
||||
found_error = payload;
|
||||
if (!*found_error
|
||||
&& ts_subtree_is_error(iterator->subtrees.buffer[0]))
|
||||
{
|
||||
*found_error = true;
|
||||
return (SActionPop | SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_vec_subtree ts_stack_pop_error(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_node *n;
|
||||
bool found_error;
|
||||
t_stack_slice_array pop;
|
||||
t_usize i;
|
||||
|
||||
n = array_get(&self->heads, version)->node;
|
||||
i = 0;
|
||||
while (i < n->link_count)
|
||||
{
|
||||
if (n->links[i].subtree && ts_subtree_is_error(n->links[i].subtree))
|
||||
{
|
||||
found_error = false;
|
||||
pop = stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_error_callback, &found_error, 1});
|
||||
if (pop.size > 0)
|
||||
{
|
||||
ts_stack_renumber_version(\
|
||||
self, pop.contents[0].version, version);
|
||||
return (pop.contents[0].subtrees);
|
||||
}
|
||||
break ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ((t_vec_subtree){NULL, 0, 0, NULL});
|
||||
}
|
||||
|
||||
t_stack_action pop_all_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
(void)payload;
|
||||
if (iterator->node->link_count == 0)
|
||||
return (SActionPop);
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_all(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_all_callback, NULL, 0}));
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_node.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:48:48 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:37:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void stack_node_retain(t_stack_node *self)
|
||||
{
|
||||
if (!self)
|
||||
return ;
|
||||
assert(self->ref_count > 0);
|
||||
self->ref_count++;
|
||||
assert(self->ref_count != 0);
|
||||
}
|
||||
|
||||
void _stack_node_release_inner(\
|
||||
t_stack_node **self, bool *continue_, t_stack_link *link)
|
||||
{
|
||||
t_stack_node *first_predecessor;
|
||||
t_usize i;
|
||||
|
||||
first_predecessor = NULL;
|
||||
if ((*self)->link_count > 0)
|
||||
{
|
||||
i = (*self)->link_count - 1;
|
||||
while (i > 0)
|
||||
{
|
||||
*link = (*self)->links[i];
|
||||
if (link->subtree)
|
||||
ts_subtree_release(link->subtree);
|
||||
stack_node_release(link->node);
|
||||
i--;
|
||||
}
|
||||
*link = (*self)->links[0];
|
||||
if (link->subtree)
|
||||
ts_subtree_release(link->subtree);
|
||||
first_predecessor = (*self)->links[0].node;
|
||||
}
|
||||
if (mem_free(*self), first_predecessor)
|
||||
{
|
||||
*self = first_predecessor;
|
||||
*continue_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void stack_node_release(t_stack_node *self)
|
||||
{
|
||||
t_stack_link link;
|
||||
bool continue_;
|
||||
|
||||
continue_ = true;
|
||||
while (continue_)
|
||||
{
|
||||
continue_ = false;
|
||||
self->ref_count--;
|
||||
if (self->ref_count > 0)
|
||||
return ;
|
||||
_stack_node_release_inner(&self, &continue_, &link);
|
||||
}
|
||||
}
|
||||
|
||||
void _node_new_from_previous(t_stack_node *node, t_stack_node *prev, \
|
||||
t_subtree subtree, bool is_pending)
|
||||
{
|
||||
node->link_count = prev != NULL;
|
||||
node->links[0] = (t_stack_link){prev, subtree, is_pending};
|
||||
node->position = prev->position;
|
||||
node->error_cost = prev->error_cost;
|
||||
node->dynamic_precedence = prev->dynamic_precedence;
|
||||
node->node_count = prev->node_count;
|
||||
if (subtree)
|
||||
{
|
||||
node->error_cost += ts_subtree_error_cost(subtree);
|
||||
node->position = length_add(node->position, ts_subtree_total_size(\
|
||||
subtree));
|
||||
node->node_count += stack__subtree_node_count(subtree);
|
||||
node->dynamic_precedence += ts_subtree_dynamic_precedence(subtree);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_node *stack_node_new(t_stack_node *prev,
|
||||
t_subtree subtree, bool is_pending, t_state_id state)
|
||||
{
|
||||
t_stack_node *node;
|
||||
|
||||
node = mem_alloc(sizeof(t_stack_node));
|
||||
*node = (typeof(*node)){.ref_count = 1, .link_count = 0, .state = state};
|
||||
if (prev != NULL)
|
||||
_node_new_from_previous(node, prev, subtree, is_pending);
|
||||
else
|
||||
{
|
||||
node->position = length_zero();
|
||||
node->error_cost = 0;
|
||||
}
|
||||
return (node);
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_summary.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:50:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:25:51 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack_action summarize_stack_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
t_summarize_stack_session *session;
|
||||
t_state_id state;
|
||||
t_u32 depth;
|
||||
t_stack_summary_entry entry;
|
||||
t_usize i;
|
||||
|
||||
session = payload;
|
||||
state = iterator->node->state;
|
||||
depth = iterator->subtree_count;
|
||||
if (depth > session->max_depth)
|
||||
return (SActionStop);
|
||||
i = session->summary->size - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
if (session->summary->contents == NULL)
|
||||
return (SActionNone);
|
||||
entry = session->summary->contents[i--];
|
||||
if (entry.depth < depth)
|
||||
break ;
|
||||
if (entry.depth == depth && entry.state == state)
|
||||
return (SActionNone);
|
||||
}
|
||||
array_push(session->summary, ((t_stack_summary_entry){\
|
||||
.position = iterator->node->position, .depth = depth, .state = state, }));
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
void ts_stack_record_summary(t_stack *self, t_stack_version version,
|
||||
t_u32 max_depth)
|
||||
{
|
||||
t_summarize_stack_session sess;
|
||||
t_stack_head *head;
|
||||
|
||||
sess = (t_summarize_stack_session){.summary = \
|
||||
mem_alloc(sizeof(t_stack_summary)), .max_depth = max_depth};
|
||||
array_init(sess.summary);
|
||||
stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, summarize_stack_callback, &sess, -1});
|
||||
head = &self->heads.contents[version];
|
||||
if (head->summary)
|
||||
{
|
||||
array_delete(head->summary);
|
||||
mem_free(head->summary);
|
||||
}
|
||||
head->summary = sess.summary;
|
||||
}
|
||||
|
||||
t_stack_summary *ts_stack_get_summary(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->summary);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_version.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:55:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:55:34 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void ts_stack_remove_version(t_stack *self, t_stack_version version)
|
||||
{
|
||||
stack_head_delete(array_get(&self->heads, version));
|
||||
array_erase(&self->heads, version);
|
||||
}
|
||||
|
||||
void ts_stack_renumber_version(t_stack *self, t_stack_version v1,
|
||||
t_stack_version v2)
|
||||
{
|
||||
t_stack_head *source_head;
|
||||
t_stack_head *target_head;
|
||||
|
||||
if (v1 == v2)
|
||||
return ;
|
||||
assert(v2 < v1);
|
||||
assert((t_u32)v1 < self->heads.size);
|
||||
source_head = &self->heads.contents[v1];
|
||||
target_head = &self->heads.contents[v2];
|
||||
if (target_head->summary && !source_head->summary)
|
||||
{
|
||||
source_head->summary = target_head->summary;
|
||||
target_head->summary = NULL;
|
||||
}
|
||||
stack_head_delete(target_head);
|
||||
*target_head = *source_head;
|
||||
array_erase(&self->heads, v1);
|
||||
}
|
||||
|
||||
void ts_stack_swap_versions(t_stack *self, t_stack_version v1,
|
||||
t_stack_version v2)
|
||||
{
|
||||
t_stack_head temporary_head;
|
||||
|
||||
temporary_head = self->heads.contents[v1];
|
||||
self->heads.contents[v1] = self->heads.contents[v2];
|
||||
self->heads.contents[v2] = temporary_head;
|
||||
}
|
||||
|
||||
t_stack_version ts_stack_copy_version(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
assert(version < self->heads.size);
|
||||
array_push(&self->heads, self->heads.contents[version]);
|
||||
head = array_back(&self->heads);
|
||||
stack_node_retain(head->node);
|
||||
if (head->last_external_token)
|
||||
(head->last_external_token->ref_count++);
|
||||
head->summary = NULL;
|
||||
return (self->heads.size - 1);
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_balance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 12:53:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:02:24 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/inner/ptypes.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
bool _subtree_compress_inner(\
|
||||
t_subtree *tree, t_symbol symbol, t_vec_subtree *stack)
|
||||
{
|
||||
t_subtree child[2];
|
||||
|
||||
if ((*tree)->ref_count > 1 || (*tree)->child_count < 2)
|
||||
return (true);
|
||||
child[0] = (ts_subtree_children(*tree)[0]);
|
||||
if (child[0]->child_count < 2 || child[0]->ref_count > 1
|
||||
|| child[0]->symbol != symbol)
|
||||
return (true);
|
||||
child[1] = (ts_subtree_children(child[0])[0]);
|
||||
if (child[1]->child_count < 2 || child[1]->ref_count > 1
|
||||
|| child[1]->symbol != symbol)
|
||||
return (true);
|
||||
ts_subtree_children(*tree)[0] = child[1];
|
||||
ts_subtree_children(child[0])[0] = ts_subtree_children(child[1])[\
|
||||
child[1]->child_count - 1];
|
||||
ts_subtree_children(child[1])[child[1]->child_count - 1] = (child[0]);
|
||||
vec_subtree_push(stack, *tree);
|
||||
*tree = child[1];
|
||||
return (false);
|
||||
}
|
||||
|
||||
void ts_subtree__compress(t_subtree self, t_u32 count,
|
||||
const t_language *language, t_vec_subtree *stack)
|
||||
{
|
||||
t_symbol symbol;
|
||||
t_subtree child[2];
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 initial_stack_size;
|
||||
|
||||
initial_stack_size = stack->len;
|
||||
tree = self;
|
||||
symbol = tree->symbol;
|
||||
i = 0;
|
||||
while (i++ < count)
|
||||
if (_subtree_compress_inner(&tree, symbol, stack))
|
||||
break ;
|
||||
while (stack->len > initial_stack_size)
|
||||
{
|
||||
vec_subtree_pop(stack, &tree);
|
||||
child[0] = (ts_subtree_children(tree)[0]);
|
||||
child[1] = (ts_subtree_children(child[0])[child[0]->child_count - 1]);
|
||||
ts_subtree_summarize_children(child[1], language);
|
||||
ts_subtree_summarize_children(child[0], language);
|
||||
ts_subtree_summarize_children(tree, language);
|
||||
}
|
||||
}
|
||||
|
||||
void _subtree_balance_repush(t_vec_subtree *tree_stack, t_subtree tree)
|
||||
{
|
||||
t_u32 i;
|
||||
t_subtree child;
|
||||
|
||||
i = 0;
|
||||
while (i < tree->child_count)
|
||||
{
|
||||
child = ts_subtree_children(tree)[i];
|
||||
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
|
||||
vec_subtree_push(tree_stack, child);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void _subtree_balance_inner(\
|
||||
const t_language *language, t_vec_subtree *tree_stack)
|
||||
{
|
||||
t_i64 repeat_delta;
|
||||
t_subtree child[2];
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 n;
|
||||
|
||||
if (vec_subtree_pop(tree_stack, &tree) && tree->repeat_depth > 0)
|
||||
{
|
||||
child[0] = ts_subtree_children(tree)[0];
|
||||
child[1] = ts_subtree_children(tree)[tree->child_count - 1];
|
||||
repeat_delta = (t_i64)ts_subtree_repeat_depth(child[0])
|
||||
- (t_i64)ts_subtree_repeat_depth(child[1]);
|
||||
if (repeat_delta > 0)
|
||||
{
|
||||
n = (t_u32)repeat_delta;
|
||||
i = n / 2;
|
||||
while (i > 0)
|
||||
{
|
||||
ts_subtree__compress(tree, i, language, tree_stack);
|
||||
n -= i;
|
||||
i /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
_subtree_balance_repush(tree_stack, tree);
|
||||
}
|
||||
|
||||
void ts_subtree_balance(t_subtree self, const t_language *language)
|
||||
{
|
||||
t_vec_subtree tree_stack;
|
||||
|
||||
tree_stack = vec_subtree_new(16, NULL);
|
||||
if (ts_subtree_child_count(self) > 0 && self->ref_count == 1)
|
||||
vec_subtree_push(&tree_stack, self);
|
||||
while (tree_stack.len > 0)
|
||||
_subtree_balance_inner(language, &tree_stack);
|
||||
vec_subtree_free(tree_stack);
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_funcs.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:36:10 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:06:16 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void _subtree_release_inner(t_vec_subtree *to_free)
|
||||
{
|
||||
t_usize i;
|
||||
t_subtree *children;
|
||||
t_subtree tree;
|
||||
|
||||
vec_subtree_pop(to_free, &tree);
|
||||
if (tree->child_count > 0)
|
||||
{
|
||||
children = ts_subtree_children(tree);
|
||||
i = 0;
|
||||
while (i < tree->child_count)
|
||||
{
|
||||
if (--(children[i])->ref_count == 0)
|
||||
vec_subtree_push(to_free, children[i]);
|
||||
i++;
|
||||
}
|
||||
mem_free(children);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tree->has_external_tokens)
|
||||
ts_external_scanner_state_delete(&tree->external_scanner_state);
|
||||
mem_free(tree);
|
||||
}
|
||||
}
|
||||
|
||||
void ts_subtree_release(t_subtree self)
|
||||
{
|
||||
t_vec_subtree to_free;
|
||||
|
||||
to_free = vec_subtree_new(16, NULL);
|
||||
if (--self->ref_count == 0)
|
||||
vec_subtree_push(&to_free, self);
|
||||
while (to_free.len > 0)
|
||||
_subtree_release_inner(&to_free);
|
||||
vec_subtree_free(to_free);
|
||||
}
|
||||
|
||||
int subtree_compare_func(t_subtree left, t_subtree right)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
if (ts_subtree_symbol(left) < ts_subtree_symbol(right))
|
||||
result = -1;
|
||||
else if (ts_subtree_symbol(right) < ts_subtree_symbol(left))
|
||||
result = 1;
|
||||
else if (ts_subtree_child_count(left) < ts_subtree_child_count(right))
|
||||
result = -1;
|
||||
else if (ts_subtree_child_count(right) < ts_subtree_child_count(left))
|
||||
result = 1;
|
||||
return (result);
|
||||
}
|
||||
|
||||
int ts_subtree_compare(t_subtree left, t_subtree right)
|
||||
{
|
||||
t_vec_subtree cmp_stack;
|
||||
t_i8 result;
|
||||
t_usize i;
|
||||
|
||||
result = 0;
|
||||
cmp_stack = vec_subtree_new(16, NULL);
|
||||
vec_subtree_push(&cmp_stack, (left));
|
||||
vec_subtree_push(&cmp_stack, (right));
|
||||
while (cmp_stack.len >= 2)
|
||||
{
|
||||
vec_subtree_pop(&cmp_stack, &left);
|
||||
vec_subtree_pop(&cmp_stack, &right);
|
||||
result = subtree_compare_func(left, right);
|
||||
if (result != 0)
|
||||
return (vec_subtree_free(cmp_stack), result);
|
||||
i = ts_subtree_child_count(left);
|
||||
while (i > 0)
|
||||
{
|
||||
vec_subtree_push(&cmp_stack, ts_subtree_children(left)[i - 1]);
|
||||
vec_subtree_push(&cmp_stack, ts_subtree_children(right)[i - 1]);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return (vec_subtree_free(cmp_stack), 0);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_last_external_token(t_subtree tree)
|
||||
{
|
||||
t_usize i;
|
||||
t_subtree child;
|
||||
|
||||
if (!ts_subtree_has_external_tokens(tree))
|
||||
return (NULL);
|
||||
while (tree->child_count > 0)
|
||||
{
|
||||
i = tree->child_count - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
child = ts_subtree_children(tree)[i];
|
||||
if (ts_subtree_has_external_tokens(child))
|
||||
{
|
||||
tree = child;
|
||||
break ;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return (tree);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:34:30 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 21:39:19 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void ts_subtree_set_symbol(t_subtree *self, t_symbol symbol,
|
||||
const t_language *language)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
|
||||
metadata = ts_language_symbol_metadata(language, symbol);
|
||||
(*self)->symbol = symbol;
|
||||
(*self)->named = metadata.named;
|
||||
(*self)->visible = metadata.visible;
|
||||
}
|
||||
|
||||
// Clone a subtree.
|
||||
t_subtree ts_subtree_clone(t_subtree self)
|
||||
{
|
||||
t_usize alloc_size;
|
||||
t_usize i;
|
||||
t_subtree *new_children;
|
||||
t_subtree *old_children;
|
||||
t_subtree_data *result;
|
||||
|
||||
alloc_size = ts_subtree_alloc_size(self->child_count);
|
||||
new_children = mem_alloc(alloc_size);
|
||||
old_children = ts_subtree_children(self);
|
||||
mem_copy(new_children, old_children, alloc_size);
|
||||
result = (t_subtree_data *)&new_children[self->child_count];
|
||||
i = 0;
|
||||
if (self->child_count > 0)
|
||||
{
|
||||
while (i < self->child_count)
|
||||
{
|
||||
new_children[i]->ref_count++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (self->has_external_tokens)
|
||||
result->external_scanner_state = \
|
||||
ts_external_scanner_state_copy(&self->external_scanner_state);
|
||||
result->ref_count = 1;
|
||||
return ((t_subtree)result);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_ensure_owner(t_subtree self)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_clone(self);
|
||||
ts_subtree_release(self);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_new.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:33:35 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:14:56 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
// Create a new parent node with the given children.
|
||||
//
|
||||
// This takes ownership of the children array.
|
||||
t_subtree ts_subtree_new_node(t_symbol symbol, t_vec_subtree *children, \
|
||||
t_u32 production_id, const t_language *language)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
bool fragile;
|
||||
t_subtree data;
|
||||
|
||||
metadata = ts_language_symbol_metadata(language, symbol);
|
||||
fragile = symbol == ts_builtin_sym_error
|
||||
|| symbol == ts_builtin_sym_error_repeat;
|
||||
vec_subtree_reserve(children, ts_subtree_alloc_size(children->len)
|
||||
/ sizeof(t_subtree));
|
||||
data = (void *)&children->buffer[children->len];
|
||||
*data = (t_subtree_data){.ref_count = 1, .symbol = symbol, .child_count = \
|
||||
children->len, .visible = metadata.visible, .named = metadata.named, \
|
||||
.has_changes = false, .has_external_scanner_state_change = false, \
|
||||
.fragile_left = fragile, .fragile_right = fragile, .is_keyword = false, \
|
||||
{{.visible_descendant_count = 0, .production_id = production_id, \
|
||||
.first_leaf = {.symbol = 0, .parse_state = 0}, }}};
|
||||
ts_subtree_summarize_children(data, language);
|
||||
return (data);
|
||||
}
|
||||
|
||||
// Create a new error node containing the given children.
|
||||
//
|
||||
// This node is treated as 'extra'. Its children are prevented from having
|
||||
// having any effect on the parse state.
|
||||
t_subtree ts_subtree_new_error_node(t_vec_subtree *children, bool extra,
|
||||
const t_language *language)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
|
||||
result->extra = extra;
|
||||
return (result);
|
||||
}
|
||||
|
||||
// Create a new 'missing leaf' node.
|
||||
//
|
||||
// This node is treated as 'extra'. Its children are prevented from having
|
||||
// having any effect on the parse state.
|
||||
t_subtree ts_subtree_new_missing_leaf(t_symbol symbol, t_length padding,
|
||||
t_u32 lookahead_bytes, const t_language *language)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_leaf((t_st_newleaf_args){\
|
||||
symbol, padding, length_zero(), lookahead_bytes, 0, \
|
||||
false, false, false, language});
|
||||
result->is_missing = true;
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_new_leaf(t_st_newleaf_args args)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
bool extra;
|
||||
t_subtree_data *data;
|
||||
|
||||
extra = args.symbol == ts_builtin_sym_end;
|
||||
metadata = ts_language_symbol_metadata(args.language, args.symbol);
|
||||
data = mem_alloc(sizeof(*data));
|
||||
*data = (t_subtree_data){.ref_count = 1, .padding = args.padding,
|
||||
.size = args.size, .lookahead_bytes = args.lookahead_bytes,
|
||||
.error_cost = 0, .child_count = 0,
|
||||
.symbol = args.symbol, .parse_state = args.parse_state,
|
||||
.visible = metadata.visible, .named = metadata.named, .extra = extra,
|
||||
.fragile_left = false, .fragile_right = false, .has_changes = false,
|
||||
.has_external_tokens = args.has_external_tokens,
|
||||
.has_external_scanner_state_change = false,
|
||||
.depends_on_column = args.depends_on_column, .is_missing = false,
|
||||
.is_keyword = args.is_keyword, {{.first_leaf = {.symbol = 0,
|
||||
.parse_state = 0}}}};
|
||||
return ((t_subtree)data);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_new_error(t_st_newerr_args args)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_leaf(\
|
||||
(t_st_newleaf_args){ts_builtin_sym_error, args.padding, \
|
||||
args.size, args.bytes_scanned, \
|
||||
args.parse_state, false, false, false, args.language});
|
||||
result->fragile_left = true;
|
||||
result->fragile_right = true;
|
||||
result->lookahead_char = args.lookahead_char;
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_summarize.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:35:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:31:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void _summarize_loop_inner1(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner2(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner3(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner4(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
|
||||
void _sumarize_end(t_subtree self, t_subtree *children)
|
||||
{
|
||||
t_subtree first_child;
|
||||
t_subtree last_child;
|
||||
|
||||
if (self->child_count > 0)
|
||||
{
|
||||
first_child = children[0];
|
||||
last_child = children[self->child_count - 1];
|
||||
self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
|
||||
self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
|
||||
if (ts_subtree_fragile_left(first_child))
|
||||
self->fragile_left = true;
|
||||
if (ts_subtree_fragile_right(last_child))
|
||||
self->fragile_right = true;
|
||||
if (self->child_count >= 2 && !self->visible && !self->named
|
||||
&& ts_subtree_symbol(first_child) == self->symbol)
|
||||
{
|
||||
if (ts_subtree_repeat_depth(first_child) > \
|
||||
ts_subtree_repeat_depth(last_child))
|
||||
self->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;
|
||||
else
|
||||
self->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct s_summarize_state _init_sumnarize_state(t_subtree self,
|
||||
const t_language *language)
|
||||
{
|
||||
struct s_summarize_state s;
|
||||
|
||||
s = (typeof(s)){};
|
||||
self->named_child_count = 0;
|
||||
self->visible_child_count = 0;
|
||||
self->error_cost = 0;
|
||||
self->repeat_depth = 0;
|
||||
self->visible_descendant_count = 0;
|
||||
self->has_external_tokens = false;
|
||||
self->depends_on_column = false;
|
||||
self->has_external_scanner_state_change = false;
|
||||
self->dynamic_precedence = 0;
|
||||
s.alias_sequence = \
|
||||
ts_language_alias_sequence(language, self->production_id);
|
||||
s.structural_index = 0;
|
||||
s.lookahead_end_byte = 0;
|
||||
s.children = ts_subtree_children(self);
|
||||
s.i = 0;
|
||||
return (s);
|
||||
}
|
||||
|
||||
// Assign all of the node's properties that depend on its children.
|
||||
void ts_subtree_summarize_children(t_subtree self,
|
||||
const t_language *language)
|
||||
{
|
||||
struct s_summarize_state s;
|
||||
|
||||
s = _init_sumnarize_state(self, language);
|
||||
while (s.i < self->child_count)
|
||||
{
|
||||
_summarize_loop_inner1(self, language, &s);
|
||||
_summarize_loop_inner2(self, language, &s);
|
||||
_summarize_loop_inner3(self, language, &s);
|
||||
_summarize_loop_inner4(self, language, &s);
|
||||
}
|
||||
self->lookahead_bytes = s.lookahead_end_byte - self->size.bytes
|
||||
- self->padding.bytes;
|
||||
if (self->symbol == ts_builtin_sym_error
|
||||
|| self->symbol == ts_builtin_sym_error_repeat)
|
||||
self->error_cost += ERROR_COST_PER_RECOVERY
|
||||
+ ERROR_COST_PER_SKIPPED_CHAR * self->size.bytes
|
||||
+ ERROR_COST_PER_SKIPPED_LINE * self->size.extent.row;
|
||||
_sumarize_end(self, s.children);
|
||||
}
|
||||
|
|
@ -1,105 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_summarize_loop.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 14:30:15 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:33:33 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void _summarize_loop_inner1(t_subtree self,
|
||||
const t_language *language, struct s_summarize_state *s)
|
||||
{
|
||||
(void)(language);
|
||||
s->child = s->children[s->i];
|
||||
if (self->size.extent.row == 0 && ts_subtree_depends_on_column(s->child))
|
||||
self->depends_on_column = true;
|
||||
if (ts_subtree_has_external_scanner_state_change(s->child))
|
||||
self->has_external_scanner_state_change = true;
|
||||
if (s->i == 0)
|
||||
{
|
||||
self->padding = ts_subtree_padding(s->child);
|
||||
self->size = ts_subtree_size(s->child);
|
||||
}
|
||||
else
|
||||
self->size = length_add(self->size, ts_subtree_total_size(s->child));
|
||||
s->child_lookahead_end_byte = self->padding.bytes + self->size.bytes
|
||||
+ ts_subtree_lookahead_bytes(s->child);
|
||||
if (s->child_lookahead_end_byte > s->lookahead_end_byte)
|
||||
s->lookahead_end_byte = s->child_lookahead_end_byte;
|
||||
if (ts_subtree_symbol(s->child) != ts_builtin_sym_error_repeat)
|
||||
self->error_cost += ts_subtree_error_cost(s->child);
|
||||
s->grandchild_count = ts_subtree_child_count(s->child);
|
||||
}
|
||||
|
||||
void _summarize_loop_inner2(t_subtree self,
|
||||
const t_language *language, struct s_summarize_state *s)
|
||||
{
|
||||
(void)(language);
|
||||
if (self->symbol == ts_builtin_sym_error
|
||||
|| self->symbol == ts_builtin_sym_error_repeat)
|
||||
{
|
||||
if (!ts_subtree_extra(s->child) && !(ts_subtree_is_error(s->child)
|
||||
&& s->grandchild_count == 0))
|
||||
{
|
||||
if (ts_subtree_visible(s->child))
|
||||
self->error_cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
else if (s->grandchild_count > 0)
|
||||
self->error_cost += ERROR_COST_PER_SKIPPED_TREE
|
||||
* s->child->visible_child_count;
|
||||
}
|
||||
}
|
||||
self->dynamic_precedence += ts_subtree_dynamic_precedence(s->child);
|
||||
self->visible_descendant_count
|
||||
+= ts_subtree_visible_descendant_count(s->child);
|
||||
}
|
||||
|
||||
void _summarize_loop_inner3(t_subtree self,
|
||||
const t_language *language, struct s_summarize_state *s)
|
||||
{
|
||||
(void)(language);
|
||||
if (s->alias_sequence && s->alias_sequence[s->structural_index] != 0
|
||||
&& !ts_subtree_extra(s->child))
|
||||
{
|
||||
self->visible_descendant_count++;
|
||||
self->visible_child_count++;
|
||||
if (ts_language_symbol_metadata(language,
|
||||
s->alias_sequence[s->structural_index]).named)
|
||||
self->named_child_count++;
|
||||
}
|
||||
else if (ts_subtree_visible(s->child))
|
||||
{
|
||||
self->visible_descendant_count++;
|
||||
self->visible_child_count++;
|
||||
if (ts_subtree_named(s->child))
|
||||
self->named_child_count++;
|
||||
}
|
||||
else if (s->grandchild_count > 0)
|
||||
{
|
||||
self->visible_child_count += s->child->visible_child_count;
|
||||
self->named_child_count += s->child->named_child_count;
|
||||
}
|
||||
}
|
||||
|
||||
void _summarize_loop_inner4(t_subtree self,
|
||||
const t_language *language, struct s_summarize_state *s)
|
||||
{
|
||||
(void)(language);
|
||||
if (ts_subtree_has_external_tokens(s->child))
|
||||
self->has_external_tokens = true;
|
||||
if (ts_subtree_is_error(s->child))
|
||||
{
|
||||
self->fragile_left = true;
|
||||
self->fragile_right = true;
|
||||
self->parse_state = TS_TREE_STATE_NONE;
|
||||
}
|
||||
if (!ts_subtree_extra(s->child))
|
||||
s->structural_index++;
|
||||
s->i++;
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_vec_helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:28:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 21:42:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem.h"
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void ts_subtree_array_copy(t_vec_subtree self, t_vec_subtree *dest)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
dest->len = self.len;
|
||||
dest->capacity = self.capacity;
|
||||
dest->buffer = self.buffer;
|
||||
if (self.capacity > 0)
|
||||
{
|
||||
dest->buffer = mem_alloc_array(self.capacity, sizeof(t_subtree));
|
||||
mem_copy(dest->buffer, self.buffer, self.len * sizeof(t_subtree));
|
||||
i = 0;
|
||||
while (i < self.len)
|
||||
{
|
||||
dest->buffer[i]->ref_count++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ts_subtree_array_clear(t_vec_subtree *self)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
i = 0;
|
||||
while (i < self->len)
|
||||
ts_subtree_release(self->buffer[i++]);
|
||||
}
|
||||
|
||||
void ts_subtree_array_delete(t_vec_subtree *self)
|
||||
{
|
||||
ts_subtree_array_clear(self);
|
||||
vec_subtree_free(*self);
|
||||
}
|
||||
|
||||
void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self,
|
||||
t_vec_subtree *destination)
|
||||
{
|
||||
t_subtree last;
|
||||
|
||||
destination->len = 0;
|
||||
while (self->len > 0)
|
||||
{
|
||||
last = self->buffer[self->len - 1];
|
||||
if (ts_subtree_extra(last))
|
||||
{
|
||||
self->len--;
|
||||
vec_subtree_push(destination, last);
|
||||
}
|
||||
else
|
||||
break ;
|
||||
}
|
||||
vec_subtree_reverse(destination);
|
||||
}
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:40:05 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:40:09 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/subtree.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_tree *ts_tree_new(t_subtree root, const t_language *language)
|
||||
{
|
||||
t_tree *result;
|
||||
|
||||
result = mem_alloc(sizeof(*result));
|
||||
result->root = root;
|
||||
result->language = language;
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_tree *ts_tree_copy(const t_tree *self)
|
||||
{
|
||||
(self->root->ref_count++);
|
||||
return (ts_tree_new(self->root, self->language));
|
||||
}
|
||||
|
||||
void ts_tree_delete(t_tree *self)
|
||||
{
|
||||
if (self == NULL)
|
||||
return ;
|
||||
ts_subtree_release(self->root);
|
||||
mem_free(self);
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:40:17 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:41:01 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/subtree.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_node ts_tree_root_node(const t_tree *self)
|
||||
{
|
||||
return (ts_node_new(self, &self->root, ts_subtree_padding(self->root), 0));
|
||||
}
|
||||
|
||||
t_node ts_tree_root_node_with_offset(const t_tree *self, t_u32 offset_bytes,
|
||||
t_point offset_extent)
|
||||
{
|
||||
t_length offset;
|
||||
|
||||
offset = (t_length){offset_bytes, offset_extent};
|
||||
return (ts_node_new(self, &self->root, length_add(offset,
|
||||
ts_subtree_padding(self->root)), 0));
|
||||
}
|
||||
|
||||
const t_language *ts_tree_language(const t_tree *self)
|
||||
{
|
||||
return (self->language);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue