fix: fixed the script kiddy

This commit is contained in:
Raphael 2024-09-20 13:29:51 +02:00
parent cd87c06903
commit 9f55be8a7c
286 changed files with 0 additions and 37434 deletions

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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]);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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());
}

File diff suppressed because it is too large Load diff

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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';
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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());
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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}));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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)));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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);
}

View file

@ -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]);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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");
}
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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, }));
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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}));
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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++;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}