fix: fixed the script kiddy
This commit is contained in:
parent
cd87c06903
commit
9f55be8a7c
286 changed files with 0 additions and 37434 deletions
|
|
@ -1,164 +0,0 @@
|
|||
SRC_FILES = \
|
||||
alias_sequences/alias_sequences \
|
||||
create/create_parse_table \
|
||||
external_scanner_states/external_scanner_states \
|
||||
external_scanner_symbol_map/external_scanner_symbol_map \
|
||||
field_map_entries/field_map_entries \
|
||||
field_map_slices/field_map_slices \
|
||||
field_names/field_names \
|
||||
lex_modes/lex_modes \
|
||||
non_terminal_alias_map/non_terminal_alias_map \
|
||||
parse_actions_entries/parse_actions_entries \
|
||||
parse_table/parse_table_0 \
|
||||
parse_table/parse_table_1 \
|
||||
parse_table/parse_table_2 \
|
||||
parse_table/parse_table_3 \
|
||||
parse_table/parse_table_4 \
|
||||
parse_table/parse_table_5 \
|
||||
parse_table/parse_table_6 \
|
||||
parse_table/parse_table_7 \
|
||||
parse_table/parse_table_8 \
|
||||
parse_table/parse_table_9 \
|
||||
parse_table/parse_table_10 \
|
||||
parse_table/parse_table_11 \
|
||||
parse_table/parse_table_12 \
|
||||
parse_table/parse_table_13 \
|
||||
parse_table/parse_table_14 \
|
||||
parse_table/parse_table_15 \
|
||||
parse_table/parse_table_16 \
|
||||
parse_table/parse_table_17 \
|
||||
parse_table/parse_table_18 \
|
||||
parse_table/parse_table_19 \
|
||||
parse_table/parse_table_20 \
|
||||
parse_table/parse_table_21 \
|
||||
parse_table/parse_table_22 \
|
||||
parse_table/parse_table_23 \
|
||||
parse_table/parse_table_24 \
|
||||
parse_table/parse_table_25 \
|
||||
parse_table/parse_table_26 \
|
||||
parse_table/parse_table_27 \
|
||||
parse_table/parse_table_28 \
|
||||
parse_table/parse_table_29 \
|
||||
parse_table/parse_table_30 \
|
||||
parse_table/parse_table_31 \
|
||||
parse_table/parse_table_32 \
|
||||
parse_table/parse_table_33 \
|
||||
parse_table/parse_table_34 \
|
||||
parse_table/parse_table_35 \
|
||||
parse_table/parse_table_36 \
|
||||
parse_table/parse_table_37 \
|
||||
parse_table/parse_table_38 \
|
||||
parse_table/parse_table_39 \
|
||||
parse_table/parse_table_40 \
|
||||
parse_table/parse_table_41 \
|
||||
parse_table/parse_table_42 \
|
||||
parse_table/parse_table_43 \
|
||||
parse_table/parse_table_44 \
|
||||
parse_table/parse_table_45 \
|
||||
parse_table/parse_table_46 \
|
||||
parse_table/parse_table_47 \
|
||||
parse_table/parse_table_48 \
|
||||
parse_table/parse_table_49 \
|
||||
parse_table/parse_table_50 \
|
||||
parse_table/parse_table_51 \
|
||||
parse_table/parse_table_52 \
|
||||
parse_table/parse_table_53 \
|
||||
parse_table/parse_table_54 \
|
||||
parse_table/parse_table_55 \
|
||||
parse_table/parse_table_56 \
|
||||
parse_table/parse_table_57 \
|
||||
parse_table/parse_table_58 \
|
||||
parse_table/parse_table_59 \
|
||||
parse_table/parse_table_60 \
|
||||
parse_table/parse_table_61 \
|
||||
parse_table/parse_table_62 \
|
||||
parse_table/parse_table_63 \
|
||||
parse_table/parse_table_64 \
|
||||
parse_table/parse_table_65 \
|
||||
parse_table/parse_table_66 \
|
||||
parse_table/parse_table_67 \
|
||||
parse_table/parse_table_68 \
|
||||
parse_table/parse_table_69 \
|
||||
parse_table/parse_table_70 \
|
||||
parse_table/parse_table_71 \
|
||||
parse_table/parse_table_72 \
|
||||
parse_table/parse_table_73 \
|
||||
parse_table/parse_table_74 \
|
||||
parse_table/parse_table_75 \
|
||||
parse_table/parse_table_76 \
|
||||
parse_table/parse_table_77 \
|
||||
parse_table/parse_table_78 \
|
||||
parse_table/parse_table_79 \
|
||||
parse_table/parse_table_80 \
|
||||
parse_table/parse_table_81 \
|
||||
parse_table/parse_table_82 \
|
||||
parse_table/parse_table_83 \
|
||||
parse_table/parse_table_84 \
|
||||
parse_table/parse_table_85 \
|
||||
parse_table/parse_table_86 \
|
||||
parse_table/parse_table_87 \
|
||||
parse_table/parse_table_88 \
|
||||
parse_table/parse_table_89 \
|
||||
parse_table/parse_table_90 \
|
||||
parse_table/parse_table_91 \
|
||||
parse_table/parse_table_92 \
|
||||
parse_table/parse_table_93 \
|
||||
parse_table/parse_table_94 \
|
||||
parse_table/parse_table_95 \
|
||||
parse_table/parse_table_96 \
|
||||
parse_table/parse_table_97 \
|
||||
parse_table/parse_table_98 \
|
||||
parse_table/parse_table_99 \
|
||||
parse_table/parse_table_100 \
|
||||
parse_table/parse_table_101 \
|
||||
parse_table/parse_table_102 \
|
||||
parse_table/parse_table_103 \
|
||||
parse_table/parse_table_104 \
|
||||
parse_table/parse_table_105 \
|
||||
parse_table/parse_table_106 \
|
||||
parse_table/parse_table_107 \
|
||||
parse_table/parse_table_108 \
|
||||
parse_table/parse_table_109 \
|
||||
parse_table/parse_table_110 \
|
||||
parse_table/parse_table_111 \
|
||||
parse_table/parse_table_112 \
|
||||
parse_table/parse_table_113 \
|
||||
parse_table/parse_table_114 \
|
||||
parse_table/parse_table_115 \
|
||||
parse_table/parse_table_116 \
|
||||
parse_table/parse_table_117 \
|
||||
parse_table/parse_table_118 \
|
||||
parse_table/parse_table_119 \
|
||||
parse_table/parse_table_120 \
|
||||
parse_table/parse_table_121 \
|
||||
parse_table/parse_table_122 \
|
||||
parse_table/parse_table_123 \
|
||||
parse_table/parse_table_124 \
|
||||
parse_table/parse_table_125 \
|
||||
parse_table/parse_table_126 \
|
||||
parse_table/parse_table_127 \
|
||||
parse_table/parse_table_128 \
|
||||
parse_table/parse_table_129 \
|
||||
parse_table/parse_table_130 \
|
||||
parse_table/parse_table_131 \
|
||||
parse_table/parse_table_132 \
|
||||
parse_table/parse_table_133 \
|
||||
parse_table/parse_table_134 \
|
||||
parse_table/parse_table_135 \
|
||||
parse_table/parse_table_136 \
|
||||
parse_table/parse_table_137 \
|
||||
parse_table/parse_table_138 \
|
||||
parse_table/parse_table_139 \
|
||||
parse_table/parse_table_140 \
|
||||
parse_table/parse_table_141 \
|
||||
parse_table/parse_table_142 \
|
||||
parse_table/parse_table_143 \
|
||||
parse_table/parse_table_144 \
|
||||
parse_table/parse_table_145 \
|
||||
parse_table/parse_table_146 \
|
||||
parse_table/parse_table_147 \
|
||||
primary_state_ids/primary_state_ids \
|
||||
symbols_metadata/symbols_metadata \
|
||||
symbols_names/symbols_names \
|
||||
unique_symbols_map/unique_symbols_map \
|
||||
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
SRC_FILES = \
|
||||
language/language_field \
|
||||
language/language_getters \
|
||||
language/language_getters2 \
|
||||
language/language_misc \
|
||||
language/language_symbol \
|
||||
language/language_symbol2 \
|
||||
length/length_funcs1 \
|
||||
length/length_funcs2 \
|
||||
lex \
|
||||
lexer/lexer_advance \
|
||||
lexer/lexer_chunk \
|
||||
lexer/lexer_end \
|
||||
lexer/lexer_get_column \
|
||||
lexer/lexer_goto \
|
||||
lexer/lexer_lifetime \
|
||||
lexer/lexer_lookahead \
|
||||
misc/create_language \
|
||||
misc/external_scanner_state \
|
||||
misc/external_scanner_state2 \
|
||||
misc/input \
|
||||
misc/reduce_action \
|
||||
node/node_child \
|
||||
node/node_child_inner \
|
||||
node/node_constructor \
|
||||
node/node_fields \
|
||||
node/node_getter_funcs1 \
|
||||
node/node_getter_funcs2 \
|
||||
node/node_getter_funcs3 \
|
||||
node/node_iterator \
|
||||
node/node_relevent \
|
||||
parser/parser_accept \
|
||||
parser/parser_advance \
|
||||
parser/parser_advance_bis \
|
||||
parser/parser_breakdown_top_of_stack \
|
||||
parser/parser_condense_stack \
|
||||
parser/parser_do_reduction \
|
||||
parser/parser_external_scanner \
|
||||
parser/parser_handle_error \
|
||||
parser/parser_lex \
|
||||
parser/parser_lifetime \
|
||||
parser/parser_outstanding_parse \
|
||||
parser/parser_parse \
|
||||
parser/parser_parse_str \
|
||||
parser/parser_recover \
|
||||
parser/parser_recover_to_tree \
|
||||
parser/parser_reduce \
|
||||
parser/parser_select \
|
||||
parser/parser_shift \
|
||||
parser/parser_versions \
|
||||
point/point_funcs1 \
|
||||
point/point_funcs2 \
|
||||
scanner/helper \
|
||||
scanner/scan \
|
||||
scanner/scanner \
|
||||
scanner/serialize \
|
||||
scanner/tree_sitter \
|
||||
stack/stack_add_link \
|
||||
stack/stack_funcs1 \
|
||||
stack/stack_funcs2 \
|
||||
stack/stack_funcs3 \
|
||||
stack/stack_funcs4 \
|
||||
stack/stack_iter \
|
||||
stack/stack_lifetime \
|
||||
stack/stack_manipulate \
|
||||
stack/stack_manipulate2 \
|
||||
stack/stack_manipulate3 \
|
||||
stack/stack_node \
|
||||
stack/stack_summary \
|
||||
stack/stack_version \
|
||||
subtree/subtree_balance \
|
||||
subtree/subtree_funcs \
|
||||
subtree/subtree_helper \
|
||||
subtree/subtree_new \
|
||||
subtree/subtree_summarize \
|
||||
subtree/subtree_summarize_loop \
|
||||
subtree/subtree_vec_helper \
|
||||
tree/tree_funcs1 \
|
||||
tree/tree_funcs2 \
|
||||
|
||||
GEN_FILES = \
|
||||
\
|
||||
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
# **************************************************************************** #
|
||||
# #
|
||||
# ::: :::::::: #
|
||||
# Grammar.mk :+: :+: :+: #
|
||||
# +:+ +:+ +:+ #
|
||||
# By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ #
|
||||
# +#+#+#+#+#+ +#+ #
|
||||
# Created: 2023/11/03 13:20:01 by maiboyer #+# #+# #
|
||||
# Updated: 2024/08/02 18:57:50 by maiboyer ### ########.fr #
|
||||
# #
|
||||
# **************************************************************************** #
|
||||
|
||||
ANAME = gmr
|
||||
|
||||
BUILD_DIR = ../build
|
||||
SRC_DIR = ./static
|
||||
|
||||
BONUS_FLAGS =
|
||||
NAME = lib$(ANAME).a
|
||||
LIB_NAME ?=
|
||||
TARGET = $(BUILD_DIR)/$(NAME)
|
||||
CC ?= cc
|
||||
CFLAGS = -Wall -Wextra -Werror -MMD -I./includes -I../includes -I../output/include
|
||||
CFLAGS += $(CFLAGS_ADDITIONAL)
|
||||
|
||||
-include Filelist.$(ANAME).mk
|
||||
|
||||
SRC = $(addsuffix .c,$(addprefix $(SRC_DIR)/,$(SRC_FILES)))
|
||||
OBJ = $(addsuffix .o,$(addprefix $(BUILD_DIR)/$(ANAME)/,$(SRC_FILES)))
|
||||
DEPS = $(addsuffix .d,$(addprefix $(BUILD_DIR)/$(ANAME)/,$(SRC_FILES)))
|
||||
|
||||
INCLUDES =
|
||||
|
||||
GREEN = \033[32m
|
||||
GREY = \033[0;90m
|
||||
RED = \033[0;31m
|
||||
GOLD = \033[38;5;220m
|
||||
END = \033[0m
|
||||
|
||||
.PHONY: all clean fclean re
|
||||
|
||||
all: $(NAME)
|
||||
|
||||
$(NAME): $(TARGET)
|
||||
|
||||
$(TARGET): $(OBJ)
|
||||
@echo -e '$(GREY) Linking \t$(END)$(GOLD)$(NAME)$(END)'
|
||||
@ar rcs $(BUILD_DIR)/$(NAME) $(OBJ)
|
||||
|
||||
$(BUILD_DIR)/$(ANAME)/%.o: $(SRC_DIR)/%.c
|
||||
@mkdir -p $(dir $@)
|
||||
@echo -e '$(GREY) Building\t$(END)$(GREEN)$<$(END)'
|
||||
@$(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@
|
||||
|
||||
clean:
|
||||
@- $(foreach LIB,$(LIBS), \
|
||||
make clean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\
|
||||
)
|
||||
$(if $(LIB_NAME),,\
|
||||
rm -rf $(BUILD_DIR) \
|
||||
)
|
||||
|
||||
fclean: clean
|
||||
@- $(foreach LIB,$(LIBS), \
|
||||
make fclean LIB_NAME=$(LIB)/ BUILD_DIR=$(realpath $(BUILD_DIR)) -C $(LIB) --no-print-directory || true;\
|
||||
)
|
||||
rm -f $(BUILD_DIR)/$(NAME)
|
||||
|
||||
re:
|
||||
@$(MAKE) --no-print-directory fclean
|
||||
@$(MAKE) --no-print-directory all
|
||||
|
||||
build_filelist:
|
||||
@rm -f Filelist.$(ANAME).mk
|
||||
@printf '%-78s\\\n' "SRC_FILES =" > Filelist.$(ANAME).mk
|
||||
@tree static -ifF | rg 'static/(.*)\.c$$' --replace '$$1' | sed -re 's/^(.*)_([0-9]+)$$/\1|\2/g' | sort -t'|' --key=1,1 --key=2,2n | sed -e's/|/_/' | xargs printf '%-78s\\\n' >> Filelist.$(ANAME).mk
|
||||
@echo "" >> Filelist.$(ANAME).mk
|
||||
@echo -e '$(GREY) Populating $(GREEN) Filelist.$(ANAME).mk$(END)'
|
||||
|
||||
%.h: ;
|
||||
|
||||
-include $(DEPS)
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
clang -Wno-unused-command-line-argument -Xclang -ast-dump=json ./lib.c -fsyntax-only -ferror-limit=99999 |
|
||||
jq '.inner[] | select(.name) | select((.name | startswith("_"))| not)' |
|
||||
jq 'select((.kind == "VarDecl" or .kind == "FunctionDecl") | not)' |
|
||||
jq 'walk(if type == "object" then del(.loc, .id, .range, .typeAliasDeclId, .isReferenced) else . end)' |
|
||||
jq 'select(.type?.qualType // .name // "" | startswith("_") | not) | select(.name // "" | endswith("_t") | not )' |
|
||||
jq -n '[inputs]'
|
||||
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* api.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/07/22 13:54:54 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:45:08 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef API_H
|
||||
#define API_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/length_inner.h"
|
||||
#include "parser/inner/point_inner.h"
|
||||
#include "parser/inner/subtree_inner.h"
|
||||
|
||||
#define ERROR_STATE 0
|
||||
#define ERROR_COST_PER_RECOVERY 500
|
||||
#define ERROR_COST_PER_MISSING_TREE 110
|
||||
#define ERROR_COST_PER_SKIPPED_TREE 100
|
||||
#define ERROR_COST_PER_SKIPPED_LINE 30
|
||||
#define ERROR_COST_PER_SKIPPED_CHAR 1
|
||||
|
||||
#define TREE_SITTER_LANGUAGE_VERSION 14
|
||||
#define TREE_SITTER_MIN_COMPATIBLE_LANGUAGE_VERSION 13
|
||||
|
||||
t_tree *ts_tree_copy(const t_tree *self);
|
||||
void ts_tree_delete(t_tree *self);
|
||||
t_node ts_tree_root_node(const t_tree *self);
|
||||
t_node ts_tree_root_node_with_offset(const t_tree *self, t_u32 offset_bytes, t_point offset_extent);
|
||||
const t_language *ts_tree_language(const t_tree *self);
|
||||
|
||||
t_const_str ts_node_type(t_node self);
|
||||
t_symbol ts_node_symbol(t_node self);
|
||||
const t_language *ts_node_language(t_node self);
|
||||
t_symbol ts_node_grammar_symbol(t_node self);
|
||||
t_u32 ts_node_start_byte(t_node self);
|
||||
t_point ts_node_start_point(t_node self);
|
||||
t_u32 ts_node_end_byte(t_node self);
|
||||
t_point ts_node_end_point(t_node self);
|
||||
char *ts_node_string(t_node self);
|
||||
bool ts_node_is_null(t_node self);
|
||||
bool ts_node_is_named(t_node self);
|
||||
bool ts_node_is_missing(t_node self);
|
||||
bool ts_node_is_extra(t_node self);
|
||||
bool ts_node_has_changes(t_node self);
|
||||
bool ts_node_has_error(t_node self);
|
||||
bool ts_node_is_error(t_node self);
|
||||
t_state_id ts_node_parse_state(t_node self);
|
||||
t_state_id ts_node_next_parse_state(t_node self);
|
||||
t_node ts_node_parent(t_node self);
|
||||
t_node ts_node_child_containing_descendant(t_node self, t_node descendant);
|
||||
t_node ts_node_child(t_node self, t_u32 child_index);
|
||||
t_const_str ts_node_field_name_for_child(t_node self, t_u32 child_index);
|
||||
t_field_id ts_node_field_id_for_child(t_node self, t_u32 child_index);
|
||||
t_u32 ts_node_child_count(t_node self);
|
||||
t_node ts_node_named_child(t_node self, t_u32 child_index);
|
||||
t_u32 ts_node_named_child_count(t_node self);
|
||||
t_node ts_node_child_by_field_name(t_node self, t_const_str name, t_u32 name_length);
|
||||
t_node ts_node_child_by_field_id(t_node self, t_field_id field_id);
|
||||
t_node ts_node_next_sibling(t_node self);
|
||||
t_node ts_node_prev_sibling(t_node self);
|
||||
t_node ts_node_next_named_sibling(t_node self);
|
||||
t_node ts_node_prev_named_sibling(t_node self);
|
||||
t_node ts_node_first_child_for_byte(t_node self, t_u32 byte);
|
||||
t_node ts_node_first_named_child_for_byte(t_node self, t_u32 byte);
|
||||
t_u32 ts_node_descendant_count(t_node self);
|
||||
t_node ts_node_descendant_for_byte_range(t_node self, t_u32 start, t_u32 end);
|
||||
t_node ts_node_descendant_for_point_range(t_node self, t_point start, t_point end);
|
||||
t_node ts_node_named_descendant_for_byte_range(t_node self, t_u32 start, t_u32 end);
|
||||
t_node ts_node_named_descendant_for_point_range(t_node self, t_point start, t_point end);
|
||||
bool ts_node_eq(t_node self, t_node other);
|
||||
|
||||
const t_language *ts_language_copy(const t_language *self);
|
||||
void ts_language_delete(const t_language *self);
|
||||
t_u32 ts_language_symbol_count(const t_language *self);
|
||||
t_u32 ts_language_state_count(const t_language *self);
|
||||
t_const_str ts_language_symbol_name(const t_language *self, t_symbol symbol);
|
||||
t_symbol ts_language_symbol_for_name(const t_language *self, t_const_str string, t_u32 length, bool is_named);
|
||||
t_u32 ts_language_field_count(const t_language *self);
|
||||
t_const_str ts_language_field_name_for_id(const t_language *self, t_field_id id);
|
||||
t_field_id ts_language_field_id_for_name(const t_language *self, t_const_str name, t_u32 name_length);
|
||||
t_symbol_type ts_language_symbol_type(const t_language *self, t_symbol symbol);
|
||||
t_u32 ts_language_version(const t_language *self);
|
||||
t_state_id ts_language_next_state(const t_language *self, t_state_id state, t_symbol symbol);
|
||||
|
||||
#endif // TREE_SITTER_API_H_
|
||||
|
|
@ -1,275 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* array.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:22 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 21:15:05 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef TREE_SITTER_ARRAY_H_
|
||||
#define TREE_SITTER_ARRAY_H_
|
||||
|
||||
#include "me/types.h"
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "me/mem/mem.h"
|
||||
|
||||
#define Array(T) \
|
||||
struct \
|
||||
{ \
|
||||
T *contents; \
|
||||
t_u32 size; \
|
||||
t_u32 capacity; \
|
||||
}
|
||||
|
||||
/// Initialize an array.
|
||||
#define array_init(self) ((self)->size = 0, (self)->capacity = 0, (self)->contents = NULL)
|
||||
|
||||
/// Create an empty array.
|
||||
#define array_new() {NULL, 0, 0}
|
||||
|
||||
/// Get a pointer to the element at a given `index` in the array.
|
||||
#define array_get(self, _index) (assert((t_u32)(_index) < (self)->size), &(self)->contents[_index])
|
||||
|
||||
/// Get a pointer to the first element in the array.
|
||||
#define array_front(self) array_get(self, 0)
|
||||
|
||||
/// Get a pointer to the last element in the array.
|
||||
#define array_back(self) array_get(self, (self)->size - 1)
|
||||
|
||||
/// Clear the array, setting its size to zero. Note that this does not free any
|
||||
/// memory allocated for the array's contents.
|
||||
#define array_clear(self) ((self)->size = 0)
|
||||
|
||||
/// Reserve `new_capacity` elements of space in the array. If `new_capacity` is
|
||||
/// less than the array's current capacity, this function has no effect.
|
||||
#define array_reserve(self, new_capacity) _array__reserve((Array *)(self), array_elem_size(self), new_capacity)
|
||||
|
||||
/// Free any memory allocated for this array. Note that this does not free any
|
||||
/// memory allocated for the array's contents.
|
||||
#define array_delete(self) _array__delete((Array *)(self))
|
||||
|
||||
/// Push a new `element` onto the end of the array.
|
||||
#define array_push(self, element) (_array__grow((Array *)(self), 1, array_elem_size(self)), (self)->contents[(self)->size++] = (element))
|
||||
|
||||
/// Increase the array's size by `count` elements.
|
||||
/// New elements are zero-initialized.
|
||||
#define array_grow_by(self, count) \
|
||||
do \
|
||||
{ \
|
||||
if ((count) == 0) \
|
||||
break; \
|
||||
_array__grow((Array *)(self), count, array_elem_size(self)); \
|
||||
memset((self)->contents + (self)->size, 0, (count) * array_elem_size(self)); \
|
||||
(self)->size += (count); \
|
||||
} while (0)
|
||||
|
||||
/// Append all elements from one array to the end of another.
|
||||
#define array_push_all(self, other) array_extend((self), (other)->size, (other)->contents)
|
||||
|
||||
/// Append `count` elements to the end of the array, reading their values from the
|
||||
/// `contents` pointer.
|
||||
#define array_extend(self, count, contents) _array__splice((Array *)(self), array_elem_size(self), (self)->size, 0, count, contents)
|
||||
|
||||
/// Remove `old_count` elements from the array starting at the given `index`. At
|
||||
/// the same index, insert `new_count` new elements, reading their values from the
|
||||
/// `new_contents` pointer.
|
||||
#define array_splice(self, _index, old_count, new_count, new_contents) \
|
||||
_array__splice((Array *)(self), array_elem_size(self), _index, old_count, new_count, new_contents)
|
||||
|
||||
/// Insert one `element` into the array at the given `index`.
|
||||
#define array_insert(self, _index, element) _array__splice((Array *)(self), array_elem_size(self), _index, 0, 1, &(element))
|
||||
|
||||
/// Remove one element from the array at the given `index`.
|
||||
#define array_erase(self, _index) _array__erase((Array *)(self), array_elem_size(self), _index)
|
||||
|
||||
/// Pop the last element off the array, returning the element by value.
|
||||
#define array_pop(self) ((self)->contents[--(self)->size])
|
||||
|
||||
/// Assign the contents of one array to another, reallocating if necessary.
|
||||
#define array_assign(self, other) _array__assign((Array *)(self), (const Array *)(other), array_elem_size(self))
|
||||
|
||||
/// Swap one array with another
|
||||
#define array_swap(self, other) _array__swap((Array *)(self), (Array *)(other))
|
||||
|
||||
/// Get the size of the array contents
|
||||
#define array_elem_size(self) (sizeof *(self)->contents)
|
||||
|
||||
/// Search a sorted array for a given `needle` value, using the given `compare`
|
||||
/// callback to determine the order.
|
||||
///
|
||||
/// If an existing element is found to be equal to `needle`, then the `index`
|
||||
/// out-parameter is set to the existing value's index, and the `exists`
|
||||
/// out-parameter is set to true. Otherwise, `index` is set to an index where
|
||||
/// `needle` should be inserted in order to preserve the sorting, and `exists`
|
||||
/// is set to false.
|
||||
#define array_search_sorted_with(self, compare, needle, _index, _exists) _array__search_sorted(self, 0, compare, , needle, _index, _exists)
|
||||
|
||||
/// Search a sorted array for a given `needle` value, using integer comparisons
|
||||
/// of a given struct field (specified with a leading dot) to determine the order.
|
||||
///
|
||||
/// See also `array_search_sorted_with`.
|
||||
#define array_search_sorted_by(self, field, needle, _index, _exists) \
|
||||
_array__search_sorted(self, 0, _compare_int, field, needle, _index, _exists)
|
||||
|
||||
/// Insert a given `value` into a sorted array, using the given `compare`
|
||||
/// callback to determine the order.
|
||||
#define array_insert_sorted_with(self, compare, value) \
|
||||
do \
|
||||
{ \
|
||||
t_u32 _index, _exists; \
|
||||
array_search_sorted_with(self, compare, &(value), &_index, &_exists); \
|
||||
if (!_exists) \
|
||||
array_insert(self, _index, value); \
|
||||
} while (0)
|
||||
|
||||
/// Insert a given `value` into a sorted array, using integer comparisons of
|
||||
/// a given struct field (specified with a leading dot) to determine the order.
|
||||
///
|
||||
/// See also `array_search_sorted_by`.
|
||||
#define array_insert_sorted_by(self, field, value) \
|
||||
do \
|
||||
{ \
|
||||
t_u32 _index, _exists; \
|
||||
array_search_sorted_by(self, field, (value)field, &_index, &_exists); \
|
||||
if (!_exists) \
|
||||
array_insert(self, _index, value); \
|
||||
} while (0)
|
||||
|
||||
// Private
|
||||
|
||||
typedef Array(void) Array;
|
||||
|
||||
/// This is not what you're looking for, see `array_delete`.
|
||||
static inline void _array__delete(Array *self)
|
||||
{
|
||||
if (self->contents)
|
||||
{
|
||||
mem_free(self->contents);
|
||||
self->contents = NULL;
|
||||
self->size = 0;
|
||||
self->capacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_erase`.
|
||||
static inline void _array__erase(Array *self, size_t element_size, t_u32 index)
|
||||
{
|
||||
assert(index < self->size);
|
||||
char *contents = (char *)self->contents;
|
||||
memmove(contents + index * element_size, contents + (index + 1) * element_size, (self->size - index - 1) * element_size);
|
||||
self->size--;
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_reserve`.
|
||||
static inline void _array__reserve(Array *self, size_t element_size, t_u32 new_capacity)
|
||||
{
|
||||
if (new_capacity > self->capacity)
|
||||
{
|
||||
if (self->contents)
|
||||
{
|
||||
self->contents = mem_realloc(self->contents, new_capacity * element_size);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->contents = mem_alloc(new_capacity * element_size);
|
||||
}
|
||||
self->capacity = new_capacity;
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_assign`.
|
||||
static inline void _array__assign(Array *self, const Array *other, size_t element_size)
|
||||
{
|
||||
_array__reserve(self, element_size, other->size);
|
||||
self->size = other->size;
|
||||
mem_copy(self->contents, other->contents, self->size * element_size);
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_swap`.
|
||||
static inline void _array__swap(Array *self, Array *other)
|
||||
{
|
||||
Array swap = *other;
|
||||
*other = *self;
|
||||
*self = swap;
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_push` or `array_grow_by`.
|
||||
static inline void _array__grow(Array *self, t_u32 count, size_t element_size)
|
||||
{
|
||||
t_u32 new_size = self->size + count;
|
||||
if (new_size > self->capacity)
|
||||
{
|
||||
t_u32 new_capacity = self->capacity * 2;
|
||||
if (new_capacity < 8)
|
||||
new_capacity = 8;
|
||||
if (new_capacity < new_size)
|
||||
new_capacity = new_size;
|
||||
_array__reserve(self, element_size, new_capacity);
|
||||
}
|
||||
}
|
||||
|
||||
/// This is not what you're looking for, see `array_splice`.
|
||||
static inline void _array__splice(Array *self, size_t element_size, t_u32 index, t_u32 old_count, t_u32 new_count, const void *elements)
|
||||
{
|
||||
char *contents;
|
||||
t_u32 new_size;
|
||||
t_u32 old_end;
|
||||
t_u32 new_end;
|
||||
|
||||
new_size = self->size + new_count - old_count;
|
||||
old_end = index + old_count;
|
||||
new_end = index + new_count;
|
||||
_array__reserve(self, element_size, new_size);
|
||||
contents = (char *)self->contents;
|
||||
if (self->size > old_end)
|
||||
mem_move(contents + new_end * element_size, contents + old_end * element_size, (self->size - old_end) * element_size);
|
||||
if (new_count > 0)
|
||||
{
|
||||
if (elements)
|
||||
mem_copy((contents + index * element_size), elements, new_count * element_size);
|
||||
else
|
||||
mem_set_zero((contents + index * element_size), new_count * element_size);
|
||||
}
|
||||
self->size += new_count - old_count;
|
||||
}
|
||||
|
||||
/// A binary search routine, based on Rust's `std::slice::binary_search_by`.
|
||||
/// This is not what you're looking for, see `array_search_sorted_with` or `array_search_sorted_by`.
|
||||
#define _array__search_sorted(self, start, compare, suffix, needle, _index, _exists) \
|
||||
do \
|
||||
{ \
|
||||
*(_index) = start; \
|
||||
*(_exists) = false; \
|
||||
t_u32 size = (self)->size - *(_index); \
|
||||
if (size == 0) \
|
||||
break; \
|
||||
int comparison; \
|
||||
while (size > 1) \
|
||||
{ \
|
||||
t_u32 half_size = size / 2; \
|
||||
t_u32 mid_index = *(_index) + half_size; \
|
||||
comparison = compare(&((self)->contents[mid_index] suffix), (needle)); \
|
||||
if (comparison <= 0) \
|
||||
*(_index) = mid_index; \
|
||||
size -= half_size; \
|
||||
} \
|
||||
comparison = compare(&((self)->contents[*(_index)] suffix), (needle)); \
|
||||
if (comparison == 0) \
|
||||
*(_exists) = true; \
|
||||
else if (comparison < 0) \
|
||||
*(_index) += 1; \
|
||||
} while (0)
|
||||
|
||||
/// Helper macro for the `_sorted_by` routines below. This takes the left (existing)
|
||||
/// parameter by reference in order to work with the generic sorting function above.
|
||||
#define _compare_int(a, b) ((int)*(a) - (int)(b))
|
||||
|
||||
#endif // TREE_SITTER_ARRAY_H_
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* external_scanner_state.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/24 13:56:34 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:54:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef EXTERNAL_SCANNER_STATE_H
|
||||
#define EXTERNAL_SCANNER_STATE_H
|
||||
|
||||
#include "me/types.h"
|
||||
|
||||
struct s_external_scanner_state
|
||||
{
|
||||
char *long_data;
|
||||
t_u32 length;
|
||||
};
|
||||
|
||||
typedef struct s_external_scanner_state t_external_scanner_state;
|
||||
typedef struct s_subtree_data t_subtree_data;
|
||||
typedef t_subtree_data *t_subtree;
|
||||
|
||||
bool ts_external_scanner_state_eq(const t_external_scanner_state *self, const t_u8 *buffer, t_u32 length);
|
||||
bool ts_subtree_external_scanner_state_eq(t_subtree self, t_subtree other);
|
||||
const t_external_scanner_state *ts_subtree_external_scanner_state(t_subtree self);
|
||||
const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *self);
|
||||
t_external_scanner_state ts_external_scanner_state_copy(const t_external_scanner_state *self);
|
||||
void ts_external_scanner_state_delete(t_external_scanner_state *self);
|
||||
void ts_external_scanner_state_init(t_external_scanner_state *self, const t_u8 *data, t_u32 length);
|
||||
|
||||
#endif /* EXTERNAL_SCANNER_STATE_H */
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:03:42 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 19:34:50 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LENGTH_INNER_H
|
||||
# define LENGTH_INNER_H
|
||||
|
||||
# include "me/types.h"
|
||||
# include "parser/inner/point_inner.h"
|
||||
|
||||
typedef struct s_length t_length;
|
||||
|
||||
struct s_length
|
||||
{
|
||||
t_u32 bytes;
|
||||
t_point extent;
|
||||
};
|
||||
|
||||
t_length length_add(t_length len1, t_length len2);
|
||||
t_length length_min(t_length len1, t_length len2);
|
||||
t_length length_saturating_sub(t_length len1, t_length len2);
|
||||
t_length length_sub(t_length len1, t_length len2);
|
||||
t_length length_zero(void);
|
||||
bool length_is_undefined(t_length length);
|
||||
|
||||
#endif /* LENGTH_INNER_H */
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:04:59 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 19:35:40 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef NODE_H
|
||||
# define NODE_H
|
||||
|
||||
# include "me/types.h"
|
||||
# include "parser/length.h"
|
||||
# include "parser/subtree.h"
|
||||
|
||||
typedef struct s_node_child_iterator NodeChildIterator;
|
||||
struct s_node_child_iterator
|
||||
{
|
||||
t_subtree parent;
|
||||
const t_tree *tree;
|
||||
t_length position;
|
||||
t_u32 child_index;
|
||||
t_u32 structural_child_index;
|
||||
const t_symbol *alias_sequence;
|
||||
};
|
||||
|
||||
NodeChildIterator ts_node_iterate_children(const t_node *node);
|
||||
t_field_id ts_node__field_id_from_language(t_node self, t_u32 structural_child_index);
|
||||
t_node ts_node__child(t_node self, t_u32 child_index, bool include_anonymous);
|
||||
t_node ts_node__null(void);
|
||||
bool ts_node__is_relevant(t_node self, bool include_anonymous);
|
||||
bool ts_node_child_iterator_done(NodeChildIterator *self);
|
||||
bool ts_node_child_iterator_next(NodeChildIterator *self, t_node *result);
|
||||
t_const_str ts_node__field_name_from_language(t_node self, t_u32 structural_child_index);
|
||||
t_u32 ts_node__relevant_child_count(t_node self, bool include_anonymous);
|
||||
t_subtree ts_node__subtree(t_node self);
|
||||
t_u32 ts_node__alias(const t_node *self);
|
||||
|
||||
#endif /* NODE_H */
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 13:56:47 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:10:08 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PARSER_INNER_H
|
||||
#define PARSER_INNER_H
|
||||
|
||||
#include "me/mem/mem.h"
|
||||
#include "me/types.h"
|
||||
#include "me/vec/vec_reduce_action.h"
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/array.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/length.h"
|
||||
#include "parser/lexer.h"
|
||||
#include "parser/reduce_action.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/subtree.h"
|
||||
#include "parser/tree.h"
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define MAX_VERSION_COUNT 40
|
||||
#define MAX_VERSION_COUNT_OVERFLOW 60
|
||||
#define MAX_SUMMARY_DEPTH 1
|
||||
#define MAX_COST_DIFFERENCE 16 * ERROR_COST_PER_SKIPPED_TREE
|
||||
|
||||
typedef enum e_error_comparison t_error_comparison;
|
||||
typedef struct s_error_status t_error_status;
|
||||
typedef struct s_string_input t_string_input;
|
||||
typedef struct s_parser t_parser;
|
||||
|
||||
struct s_parser
|
||||
{
|
||||
t_lexer lexer;
|
||||
t_stack *stack;
|
||||
const t_language *language;
|
||||
t_vec_reduce_action reduce_actions;
|
||||
t_subtree finished_tree;
|
||||
t_vec_subtree trailing_extras;
|
||||
t_vec_subtree trailing_extras2;
|
||||
t_vec_subtree scratch_trees;
|
||||
void *external_scanner_payload;
|
||||
t_u32 accept_count;
|
||||
t_u32 operation_count;
|
||||
bool has_scanner_error;
|
||||
};
|
||||
|
||||
struct s_error_status
|
||||
{
|
||||
t_u32 cost;
|
||||
t_u32 node_count;
|
||||
int dynamic_precedence;
|
||||
bool is_in_error;
|
||||
};
|
||||
|
||||
enum e_error_comparison
|
||||
{
|
||||
|
||||
ECTakeLeft,
|
||||
ECPreferLeft,
|
||||
ECNone,
|
||||
ECPreferRight,
|
||||
ECTakeRight,
|
||||
};
|
||||
|
||||
struct s_string_input
|
||||
{
|
||||
const t_u8 *string;
|
||||
t_u32 length;
|
||||
};
|
||||
|
||||
struct s_parser_advance_state
|
||||
{
|
||||
TSParseAction action;
|
||||
TableEntry table_entry;
|
||||
bool end_of_non_terminal_extra;
|
||||
bool is_fragile;
|
||||
bool needs_lex;
|
||||
t_stack_version last_reduction_version;
|
||||
t_stack_version reduction_version;
|
||||
t_state_id next_state;
|
||||
t_state_id state;
|
||||
t_subtree lookahead;
|
||||
t_subtree mutable_lookahead;
|
||||
t_u32 i;
|
||||
};
|
||||
|
||||
struct s_parser_parse_state
|
||||
{
|
||||
t_tree *result;
|
||||
t_u32 position;
|
||||
t_u32 last_position;
|
||||
t_u32 version_count;
|
||||
t_stack_version version;
|
||||
t_u32 min_error_cost;
|
||||
bool first;
|
||||
};
|
||||
|
||||
t_parser *ts_parser_new(t_language *language);
|
||||
t_tree *ts_parser_parse(t_parser *self, t_input input);
|
||||
t_tree *ts_parser_parse_string(t_parser *self, t_const_str string, t_u32 length);
|
||||
bool _parse_condition(t_parser *self, t_u32 *version_count, t_stack_version *version);
|
||||
bool ts_parser__advance(t_parser *self, t_stack_version version);
|
||||
bool ts_parser__better_version_exists(t_parser *self, t_stack_version version, bool is_in_error, t_u32 cost);
|
||||
bool ts_parser__breakdown_top_of_stack(t_parser *self, t_stack_version version);
|
||||
bool ts_parser__do_all_potential_reductions(t_parser *self, t_stack_version starting_version, t_symbol lookahead_symbol);
|
||||
bool ts_parser__external_scanner_scan(t_parser *self, t_state_id external_lex_state);
|
||||
bool ts_parser__recover_to_state(t_parser *self, t_stack_version version, t_u32 depth, t_state_id goal_state);
|
||||
bool ts_parser__select_children(t_parser *self, t_subtree left, const t_vec_subtree *children);
|
||||
bool ts_parser__select_tree(t_parser *self, t_subtree left, t_subtree right);
|
||||
bool ts_parser_has_outstanding_parse(t_parser *self);
|
||||
const t_u8 *ts_string_input_read(void *_self, t_u32 byte, t_point point, t_u32 *length);
|
||||
t_error_comparison ts_parser__compare_versions(t_parser *self, t_error_status a, t_error_status b);
|
||||
t_error_status ts_parser__version_status(t_parser *self, t_stack_version version);
|
||||
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_subtree ts_parser__lex(t_parser *self, t_stack_version version, t_state_id parse_state);
|
||||
t_u32 ts_parser__condense_stack(t_parser *self);
|
||||
t_u32 ts_parser__external_scanner_serialize(t_parser *self);
|
||||
void ts_parser__accept(t_parser *self, t_stack_version version, t_subtree lookahead);
|
||||
void ts_parser__external_scanner_create(t_parser *self);
|
||||
void ts_parser__external_scanner_deserialize(t_parser *self, t_subtree external_token);
|
||||
void ts_parser__external_scanner_destroy(t_parser *self);
|
||||
void ts_parser__handle_error(t_parser *self, t_stack_version version, t_subtree lookahead);
|
||||
void ts_parser__recover(t_parser *self, t_stack_version version, t_subtree lookahead);
|
||||
void ts_parser__shift(t_parser *self, t_stack_version version, t_state_id state, t_subtree lookahead, bool extra);
|
||||
void ts_parser_delete(t_parser *self);
|
||||
void ts_parser_reset(t_parser *self);
|
||||
|
||||
#endif /* PARSER_INNER_H */
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:05:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:38:38 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef POINT_INNER_H
|
||||
#define POINT_INNER_H
|
||||
|
||||
#include "me/types.h"
|
||||
|
||||
typedef struct s_point t_point;
|
||||
|
||||
struct s_point
|
||||
{
|
||||
t_u32 row;
|
||||
t_u32 column;
|
||||
};
|
||||
|
||||
t_point point__new(t_u32 row, t_u32 column);
|
||||
t_point point_add(t_point a, t_point b);
|
||||
t_point point_max(t_point a, t_point b);
|
||||
t_point point_min(t_point a, t_point b);
|
||||
t_point point_sub(t_point a, t_point b);
|
||||
bool point_eq(t_point a, t_point b);
|
||||
bool point_gt(t_point a, t_point b);
|
||||
bool point_gte(t_point a, t_point b);
|
||||
bool point_lt(t_point a, t_point b);
|
||||
bool point_lte(t_point a, t_point b);
|
||||
|
||||
|
||||
#endif /* POINT_INNER_H */
|
||||
|
|
@ -1,58 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* ptypes.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:08:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:45:06 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PTYPES_H
|
||||
#define PTYPES_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/length_inner.h"
|
||||
#include "parser/inner/point_inner.h"
|
||||
|
||||
typedef t_u16 t_state_id;
|
||||
typedef t_u16 t_symbol;
|
||||
typedef t_u16 t_field_id;
|
||||
typedef struct s_language t_language;
|
||||
typedef struct s_parser t_parser;
|
||||
typedef struct s_tree t_tree;
|
||||
|
||||
typedef enum e_symbol_type
|
||||
{
|
||||
t_symbol_typeRegular,
|
||||
t_symbol_typeAnonymous,
|
||||
t_symbol_typeAuxiliary,
|
||||
} t_symbol_type;
|
||||
|
||||
typedef struct s_srange
|
||||
{
|
||||
t_point start_point;
|
||||
t_point end_point;
|
||||
t_u32 start_byte;
|
||||
t_u32 end_byte;
|
||||
} t_range;
|
||||
|
||||
typedef struct s_input
|
||||
{
|
||||
void *payload;
|
||||
const t_u8 *(*read)(void *payload, t_u32 byte_index, t_point position, t_u32 *bytes_read);
|
||||
} t_input;
|
||||
|
||||
typedef struct s_node
|
||||
{
|
||||
t_u32 start_byte;
|
||||
t_u32 start_row;
|
||||
t_u32 start_col;
|
||||
t_u32 alias;
|
||||
const void *id;
|
||||
const t_tree *tree;
|
||||
} t_node;
|
||||
|
||||
#endif /* PTYPES_H */
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* reduce_action_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/06 16:56:42 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/06 16:57:13 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef REDUCE_ACTION_INNER_H
|
||||
#define REDUCE_ACTION_INNER_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/ptypes.h"
|
||||
|
||||
struct s_reduce_action
|
||||
{
|
||||
t_u32 count;
|
||||
t_symbol symbol;
|
||||
int dynamic_precedence;
|
||||
t_u16 production_id;
|
||||
};
|
||||
typedef struct s_reduce_action t_reduce_action;
|
||||
|
||||
#endif /* REDUCE_ACTION_INNER_H */
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scanner_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 13:57:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/15 20:26:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef SCANNER_INNER_H
|
||||
#define SCANNER_INNER_H
|
||||
|
||||
#include "me/char/char.h"
|
||||
#include "me/mem/mem.h"
|
||||
#include "me/str/str.h"
|
||||
#include "me/string/string.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
typedef struct s_heredoc t_heredoc;
|
||||
typedef struct s_scanner t_scanner;
|
||||
|
||||
enum e_token_type
|
||||
{
|
||||
FILE_DESCRIPTOR,
|
||||
EMPTY_VALUE,
|
||||
CONCAT,
|
||||
VARIABLE_NAME,
|
||||
REGEX,
|
||||
EXPANSION_WORD,
|
||||
EXTGLOB_PATTERN,
|
||||
BARE_DOLLAR,
|
||||
IMMEDIATE_DOUBLE_HASH,
|
||||
NEWLINE,
|
||||
OPENING_PAREN,
|
||||
ERROR_RECOVERY,
|
||||
};
|
||||
|
||||
struct s_scanner
|
||||
{
|
||||
t_u8 last_glob_paren_depth;
|
||||
bool ext_was_in_double_quote;
|
||||
bool ext_saw_outside_quote;
|
||||
};
|
||||
|
||||
|
||||
#endif /* SCANNER_INNER_H */
|
||||
|
|
@ -1,193 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:37:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:23:03 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef STACK_INNER_H
|
||||
#define STACK_INNER_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/length_inner.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
#define MAX_LINK_COUNT 8
|
||||
#define MAX_NODE_POOL_SIZE 50
|
||||
#define MAX_ITERATOR_COUNT 64
|
||||
#define STACK_VERSION_NONE -1
|
||||
|
||||
typedef struct s_stack t_stack;
|
||||
typedef t_u32 t_stack_version;
|
||||
typedef struct s_stack_slice t_stack_slice;
|
||||
typedef struct s_stack_summary_entry t_stack_summary_entry;
|
||||
typedef Array(t_stack_slice) t_stack_slice_array;
|
||||
typedef Array(t_stack_summary_entry) t_stack_summary;
|
||||
|
||||
typedef enum e_stack_status t_stack_status;
|
||||
typedef struct s_stack_head t_stack_head;
|
||||
typedef struct s_stack_iterator t_stack_iterator;
|
||||
typedef struct s_stack_link t_stack_link;
|
||||
typedef struct s_stack_node t_stack_node;
|
||||
typedef struct s_summarize_stack_session t_summarize_stack_session;
|
||||
typedef t_u32 t_stack_action;
|
||||
|
||||
typedef t_stack_action (*t_stack_callback)(void *,
|
||||
const t_stack_iterator *);
|
||||
|
||||
struct s_stack_link
|
||||
{
|
||||
t_stack_node *node;
|
||||
t_subtree subtree;
|
||||
bool is_pending;
|
||||
};
|
||||
|
||||
struct s_stack_node
|
||||
{
|
||||
t_state_id state;
|
||||
t_length position;
|
||||
t_stack_link links[MAX_LINK_COUNT];
|
||||
t_u16 link_count;
|
||||
t_u32 ref_count;
|
||||
t_u32 error_cost;
|
||||
t_u32 node_count;
|
||||
int dynamic_precedence;
|
||||
};
|
||||
|
||||
struct s_stack_iterator
|
||||
{
|
||||
t_stack_node *node;
|
||||
t_vec_subtree subtrees;
|
||||
t_u32 subtree_count;
|
||||
bool is_pending;
|
||||
};
|
||||
|
||||
enum e_stack_status
|
||||
{
|
||||
SStatusActive,
|
||||
SStatusPaused,
|
||||
SStatusHalted,
|
||||
};
|
||||
|
||||
struct s_stack_head
|
||||
{
|
||||
t_stack_node *node;
|
||||
t_stack_summary *summary;
|
||||
t_u32 node_count_at_last_error;
|
||||
t_subtree last_external_token;
|
||||
t_subtree lookahead_when_paused;
|
||||
t_stack_status status;
|
||||
};
|
||||
|
||||
struct s_stack
|
||||
{
|
||||
Array(t_stack_head) heads;
|
||||
t_stack_slice_array slices;
|
||||
Array(t_stack_iterator) iterators;
|
||||
t_stack_node *base_node;
|
||||
};
|
||||
|
||||
enum e_stack_action
|
||||
{
|
||||
SActionNone,
|
||||
SActionStop = 1,
|
||||
SActionPop = 2,
|
||||
};
|
||||
|
||||
struct s_summarize_stack_session
|
||||
{
|
||||
t_stack_summary *summary;
|
||||
t_u32 max_depth;
|
||||
};
|
||||
|
||||
struct s_stack_slice
|
||||
{
|
||||
t_vec_subtree subtrees;
|
||||
t_stack_version version;
|
||||
};
|
||||
|
||||
struct s_stack_summary_entry
|
||||
{
|
||||
t_length position;
|
||||
t_u32 depth;
|
||||
t_state_id state;
|
||||
};
|
||||
|
||||
struct s_stack_push_arg
|
||||
{
|
||||
t_stack_version version;
|
||||
t_subtree subtree;
|
||||
bool pending;
|
||||
t_state_id state;
|
||||
};
|
||||
|
||||
struct s_stack_iter_args
|
||||
{
|
||||
t_stack_version version;
|
||||
t_stack_callback callback;
|
||||
void *payload;
|
||||
int goal_subtree_count;
|
||||
};
|
||||
|
||||
struct s_stack_iter_indexes
|
||||
{
|
||||
t_usize i;
|
||||
t_usize j;
|
||||
t_usize size;
|
||||
};
|
||||
|
||||
|
||||
t_length ts_stack_position(const t_stack *self, t_stack_version version);
|
||||
t_state_id ts_stack_state(const t_stack *self, t_stack_version version);
|
||||
bool stack__subtree_is_equivalent(t_subtree left, t_subtree right);
|
||||
bool ts_stack_can_merge(t_stack *self, t_stack_version version1, t_stack_version version2);
|
||||
bool ts_stack_has_advanced_since_error(const t_stack *self, t_stack_version version);
|
||||
bool ts_stack_is_active(const t_stack *self, t_stack_version version);
|
||||
bool ts_stack_is_halted(const t_stack *self, t_stack_version version);
|
||||
bool ts_stack_is_paused(const t_stack *self, t_stack_version version);
|
||||
bool ts_stack_merge(t_stack *self, t_stack_version version1, t_stack_version version2);
|
||||
int ts_stack_dynamic_precedence(t_stack *self, t_stack_version version);
|
||||
t_stack *ts_stack_new(void);
|
||||
t_stack_action pop_all_callback(void *payload, const t_stack_iterator *iterator);
|
||||
t_stack_action pop_count_callback(void *payload, const t_stack_iterator *iterator);
|
||||
t_stack_action pop_error_callback(void *payload, const t_stack_iterator *iterator);
|
||||
t_stack_action pop_pending_callback(void *payload, const t_stack_iterator *iterator);
|
||||
t_stack_action summarize_stack_callback(void *payload, const t_stack_iterator *iterator);
|
||||
t_stack_node *stack_node_new(t_stack_node *previous_node, t_subtree subtree, bool is_pending, t_state_id state);
|
||||
t_stack_slice_array stack__iter(t_stack *self, struct s_stack_iter_args args);
|
||||
t_stack_slice_array ts_stack_pop_all(t_stack *self, t_stack_version version);
|
||||
t_stack_slice_array ts_stack_pop_count(t_stack *self, t_stack_version version, t_u32 count);
|
||||
t_stack_slice_array ts_stack_pop_pending(t_stack *self, t_stack_version version);
|
||||
t_stack_summary *ts_stack_get_summary(t_stack *self, t_stack_version version);
|
||||
t_stack_version ts_stack__add_version(t_stack *self, t_stack_version original_version, t_stack_node *node);
|
||||
t_stack_version ts_stack_copy_version(t_stack *self, t_stack_version version);
|
||||
t_subtree ts_stack_last_external_token(const t_stack *self, t_stack_version version);
|
||||
t_subtree ts_stack_resume(t_stack *self, t_stack_version version);
|
||||
t_u32 stack__subtree_node_count(t_subtree subtree);
|
||||
t_u32 ts_stack_error_cost(const t_stack *self, t_stack_version version);
|
||||
t_u32 ts_stack_node_count_since_error(const t_stack *self, t_stack_version version);
|
||||
t_u32 ts_stack_version_count(const t_stack *self);
|
||||
t_vec_subtree ts_stack_pop_error(t_stack *self, t_stack_version version);
|
||||
void stack_head_delete(t_stack_head *self);
|
||||
void stack_node_add_link(t_stack_node *self, t_stack_link link);
|
||||
void stack_node_release(t_stack_node *self);
|
||||
void stack_node_retain(t_stack_node *self);
|
||||
void ts_stack__add_slice(t_stack *self, t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees);
|
||||
void ts_stack_clear(t_stack *self);
|
||||
void ts_stack_delete(t_stack *self);
|
||||
void ts_stack_halt(t_stack *self, t_stack_version version);
|
||||
void ts_stack_pause(t_stack *self, t_stack_version version, t_subtree lookahead);
|
||||
void ts_stack_push(t_stack *self, struct s_stack_push_arg args);
|
||||
void ts_stack_record_summary(t_stack *self, t_stack_version version, t_u32 max_depth);
|
||||
void ts_stack_remove_version(t_stack *self, t_stack_version version);
|
||||
void ts_stack_renumber_version(t_stack *self, t_stack_version v1, t_stack_version v2);
|
||||
void ts_stack_set_last_external_token(t_stack *self, t_stack_version version, t_subtree token);
|
||||
void ts_stack_swap_versions(t_stack *self, t_stack_version v1, t_stack_version v2);
|
||||
|
||||
|
||||
#endif /* STACK_INNER_H */
|
||||
|
|
@ -1,117 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_inner.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:01:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:30:56 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef SUBTREE_INNER_H
|
||||
#define SUBTREE_INNER_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/inner/length_inner.h"
|
||||
#include "parser/inner/ptypes.h"
|
||||
|
||||
// A heap-allocated representation of a subtree.
|
||||
//
|
||||
// This representation is used for parent nodes, external tokens,
|
||||
// errors, and other leaf nodes whose data is too large to fit into
|
||||
// the inline representation.
|
||||
typedef struct s_subtree_data t_subtree_data;
|
||||
|
||||
struct s_subtree_data
|
||||
{
|
||||
t_u32 ref_count;
|
||||
t_length padding;
|
||||
t_length size;
|
||||
t_u32 lookahead_bytes;
|
||||
t_u32 error_cost;
|
||||
t_u32 child_count;
|
||||
t_symbol symbol;
|
||||
t_state_id parse_state;
|
||||
|
||||
bool visible;
|
||||
bool named;
|
||||
bool extra;
|
||||
bool fragile_left;
|
||||
bool fragile_right;
|
||||
bool has_changes;
|
||||
bool has_external_tokens;
|
||||
bool has_external_scanner_state_change;
|
||||
bool depends_on_column;
|
||||
bool is_missing;
|
||||
bool is_keyword;
|
||||
|
||||
union {
|
||||
// Non-terminal subtrees (`child_count > 0`)
|
||||
struct
|
||||
{
|
||||
t_u32 visible_child_count;
|
||||
t_u32 named_child_count;
|
||||
t_u32 visible_descendant_count;
|
||||
t_i32 dynamic_precedence;
|
||||
t_u16 repeat_depth;
|
||||
t_u16 production_id;
|
||||
struct
|
||||
{
|
||||
t_symbol symbol;
|
||||
t_state_id parse_state;
|
||||
} first_leaf;
|
||||
};
|
||||
|
||||
// External terminal subtrees (`child_count == 0 && has_external_tokens`)
|
||||
t_external_scanner_state external_scanner_state;
|
||||
|
||||
// Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)
|
||||
t_i32 lookahead_char;
|
||||
};
|
||||
};
|
||||
|
||||
// The fundamental building block of a syntax tree.
|
||||
typedef t_subtree_data *t_subtree;
|
||||
|
||||
typedef struct s_subtree_new_leaf_args t_st_newleaf_args;
|
||||
typedef struct s_subtree_new_error_args t_st_newerr_args;
|
||||
|
||||
struct s_subtree_new_leaf_args
|
||||
{
|
||||
t_symbol symbol;
|
||||
t_length padding;
|
||||
t_length size;
|
||||
t_u32 lookahead_bytes;
|
||||
t_state_id parse_state;
|
||||
bool has_external_tokens;
|
||||
bool depends_on_column;
|
||||
bool is_keyword;
|
||||
const t_language *language;
|
||||
};
|
||||
|
||||
struct s_subtree_new_error_args
|
||||
{
|
||||
t_i32 lookahead_char;
|
||||
t_length padding;
|
||||
t_length size;
|
||||
t_u32 bytes_scanned;
|
||||
t_state_id parse_state;
|
||||
const t_language *language;
|
||||
};
|
||||
|
||||
struct s_summarize_state
|
||||
{
|
||||
t_u32 structural_index;
|
||||
const t_symbol *alias_sequence;
|
||||
t_u32 lookahead_end_byte;
|
||||
t_subtree *children;
|
||||
t_subtree child;
|
||||
t_u32 child_lookahead_end_byte;
|
||||
t_u32 grandchild_count;
|
||||
t_usize i;
|
||||
};
|
||||
|
||||
#endif /* SUBTREE_INNER_H */
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* input.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:19 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef INPUT_H
|
||||
#define INPUT_H
|
||||
|
||||
#include "me/types.h"
|
||||
|
||||
#define TS_DECODE_ERROR -1i
|
||||
|
||||
typedef t_u32 (*UnicodeDecodeFunction)(const t_u8 *string, t_u32 length, t_i32 *code_point);
|
||||
|
||||
t_u32 ts_decode_ascii(const t_u8 *string, t_u32 length, t_i32 *code_point);
|
||||
|
||||
#endif // INPUT_H
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:18 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:54:21 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LANGUAGE_H
|
||||
#define LANGUAGE_H
|
||||
|
||||
#include "parser/parser.h"
|
||||
#include "me/types.h"
|
||||
|
||||
#define ts_builtin_sym_error_repeat (ts_builtin_sym_error - 1)
|
||||
|
||||
#define LANGUAGE_VERSION_WITH_PRIMARY_STATES 14
|
||||
#define LANGUAGE_VERSION_USABLE_VIA_WASM 13
|
||||
|
||||
struct s_table_entry
|
||||
{
|
||||
const TSParseAction *actions;
|
||||
t_u32 action_count;
|
||||
bool is_reusable;
|
||||
};
|
||||
|
||||
typedef struct s_table_entry TableEntry;
|
||||
|
||||
void ts_language_table_entry(const t_language *, t_state_id, t_symbol, TableEntry *);
|
||||
t_symbol_metadata ts_language_symbol_metadata(const t_language *, t_symbol);
|
||||
t_symbol ts_language_public_symbol(const t_language *, t_symbol);
|
||||
t_state_id ts_language_next_state(const t_language *self, t_state_id state, t_symbol symbol);
|
||||
bool ts_language_is_symbol_external(const t_language *self, t_symbol symbol);
|
||||
const TSParseAction *ts_language_actions(const t_language *self, t_state_id state, t_symbol symbol, t_u32 *count);
|
||||
bool ts_language_has_reduce_action(const t_language *self, t_state_id state, t_symbol symbol);
|
||||
t_u16 ts_language_lookup(const t_language *self, t_state_id state, t_symbol symbol);
|
||||
bool ts_language_has_actions(const t_language *self, t_state_id state, t_symbol symbol);
|
||||
const bool *ts_language_enabled_external_tokens(const t_language *self, t_u32 external_scanner_state);
|
||||
const t_symbol *ts_language_alias_sequence(const t_language *self, t_u32 production_id);
|
||||
t_symbol ts_language_alias_at(const t_language *self, t_u32 production_id, t_u32 child_index);
|
||||
void ts_language_field_map(const t_language *self, t_u32 production_id, const TSFieldMapEntry **start, const TSFieldMapEntry **end);
|
||||
void ts_language_aliases_for_symbol(const t_language *self, t_symbol original_symbol, const t_symbol **start, const t_symbol **end);
|
||||
|
||||
#endif // LANGUAGE_H
|
||||
|
|
@ -1,21 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:16 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:36:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LENGTH_H
|
||||
#define LENGTH_H
|
||||
|
||||
#include "parser/inner/length_inner.h"
|
||||
|
||||
static const t_length LENGTH_UNDEFINED = {0, {0, 1}};
|
||||
static const t_length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
|
||||
|
||||
#endif
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:15 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:52:25 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef LEXER_H
|
||||
#define LEXER_H
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/length.h"
|
||||
#include "parser/parser.h"
|
||||
#include "me/types.h"
|
||||
|
||||
typedef struct s_lexer t_lexer;
|
||||
|
||||
struct s_lexer
|
||||
{
|
||||
struct s_lexer_functions funcs;
|
||||
t_length current_position;
|
||||
t_length token_start_position;
|
||||
t_length token_end_position;
|
||||
t_range *included_ranges;
|
||||
const t_u8 *chunk;
|
||||
t_input input;
|
||||
t_u32 included_range_count;
|
||||
t_u32 current_included_range_index;
|
||||
t_u32 chunk_start;
|
||||
t_u32 chunk_size;
|
||||
t_u32 lookahead_size;
|
||||
bool did_get_column;
|
||||
t_u8 debug_buffer[TREE_SITTER_SERIALIZATION_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
|
||||
void ts_lexer_init(t_lexer *self);
|
||||
void ts_lexer_delete(t_lexer *self);
|
||||
void ts_lexer_set_input(t_lexer *self, t_input input);
|
||||
void ts_lexer_reset(t_lexer *self, t_length length);
|
||||
void ts_lexer_start(t_lexer *self);
|
||||
void ts_lexer_finish(t_lexer *self, t_u32 *lookahead);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_mark_end(t_lexer *self);
|
||||
bool ts_lexer_set_included_ranges(t_lexer *self, const t_range *ranges, t_u32 count);
|
||||
t_range *ts_lexer_included_ranges(const t_lexer *self, t_u32 *count);
|
||||
|
||||
#endif // LEXER_H
|
||||
|
|
@ -1,278 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:13 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:57:51 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PARSER_H
|
||||
#define PARSER_H
|
||||
|
||||
#include "me/types.h"
|
||||
|
||||
#define ts_builtin_sym_error ((t_symbol)-1)
|
||||
#define ts_builtin_sym_end 0
|
||||
#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
|
||||
|
||||
typedef t_u16 t_state_id;
|
||||
typedef t_u16 t_symbol;
|
||||
typedef t_u16 t_field_id;
|
||||
typedef struct s_language t_language;
|
||||
typedef struct s_lexer t_lexer;
|
||||
|
||||
typedef struct s_field_map_entry
|
||||
{
|
||||
t_field_id field_id;
|
||||
t_u8 child_index;
|
||||
bool inherited;
|
||||
} TSFieldMapEntry;
|
||||
|
||||
typedef struct s_field_map_slice
|
||||
{
|
||||
t_u16 index;
|
||||
t_u16 length;
|
||||
} TSFieldMapSlice;
|
||||
|
||||
typedef struct s_symbol_metadata
|
||||
{
|
||||
bool visible;
|
||||
bool named;
|
||||
bool supertype;
|
||||
} t_symbol_metadata;
|
||||
|
||||
struct s_lexer_functions
|
||||
{
|
||||
t_i32 lookahead;
|
||||
t_symbol result_symbol;
|
||||
void (*advance)(t_lexer *, bool);
|
||||
void (*mark_end)(t_lexer *);
|
||||
t_u32 (*get_column)(t_lexer *);
|
||||
bool (*eof)(const t_lexer *);
|
||||
};
|
||||
|
||||
typedef enum e_parse_action_type
|
||||
{
|
||||
TSParseActionTypeShift,
|
||||
TSParseActionTypeReduce,
|
||||
TSParseActionTypeAccept,
|
||||
TSParseActionTypeRecover,
|
||||
} TSParseActionType;
|
||||
|
||||
typedef union u_parse_action {
|
||||
struct s_parse_action_shift
|
||||
{
|
||||
t_u8 type;
|
||||
t_state_id state;
|
||||
bool extra;
|
||||
bool repetition;
|
||||
} shift;
|
||||
struct s_parse_action_reduce
|
||||
{
|
||||
t_u8 type;
|
||||
t_u8 child_count;
|
||||
t_symbol symbol;
|
||||
t_i16 dynamic_precedence;
|
||||
t_u16 production_id;
|
||||
} reduce;
|
||||
t_u8 type;
|
||||
} TSParseAction;
|
||||
|
||||
typedef struct s_lex_mode
|
||||
{
|
||||
t_u16 lex_state;
|
||||
t_u16 external_lex_state;
|
||||
} TSLexMode;
|
||||
|
||||
typedef union u_parse_action_entry {
|
||||
TSParseAction action;
|
||||
struct s_parse_action_entry_inner
|
||||
{
|
||||
t_u8 count;
|
||||
bool reusable;
|
||||
} entry;
|
||||
} TSParseActionEntry;
|
||||
|
||||
typedef struct s_character_range
|
||||
{
|
||||
t_i32 start;
|
||||
t_i32 end;
|
||||
} TSCharacterRange;
|
||||
|
||||
struct s_language
|
||||
{
|
||||
t_u32 version;
|
||||
t_u32 symbol_count;
|
||||
t_u32 alias_count;
|
||||
t_u32 token_count;
|
||||
t_u32 external_token_count;
|
||||
t_u32 state_count;
|
||||
t_u32 large_state_count;
|
||||
t_u32 production_id_count;
|
||||
t_u32 field_count;
|
||||
t_u16 max_alias_sequence_length;
|
||||
const t_u16 *parse_table;
|
||||
const t_u16 *small_parse_table;
|
||||
const t_u32 *small_parse_table_map;
|
||||
const TSParseActionEntry *parse_actions;
|
||||
t_const_str const *symbol_names;
|
||||
t_const_str const *field_names;
|
||||
const TSFieldMapSlice *field_map_slices;
|
||||
const TSFieldMapEntry *field_map_entries;
|
||||
const t_symbol_metadata *symbol_metadata;
|
||||
const t_symbol *public_symbol_map;
|
||||
const t_u16 *alias_map;
|
||||
const t_symbol *alias_sequences;
|
||||
const TSLexMode *lex_modes;
|
||||
bool (*lex_fn)(t_lexer *, t_state_id);
|
||||
bool (*keyword_lex_fn)(t_lexer *, t_state_id);
|
||||
t_symbol keyword_capture_token;
|
||||
struct ExternalScannerDefinition
|
||||
{
|
||||
const bool *states;
|
||||
const t_symbol *symbol_map;
|
||||
void *(*create)(void);
|
||||
void (*destroy)(void *);
|
||||
bool (*scan)(void *, t_lexer *, const bool *symbol_whitelist);
|
||||
t_u32 (*serialize)(void *, t_u8 *);
|
||||
void (*deserialize)(void *, const t_u8 *, t_u32);
|
||||
} external_scanner;
|
||||
const t_state_id *primary_state_ids;
|
||||
};
|
||||
|
||||
static inline bool set_contains(TSCharacterRange *ranges, t_u32 len, t_i32 lookahead)
|
||||
{
|
||||
t_u32 index = 0;
|
||||
t_u32 size = len - index;
|
||||
while (size > 1)
|
||||
{
|
||||
t_u32 half_size = size / 2;
|
||||
t_u32 mid_index = index + half_size;
|
||||
TSCharacterRange *range = &ranges[mid_index];
|
||||
if (lookahead >= range->start && lookahead <= range->end)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (lookahead > range->end)
|
||||
{
|
||||
index = mid_index;
|
||||
}
|
||||
size -= half_size;
|
||||
}
|
||||
TSCharacterRange *range = &ranges[index];
|
||||
return (lookahead >= range->start && lookahead <= range->end);
|
||||
}
|
||||
|
||||
/*
|
||||
* Lexer Macros
|
||||
*/
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
#define START_LEXER() \
|
||||
bool result = false; \
|
||||
bool skip = false; \
|
||||
UNUSED \
|
||||
bool eof = false; \
|
||||
t_i32 lookahead; \
|
||||
goto start; \
|
||||
next_state: \
|
||||
lexer->funcs.advance((void *)lexer, skip); \
|
||||
start: \
|
||||
skip = false; \
|
||||
lookahead = lexer->funcs.lookahead;
|
||||
|
||||
#define ADVANCE(state_value) \
|
||||
{ \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define ADVANCE_MAP(...) \
|
||||
{ \
|
||||
static const t_u16 map[] = {__VA_ARGS__}; \
|
||||
for (t_u32 i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) \
|
||||
{ \
|
||||
if (map[i] == lookahead) \
|
||||
{ \
|
||||
state = map[i + 1]; \
|
||||
goto next_state; \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SKIP(state_value) \
|
||||
{ \
|
||||
skip = true; \
|
||||
state = state_value; \
|
||||
goto next_state; \
|
||||
}
|
||||
|
||||
#define ACCEPT_TOKEN(symbol_value) \
|
||||
result = true; \
|
||||
lexer->funcs.result_symbol = symbol_value; \
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
|
||||
#define END_STATE() return result;
|
||||
|
||||
/*
|
||||
* Parse Table Macros
|
||||
*/
|
||||
|
||||
#define SMALL_STATE(id) ((id)-LARGE_STATE_COUNT)
|
||||
|
||||
#define STATE(id) id
|
||||
|
||||
#define ACTIONS(id) id
|
||||
|
||||
#define SHIFT(state_value) \
|
||||
{ \
|
||||
{ \
|
||||
.shift = {.type = TSParseActionTypeShift, .state = (state_value) } \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SHIFT_REPEAT(state_value) \
|
||||
{ \
|
||||
{ \
|
||||
.shift = {.type = TSParseActionTypeShift, .state = (state_value), .repetition = true } \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SHIFT_EXTRA() \
|
||||
{ \
|
||||
{ \
|
||||
.shift = {.type = TSParseActionTypeShift, .extra = true } \
|
||||
} \
|
||||
}
|
||||
|
||||
#define REDUCE(symbol_name, children, precedence, prod_id) \
|
||||
{ \
|
||||
{ \
|
||||
.reduce = {.type = TSParseActionTypeReduce, \
|
||||
.symbol = symbol_name, \
|
||||
.child_count = children, \
|
||||
.dynamic_precedence = precedence, \
|
||||
.production_id = prod_id}, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define RECOVER() \
|
||||
{ \
|
||||
{ \
|
||||
.type = TSParseActionTypeRecover \
|
||||
} \
|
||||
}
|
||||
|
||||
#define ACCEPT_INPUT() \
|
||||
{ \
|
||||
{ \
|
||||
.type = TSParseActionTypeAccept \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif // PARSER_H
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:10 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef POINT_H
|
||||
#define POINT_H
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "me/types.h"
|
||||
|
||||
#define POINT_ZERO ((t_point){0, 0})
|
||||
#define POINT_MAX ((t_point){UINT32_MAX, UINT32_MAX})
|
||||
|
||||
t_point point_max(t_point a, t_point b);
|
||||
t_point point_min(t_point a, t_point b);
|
||||
t_point point__new(t_u32 row, t_u32 column);
|
||||
t_point point_add(t_point a, t_point b);
|
||||
t_point point_sub(t_point a, t_point b);
|
||||
bool point_lte(t_point a, t_point b);
|
||||
bool point_lt(t_point a, t_point b);
|
||||
bool point_gte(t_point a, t_point b);
|
||||
bool point_gt(t_point a, t_point b);
|
||||
bool point_eq(t_point a, t_point b);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,26 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* reduce_action.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:09 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/06 17:08:38 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef REDUCE_ACTION_H
|
||||
#define REDUCE_ACTION_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/array.h"
|
||||
#include "parser/inner/reduce_action_inner.h"
|
||||
#include "me/vec/vec_reduce_action.h"
|
||||
|
||||
typedef t_vec_reduce_action t_vec_reduce_action;
|
||||
|
||||
void ts_reduce_action_set_add(t_vec_reduce_action *self, t_reduce_action new_action);
|
||||
|
||||
#endif // REDUCE_ACTION_H
|
||||
|
|
@ -1,216 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:37:37 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef SUBTREE_H
|
||||
#define SUBTREE_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/array.h"
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/length.h"
|
||||
#include "parser/parser.h"
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define TS_TREE_STATE_NONE USHRT_MAX
|
||||
#define NULL_SUBTREE ((t_subtree)NULL)
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/inner/subtree_inner.h"
|
||||
|
||||
typedef t_vec_subtree t_vec_subtree;
|
||||
|
||||
bool _subtree_compress_inner(t_subtree *tree, t_symbol symbol, t_vec_subtree *stack);
|
||||
int subtree_compare_func(t_subtree left, t_subtree right);
|
||||
int ts_subtree_compare(t_subtree left, t_subtree right);
|
||||
struct s_summarize_state _init_sumnarize_state(t_subtree self, const t_language *language);
|
||||
t_subtree ts_subtree_clone(t_subtree self);
|
||||
t_subtree ts_subtree_ensure_owner(t_subtree self);
|
||||
t_subtree ts_subtree_last_external_token(t_subtree tree);
|
||||
t_subtree ts_subtree_new_error(t_st_newerr_args args);
|
||||
t_subtree ts_subtree_new_error_node(t_vec_subtree *children, bool extra, const t_language *language);
|
||||
t_subtree ts_subtree_new_leaf(t_st_newleaf_args args);
|
||||
t_subtree ts_subtree_new_missing_leaf(t_symbol symbol, t_length padding, t_u32 lookahead_bytes, const t_language *language);
|
||||
t_subtree ts_subtree_new_node(t_symbol symbol, t_vec_subtree *children, t_u32 production_id, const t_language *language);
|
||||
void _subtree_balance_inner(const t_language *language, t_vec_subtree *tree_stack);
|
||||
void _subtree_balance_repush(t_vec_subtree *tree_stack, t_subtree tree);
|
||||
void _subtree_release_inner(t_vec_subtree *to_free);
|
||||
void _sumarize_end(t_subtree self, t_subtree *children);
|
||||
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 ts_subtree__compress(t_subtree self, t_u32 count, const t_language *language, t_vec_subtree *stack);
|
||||
void ts_subtree_array_clear(t_vec_subtree *self);
|
||||
void ts_subtree_array_copy(t_vec_subtree self, t_vec_subtree *dest);
|
||||
void ts_subtree_array_delete(t_vec_subtree *self);
|
||||
void ts_subtree_array_remove_trailing_extras(t_vec_subtree *self, t_vec_subtree *destination);
|
||||
void ts_subtree_balance(t_subtree self, const t_language *language);
|
||||
void ts_subtree_release(t_subtree self);
|
||||
void ts_subtree_set_symbol(t_subtree *self, t_symbol symbol, const t_language *language);
|
||||
void ts_subtree_summarize_children(t_subtree self, const t_language *language);
|
||||
|
||||
static inline t_symbol ts_subtree_symbol(t_subtree self)
|
||||
{
|
||||
return ((self)->symbol);
|
||||
}
|
||||
static inline bool ts_subtree_visible(t_subtree self)
|
||||
{
|
||||
return ((self)->visible);
|
||||
}
|
||||
static inline bool ts_subtree_named(t_subtree self)
|
||||
{
|
||||
return ((self)->named);
|
||||
}
|
||||
static inline bool ts_subtree_extra(t_subtree self)
|
||||
{
|
||||
return ((self)->extra);
|
||||
}
|
||||
static inline bool ts_subtree_has_changes(t_subtree self)
|
||||
{
|
||||
return ((self)->has_changes);
|
||||
}
|
||||
static inline bool ts_subtree_missing(t_subtree self)
|
||||
{
|
||||
return ((self)->is_missing);
|
||||
}
|
||||
static inline bool ts_subtree_is_keyword(t_subtree self)
|
||||
{
|
||||
return ((self)->is_keyword);
|
||||
}
|
||||
static inline t_state_id ts_subtree_parse_state(t_subtree self)
|
||||
{
|
||||
return ((self)->parse_state);
|
||||
}
|
||||
static inline t_u32 ts_subtree_lookahead_bytes(t_subtree self)
|
||||
{
|
||||
return ((self)->lookahead_bytes);
|
||||
}
|
||||
|
||||
// Get the size needed to store a heap-allocated subtree with the given
|
||||
// number of children.
|
||||
static inline size_t ts_subtree_alloc_size(t_u32 child_count)
|
||||
{
|
||||
return child_count * sizeof(t_subtree) + sizeof(t_subtree_data);
|
||||
}
|
||||
|
||||
// Get a subtree's children, which are allocated immediately before the
|
||||
// tree's own heap data.
|
||||
static inline t_subtree *ts_subtree_children(t_subtree self)
|
||||
{
|
||||
return ((t_subtree *)((self)) - (self)->child_count);
|
||||
}
|
||||
|
||||
static inline void ts_subtree_set_extra(t_subtree *self, bool is_extra)
|
||||
{
|
||||
(*self)->extra = is_extra;
|
||||
}
|
||||
|
||||
static inline t_symbol ts_subtree_leaf_symbol(t_subtree self)
|
||||
{
|
||||
if (self->child_count == 0)
|
||||
return self->symbol;
|
||||
return self->first_leaf.symbol;
|
||||
}
|
||||
|
||||
static inline t_state_id ts_subtree_leaf_parse_state(t_subtree self)
|
||||
{
|
||||
if (self->child_count == 0)
|
||||
return self->parse_state;
|
||||
return self->first_leaf.parse_state;
|
||||
}
|
||||
|
||||
static inline t_length ts_subtree_padding(t_subtree self)
|
||||
{
|
||||
return self->padding;
|
||||
}
|
||||
|
||||
static inline t_length ts_subtree_size(t_subtree self)
|
||||
{
|
||||
return self->size;
|
||||
}
|
||||
|
||||
static inline t_length ts_subtree_total_size(t_subtree self)
|
||||
{
|
||||
return (length_add(ts_subtree_padding(self), ts_subtree_size(self)));
|
||||
}
|
||||
|
||||
static inline t_u32 ts_subtree_total_bytes(t_subtree self)
|
||||
{
|
||||
return (ts_subtree_total_size(self).bytes);
|
||||
}
|
||||
|
||||
static inline t_u32 ts_subtree_child_count(t_subtree self)
|
||||
{
|
||||
return (self->child_count);
|
||||
}
|
||||
|
||||
static inline t_u32 ts_subtree_repeat_depth(t_subtree self)
|
||||
{
|
||||
return (self->repeat_depth);
|
||||
}
|
||||
|
||||
static inline t_u32 ts_subtree_visible_descendant_count(t_subtree self)
|
||||
{
|
||||
return ((self->child_count == 0) ? 0 : self->visible_descendant_count);
|
||||
}
|
||||
|
||||
static inline t_u32 ts_subtree_error_cost(t_subtree self)
|
||||
{
|
||||
if (ts_subtree_missing(self))
|
||||
return (ERROR_COST_PER_MISSING_TREE + ERROR_COST_PER_RECOVERY);
|
||||
else
|
||||
return (self->error_cost);
|
||||
}
|
||||
|
||||
static inline t_i32 ts_subtree_dynamic_precedence(t_subtree self)
|
||||
{
|
||||
return ((self->child_count == 0) ? 0 : self->dynamic_precedence);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_fragile_left(t_subtree self)
|
||||
{
|
||||
return (self->fragile_left);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_fragile_right(t_subtree self)
|
||||
{
|
||||
return (self->fragile_right);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_has_external_tokens(t_subtree self)
|
||||
{
|
||||
return (self->has_external_tokens);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_has_external_scanner_state_change(t_subtree self)
|
||||
{
|
||||
return (self->has_external_scanner_state_change);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_depends_on_column(t_subtree self)
|
||||
{
|
||||
return (self->depends_on_column);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_is_error(t_subtree self)
|
||||
{
|
||||
return (ts_subtree_symbol(self) == ts_builtin_sym_error);
|
||||
}
|
||||
|
||||
static inline bool ts_subtree_is_eof(t_subtree self)
|
||||
{
|
||||
return (ts_subtree_symbol(self) == ts_builtin_sym_end);
|
||||
}
|
||||
#endif // SUBTREE_H
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 12:03:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 20:18:46 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef TREE_H
|
||||
#define TREE_H
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
struct s_tree
|
||||
{
|
||||
t_subtree root;
|
||||
const t_language *language;
|
||||
};
|
||||
|
||||
t_tree *ts_tree_new(t_subtree root, const t_language *language);
|
||||
t_node ts_node_new(const t_tree *, const t_subtree *, t_length, t_symbol);
|
||||
|
||||
#endif // TREE_H
|
||||
|
|
@ -1,226 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parse_types.h :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/24 23:01:45 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:57:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#ifndef PARSE_TYPES_H
|
||||
#define PARSE_TYPES_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/lexer.h"
|
||||
#include "parser/parser.h"
|
||||
#include "me/types.h"
|
||||
|
||||
typedef t_symbol_metadata t_symbol_metadata;
|
||||
typedef t_symbol t_symbol;
|
||||
typedef t_state_id t_state_id;
|
||||
typedef t_field_id t_field_id;
|
||||
typedef t_lexer t_lexer_funcs;
|
||||
typedef TSFieldMapSlice t_field_map_slice;
|
||||
typedef TSFieldMapEntry t_field_map_entry;
|
||||
typedef TSParseActionEntry t_parse_action_entry;
|
||||
typedef TSLexMode t_lex_modes;
|
||||
typedef TSCharacterRange t_char_range;
|
||||
|
||||
|
||||
struct s_lexer_state
|
||||
{
|
||||
t_u32 lookahead;
|
||||
t_state_id state;
|
||||
bool result;
|
||||
bool skip;
|
||||
bool eof;
|
||||
};
|
||||
|
||||
typedef struct s_lexer_state t_lexer_state;
|
||||
|
||||
#define ActionTypeShift TSParseActionTypeShift
|
||||
#define ActionTypeReduce TSParseActionTypeReduce
|
||||
#define ActionTypeRecover TSParseActionTypeRecover
|
||||
#define ActionTypeAccept TSParseActionTypeAccept
|
||||
|
||||
#ifndef inline
|
||||
# define inline __inline__
|
||||
#endif
|
||||
|
||||
static inline bool lex_skip(t_state_id state_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||
{
|
||||
(void)(lexer);
|
||||
s->skip = true;
|
||||
s->state = state_value;
|
||||
return (true);
|
||||
};
|
||||
|
||||
static inline bool lex_advance(t_state_id state_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||
{
|
||||
(void)(lexer);
|
||||
s->state = state_value;
|
||||
return (true);
|
||||
};
|
||||
|
||||
static inline bool lex_accept_token(t_symbol symbol_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||
{
|
||||
s->result = true;
|
||||
lexer->funcs.result_symbol = symbol_value;
|
||||
lexer->funcs.mark_end(lexer);
|
||||
return (true);
|
||||
};
|
||||
|
||||
static inline bool lex_end_state(t_lexer_funcs *lexer, t_lexer_state *s)
|
||||
{
|
||||
(void)(lexer);
|
||||
(void)(s);
|
||||
return (false);
|
||||
};
|
||||
|
||||
static inline t_field_map_entry fmap_entry(t_field_id field_id, uint8_t child_index, bool inherited)
|
||||
{
|
||||
return ((t_field_map_entry){
|
||||
.field_id = field_id,
|
||||
.child_index = child_index,
|
||||
.inherited = inherited,
|
||||
});
|
||||
};
|
||||
|
||||
static inline t_field_map_slice fmap_slice(t_u16 index, t_u16 length)
|
||||
{
|
||||
return ((t_field_map_slice){
|
||||
.index = index,
|
||||
.length = length,
|
||||
});
|
||||
};
|
||||
|
||||
static inline t_symbol_metadata sym_metadata(bool visible, bool named, bool supertype)
|
||||
{
|
||||
return ((t_symbol_metadata){
|
||||
.visible = visible,
|
||||
.named = named,
|
||||
.supertype = supertype,
|
||||
});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry entry(uint8_t count, bool reusable)
|
||||
{
|
||||
return ((t_parse_action_entry){.entry = {.count = count, .reusable = reusable}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry shift(t_state_id state_value)
|
||||
{
|
||||
return ((t_parse_action_entry){{.shift = {
|
||||
.type = ActionTypeShift,
|
||||
.state = (state_value),
|
||||
}}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry shift_repeat(t_state_id state_value)
|
||||
{
|
||||
return ((t_parse_action_entry){{.shift = {.type = ActionTypeShift, .state = (state_value), .repetition = true}}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry shift_extra(void)
|
||||
{
|
||||
return ((t_parse_action_entry){{.shift = {.type = ActionTypeShift, .extra = true}}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry reduce(
|
||||
|
||||
t_symbol symbol, uint8_t child_count, int16_t dynamic_precedence, t_u16 production_id)
|
||||
{
|
||||
return ((t_parse_action_entry){{.reduce = {
|
||||
.type = ActionTypeReduce,
|
||||
.child_count = child_count,
|
||||
.symbol = symbol,
|
||||
.dynamic_precedence = dynamic_precedence,
|
||||
.production_id = production_id,
|
||||
}}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry recover(void)
|
||||
{
|
||||
return ((t_parse_action_entry){{.type = ActionTypeRecover}});
|
||||
};
|
||||
|
||||
static inline t_parse_action_entry accept(void)
|
||||
{
|
||||
return ((t_parse_action_entry){{.type = ActionTypeAccept}});
|
||||
};
|
||||
|
||||
/*
|
||||
static inline bool set_contains(t_char_range *ranges, t_u32 len, int32_t lookahead)
|
||||
{
|
||||
t_u32 index = 0;
|
||||
t_u32 size = len - index;
|
||||
while (size > 1)
|
||||
{
|
||||
t_u32 half_size = size / 2;
|
||||
t_u32 mid_index = index + half_size;
|
||||
t_char_range *range = &ranges[mid_index];
|
||||
if (lookahead >= range->start && lookahead <= range->end)
|
||||
{
|
||||
return (true);
|
||||
}
|
||||
else if (lookahead > range->end)
|
||||
{
|
||||
index = mid_index;
|
||||
}
|
||||
size -= half_size;
|
||||
}
|
||||
t_char_range *range = &ranges[index];
|
||||
return (lookahead >= range->start && lookahead <= range->end);
|
||||
};
|
||||
*/
|
||||
|
||||
static inline bool advance_map_inner(t_u32 *map, t_u32 elems, t_lexer_funcs *l, t_lexer_state *s)
|
||||
{
|
||||
t_u32 i;
|
||||
|
||||
(void)(l);
|
||||
i = 0;
|
||||
while (i < elems)
|
||||
{
|
||||
if (map[i] == (t_u32)s->lookahead)
|
||||
{
|
||||
s->state = map[i + 1];
|
||||
return (true);
|
||||
}
|
||||
i += 2;
|
||||
}
|
||||
return (false);
|
||||
};
|
||||
|
||||
static inline t_lex_modes lex_mode_external(t_u16 lex_state, t_u16 ext_lex_state)
|
||||
{
|
||||
return ((t_lex_modes){
|
||||
.lex_state = lex_state,
|
||||
.external_lex_state = ext_lex_state,
|
||||
});
|
||||
};
|
||||
|
||||
static inline t_lex_modes lex_mode_normal(t_u16 lex_state)
|
||||
{
|
||||
return ((t_lex_modes){
|
||||
.lex_state = lex_state,
|
||||
});
|
||||
};
|
||||
|
||||
static inline t_u16 actions(t_u16 val)
|
||||
{
|
||||
return (val);
|
||||
};
|
||||
|
||||
static inline t_u16 state(t_u16 val)
|
||||
{
|
||||
return (val);
|
||||
};
|
||||
|
||||
#endif /* PARSE_TYPES_H */
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_field.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:47:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:10:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/str/str.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
t_const_str ts_language_field_name_for_id(const t_language *self, t_field_id id)
|
||||
{
|
||||
t_u32 count;
|
||||
|
||||
count = ts_language_field_count(self);
|
||||
if (count && id <= count)
|
||||
return (self->field_names[id]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_field_id ts_language_field_id_for_name(const t_language *self,
|
||||
t_const_str name, t_u32 name_length)
|
||||
{
|
||||
t_u16 count;
|
||||
t_symbol i;
|
||||
|
||||
count = (t_u16)ts_language_field_count(self);
|
||||
i = 1;
|
||||
while (i < count + 1)
|
||||
{
|
||||
if (str_n_compare(name, self->field_names[i], name_length)
|
||||
&& self->field_names[i][name_length] == 0)
|
||||
return (i);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ts_language_field_map(const t_language *self, t_u32 production_id,
|
||||
const TSFieldMapEntry **start, const TSFieldMapEntry **end)
|
||||
{
|
||||
TSFieldMapSlice slice;
|
||||
|
||||
if (self->field_count == 0)
|
||||
{
|
||||
*start = NULL;
|
||||
*end = NULL;
|
||||
return ;
|
||||
}
|
||||
slice = self->field_map_slices[production_id];
|
||||
*start = &self->field_map_entries[slice.index];
|
||||
*end = &self->field_map_entries[slice.index] + slice.length;
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_getters.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:42:37 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:43:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
t_u32 ts_language_symbol_count(const t_language *self)
|
||||
{
|
||||
return (self->symbol_count + self->alias_count);
|
||||
}
|
||||
|
||||
t_u32 ts_language_state_count(const t_language *self)
|
||||
{
|
||||
return (self->state_count);
|
||||
}
|
||||
|
||||
t_u32 ts_language_version(const t_language *self)
|
||||
{
|
||||
return (self->version);
|
||||
}
|
||||
|
||||
t_u32 ts_language_field_count(const t_language *self)
|
||||
{
|
||||
return (self->field_count);
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_getters2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:50:29 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:54:52 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
bool ts_language_has_actions(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
return (ts_language_lookup(self, state, symbol) != 0);
|
||||
}
|
||||
|
||||
const bool *ts_language_enabled_external_tokens(const t_language *self,
|
||||
t_u32 external_scanner_state)
|
||||
{
|
||||
if (external_scanner_state == 0)
|
||||
return (NULL);
|
||||
else
|
||||
return (self->external_scanner.states \
|
||||
+ self->external_token_count * external_scanner_state);
|
||||
}
|
||||
|
||||
const t_symbol *ts_language_alias_sequence(const t_language *self,
|
||||
t_u32 production_id)
|
||||
{
|
||||
if (production_id)
|
||||
return (&self->alias_sequences[production_id \
|
||||
* self->max_alias_sequence_length]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_symbol ts_language_alias_at(const t_language *self, t_u32 production_id,
|
||||
t_u32 child_index)
|
||||
{
|
||||
if (production_id)
|
||||
return (self->alias_sequences[production_id \
|
||||
* self->max_alias_sequence_length + child_index]);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,104 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_misc.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:51:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:55:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
void ts_language_table_entry(const t_language *self, t_state_id state,
|
||||
t_symbol symbol, TableEntry *result)
|
||||
{
|
||||
t_u32 action_index;
|
||||
const TSParseActionEntry *entry;
|
||||
|
||||
if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat)
|
||||
{
|
||||
result->action_count = 0;
|
||||
result->is_reusable = false;
|
||||
result->actions = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
action_index = ts_language_lookup(self, state, symbol);
|
||||
entry = &self->parse_actions[action_index];
|
||||
result->action_count = entry->entry.count;
|
||||
result->is_reusable = entry->entry.reusable;
|
||||
result->actions = (const TSParseAction *)(entry + 1);
|
||||
}
|
||||
}
|
||||
|
||||
t_state_id ts_language_next_state(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
t_u32 count;
|
||||
const TSParseAction *actions;
|
||||
TSParseAction action;
|
||||
|
||||
if (symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
else if (symbol < self->token_count)
|
||||
{
|
||||
actions = ts_language_actions(self, state, symbol, &count);
|
||||
if (count > 0)
|
||||
{
|
||||
action = actions[count - 1];
|
||||
if (action.type == TSParseActionTypeShift)
|
||||
{
|
||||
if (action.shift.extra)
|
||||
return (state);
|
||||
return (action.shift.state);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (ts_language_lookup(self, state, symbol));
|
||||
}
|
||||
|
||||
const TSParseAction *ts_language_actions(const t_language *self,
|
||||
t_state_id state, t_symbol symbol, t_u32 *count)
|
||||
{
|
||||
TableEntry entry;
|
||||
|
||||
ts_language_table_entry(self, state, symbol, &entry);
|
||||
*count = entry.action_count;
|
||||
return (entry.actions);
|
||||
}
|
||||
|
||||
bool ts_language_has_reduce_action(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
TableEntry entry;
|
||||
|
||||
ts_language_table_entry(self, state, symbol, &entry);
|
||||
return (entry.action_count > 0
|
||||
&& entry.actions[0].type == TSParseActionTypeReduce);
|
||||
}
|
||||
|
||||
// Lookup the table value for a given symbol and state.
|
||||
//
|
||||
// For non-terminal symbols, the table value represents a successor state.
|
||||
// For terminal symbols, it represents an index in the actions table.
|
||||
// For 'large' parse states, this is a direct lookup. For 'small' parse
|
||||
// states, this requires searching through the symbol groups to find
|
||||
// the given symbol.
|
||||
t_u16 ts_language_lookup(const t_language *self, t_state_id state,
|
||||
t_symbol symbol)
|
||||
{
|
||||
if (state >= self->large_state_count)
|
||||
return (me_abort("we got a small parse table, which isn't supported"),
|
||||
-1);
|
||||
return (self->parse_table[state * self->symbol_count + symbol]);
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_symbol.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:43:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:51:19 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/str/str.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
t_symbol_metadata ts_language_symbol_metadata(const t_language *self,
|
||||
t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return ((t_symbol_metadata){.visible = true, .named = true});
|
||||
else if (symbol == ts_builtin_sym_error_repeat)
|
||||
return ((t_symbol_metadata){.visible = false, .named = false});
|
||||
else
|
||||
return (self->symbol_metadata[symbol]);
|
||||
}
|
||||
|
||||
t_symbol ts_language_public_symbol(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return (symbol);
|
||||
return (self->public_symbol_map[symbol]);
|
||||
}
|
||||
|
||||
t_const_str ts_language_symbol_name(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
if (symbol == ts_builtin_sym_error)
|
||||
return ("ERROR");
|
||||
else if (symbol == ts_builtin_sym_error_repeat)
|
||||
return ("_ERROR");
|
||||
else if (symbol < ts_language_symbol_count(self))
|
||||
return (self->symbol_names[symbol]);
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_symbol ts_language_symbol_for_name(const t_language *self,
|
||||
t_const_str string, t_u32 length, bool is_named)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
t_u16 count;
|
||||
t_symbol i;
|
||||
t_const_str symbol_name;
|
||||
|
||||
if (str_n_compare(string, "ERROR", length))
|
||||
return (ts_builtin_sym_error);
|
||||
count = (t_u16)ts_language_symbol_count(self);
|
||||
i = 0;
|
||||
while (i < count)
|
||||
{
|
||||
metadata = ts_language_symbol_metadata(self, i);
|
||||
if ((!metadata.visible && !metadata.supertype)
|
||||
|| metadata.named != is_named)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
symbol_name = self->symbol_names[i];
|
||||
if (str_n_compare(symbol_name, string, length) && !symbol_name[length])
|
||||
return (self->public_symbol_map[i]);
|
||||
i++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_symbol_type ts_language_symbol_type(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
|
||||
metadata = ts_language_symbol_metadata(self, symbol);
|
||||
if (metadata.named && metadata.visible)
|
||||
return (t_symbol_typeRegular);
|
||||
else if (metadata.visible)
|
||||
return (t_symbol_typeAnonymous);
|
||||
else
|
||||
return (t_symbol_typeAuxiliary);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* language_symbol2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:46:08 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:46:44 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
void ts_language_aliases_for_symbol(const t_language *self,
|
||||
t_symbol original_symbol, const t_symbol **start, const t_symbol **end)
|
||||
{
|
||||
t_u32 idx;
|
||||
t_symbol symbol;
|
||||
t_u16 count;
|
||||
|
||||
*start = &self->public_symbol_map[original_symbol];
|
||||
*end = *start + 1;
|
||||
idx = 0;
|
||||
while (true)
|
||||
{
|
||||
symbol = self->alias_map[idx++];
|
||||
if (symbol == 0 || symbol > original_symbol)
|
||||
break ;
|
||||
count = self->alias_map[idx++];
|
||||
if (symbol == original_symbol)
|
||||
{
|
||||
*start = &self->alias_map[idx];
|
||||
*end = &self->alias_map[idx + count];
|
||||
break ;
|
||||
}
|
||||
idx += count;
|
||||
}
|
||||
}
|
||||
|
||||
bool ts_language_is_symbol_external(const t_language *self, t_symbol symbol)
|
||||
{
|
||||
return (0 < symbol && symbol < self->external_token_count + 1);
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:38:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:53:22 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/length.h"
|
||||
#include "parser/point.h"
|
||||
|
||||
bool length_is_undefined(t_length length)
|
||||
{
|
||||
return (length.bytes == 0 && length.extent.column != 0);
|
||||
}
|
||||
|
||||
t_length length_min(t_length len1, t_length len2)
|
||||
{
|
||||
if (len1.bytes < len2.bytes)
|
||||
return (len1);
|
||||
return (len2);
|
||||
}
|
||||
|
||||
t_length length_add(t_length len1, t_length len2)
|
||||
{
|
||||
t_length result;
|
||||
|
||||
result.bytes = len1.bytes + len2.bytes;
|
||||
result.extent = point_add(len1.extent, len2.extent);
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_length length_sub(t_length len1, t_length len2)
|
||||
{
|
||||
t_length result;
|
||||
|
||||
result.bytes = len1.bytes - len2.bytes;
|
||||
result.extent = point_sub(len1.extent, len2.extent);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* length_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:38:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:39:17 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/length.h"
|
||||
#include "parser/point.h"
|
||||
|
||||
t_length length_zero(void)
|
||||
{
|
||||
return ((t_length){0, {0, 0}});
|
||||
}
|
||||
|
||||
t_length length_saturating_sub(t_length len1, t_length len2)
|
||||
{
|
||||
if (len1.bytes > len2.bytes)
|
||||
return (length_sub(len1, len2));
|
||||
else
|
||||
return (length_zero());
|
||||
}
|
||||
2436
parser/src/lex.c
2436
parser/src/lex.c
File diff suppressed because it is too large
Load diff
|
|
@ -1,105 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_advance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:06:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:58:25 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
bool ts_lexer__do_advance_loop(t_lexer *self, const t_range **current_range);
|
||||
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||
const t_range *cur);
|
||||
|
||||
// Intended to be called only from functions that control logging.
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip)
|
||||
{
|
||||
const t_range *cur = \
|
||||
&self->included_ranges[self->current_included_range_index];
|
||||
|
||||
if (self->lookahead_size)
|
||||
{
|
||||
self->current_position.bytes += self->lookahead_size;
|
||||
if (self->funcs.lookahead == '\n')
|
||||
{
|
||||
self->current_position.extent.row++;
|
||||
self->current_position.extent.column = 0;
|
||||
}
|
||||
else
|
||||
self->current_position.extent.column += self->lookahead_size;
|
||||
}
|
||||
while (self->current_position.bytes >= cur->end_byte
|
||||
|| cur->end_byte == cur->start_byte)
|
||||
if (ts_lexer__do_advance_loop(self, &cur))
|
||||
break ;
|
||||
ts_lexer__do_advance_after_loop(self, skip, cur);
|
||||
}
|
||||
|
||||
// Advance to the next character in the source code, retrieving a new
|
||||
// chunk of source code if needed.
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip)
|
||||
{
|
||||
t_lexer *self;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
if (!self->chunk)
|
||||
return ;
|
||||
ts_lexer__do_advance(self, skip);
|
||||
}
|
||||
|
||||
bool ts_lexer__do_advance_loop(t_lexer *self, const t_range **current_range)
|
||||
{
|
||||
if (self->current_included_range_index < self->included_range_count)
|
||||
self->current_included_range_index++;
|
||||
if (self->current_included_range_index < self->included_range_count)
|
||||
{
|
||||
(*current_range)++;
|
||||
self->current_position = (t_length){
|
||||
(*current_range)->start_byte,
|
||||
(*current_range)->start_point,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
(*current_range) = NULL;
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||
const t_range *cur)
|
||||
{
|
||||
if (skip)
|
||||
self->token_start_position = self->current_position;
|
||||
if (cur)
|
||||
{
|
||||
if (self->current_position.bytes < self->chunk_start
|
||||
|| self->current_position.bytes >= self->chunk_start
|
||||
+ self->chunk_size)
|
||||
ts_lexer__get_chunk(self);
|
||||
ts_lexer__get_lookahead(self);
|
||||
}
|
||||
else
|
||||
{
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->funcs.lookahead = '\0';
|
||||
self->lookahead_size = 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_chunk.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:07:46 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:07:52 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
// Clear the currently stored chunk of source code, because the lexer's
|
||||
// position has changed.
|
||||
void ts_lexer__clear_chunk(t_lexer *self)
|
||||
{
|
||||
self->chunk = NULL;
|
||||
self->chunk_size = 0;
|
||||
self->chunk_start = 0;
|
||||
}
|
||||
|
||||
// Call the lexer's input callback to obtain a new chunk of source code
|
||||
// for the current position.
|
||||
void ts_lexer__get_chunk(t_lexer *self)
|
||||
{
|
||||
self->chunk_start = self->current_position.bytes;
|
||||
self->chunk = self->input.read(self->input.payload,
|
||||
self->current_position.bytes, self->current_position.extent,
|
||||
&self->chunk_size);
|
||||
if (!self->chunk_size)
|
||||
{
|
||||
self->current_included_range_index = self->included_range_count;
|
||||
self->chunk = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_end.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:07:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:58:53 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
// Check if the lexer has reached EOF. This state is stored
|
||||
// by setting the lexer's `current_included_range_index` such that
|
||||
// it has consumed all of its available ranges.
|
||||
bool ts_lexer__eof(const t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
return (self->current_included_range_index == self->included_range_count);
|
||||
}
|
||||
|
||||
// Mark that a token match has completed. This can be called multiple
|
||||
// times if a longer match is found later.
|
||||
void ts_lexer__mark_end(t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
t_range *current_included_range;
|
||||
t_range *previous_included_range;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
if (!ts_lexer__eof(self))
|
||||
{
|
||||
current_included_range = \
|
||||
&self->included_ranges[self->current_included_range_index];
|
||||
if (self->current_included_range_index > 0 \
|
||||
&& self->current_position.bytes == current_included_range->start_byte)
|
||||
{
|
||||
previous_included_range = current_included_range - 1;
|
||||
self->token_end_position = (t_length){
|
||||
previous_included_range->end_byte,
|
||||
previous_included_range->end_point,
|
||||
};
|
||||
return ;
|
||||
}
|
||||
}
|
||||
self->token_end_position = self->current_position;
|
||||
}
|
||||
|
||||
void ts_lexer_advance_to_end(t_lexer *self)
|
||||
{
|
||||
while (self->chunk)
|
||||
ts_lexer__advance(self, false);
|
||||
}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_get_column.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:04:55 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 18:18:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self)
|
||||
{
|
||||
t_lexer *self;
|
||||
t_u32 goal_byte;
|
||||
t_u32 result;
|
||||
|
||||
self = (t_lexer *)_self;
|
||||
goal_byte = self->current_position.bytes;
|
||||
self->did_get_column = true;
|
||||
self->current_position.bytes -= self->current_position.extent.column;
|
||||
self->current_position.extent.column = 0;
|
||||
if (self->current_position.bytes < self->chunk_start)
|
||||
ts_lexer__get_chunk(self);
|
||||
result = 0;
|
||||
if (!ts_lexer__eof(_self))
|
||||
{
|
||||
ts_lexer__get_lookahead(self);
|
||||
while (self->current_position.bytes < goal_byte && self->chunk)
|
||||
{
|
||||
result++;
|
||||
ts_lexer__do_advance(self, false);
|
||||
if (ts_lexer__eof(_self))
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,96 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_goto.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:08:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:59:09 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||
t_range *included_range, t_usize i);
|
||||
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range);
|
||||
|
||||
void ts_lexer_goto(t_lexer *self, t_length position)
|
||||
{
|
||||
bool found_included_range;
|
||||
t_range *included_range;
|
||||
t_u32 i;
|
||||
|
||||
included_range = NULL;
|
||||
found_included_range = false;
|
||||
self->current_position = position;
|
||||
i = 0;
|
||||
while (i < self->included_range_count)
|
||||
{
|
||||
included_range = &self->included_ranges[i];
|
||||
if (included_range->end_byte > self->current_position.bytes
|
||||
&& included_range->end_byte > included_range->start_byte)
|
||||
{
|
||||
ts_lexer_goto_inside_loop(self, &found_included_range,
|
||||
included_range, i);
|
||||
break ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ts_lexer_goto_after_loop(self, found_included_range);
|
||||
}
|
||||
|
||||
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||
t_range *included_range, t_usize i)
|
||||
{
|
||||
if (included_range->start_byte >= self->current_position.bytes)
|
||||
{
|
||||
self->current_position = (t_length){
|
||||
.bytes = included_range->start_byte,
|
||||
.extent = included_range->start_point,
|
||||
};
|
||||
}
|
||||
self->current_included_range_index = i;
|
||||
*found_included_range = true;
|
||||
}
|
||||
|
||||
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range)
|
||||
{
|
||||
t_range *last_included_range;
|
||||
|
||||
if (found_included_range)
|
||||
{
|
||||
if (self->chunk && (self->current_position.bytes < self->chunk_start
|
||||
|| self->current_position.bytes >= self->chunk_start
|
||||
+ self->chunk_size))
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->lookahead_size = 0;
|
||||
self->funcs.lookahead = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
self->current_included_range_index = self->included_range_count;
|
||||
last_included_range = &self->included_ranges[self->included_range_count
|
||||
- 1];
|
||||
self->current_position = (t_length){
|
||||
.bytes = last_included_range->end_byte,
|
||||
.extent = last_included_range->end_point,
|
||||
};
|
||||
ts_lexer__clear_chunk(self);
|
||||
self->lookahead_size = 1;
|
||||
self->funcs.lookahead = '\0';
|
||||
}
|
||||
}
|
||||
|
|
@ -1,90 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:58:01 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 16:59:58 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
#define BYTE_ORDER_MARK 0xFEFF
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer_init(t_lexer *self)
|
||||
{
|
||||
static t_range default_range = {.start_point = {\
|
||||
.row = 0, .column = 0, }, .end_point = {.row = UINT32_MAX, \
|
||||
.column = UINT32_MAX, }, .start_byte = 0, .end_byte = UINT32_MAX};
|
||||
|
||||
*self = (t_lexer){
|
||||
.funcs = {
|
||||
.advance = ts_lexer__advance,
|
||||
.mark_end = ts_lexer__mark_end,
|
||||
.get_column = NULL, //ts_lexer__get_column,
|
||||
.eof = ts_lexer__eof,
|
||||
.lookahead = 0,
|
||||
.result_symbol = 0, },
|
||||
.chunk = NULL,
|
||||
.chunk_size = 0,
|
||||
.chunk_start = 0,
|
||||
.current_position = {0, {0, 0}},
|
||||
.included_ranges = (void *)&default_range,
|
||||
.included_range_count = 1,
|
||||
.current_included_range_index = 0,
|
||||
};
|
||||
}
|
||||
|
||||
void ts_lexer_set_input(t_lexer *self, t_input input)
|
||||
{
|
||||
self->input = input;
|
||||
ts_lexer__clear_chunk(self);
|
||||
ts_lexer_goto(self, self->current_position);
|
||||
}
|
||||
|
||||
void ts_lexer_reset(t_lexer *self, t_length position)
|
||||
{
|
||||
if (position.bytes != self->current_position.bytes)
|
||||
ts_lexer_goto(self, position);
|
||||
}
|
||||
|
||||
void ts_lexer_start(t_lexer *self)
|
||||
{
|
||||
self->token_start_position = self->current_position;
|
||||
self->token_end_position = LENGTH_UNDEFINED;
|
||||
self->funcs.result_symbol = 0;
|
||||
self->did_get_column = false;
|
||||
if (!ts_lexer__eof(self))
|
||||
{
|
||||
if (!self->chunk_size)
|
||||
ts_lexer__get_chunk(self);
|
||||
if (!self->lookahead_size)
|
||||
ts_lexer__get_lookahead(self);
|
||||
if (self->current_position.bytes == 0
|
||||
&& self->funcs.lookahead == BYTE_ORDER_MARK)
|
||||
ts_lexer__advance(self, true);
|
||||
}
|
||||
}
|
||||
|
||||
void ts_lexer_finish(t_lexer *self, t_u32 *lookahead_end_byte)
|
||||
{
|
||||
if (length_is_undefined(self->token_end_position))
|
||||
ts_lexer__mark_end(self);
|
||||
(void)(lookahead_end_byte);
|
||||
if (self->token_end_position.bytes < self->token_start_position.bytes)
|
||||
self->token_start_position = self->token_end_position;
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* lexer_lookahead.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 18:09:03 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:00:15 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/input.h"
|
||||
#include "parser/lexer.h"
|
||||
|
||||
bool ts_lexer__eof(const t_lexer *_self);
|
||||
t_u32 ts_lexer__get_column(t_lexer *_self);
|
||||
void ts_lexer__advance(t_lexer *_self, bool skip);
|
||||
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||
void ts_lexer__clear_chunk(t_lexer *self);
|
||||
void ts_lexer__get_chunk(t_lexer *self);
|
||||
void ts_lexer__get_lookahead(t_lexer *self);
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
void ts_lexer_advance_to_end(t_lexer *self);
|
||||
void ts_lexer_goto(t_lexer *self, t_length position);
|
||||
|
||||
void ts_lexer__get_lookahead(t_lexer *self)
|
||||
{
|
||||
t_u32 position_in_chunk;
|
||||
t_u32 size;
|
||||
const t_u8 *chunk;
|
||||
|
||||
position_in_chunk = self->current_position.bytes - self->chunk_start;
|
||||
size = self->chunk_size - position_in_chunk;
|
||||
if (size == 0)
|
||||
{
|
||||
self->lookahead_size = 1;
|
||||
self->funcs.lookahead = '\0';
|
||||
return ;
|
||||
}
|
||||
chunk = (const t_u8 *)self->chunk + position_in_chunk;
|
||||
self->lookahead_size = ts_decode_ascii(chunk, size, &self->funcs.lookahead);
|
||||
if (self->funcs.lookahead == TS_DECODE_ERROR)
|
||||
self->lookahead_size = 1;
|
||||
}
|
||||
|
|
@ -1,103 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* create_language.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/04/25 16:13:52 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:36:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "../static/headers/constants.h"
|
||||
#include "../static/headers/symbols.h"
|
||||
#include "me/types.h"
|
||||
#include "parser/parser.h"
|
||||
|
||||
// bool lex_keywords_main(t_lexer *lexer, t_state_id state);
|
||||
// bool lex_normal_main(t_lexer *lexer, t_state_id state);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *ctx, t_lexer *lexer, \
|
||||
const bool *ret);
|
||||
void *create_external_scanner_states(void);
|
||||
void *create_field_names(void);
|
||||
void *create_symbols_names(void);
|
||||
void *create_field_map_entries(void);
|
||||
void *create_field_map_slices(void);
|
||||
void *create_lex_modes(void);
|
||||
void *create_parse_actions_entries(void);
|
||||
void *create_primary_state_ids(void);
|
||||
void *create_alias_sequences(void);
|
||||
void *create_external_scanner_symbol_map(void);
|
||||
void *create_non_terminal_alias_map(void);
|
||||
void *create_unique_symbols_map(void);
|
||||
void *create_symbols_metadata(void);
|
||||
void *create_parse_table(void);
|
||||
bool ts_lex_keywords(t_lexer *lexer, t_state_id state);
|
||||
bool ts_lex(t_lexer *lexer, t_state_id state);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *ctx, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *ctx, \
|
||||
const t_u8 *state, t_u32 val);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *ctx);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
|
||||
static struct ExternalScannerDefinition init_scanner(void)
|
||||
{
|
||||
return ((struct ExternalScannerDefinition){
|
||||
create_external_scanner_states(),
|
||||
create_external_scanner_symbol_map(),
|
||||
tree_sitter_sh_external_scanner_create,
|
||||
tree_sitter_sh_external_scanner_destroy,
|
||||
tree_sitter_sh_external_scanner_scan,
|
||||
tree_sitter_sh_external_scanner_serialize,
|
||||
tree_sitter_sh_external_scanner_deserialize,
|
||||
});
|
||||
}
|
||||
|
||||
static void init_language(t_language *language)
|
||||
{
|
||||
static uint32_t empty_map[] = {0, 0, 0};
|
||||
|
||||
language->parse_table = create_parse_table();
|
||||
language->small_parse_table = (void *)empty_map;
|
||||
language->small_parse_table_map = (void *)empty_map;
|
||||
language->parse_actions = create_parse_actions_entries();
|
||||
language->symbol_names = create_symbols_names();
|
||||
language->field_names = create_field_names();
|
||||
language->field_map_slices = create_field_map_slices();
|
||||
language->field_map_entries = create_field_map_entries();
|
||||
language->symbol_metadata = create_symbols_metadata();
|
||||
language->public_symbol_map = create_unique_symbols_map();
|
||||
language->alias_map = create_non_terminal_alias_map();
|
||||
language->alias_sequences = create_alias_sequences();
|
||||
language->lex_modes = create_lex_modes();
|
||||
language->primary_state_ids = create_primary_state_ids();
|
||||
language->lex_fn = ts_lex;
|
||||
language->keyword_lex_fn = ts_lex_keywords;
|
||||
language->keyword_capture_token = sym_word;
|
||||
language->external_scanner = init_scanner();
|
||||
}
|
||||
|
||||
const t_language *tree_sitter_sh(void)
|
||||
{
|
||||
static bool init = false;
|
||||
static t_language language = {
|
||||
.version = LANGUAGE_VERSION,
|
||||
.symbol_count = SYMBOL_COUNT,
|
||||
.alias_count = ALIAS_COUNT,
|
||||
.token_count = TOKEN_COUNT,
|
||||
.external_token_count = EXTERNAL_TOKEN_COUNT,
|
||||
.state_count = STATE_COUNT,
|
||||
.large_state_count = LARGE_STATE_COUNT,
|
||||
.production_id_count = PRODUCTION_ID_COUNT,
|
||||
.field_count = FIELD_COUNT,
|
||||
.max_alias_sequence_length = MAX_ALIAS_SEQUENCE_LENGTH,
|
||||
};
|
||||
|
||||
if (!init)
|
||||
{
|
||||
init_language(&language);
|
||||
init = true;
|
||||
}
|
||||
return ((t_language *)&language);
|
||||
}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* external_scanner_state.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/24 13:55:33 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:05:53 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void ts_external_scanner_state_init(t_external_scanner_state *self,
|
||||
const t_u8 *data, t_u32 length)
|
||||
{
|
||||
self->length = length;
|
||||
self->long_data = mem_alloc(length);
|
||||
mem_copy(self->long_data, data, length);
|
||||
}
|
||||
|
||||
t_external_scanner_state ts_external_scanner_state_copy(\
|
||||
const t_external_scanner_state *self)
|
||||
{
|
||||
t_external_scanner_state result;
|
||||
|
||||
result = *self;
|
||||
result.long_data = mem_alloc(self->length);
|
||||
mem_copy(result.long_data, self->long_data, self->length);
|
||||
return (result);
|
||||
}
|
||||
|
||||
void ts_external_scanner_state_delete(t_external_scanner_state *self)
|
||||
{
|
||||
mem_free(self->long_data);
|
||||
}
|
||||
|
||||
const t_u8 *ts_external_scanner_state_data(\
|
||||
const t_external_scanner_state *self)
|
||||
{
|
||||
return ((const t_u8 *)self->long_data);
|
||||
}
|
||||
|
||||
bool ts_external_scanner_state_eq(const t_external_scanner_state *self,
|
||||
const t_u8 *buffer, t_u32 length)
|
||||
{
|
||||
return (self->length == length
|
||||
&& mem_compare(ts_external_scanner_state_data(self), buffer, length));
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* external_scanner_state2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:37:45 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:06:09 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/external_scanner_state.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
const t_external_scanner_state *ts_subtree_external_scanner_state(\
|
||||
t_subtree self)
|
||||
{
|
||||
static const t_external_scanner_state empty_state = {NULL, .length = 0};
|
||||
|
||||
if (self && self->has_external_tokens && self->child_count == 0)
|
||||
return (&self->external_scanner_state);
|
||||
else
|
||||
return (&empty_state);
|
||||
}
|
||||
|
||||
bool ts_subtree_external_scanner_state_eq(t_subtree self, t_subtree other)
|
||||
{
|
||||
const t_external_scanner_state *state_self = \
|
||||
ts_subtree_external_scanner_state(self);
|
||||
const t_external_scanner_state *state_other = \
|
||||
ts_subtree_external_scanner_state(other);
|
||||
|
||||
return (ts_external_scanner_state_eq(state_self,
|
||||
ts_external_scanner_state_data(state_other), state_other->length));
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* input.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:33:08 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:33:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/input.h"
|
||||
#include "me/types.h"
|
||||
|
||||
t_u32 ts_decode_ascii(const t_u8 *string, t_u32 length, t_i32 *code_point)
|
||||
{
|
||||
if (string == NULL || length == 0 || code_point == 0)
|
||||
return (0);
|
||||
*code_point = 0;
|
||||
*(t_u8 *)code_point = *string;
|
||||
return (1);
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* reduce_action.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:33:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 12:55:11 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/reduce_action.h"
|
||||
#include "me/vec/vec_reduce_action.h"
|
||||
|
||||
void ts_reduce_action_set_add(\
|
||||
t_vec_reduce_action *self, t_reduce_action new_action)
|
||||
{
|
||||
t_reduce_action action;
|
||||
t_u32 i;
|
||||
|
||||
i = 0;
|
||||
while (i < self->len)
|
||||
{
|
||||
action = self->buffer[i];
|
||||
if (action.symbol == new_action.symbol \
|
||||
&& action.count == new_action.count)
|
||||
return ;
|
||||
i++;
|
||||
}
|
||||
vec_reduce_action_push(self, new_action);
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_child.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:14:40 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:21:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
|
||||
t_u32 ts_node_child_count(t_node self)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
return (tree->visible_child_count);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_u32 ts_node_named_child_count(t_node self)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
return (tree->named_child_count);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
t_field_id ts_node_field_id_for_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
t_node result;
|
||||
bool did_descend;
|
||||
t_field_id inherited_field_id;
|
||||
t_node child;
|
||||
t_u32 index;
|
||||
NodeChildIterator iterator;
|
||||
t_u32 grandchild_index;
|
||||
t_u32 grandchild_count;
|
||||
t_field_id field_id;
|
||||
|
||||
result = self;
|
||||
did_descend = true;
|
||||
inherited_field_id = 0;
|
||||
while (did_descend)
|
||||
{
|
||||
did_descend = false;
|
||||
index = 0;
|
||||
iterator = ts_node_iterate_children(&result);
|
||||
while (ts_node_child_iterator_next(&iterator, &child))
|
||||
{
|
||||
if (ts_node__is_relevant(child, true))
|
||||
{
|
||||
if (index == child_index)
|
||||
{
|
||||
if (ts_node_is_extra(child))
|
||||
return (0);
|
||||
field_id = ts_node__field_id_from_language(result,
|
||||
iterator.structural_child_index - 1);
|
||||
if (field_id)
|
||||
return (field_id);
|
||||
return (inherited_field_id);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandchild_index = child_index - index;
|
||||
grandchild_count = ts_node__relevant_child_count(child, true);
|
||||
if (grandchild_index < grandchild_count)
|
||||
{
|
||||
field_id = ts_node__field_id_from_language(result,
|
||||
iterator.structural_child_index - 1);
|
||||
if (field_id)
|
||||
inherited_field_id = field_id;
|
||||
did_descend = true;
|
||||
result = child;
|
||||
child_index = grandchild_index;
|
||||
break ;
|
||||
}
|
||||
index += grandchild_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_childinner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:16:18 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:23:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
|
||||
t_node ts_node__child(t_node self, t_u32 child_index, bool include_anonymous)
|
||||
{
|
||||
t_node result;
|
||||
bool did_descend;
|
||||
t_node child;
|
||||
t_u32 index;
|
||||
NodeChildIterator iterator;
|
||||
t_u32 grandchild_index;
|
||||
t_u32 grandchild_count;
|
||||
|
||||
result = self;
|
||||
did_descend = true;
|
||||
while (did_descend)
|
||||
{
|
||||
did_descend = false;
|
||||
index = 0;
|
||||
iterator = ts_node_iterate_children(&result);
|
||||
while (ts_node_child_iterator_next(&iterator, &child))
|
||||
{
|
||||
if (ts_node__is_relevant(child, include_anonymous))
|
||||
{
|
||||
if (index == child_index)
|
||||
return (child);
|
||||
index++;
|
||||
}
|
||||
else
|
||||
{
|
||||
grandchild_index = child_index - index;
|
||||
grandchild_count = ts_node__relevant_child_count(child,
|
||||
include_anonymous);
|
||||
if (grandchild_index < grandchild_count)
|
||||
{
|
||||
did_descend = true;
|
||||
result = child;
|
||||
child_index = grandchild_index;
|
||||
break ;
|
||||
}
|
||||
index += grandchild_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ts_node__null());
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_constructor.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:10:57 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:24:15 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/api.h"
|
||||
#include "parser/length.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
t_node ts_node_new(const t_tree *tree, const t_subtree *subtree, \
|
||||
t_length position, t_symbol alias)
|
||||
{
|
||||
return ((t_node){
|
||||
position.bytes, position.extent.row, position.extent.column, \
|
||||
alias, subtree, tree,
|
||||
});
|
||||
}
|
||||
|
||||
t_node ts_node__null(void)
|
||||
{
|
||||
return (ts_node_new(NULL, NULL, length_zero(), 0));
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_fields.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:15:23 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:25:26 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/api.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_const_str ts_node__field_name_from_language(t_node self,
|
||||
t_u32 structural_child_index)
|
||||
{
|
||||
const TSFieldMapEntry *field_map;
|
||||
const TSFieldMapEntry *field_map_end;
|
||||
|
||||
ts_language_field_map(self.tree->language,
|
||||
ts_node__subtree(self)->production_id, &field_map, &field_map_end);
|
||||
while (field_map != field_map_end)
|
||||
{
|
||||
if (!field_map->inherited
|
||||
&& field_map->child_index == structural_child_index)
|
||||
return (self.tree->language->field_names[field_map->field_id]);
|
||||
field_map++;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
t_field_id ts_node__field_id_from_language(t_node self,
|
||||
t_u32 structural_child_index)
|
||||
{
|
||||
const TSFieldMapEntry *field_map;
|
||||
const TSFieldMapEntry *field_map_end;
|
||||
|
||||
ts_language_field_map(self.tree->language,
|
||||
ts_node__subtree(self)->production_id, &field_map, &field_map_end);
|
||||
while (field_map != field_map_end)
|
||||
{
|
||||
if (!field_map->inherited
|
||||
&& field_map->child_index == structural_child_index)
|
||||
return (field_map->field_id);
|
||||
field_map++;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:04:21 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
bool ts_node_is_extra(t_node self)
|
||||
{
|
||||
return (ts_subtree_extra(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
bool ts_node_is_named(t_node self)
|
||||
{
|
||||
t_symbol alias;
|
||||
|
||||
alias = ts_node__alias(&self);
|
||||
if (alias)
|
||||
return (ts_language_symbol_metadata(self.tree->language, alias).named);
|
||||
return (ts_subtree_named(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
t_node ts_node_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
return (ts_node__child(self, child_index, true));
|
||||
}
|
||||
|
||||
t_node ts_node_named_child(t_node self, t_u32 child_index)
|
||||
{
|
||||
return (ts_node__child(self, child_index, false));
|
||||
}
|
||||
|
|
@ -1,40 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:29:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:25 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_u32 ts_node_start_byte(t_node self)
|
||||
{
|
||||
return (self.start_byte);
|
||||
}
|
||||
|
||||
const t_language *ts_node_language(t_node self)
|
||||
{
|
||||
return (self.tree->language);
|
||||
}
|
||||
|
||||
t_point ts_node_start_point(t_node self)
|
||||
{
|
||||
return ((t_point){self.start_row, self.start_col});
|
||||
}
|
||||
|
||||
t_u32 ts_node__alias(const t_node *self)
|
||||
{
|
||||
return (self->alias);
|
||||
}
|
||||
|
||||
t_subtree ts_node__subtree(t_node self)
|
||||
{
|
||||
return (*(const t_subtree *)self.id);
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_getter_funcs3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:29:34 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:29:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
t_u32 ts_node_end_byte(t_node self)
|
||||
{
|
||||
return (ts_node_start_byte(self)
|
||||
+ ts_subtree_size(ts_node__subtree(self)).bytes);
|
||||
}
|
||||
|
||||
t_symbol ts_node_symbol(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_node__alias(&self);
|
||||
if (!symbol)
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_public_symbol(self.tree->language, symbol));
|
||||
}
|
||||
|
||||
t_const_str ts_node_type(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_node__alias(&self);
|
||||
if (!symbol)
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_symbol_name(self.tree->language, symbol));
|
||||
}
|
||||
|
||||
t_symbol ts_node_grammar_symbol(t_node self)
|
||||
{
|
||||
return (ts_subtree_symbol(ts_node__subtree(self)));
|
||||
}
|
||||
|
||||
t_const_str ts_node_grammar_type(t_node self)
|
||||
{
|
||||
t_symbol symbol;
|
||||
|
||||
symbol = ts_subtree_symbol(ts_node__subtree(self));
|
||||
return (ts_language_symbol_name(self.tree->language, symbol));
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_iterator.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:14:00 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:07:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
NodeChildIterator ts_node_iterate_children(const t_node *node)
|
||||
{
|
||||
t_subtree subtree;
|
||||
const t_symbol *alias_sequence;
|
||||
|
||||
subtree = ts_node__subtree(*node);
|
||||
if (ts_subtree_child_count(subtree) == 0)
|
||||
return ((NodeChildIterator){NULL, node->tree, length_zero(), 0, 0,
|
||||
NULL});
|
||||
alias_sequence = ts_language_alias_sequence(node->tree->language,
|
||||
subtree->production_id);
|
||||
return ((NodeChildIterator){
|
||||
.tree = node->tree,
|
||||
.parent = subtree,
|
||||
.position = {ts_node_start_byte(*node), ts_node_start_point(*node)},
|
||||
.child_index = 0,
|
||||
.structural_child_index = 0,
|
||||
.alias_sequence = alias_sequence,
|
||||
});
|
||||
}
|
||||
|
||||
bool ts_node_child_iterator_done(NodeChildIterator *self)
|
||||
{
|
||||
return (self->child_index == self->parent->child_count);
|
||||
}
|
||||
|
||||
bool ts_node_child_iterator_next(NodeChildIterator *self, t_node *result)
|
||||
{
|
||||
const t_subtree *child;
|
||||
t_symbol alias_symbol;
|
||||
|
||||
if (!self->parent || ts_node_child_iterator_done(self))
|
||||
return (false);
|
||||
alias_symbol = 0;
|
||||
child = &ts_subtree_children(self->parent)[self->child_index];
|
||||
if (!ts_subtree_extra(*child))
|
||||
{
|
||||
if (self->alias_sequence)
|
||||
alias_symbol = self->alias_sequence[self->structural_child_index];
|
||||
self->structural_child_index++;
|
||||
}
|
||||
if (self->child_index > 0)
|
||||
self->position = length_add(self->position, ts_subtree_padding(*child));
|
||||
*result = ts_node_new(self->tree, child, self->position, alias_symbol);
|
||||
self->position = length_add(self->position, ts_subtree_size(*child));
|
||||
self->child_index++;
|
||||
return (true);
|
||||
}
|
||||
|
|
@ -1,45 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* node_relevent.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:16:53 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:07:16 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/node.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/tree.h"
|
||||
|
||||
bool ts_node__is_relevant(t_node self, bool include_anonymous)
|
||||
{
|
||||
t_symbol alias;
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (include_anonymous)
|
||||
return (ts_subtree_visible(tree) || ts_node__alias(&self));
|
||||
alias = ts_node__alias(&self);
|
||||
if (alias)
|
||||
return (ts_language_symbol_metadata(self.tree->language, alias).named);
|
||||
else
|
||||
return (ts_subtree_visible(tree) && ts_subtree_named(tree));
|
||||
}
|
||||
|
||||
t_u32 ts_node__relevant_child_count(t_node self, bool include_anonymous)
|
||||
{
|
||||
t_subtree tree;
|
||||
|
||||
tree = ts_node__subtree(self);
|
||||
if (ts_subtree_child_count(tree) > 0)
|
||||
{
|
||||
if (include_anonymous)
|
||||
return (tree->visible_child_count);
|
||||
else
|
||||
return (tree->named_child_count);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_accept.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:02:35 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:37:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void _parser_accept_endloop(t_parser *self, t_subtree root, t_u32 *i)
|
||||
{
|
||||
self->accept_count++;
|
||||
if (self->finished_tree)
|
||||
{
|
||||
if (ts_parser__select_tree(self, self->finished_tree, root))
|
||||
{
|
||||
ts_subtree_release(self->finished_tree);
|
||||
self->finished_tree = root;
|
||||
}
|
||||
else
|
||||
ts_subtree_release(root);
|
||||
}
|
||||
else
|
||||
self->finished_tree = root;
|
||||
(*i)++;
|
||||
}
|
||||
|
||||
bool parser_select_root(\
|
||||
t_parser *self, t_vec_subtree *trees, t_subtree *root, t_u32 *j)
|
||||
{
|
||||
t_u32 k;
|
||||
t_u32 n;
|
||||
const t_subtree *childs;
|
||||
t_subtree tree;
|
||||
|
||||
tree = trees->buffer[*j];
|
||||
if (!ts_subtree_extra(tree))
|
||||
{
|
||||
n = ts_subtree_child_count(tree);
|
||||
childs = ts_subtree_children(tree);
|
||||
k = 0;
|
||||
while (k < n)
|
||||
{
|
||||
childs[k]->ref_count++;
|
||||
k++;
|
||||
}
|
||||
vec_subtree_splice(trees, vec_subtree_splice_args(*j, 1, n, childs));
|
||||
*root = ts_subtree_new_node(ts_subtree_symbol(tree), trees, \
|
||||
tree->production_id, self->language);
|
||||
ts_subtree_release(tree);
|
||||
return (true);
|
||||
}
|
||||
return ((*j)--, false);
|
||||
}
|
||||
|
||||
void ts_parser__accept(\
|
||||
t_parser *self, t_stack_version v, t_subtree lookahead)
|
||||
{
|
||||
t_stack_slice_array pop;
|
||||
t_vec_subtree trees;
|
||||
t_subtree root;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
|
||||
if (!ts_subtree_is_eof(lookahead))
|
||||
me_abort("failed assertion: lookahead isn't eof tree");
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){v, lookahead, 0, 1});
|
||||
pop = ts_stack_pop_all(self->stack, v);
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
trees = pop.contents[i].subtrees;
|
||||
root = NULL;
|
||||
j = trees.len - 1;
|
||||
while (j + 1 > 0)
|
||||
if (parser_select_root(self, &trees, &root, &j))
|
||||
break ;
|
||||
_parser_accept_endloop(self, root, &i);
|
||||
}
|
||||
ts_stack_remove_version(self->stack, pop.contents[0].version);
|
||||
ts_stack_halt(self->stack, v);
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_advance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:01:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:17:53 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parser_advance_do_lex(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state);
|
||||
bool _parser_advance_shift(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state);
|
||||
|
||||
bool _process_single_action(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
state->action = state->table_entry.actions[state->i];
|
||||
if (state->action.type == TSParseActionTypeShift)
|
||||
{
|
||||
if (_parser_advance_shift(self, version, state))
|
||||
return (true);
|
||||
return (false);
|
||||
}
|
||||
if (state->action.type == TSParseActionTypeReduce)
|
||||
{
|
||||
state->is_fragile = state->table_entry.action_count > 1;
|
||||
state->end_of_non_terminal_extra = state->lookahead == NULL;
|
||||
state->reduction_version = ts_parser__reduce(self, version,
|
||||
state->action.reduce.symbol, state->action.reduce.child_count,
|
||||
state->action.reduce.dynamic_precedence,
|
||||
state->action.reduce.production_id, state->is_fragile,
|
||||
state->end_of_non_terminal_extra);
|
||||
if (state->reduction_version != (t_stack_version)STACK_VERSION_NONE)
|
||||
state->last_reduction_version = state->reduction_version;
|
||||
state->i++;
|
||||
}
|
||||
if (state->action.type == TSParseActionTypeAccept)
|
||||
return (ts_parser__accept(self, version, state->lookahead), true);
|
||||
if (state->action.type == TSParseActionTypeRecover)
|
||||
return (ts_parser__recover(self, version, state->lookahead), true);
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _parser_handle_first_reduction(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
if (state->last_reduction_version != (t_stack_version)STACK_VERSION_NONE)
|
||||
{
|
||||
ts_stack_renumber_version(self->stack, state->last_reduction_version,
|
||||
version);
|
||||
state->state = ts_stack_state(self->stack, version);
|
||||
if (!state->lookahead)
|
||||
state->needs_lex = true;
|
||||
else
|
||||
ts_language_table_entry(self->language, state->state,
|
||||
ts_subtree_leaf_symbol(state->lookahead), &state->table_entry);
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _parser_handle_keyword(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
(void)(version);
|
||||
if (ts_subtree_is_keyword(state->lookahead)
|
||||
&& ts_subtree_symbol(state->lookahead) \
|
||||
!= self->language->keyword_capture_token)
|
||||
{
|
||||
ts_language_table_entry(self->language, state->state,
|
||||
self->language->keyword_capture_token, &state->table_entry);
|
||||
if (state->table_entry.action_count > 0)
|
||||
{
|
||||
state->mutable_lookahead = ts_subtree_ensure_owner(\
|
||||
state->lookahead);
|
||||
ts_subtree_set_symbol(&state->mutable_lookahead,
|
||||
self->language->keyword_capture_token, self->language);
|
||||
state->lookahead = state->mutable_lookahead;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _parser_loop_inner(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
while (state->i < state->table_entry.action_count)
|
||||
if (_process_single_action(self, version, state))
|
||||
return (true);
|
||||
if (_parser_handle_first_reduction(self, version, state))
|
||||
return (false);
|
||||
if (!state->lookahead)
|
||||
return (ts_stack_halt(self->stack, version), true);
|
||||
if (_parser_handle_keyword(self, version, state))
|
||||
return (false);
|
||||
if (state->state == ERROR_STATE)
|
||||
return (ts_parser__recover(self, version, state->lookahead), true);
|
||||
if (ts_parser__breakdown_top_of_stack(self, version))
|
||||
{
|
||||
state->state = ts_stack_state(self->stack, version);
|
||||
ts_subtree_release(state->lookahead);
|
||||
state->needs_lex = true;
|
||||
return (false);
|
||||
}
|
||||
return (ts_stack_pause(self->stack, version, state->lookahead), true);
|
||||
}
|
||||
|
||||
bool ts_parser__advance(t_parser *self, t_stack_version version)
|
||||
{
|
||||
struct s_parser_advance_state state;
|
||||
|
||||
state.lookahead = NULL;
|
||||
state.table_entry = (TableEntry){.action_count = 0};
|
||||
state.state = ts_stack_state(self->stack, version);
|
||||
state.needs_lex = true;
|
||||
while (true)
|
||||
{
|
||||
if (_parser_advance_do_lex(self, version, &state))
|
||||
return (false);
|
||||
if (_parser_loop_inner(self, version, &state))
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_advance_bis.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:01:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:00:08 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parser_advance_do_lex(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
if (state->needs_lex)
|
||||
{
|
||||
state->needs_lex = false;
|
||||
state->lookahead = ts_parser__lex(self, version, state->state);
|
||||
if (self->has_scanner_error)
|
||||
return (true);
|
||||
if (state->lookahead)
|
||||
ts_language_table_entry(self->language, state->state,
|
||||
ts_subtree_symbol(state->lookahead), &state->table_entry);
|
||||
else
|
||||
ts_language_table_entry(self->language, state->state,
|
||||
ts_builtin_sym_end, &state->table_entry);
|
||||
}
|
||||
state->last_reduction_version = (t_stack_version)STACK_VERSION_NONE;
|
||||
state->i = 0;
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _parser_advance_shift(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
struct s_parser_advance_state *state)
|
||||
{
|
||||
if (state->action.shift.repetition)
|
||||
{
|
||||
state->i++;
|
||||
return (false);
|
||||
}
|
||||
if (state->action.shift.extra)
|
||||
state->next_state = state->state;
|
||||
else
|
||||
state->next_state = state->action.shift.state;
|
||||
if (ts_subtree_child_count(state->lookahead) > 0)
|
||||
state->next_state = ts_language_next_state(self->language, state->state,
|
||||
ts_subtree_symbol(state->lookahead));
|
||||
ts_parser__shift(self, version, state->next_state, state->lookahead,
|
||||
state->action.shift.extra);
|
||||
return (true);
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_breakdown_top_of_stack.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:36:06 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:19:45 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__breakdown_top_of_stack(t_parser *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_state_id state;
|
||||
bool did_break_down;
|
||||
bool pending;
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_subtree child;
|
||||
t_subtree parent;
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_u32 n;
|
||||
bool first;
|
||||
|
||||
first = true;
|
||||
did_break_down = false;
|
||||
pending = false;
|
||||
while (pending || first)
|
||||
{
|
||||
first = false;
|
||||
pop = ts_stack_pop_pending(self->stack, version);
|
||||
if (!pop.size)
|
||||
break ;
|
||||
did_break_down = true;
|
||||
pending = false;
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
state = ts_stack_state(self->stack, slice.version);
|
||||
parent = *slice.subtrees.buffer;
|
||||
j = 0;
|
||||
n = ts_subtree_child_count(parent);
|
||||
while (j < n)
|
||||
{
|
||||
child = ts_subtree_children(parent)[j];
|
||||
pending = ts_subtree_child_count(child) > 0;
|
||||
if (ts_subtree_is_error(child))
|
||||
state = ERROR_STATE;
|
||||
else if (!ts_subtree_extra(child))
|
||||
state = ts_language_next_state(self->language, state,
|
||||
ts_subtree_symbol(child));
|
||||
child->ref_count++;
|
||||
ts_stack_push(self->stack,
|
||||
(struct s_stack_push_arg){slice.version, child, pending,
|
||||
state});
|
||||
j++;
|
||||
}
|
||||
j = 1;
|
||||
while (j < slice.subtrees.len)
|
||||
{
|
||||
tree = slice.subtrees.buffer[j];
|
||||
ts_stack_push(self->stack,
|
||||
(struct s_stack_push_arg){slice.version, tree, false,
|
||||
state});
|
||||
j++;
|
||||
}
|
||||
ts_subtree_release(parent);
|
||||
array_delete(&slice.subtrees);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return (did_break_down);
|
||||
}
|
||||
|
|
@ -1,108 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_condense_stack.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:57:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 13:57:41 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_u32 ts_parser__condense_stack(t_parser *self)
|
||||
{
|
||||
bool has_unpaused_version;
|
||||
t_error_comparison cmp;
|
||||
t_error_status status_i;
|
||||
t_error_status status_j;
|
||||
t_stack_version i;
|
||||
t_stack_version j;
|
||||
t_stack_version n;
|
||||
t_subtree lookahead;
|
||||
t_u32 min_error_cost;
|
||||
|
||||
min_error_cost = UINT_MAX;
|
||||
i = 0;
|
||||
while (i < ts_stack_version_count(self->stack))
|
||||
{
|
||||
if (ts_stack_is_halted(self->stack, i))
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
continue ;
|
||||
}
|
||||
status_i = ts_parser__version_status(self, i);
|
||||
if (!status_i.is_in_error && status_i.cost < min_error_cost)
|
||||
min_error_cost = status_i.cost;
|
||||
j = 0;
|
||||
while (j < i)
|
||||
{
|
||||
status_j = ts_parser__version_status(self, j);
|
||||
cmp = ts_parser__compare_versions(self, status_j, status_i);
|
||||
if (cmp == ECTakeLeft)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
if ((cmp == ECPreferLeft || cmp == ECNone)
|
||||
&& ts_stack_merge(self->stack, j, i))
|
||||
{
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
if (cmp == ECPreferRight)
|
||||
{
|
||||
if (ts_stack_merge(self->stack, j, i))
|
||||
{
|
||||
i--;
|
||||
j = i;
|
||||
}
|
||||
else
|
||||
ts_stack_swap_versions(self->stack, i, j);
|
||||
}
|
||||
if (cmp == ECTakeRight)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, j);
|
||||
i--;
|
||||
j--;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
while (ts_stack_version_count(self->stack) > MAX_VERSION_COUNT)
|
||||
ts_stack_remove_version(self->stack, MAX_VERSION_COUNT);
|
||||
if (ts_stack_version_count(self->stack) > 0)
|
||||
{
|
||||
has_unpaused_version = false;
|
||||
i = 0;
|
||||
n = ts_stack_version_count(self->stack);
|
||||
while (i < n)
|
||||
{
|
||||
if (ts_stack_is_paused(self->stack, i))
|
||||
{
|
||||
if (!has_unpaused_version
|
||||
&& self->accept_count < MAX_VERSION_COUNT)
|
||||
{
|
||||
min_error_cost = ts_stack_error_cost(self->stack, i);
|
||||
lookahead = ts_stack_resume(self->stack, i);
|
||||
ts_parser__handle_error(self, i, lookahead);
|
||||
has_unpaused_version = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ts_stack_remove_version(self->stack, i);
|
||||
i--;
|
||||
n--;
|
||||
}
|
||||
}
|
||||
else
|
||||
has_unpaused_version = true;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return (min_error_cost);
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_do_reduction.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:04:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:21:23 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__do_all_potential_reductions(t_parser *self,
|
||||
t_stack_version starting_version, t_symbol lookahead_symbol)
|
||||
{
|
||||
t_u32 initial_version_count;
|
||||
bool can_shift_lookahead_symbol;
|
||||
t_stack_version version;
|
||||
t_u32 i;
|
||||
t_u32 version_count;
|
||||
bool merged;
|
||||
t_stack_version j;
|
||||
t_state_id state;
|
||||
bool has_shift_action;
|
||||
t_symbol first_symbol;
|
||||
t_symbol end_symbol;
|
||||
t_stack_version reduction_version;
|
||||
t_reduce_action reduce_action;
|
||||
t_u32 k;
|
||||
t_symbol symbol;
|
||||
TableEntry entry;
|
||||
TSParseAction action;
|
||||
|
||||
initial_version_count = ts_stack_version_count(self->stack);
|
||||
can_shift_lookahead_symbol = false;
|
||||
version = starting_version;
|
||||
i = 0;
|
||||
while (true)
|
||||
{
|
||||
version_count = ts_stack_version_count(self->stack);
|
||||
if (version >= version_count)
|
||||
break ;
|
||||
merged = false;
|
||||
j = initial_version_count;
|
||||
while (j < version)
|
||||
{
|
||||
if (ts_stack_merge(self->stack, j, version))
|
||||
{
|
||||
merged = true;
|
||||
break ;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (merged)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
state = ts_stack_state(self->stack, version);
|
||||
has_shift_action = false;
|
||||
self->reduce_actions.len = 0;
|
||||
if (lookahead_symbol != 0)
|
||||
{
|
||||
first_symbol = lookahead_symbol;
|
||||
end_symbol = lookahead_symbol + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
first_symbol = 1;
|
||||
end_symbol = self->language->token_count;
|
||||
}
|
||||
symbol = first_symbol;
|
||||
while (symbol < end_symbol)
|
||||
{
|
||||
ts_language_table_entry(self->language, state, symbol, &entry);
|
||||
k = 0;
|
||||
while (k < entry.action_count)
|
||||
{
|
||||
action = entry.actions[k];
|
||||
if ((action.type == TSParseActionTypeShift
|
||||
|| action.type == TSParseActionTypeRecover)
|
||||
&& (!action.shift.extra && !action.shift.repetition))
|
||||
has_shift_action = true;
|
||||
if ((action.type == TSParseActionTypeReduce)
|
||||
&& (action.reduce.child_count > 0))
|
||||
ts_reduce_action_set_add(&self->reduce_actions,
|
||||
(t_reduce_action){
|
||||
.symbol = action.reduce.symbol,
|
||||
.count = action.reduce.child_count,
|
||||
.dynamic_precedence = action.reduce.dynamic_precedence,
|
||||
.production_id = action.reduce.production_id,
|
||||
});
|
||||
k++;
|
||||
}
|
||||
symbol++;
|
||||
}
|
||||
reduction_version = STACK_VERSION_NONE;
|
||||
k = 0;
|
||||
while (k < self->reduce_actions.len)
|
||||
{
|
||||
reduce_action = self->reduce_actions.buffer[k];
|
||||
reduction_version = ts_parser__reduce(self, version,
|
||||
reduce_action.symbol, reduce_action.count,
|
||||
reduce_action.dynamic_precedence,
|
||||
reduce_action.production_id, true, false);
|
||||
k++;
|
||||
}
|
||||
if (has_shift_action)
|
||||
can_shift_lookahead_symbol = true;
|
||||
else if (reduction_version != (t_stack_version)STACK_VERSION_NONE
|
||||
&& i < MAX_VERSION_COUNT)
|
||||
{
|
||||
ts_stack_renumber_version(self->stack, reduction_version, version);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
else if (lookahead_symbol != 0)
|
||||
ts_stack_remove_version(self->stack, version);
|
||||
if (version == starting_version)
|
||||
version = version_count;
|
||||
else
|
||||
version++;
|
||||
i++;
|
||||
}
|
||||
return (can_shift_lookahead_symbol);
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_external_scanner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/11 16:44:11 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:38:35 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__external_scanner_create(t_parser *self)
|
||||
{
|
||||
self->external_scanner_payload = self->language->external_scanner.create();
|
||||
}
|
||||
|
||||
void ts_parser__external_scanner_destroy(t_parser *self)
|
||||
{
|
||||
if (self->external_scanner_payload != NULL)
|
||||
{
|
||||
self->language->external_scanner.destroy(\
|
||||
self->external_scanner_payload);
|
||||
self->external_scanner_payload = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
t_u32 ts_parser__external_scanner_serialize(t_parser *self)
|
||||
{
|
||||
t_u32 length;
|
||||
|
||||
length = self->language->external_scanner.serialize(\
|
||||
self->external_scanner_payload, self->lexer.debug_buffer);
|
||||
if (length > TREE_SITTER_SERIALIZATION_BUFFER_SIZE)
|
||||
me_abort("assertion failed in " __FILE__ " `length > " \
|
||||
"TREE_SITTER_SERIALIZATION_BUFFER_SIZE`");
|
||||
return (length);
|
||||
}
|
||||
|
||||
void ts_parser__external_scanner_deserialize(t_parser *self, \
|
||||
t_subtree external_token)
|
||||
{
|
||||
const t_u8 *data;
|
||||
t_u32 length;
|
||||
|
||||
data = NULL;
|
||||
length = 0;
|
||||
if (external_token)
|
||||
{
|
||||
data = ts_external_scanner_state_data(\
|
||||
&external_token->external_scanner_state);
|
||||
length = external_token->external_scanner_state.length;
|
||||
printf("HERE\n");
|
||||
}
|
||||
self->language->external_scanner.deserialize(\
|
||||
self->external_scanner_payload, data, length);
|
||||
}
|
||||
|
||||
bool ts_parser__external_scanner_scan(t_parser *self,
|
||||
t_state_id external_lex_state)
|
||||
{
|
||||
const bool *valid_external_tokens;
|
||||
|
||||
valid_external_tokens = ts_language_enabled_external_tokens(\
|
||||
self->language, external_lex_state);
|
||||
return (self->language->external_scanner.scan(\
|
||||
self->external_scanner_payload, &self->lexer, valid_external_tokens));
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_handle_error.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:04:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:50 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_lexer__mark_end(t_lexer *_self);
|
||||
|
||||
void ts_parser__handle_error(t_parser *self, t_stack_version version,
|
||||
t_subtree lookahead)
|
||||
{
|
||||
t_length padding;
|
||||
t_length position;
|
||||
t_state_id state;
|
||||
t_state_id state_after_missing_symbol;
|
||||
t_symbol missing_symbol;
|
||||
bool did_insert_missing_token;
|
||||
t_stack_version v;
|
||||
t_stack_version version_with_missing_tree;
|
||||
t_subtree missing_tree;
|
||||
t_u32 i;
|
||||
t_u32 lookahead_bytes;
|
||||
t_u32 previous_version_count;
|
||||
t_u32 version_count;
|
||||
|
||||
previous_version_count = ts_stack_version_count(self->stack);
|
||||
ts_parser__do_all_potential_reductions(self, version, 0);
|
||||
version_count = ts_stack_version_count(self->stack);
|
||||
position = ts_stack_position(self->stack, version);
|
||||
did_insert_missing_token = false;
|
||||
v = version;
|
||||
while (v < version_count)
|
||||
{
|
||||
if (!did_insert_missing_token)
|
||||
{
|
||||
state = ts_stack_state(self->stack, v);
|
||||
missing_symbol = 1;
|
||||
while (missing_symbol < (t_u16)self->language->token_count)
|
||||
{
|
||||
state_after_missing_symbol = ts_language_next_state(self->language,
|
||||
state, missing_symbol);
|
||||
if (state_after_missing_symbol == 0
|
||||
|| state_after_missing_symbol == state)
|
||||
{
|
||||
missing_symbol++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_language_has_reduce_action(self->language,
|
||||
state_after_missing_symbol,
|
||||
ts_subtree_leaf_symbol(lookahead)))
|
||||
{
|
||||
ts_lexer_reset(&self->lexer, position);
|
||||
ts_lexer__mark_end((void *)&self->lexer);
|
||||
padding = length_sub(self->lexer.token_end_position,
|
||||
position);
|
||||
lookahead_bytes = ts_subtree_total_bytes(lookahead)
|
||||
+ ts_subtree_lookahead_bytes(lookahead);
|
||||
version_with_missing_tree = ts_stack_copy_version(self->stack,
|
||||
v);
|
||||
missing_tree = ts_subtree_new_missing_leaf(missing_symbol,
|
||||
padding, lookahead_bytes, self->language);
|
||||
ts_stack_push(self->stack,
|
||||
(struct s_stack_push_arg){version_with_missing_tree,
|
||||
missing_tree, false, state_after_missing_symbol});
|
||||
if (ts_parser__do_all_potential_reductions(self,
|
||||
version_with_missing_tree,
|
||||
ts_subtree_leaf_symbol(lookahead)))
|
||||
{
|
||||
did_insert_missing_token = true;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
missing_symbol++;
|
||||
}
|
||||
}
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){v, NULL, false,
|
||||
ERROR_STATE});
|
||||
if (v == version)
|
||||
v = previous_version_count;
|
||||
else
|
||||
v += 1;
|
||||
}
|
||||
i = previous_version_count;
|
||||
while (i < version_count)
|
||||
{
|
||||
ts_stack_merge(self->stack, version, previous_version_count);
|
||||
i++;
|
||||
}
|
||||
ts_stack_record_summary(self->stack, version, MAX_SUMMARY_DEPTH);
|
||||
ts_parser__recover(self, version, lookahead);
|
||||
}
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_lex.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:54:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:22:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_subtree ts_parser__lex(t_parser *self, t_stack_version version,
|
||||
t_state_id parse_state)
|
||||
{
|
||||
t_length current_position;
|
||||
t_length error_end_position;
|
||||
t_length error_start_position;
|
||||
t_length padding;
|
||||
t_length size;
|
||||
t_length start_position;
|
||||
TSLexMode lex_mode;
|
||||
t_symbol symbol;
|
||||
bool called_get_column;
|
||||
bool error_mode;
|
||||
bool external_scanner_state_changed;
|
||||
bool found_external_token;
|
||||
bool found_token;
|
||||
bool is_keyword;
|
||||
bool skipped_error;
|
||||
t_i32 first_error_character;
|
||||
t_subtree external_token;
|
||||
t_subtree result;
|
||||
t_u32 end_byte;
|
||||
t_u32 external_scanner_state_len;
|
||||
t_u32 lookahead_bytes;
|
||||
t_u32 lookahead_end_byte;
|
||||
|
||||
lex_mode = self->language->lex_modes[parse_state];
|
||||
if (lex_mode.lex_state == (t_u16)-1)
|
||||
return (NULL);
|
||||
start_position = ts_stack_position(self->stack, version);
|
||||
external_token = ts_stack_last_external_token(self->stack, version);
|
||||
found_external_token = false;
|
||||
error_mode = parse_state == ERROR_STATE;
|
||||
skipped_error = false;
|
||||
called_get_column = false;
|
||||
first_error_character = 0;
|
||||
error_start_position = length_zero();
|
||||
error_end_position = length_zero();
|
||||
lookahead_end_byte = 0;
|
||||
external_scanner_state_len = 0;
|
||||
external_scanner_state_changed = false;
|
||||
ts_lexer_reset(&self->lexer, start_position);
|
||||
while (true)
|
||||
{
|
||||
found_token = false;
|
||||
current_position = self->lexer.current_position;
|
||||
if (lex_mode.external_lex_state != 0)
|
||||
{
|
||||
ts_lexer_start(&self->lexer);
|
||||
ts_parser__external_scanner_deserialize(self, external_token);
|
||||
found_token = ts_parser__external_scanner_scan(self,
|
||||
lex_mode.external_lex_state);
|
||||
if (self->has_scanner_error)
|
||||
return (NULL);
|
||||
ts_lexer_finish(&self->lexer, &lookahead_end_byte);
|
||||
if (found_token)
|
||||
{
|
||||
external_scanner_state_len = ts_parser__external_scanner_serialize(self);
|
||||
external_scanner_state_changed = !ts_external_scanner_state_eq(ts_subtree_external_scanner_state(external_token),
|
||||
self->lexer.debug_buffer, external_scanner_state_len);
|
||||
if (self->lexer.token_end_position.bytes <= current_position.bytes
|
||||
&& (error_mode
|
||||
|| !ts_stack_has_advanced_since_error(self->stack,
|
||||
version)) && !external_scanner_state_changed)
|
||||
found_token = false;
|
||||
}
|
||||
if (found_token)
|
||||
{
|
||||
found_external_token = true;
|
||||
called_get_column = self->lexer.did_get_column;
|
||||
break ;
|
||||
}
|
||||
ts_lexer_reset(&self->lexer, current_position);
|
||||
}
|
||||
ts_lexer_start(&self->lexer);
|
||||
found_token = self->language->lex_fn(&self->lexer, lex_mode.lex_state);
|
||||
ts_lexer_finish(&self->lexer, &lookahead_end_byte);
|
||||
if (found_token)
|
||||
break ;
|
||||
if (!error_mode)
|
||||
{
|
||||
error_mode = true;
|
||||
lex_mode = self->language->lex_modes[ERROR_STATE];
|
||||
ts_lexer_reset(&self->lexer, start_position);
|
||||
continue ;
|
||||
}
|
||||
if (!skipped_error)
|
||||
{
|
||||
skipped_error = true;
|
||||
error_start_position = self->lexer.token_start_position;
|
||||
error_end_position = self->lexer.token_start_position;
|
||||
first_error_character = self->lexer.funcs.lookahead;
|
||||
}
|
||||
if (self->lexer.current_position.bytes == error_end_position.bytes)
|
||||
{
|
||||
if (self->lexer.funcs.eof(&self->lexer))
|
||||
{
|
||||
self->lexer.funcs.result_symbol = ts_builtin_sym_error;
|
||||
break ;
|
||||
}
|
||||
self->lexer.funcs.advance(&self->lexer, false);
|
||||
}
|
||||
error_end_position = self->lexer.current_position;
|
||||
}
|
||||
if (skipped_error)
|
||||
{
|
||||
padding = length_sub(error_start_position, start_position);
|
||||
size = length_sub(error_end_position, error_start_position);
|
||||
lookahead_bytes = lookahead_end_byte - error_end_position.bytes;
|
||||
result = ts_subtree_new_error((t_st_newerr_args){first_error_character,
|
||||
padding, size, lookahead_bytes, parse_state, self->language});
|
||||
}
|
||||
else
|
||||
{
|
||||
is_keyword = false;
|
||||
symbol = self->lexer.funcs.result_symbol;
|
||||
padding = length_sub(self->lexer.token_start_position, start_position);
|
||||
size = length_sub(self->lexer.token_end_position,
|
||||
self->lexer.token_start_position);
|
||||
lookahead_bytes = lookahead_end_byte
|
||||
- self->lexer.token_end_position.bytes;
|
||||
if (found_external_token)
|
||||
{
|
||||
symbol = self->language->external_scanner.symbol_map[symbol];
|
||||
}
|
||||
else if (symbol == self->language->keyword_capture_token && symbol != 0)
|
||||
{
|
||||
end_byte = self->lexer.token_end_position.bytes;
|
||||
ts_lexer_reset(&self->lexer, self->lexer.token_start_position);
|
||||
ts_lexer_start(&self->lexer);
|
||||
is_keyword = self->language->keyword_lex_fn(&self->lexer, 0);
|
||||
if (is_keyword && self->lexer.token_end_position.bytes == end_byte
|
||||
&& ts_language_has_actions(self->language, parse_state,
|
||||
self->lexer.funcs.result_symbol))
|
||||
{
|
||||
symbol = self->lexer.funcs.result_symbol;
|
||||
}
|
||||
}
|
||||
result = ts_subtree_new_leaf((t_st_newleaf_args){symbol, padding, size,
|
||||
lookahead_bytes, parse_state, found_external_token,
|
||||
called_get_column, is_keyword, self->language});
|
||||
if (found_external_token)
|
||||
{
|
||||
ts_external_scanner_state_init(&result->external_scanner_state,
|
||||
self->lexer.debug_buffer, external_scanner_state_len);
|
||||
result->has_external_scanner_state_change = external_scanner_state_changed;
|
||||
}
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 13:56:13 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 14:12:29 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_parser *ts_parser_new(t_language *language)
|
||||
{
|
||||
t_parser *self;
|
||||
|
||||
self = mem_alloc(sizeof(*self));
|
||||
ts_lexer_init(&self->lexer);
|
||||
self->reduce_actions = vec_reduce_action_new(4, NULL);
|
||||
self->stack = ts_stack_new();
|
||||
self->finished_tree = NULL;
|
||||
self->language = language;
|
||||
self->has_scanner_error = false;
|
||||
self->external_scanner_payload = NULL;
|
||||
self->operation_count = 0;
|
||||
return (self);
|
||||
}
|
||||
|
||||
void ts_parser_delete(t_parser *self)
|
||||
{
|
||||
if (!self)
|
||||
return ;
|
||||
ts_parser_reset(self);
|
||||
self->language = NULL;
|
||||
ts_stack_delete(self->stack);
|
||||
vec_reduce_action_free(self->reduce_actions);
|
||||
array_delete(&self->trailing_extras);
|
||||
array_delete(&self->trailing_extras2);
|
||||
array_delete(&self->scratch_trees);
|
||||
mem_free(self);
|
||||
}
|
||||
|
||||
void ts_parser_reset(t_parser *self)
|
||||
{
|
||||
ts_parser__external_scanner_destroy(self);
|
||||
ts_lexer_reset(&self->lexer, length_zero());
|
||||
ts_stack_clear(self->stack);
|
||||
if (self->finished_tree)
|
||||
{
|
||||
ts_subtree_release(self->finished_tree);
|
||||
self->finished_tree = NULL;
|
||||
}
|
||||
self->accept_count = 0;
|
||||
self->has_scanner_error = false;
|
||||
}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_outstanding_parse.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:56:59 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 13:57:06 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser_has_outstanding_parse(t_parser *self)
|
||||
{
|
||||
return (self->external_scanner_payload || ts_stack_state(self->stack,
|
||||
0) != 1 || ts_stack_node_count_since_error(self->stack, 0) != 0);
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_parse.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:56:28 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:18:23 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parse_condition(t_parser *self, t_u32 *version_count,
|
||||
t_stack_version *version)
|
||||
{
|
||||
*version_count = ts_stack_version_count(self->stack);
|
||||
return (*version < *version_count);
|
||||
}
|
||||
|
||||
t_error _parser_parse_init_state(\
|
||||
t_parser *self, t_input input, struct s_parser_parse_state *state)
|
||||
{
|
||||
self->operation_count = 0;
|
||||
state->first = true;
|
||||
state->last_position = 0;
|
||||
state->position = 0;
|
||||
state->result = NULL;
|
||||
state->version = 0;
|
||||
state->version_count = 0;
|
||||
if (!self->language || !input.read)
|
||||
return (ERROR);
|
||||
ts_lexer_set_input(&self->lexer, input);
|
||||
if (!ts_parser_has_outstanding_parse(self))
|
||||
{
|
||||
ts_parser__external_scanner_create(self);
|
||||
if (self->has_scanner_error)
|
||||
return (ts_parser_reset(self), ERROR);
|
||||
}
|
||||
return (NO_ERROR);
|
||||
}
|
||||
|
||||
t_tree *_parser_parse_end(\
|
||||
t_parser *self, t_input input, struct s_parser_parse_state state)
|
||||
{
|
||||
(void)(input);
|
||||
if (self->finished_tree == NULL)
|
||||
me_abort("self->finished_tree == NULL");
|
||||
ts_subtree_balance(self->finished_tree, self->language);
|
||||
state.result = ts_tree_new(self->finished_tree, self->language);
|
||||
self->finished_tree = NULL;
|
||||
ts_parser_reset(self);
|
||||
return (state.result);
|
||||
}
|
||||
|
||||
t_error _parser_parse_mainloop(\
|
||||
t_parser *self, t_input input, struct s_parser_parse_state *state)
|
||||
{
|
||||
(void)(input);
|
||||
state->first = false;
|
||||
state->version = 0;
|
||||
while (_parse_condition(self, &state->version_count, &state->version))
|
||||
{
|
||||
while (ts_stack_is_active(self->stack, state->version))
|
||||
{
|
||||
if (!ts_parser__advance(self, state->version))
|
||||
{
|
||||
if (self->has_scanner_error)
|
||||
return (ts_parser_reset(self), ERROR);
|
||||
return (ERROR);
|
||||
}
|
||||
state->position = \
|
||||
ts_stack_position(self->stack, state->version).bytes;
|
||||
if (state->position > state->last_position \
|
||||
|| (state->version > 0 && state->position == state->last_position))
|
||||
{
|
||||
state->last_position = state->position;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
state->version++;
|
||||
}
|
||||
return (NO_ERROR);
|
||||
}
|
||||
|
||||
t_tree *ts_parser_parse(t_parser *self, t_input input)
|
||||
{
|
||||
struct s_parser_parse_state state;
|
||||
|
||||
if (_parser_parse_init_state(self, input, &state))
|
||||
return (NULL);
|
||||
while (state.first || state.version_count != 0)
|
||||
{
|
||||
if (_parser_parse_mainloop(self, input, &state))
|
||||
return (NULL);
|
||||
state.min_error_cost = ts_parser__condense_stack(self);
|
||||
if (self->finished_tree \
|
||||
&& ts_subtree_error_cost(self->finished_tree) < state.min_error_cost)
|
||||
{
|
||||
ts_stack_clear(self->stack);
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return (_parser_parse_end(self, input, state));
|
||||
}
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_parse_str.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:49:37 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/13 14:19:20 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
const t_u8 *ts_string_input_read(void *_self, t_u32 byte, t_point point,
|
||||
t_u32 *length)
|
||||
{
|
||||
t_string_input *self;
|
||||
|
||||
(void)point;
|
||||
self = (t_string_input *)_self;
|
||||
if (byte >= self->length)
|
||||
{
|
||||
*length = 0;
|
||||
return ((const t_u8 *)"");
|
||||
}
|
||||
else
|
||||
{
|
||||
*length = self->length - byte;
|
||||
return (self->string + byte);
|
||||
}
|
||||
}
|
||||
|
||||
t_tree *ts_parser_parse_string(t_parser *self, t_const_str string,
|
||||
t_u32 length)
|
||||
{
|
||||
t_string_input input;
|
||||
|
||||
input = (t_string_input){(const t_u8 *)string, length};
|
||||
return (ts_parser_parse(self, (t_input){&input, ts_string_input_read}));
|
||||
}
|
||||
|
|
@ -1,178 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_recover.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:46:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:18:36 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__recover(t_parser *self, t_stack_version version,
|
||||
t_subtree lookahead)
|
||||
{
|
||||
t_length position;
|
||||
bool did_recover;
|
||||
bool would_merge;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_summary *summary;
|
||||
t_stack_summary_entry entry;
|
||||
t_subtree parent;
|
||||
t_u32 current_error_cost;
|
||||
t_u32 depth;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_u32 new_cost;
|
||||
t_u32 node_count_since_error;
|
||||
t_u32 previous_version_count;
|
||||
t_vec_subtree children;
|
||||
t_u32 n;
|
||||
const TSParseAction *actions;
|
||||
t_subtree error_repeat;
|
||||
t_subtree mutable_lookahead;
|
||||
|
||||
did_recover = false;
|
||||
previous_version_count = ts_stack_version_count(self->stack);
|
||||
position = ts_stack_position(self->stack, version);
|
||||
summary = ts_stack_get_summary(self->stack, version);
|
||||
node_count_since_error = ts_stack_node_count_since_error(self->stack,
|
||||
version);
|
||||
current_error_cost = ts_stack_error_cost(self->stack, version);
|
||||
if (summary && !ts_subtree_is_error(lookahead))
|
||||
{
|
||||
i = 0;
|
||||
while (i < summary->size)
|
||||
{
|
||||
entry = summary->contents[i];
|
||||
if (entry.state == ERROR_STATE)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
if (entry.position.bytes == position.bytes)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
depth = entry.depth;
|
||||
if (node_count_since_error > 0)
|
||||
depth++;
|
||||
would_merge = false;
|
||||
j = 0;
|
||||
while (j < previous_version_count)
|
||||
{
|
||||
if (ts_stack_state(self->stack, j) == entry.state
|
||||
&& ts_stack_position(self->stack,
|
||||
j).bytes == position.bytes)
|
||||
{
|
||||
would_merge = true;
|
||||
break ;
|
||||
}
|
||||
j++;
|
||||
}
|
||||
if (would_merge)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
new_cost = current_error_cost + entry.depth
|
||||
* ERROR_COST_PER_SKIPPED_TREE + (position.bytes
|
||||
- entry.position.bytes) * ERROR_COST_PER_SKIPPED_CHAR
|
||||
+ (position.extent.row - entry.position.extent.row)
|
||||
* ERROR_COST_PER_SKIPPED_LINE;
|
||||
if (ts_parser__better_version_exists(self, version, false,
|
||||
new_cost))
|
||||
break ;
|
||||
if (ts_language_has_actions(self->language, entry.state,
|
||||
ts_subtree_symbol(lookahead)))
|
||||
{
|
||||
if (ts_parser__recover_to_state(self, version, depth,
|
||||
entry.state))
|
||||
{
|
||||
did_recover = true;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = previous_version_count;
|
||||
while (i < ts_stack_version_count(self->stack))
|
||||
{
|
||||
if (!ts_stack_is_active(self->stack, i))
|
||||
ts_stack_remove_version(self->stack, i--);
|
||||
i++;
|
||||
}
|
||||
if (did_recover && ts_stack_version_count(self->stack) > MAX_VERSION_COUNT)
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
if (did_recover && ts_subtree_has_external_scanner_state_change(lookahead))
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
if (ts_subtree_is_eof(lookahead))
|
||||
{
|
||||
children = vec_subtree_new(16, NULL);
|
||||
parent = ts_subtree_new_error_node(&children, false, self->language);
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){version, parent,
|
||||
false, 1});
|
||||
ts_parser__accept(self, version, lookahead);
|
||||
return ;
|
||||
}
|
||||
new_cost = current_error_cost + ERROR_COST_PER_SKIPPED_TREE
|
||||
+ ts_subtree_total_bytes(lookahead) * ERROR_COST_PER_SKIPPED_CHAR
|
||||
+ ts_subtree_total_size(lookahead).extent.row
|
||||
* ERROR_COST_PER_SKIPPED_LINE;
|
||||
if (ts_parser__better_version_exists(self, version, false, new_cost))
|
||||
{
|
||||
ts_stack_halt(self->stack, version);
|
||||
ts_subtree_release(lookahead);
|
||||
return ;
|
||||
}
|
||||
actions = ts_language_actions(self->language, 1,
|
||||
ts_subtree_symbol(lookahead), &n);
|
||||
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n
|
||||
- 1].shift.extra)
|
||||
{
|
||||
mutable_lookahead = ts_subtree_ensure_owner(lookahead);
|
||||
ts_subtree_set_extra(&mutable_lookahead, true);
|
||||
lookahead = (mutable_lookahead);
|
||||
}
|
||||
children = vec_subtree_new(1, NULL);
|
||||
vec_subtree_push(&children, lookahead);
|
||||
error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children,
|
||||
0, self->language);
|
||||
if (node_count_since_error > 0)
|
||||
{
|
||||
pop = ts_stack_pop_count(self->stack, version, 1);
|
||||
if (pop.size > 1)
|
||||
{
|
||||
i = 1;
|
||||
while (i < pop.size)
|
||||
ts_subtree_array_delete(&pop.contents[i++].subtrees);
|
||||
while (ts_stack_version_count(self->stack) > pop.contents[0].version
|
||||
+ 1)
|
||||
ts_stack_remove_version(self->stack, pop.contents[0].version
|
||||
+ 1);
|
||||
}
|
||||
ts_stack_renumber_version(self->stack, pop.contents[0].version,
|
||||
version);
|
||||
vec_subtree_push(&pop.contents[0].subtrees, (error_repeat));
|
||||
error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat,
|
||||
&pop.contents[0].subtrees, 0, self->language);
|
||||
}
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){version,
|
||||
(error_repeat), false, ERROR_STATE});
|
||||
if (ts_subtree_has_external_tokens(lookahead))
|
||||
ts_stack_set_last_external_token(self->stack, version,
|
||||
ts_subtree_last_external_token(lookahead));
|
||||
}
|
||||
|
|
@ -1,93 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_recover_to_tree.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:48:22 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:23:55 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool ts_parser__recover_to_state(t_parser *self, t_stack_version version,
|
||||
t_u32 depth, t_state_id goal_state)
|
||||
{
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_version previous_version;
|
||||
t_subtree error;
|
||||
t_subtree error_tree;
|
||||
t_subtree tree;
|
||||
t_u32 error_child_count;
|
||||
t_u32 i;
|
||||
t_u32 j;
|
||||
t_vec_subtree error_trees;
|
||||
|
||||
previous_version = STACK_VERSION_NONE;
|
||||
pop = ts_stack_pop_count(self->stack, version, depth);
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
if (slice.version == previous_version)
|
||||
{
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
array_erase(&pop, i--);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_stack_state(self->stack, slice.version) != goal_state)
|
||||
{
|
||||
ts_stack_halt(self->stack, slice.version);
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
array_erase(&pop, i--);
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
error_trees = ts_stack_pop_error(self->stack, slice.version);
|
||||
if (error_trees.len > 0)
|
||||
{
|
||||
error_tree = error_trees.buffer[0];
|
||||
error_child_count = ts_subtree_child_count(error_tree);
|
||||
if (error_child_count > 0)
|
||||
{
|
||||
vec_subtree_splice(&slice.subtrees, vec_subtree_splice_args(0,
|
||||
0, error_child_count, ts_subtree_children(error_tree)));
|
||||
j = 0;
|
||||
while (j < error_child_count)
|
||||
{
|
||||
slice.subtrees.buffer[j]->ref_count++;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
ts_subtree_array_delete(&error_trees);
|
||||
}
|
||||
ts_subtree_array_remove_trailing_extras(&slice.subtrees,
|
||||
&self->trailing_extras);
|
||||
if (slice.subtrees.len > 0)
|
||||
{
|
||||
error = ts_subtree_new_error_node(&slice.subtrees, true,
|
||||
self->language);
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version,
|
||||
error, false, goal_state});
|
||||
}
|
||||
else
|
||||
{
|
||||
vec_subtree_free(slice.subtrees);
|
||||
}
|
||||
j = 0;
|
||||
while (j < self->trailing_extras.len)
|
||||
{
|
||||
tree = self->trailing_extras.buffer[j];
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){slice.version,
|
||||
tree, false, goal_state});
|
||||
j++;
|
||||
}
|
||||
previous_version = slice.version;
|
||||
i++;
|
||||
}
|
||||
return (previous_version != (t_stack_version)STACK_VERSION_NONE);
|
||||
}
|
||||
|
|
@ -1,129 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_reduce.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 14:03:09 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:24 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
t_stack_version ts_parser__reduce(t_parser *self, t_stack_version version,
|
||||
t_symbol symbol, t_u32 count, int dynamic_precedence,
|
||||
t_u16 production_id, bool is_fragile, bool end_of_non_terminal_extra)
|
||||
{
|
||||
t_state_id next_state;
|
||||
t_state_id state;
|
||||
t_stack_slice next_slice;
|
||||
t_stack_slice slice;
|
||||
t_stack_slice_array pop;
|
||||
t_stack_version k;
|
||||
t_stack_version slice_version;
|
||||
t_subtree parent;
|
||||
t_u32 i;
|
||||
t_u32 initial_version_count;
|
||||
t_u32 j;
|
||||
t_u32 removed_version_count;
|
||||
t_vec_subtree children;
|
||||
t_vec_subtree next_slice_children;
|
||||
|
||||
initial_version_count = ts_stack_version_count(self->stack);
|
||||
pop = ts_stack_pop_count(self->stack, version, count);
|
||||
removed_version_count = 0;
|
||||
i = 0;
|
||||
while (i < pop.size)
|
||||
{
|
||||
slice = pop.contents[i];
|
||||
slice_version = slice.version - removed_version_count;
|
||||
if (slice_version > MAX_VERSION_COUNT + MAX_VERSION_COUNT_OVERFLOW)
|
||||
{
|
||||
ts_stack_remove_version(self->stack, slice_version);
|
||||
ts_subtree_array_delete(&slice.subtrees);
|
||||
removed_version_count++;
|
||||
while (i + 1 < pop.size)
|
||||
{
|
||||
next_slice = pop.contents[i + 1];
|
||||
if (next_slice.version != slice.version)
|
||||
break ;
|
||||
ts_subtree_array_delete(&next_slice.subtrees);
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
children = slice.subtrees;
|
||||
ts_subtree_array_remove_trailing_extras(&children,
|
||||
&self->trailing_extras);
|
||||
parent = ts_subtree_new_node(symbol, &children, production_id,
|
||||
self->language);
|
||||
while (i + 1 < pop.size)
|
||||
{
|
||||
next_slice = pop.contents[i + 1];
|
||||
if (next_slice.version != slice.version)
|
||||
break ;
|
||||
i++;
|
||||
next_slice_children = next_slice.subtrees;
|
||||
ts_subtree_array_remove_trailing_extras(&next_slice_children,
|
||||
&self->trailing_extras2);
|
||||
if (ts_parser__select_children(self, (parent),
|
||||
&next_slice_children))
|
||||
{
|
||||
ts_subtree_array_clear(&self->trailing_extras);
|
||||
ts_subtree_release(parent);
|
||||
array_swap(&self->trailing_extras, &self->trailing_extras2);
|
||||
parent = ts_subtree_new_node(symbol, &next_slice_children,
|
||||
production_id, self->language);
|
||||
}
|
||||
else
|
||||
{
|
||||
self->trailing_extras2.len = 0;
|
||||
ts_subtree_array_delete(&next_slice.subtrees);
|
||||
}
|
||||
}
|
||||
state = ts_stack_state(self->stack, slice_version);
|
||||
next_state = ts_language_next_state(self->language, state, symbol);
|
||||
if (end_of_non_terminal_extra && next_state == state)
|
||||
parent->extra = true;
|
||||
if (is_fragile || pop.size > 1 || initial_version_count > 1)
|
||||
{
|
||||
parent->fragile_left = true;
|
||||
parent->fragile_right = true;
|
||||
parent->parse_state = TS_TREE_STATE_NONE;
|
||||
}
|
||||
else
|
||||
parent->parse_state = state;
|
||||
parent->dynamic_precedence += dynamic_precedence;
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){slice_version,
|
||||
(parent), false, next_state});
|
||||
j = 0;
|
||||
while (j < self->trailing_extras.len)
|
||||
{
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){slice_version,
|
||||
self->trailing_extras.buffer[j], false, next_state});
|
||||
j++;
|
||||
}
|
||||
k = 0;
|
||||
while (k < slice_version)
|
||||
{
|
||||
if (k == version)
|
||||
{
|
||||
k++;
|
||||
continue ;
|
||||
}
|
||||
if (ts_stack_merge(self->stack, k, slice_version))
|
||||
{
|
||||
removed_version_count++;
|
||||
break ;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (ts_stack_version_count(self->stack) > initial_version_count)
|
||||
return (initial_version_count);
|
||||
return (STACK_VERSION_NONE);
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_select.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:55:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 21:38:54 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
// Determine if a given tree should be replaced by an
|
||||
// alternative tree.
|
||||
//
|
||||
// The decision is based on the trees' error costs (if any),
|
||||
// their dynamic precedence, and finally, as a default, by a
|
||||
// recursive comparison of the trees' symbols.
|
||||
bool ts_parser__select_tree(t_parser *self, t_subtree left, t_subtree right)
|
||||
{
|
||||
int comparison;
|
||||
|
||||
(void)(self);
|
||||
if (!left)
|
||||
return (true);
|
||||
if (!right)
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(right) < ts_subtree_error_cost(left))
|
||||
return (true);
|
||||
if (ts_subtree_error_cost(left) < ts_subtree_error_cost(right))
|
||||
return (false);
|
||||
if (ts_subtree_dynamic_precedence(right) \
|
||||
> ts_subtree_dynamic_precedence(left))
|
||||
return (true);
|
||||
if (ts_subtree_dynamic_precedence(left) \
|
||||
> ts_subtree_dynamic_precedence(right))
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(left) > 0)
|
||||
return (true);
|
||||
comparison = ts_subtree_compare(left, right);
|
||||
return (comparison == 1);
|
||||
}
|
||||
|
||||
// Determine if a given tree's children should be replaced
|
||||
// by an alternative array of children.
|
||||
bool ts_parser__select_children(t_parser *self, t_subtree left,
|
||||
const t_vec_subtree *children)
|
||||
{
|
||||
t_subtree scratch_tree;
|
||||
|
||||
vec_subtree_copy_into(&self->scratch_trees, (void *)children);
|
||||
scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left),
|
||||
&self->scratch_trees, 0, self->language);
|
||||
return (ts_parser__select_tree(self, left, (scratch_tree)));
|
||||
}
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_shift.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:55:29 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:20:02 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
void ts_parser__shift(t_parser *self, t_stack_version version,
|
||||
t_state_id state, t_subtree lookahead, bool extra)
|
||||
{
|
||||
bool is_leaf;
|
||||
t_subtree result;
|
||||
t_subtree subtree_to_push;
|
||||
|
||||
is_leaf = ts_subtree_child_count(lookahead) == 0;
|
||||
subtree_to_push = lookahead;
|
||||
if (extra != ts_subtree_extra(lookahead) && is_leaf)
|
||||
{
|
||||
result = ts_subtree_ensure_owner(lookahead);
|
||||
ts_subtree_set_extra(&result, extra);
|
||||
subtree_to_push = (result);
|
||||
}
|
||||
ts_stack_push(self->stack, (struct s_stack_push_arg){version,
|
||||
subtree_to_push, !is_leaf, state});
|
||||
if (ts_subtree_has_external_tokens(subtree_to_push))
|
||||
ts_stack_set_last_external_token(self->stack, version,
|
||||
ts_subtree_last_external_token(subtree_to_push));
|
||||
}
|
||||
|
|
@ -1,128 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* parser_versions.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/13 13:42:50 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 22:17:04 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/parser_inner.h"
|
||||
|
||||
bool _parser_compare_inner(t_parser *self, \
|
||||
t_error_status a, t_error_status b, t_error_comparison *ret)
|
||||
{
|
||||
(void)(self);
|
||||
if (!a.is_in_error && b.is_in_error)
|
||||
{
|
||||
if (a.cost < b.cost)
|
||||
return (*ret = ECTakeLeft, true);
|
||||
else
|
||||
return (*ret = ECPreferLeft, true);
|
||||
}
|
||||
if (a.is_in_error && !b.is_in_error)
|
||||
{
|
||||
if (b.cost < a.cost)
|
||||
return (*ret = ECTakeRight, true);
|
||||
else
|
||||
return (*ret = ECPreferRight, true);
|
||||
}
|
||||
if (a.cost < b.cost)
|
||||
{
|
||||
if ((b.cost - a.cost) * (1 + a.node_count) > MAX_COST_DIFFERENCE)
|
||||
return (*ret = ECTakeLeft, true);
|
||||
else
|
||||
return (*ret = ECPreferLeft, true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
t_error_comparison ts_parser__compare_versions(t_parser *self,
|
||||
t_error_status a, t_error_status b)
|
||||
{
|
||||
t_error_comparison ret;
|
||||
|
||||
if (_parser_compare_inner(self, a, b, &ret))
|
||||
return (ret);
|
||||
if (b.cost < a.cost)
|
||||
{
|
||||
if ((a.cost - b.cost) * (1 + b.node_count) > MAX_COST_DIFFERENCE)
|
||||
return (ECTakeRight);
|
||||
else
|
||||
return (ECPreferRight);
|
||||
}
|
||||
if (a.dynamic_precedence > b.dynamic_precedence)
|
||||
return (ECPreferLeft);
|
||||
if (b.dynamic_precedence > a.dynamic_precedence)
|
||||
return (ECPreferRight);
|
||||
return (ECNone);
|
||||
}
|
||||
|
||||
t_error_status ts_parser__version_status(t_parser *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_u32 cost;
|
||||
bool is_paused;
|
||||
|
||||
cost = ts_stack_error_cost(self->stack, version);
|
||||
is_paused = ts_stack_is_paused(self->stack, version);
|
||||
if (is_paused)
|
||||
cost += ERROR_COST_PER_SKIPPED_TREE;
|
||||
return ((t_error_status){.cost = cost,
|
||||
.node_count = ts_stack_node_count_since_error(self->stack, version),
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
|
||||
.is_in_error = is_paused || ts_stack_state(self->stack,
|
||||
version) == ERROR_STATE});
|
||||
}
|
||||
|
||||
bool _better_version_end(\
|
||||
t_parser *self, t_stack_version version, \
|
||||
t_length position, t_error_status status)
|
||||
{
|
||||
t_stack_version i;
|
||||
t_stack_version n;
|
||||
t_error_comparison cmp;
|
||||
t_error_status status_i;
|
||||
|
||||
i = 0;
|
||||
n = ts_stack_version_count(self->stack);
|
||||
while (i < n)
|
||||
{
|
||||
if (i == version || !ts_stack_is_active(self->stack, i)
|
||||
|| ts_stack_position(self->stack, i).bytes < position.bytes)
|
||||
{
|
||||
i++;
|
||||
continue ;
|
||||
}
|
||||
status_i = ts_parser__version_status(self, i);
|
||||
cmp = ts_parser__compare_versions(self, status, status_i);
|
||||
if (cmp == ECTakeRight)
|
||||
return (true);
|
||||
if (cmp == ECPreferRight && ts_stack_can_merge(self->stack, i, version))
|
||||
return (true);
|
||||
i++;
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool ts_parser__better_version_exists(t_parser *self,
|
||||
t_stack_version version, bool is_in_error, t_u32 cost)
|
||||
{
|
||||
t_length position;
|
||||
t_error_status status;
|
||||
|
||||
if (self->finished_tree
|
||||
&& ts_subtree_error_cost(self->finished_tree) <= cost)
|
||||
return (true);
|
||||
position = ts_stack_position(self->stack, version);
|
||||
status = (t_error_status){
|
||||
.cost = cost,
|
||||
.is_in_error = is_in_error,
|
||||
.dynamic_precedence = ts_stack_dynamic_precedence(self->stack, version),
|
||||
.node_count = ts_stack_node_count_since_error(self->stack, version),
|
||||
};
|
||||
return (_better_version_end(self, version, position, status));
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:31:13 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:31:33 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/point.h"
|
||||
|
||||
t_point point__new(t_u32 row, t_u32 column)
|
||||
{
|
||||
return ((t_point){row, column});
|
||||
}
|
||||
|
||||
t_point point_add(t_point a, t_point b)
|
||||
{
|
||||
if (b.row > 0)
|
||||
return (point__new(a.row + b.row, b.column));
|
||||
else
|
||||
return (point__new(a.row, a.column + b.column));
|
||||
}
|
||||
|
||||
t_point point_sub(t_point a, t_point b)
|
||||
{
|
||||
if (a.row > b.row)
|
||||
return (point__new(a.row - b.row, a.column));
|
||||
else
|
||||
return (point__new(0, a.column - b.column));
|
||||
}
|
||||
|
||||
bool point_lte(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row < b.row) || (a.row == b.row && a.column <= b.column));
|
||||
}
|
||||
|
||||
bool point_lt(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row < b.row) || (a.row == b.row && a.column < b.column));
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* point_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:31:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 17:31:57 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/point.h"
|
||||
|
||||
bool point_gt(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row > b.row) || (a.row == b.row && a.column > b.column));
|
||||
}
|
||||
|
||||
bool point_gte(t_point a, t_point b)
|
||||
{
|
||||
return ((a.row > b.row) || (a.row == b.row && a.column >= b.column));
|
||||
}
|
||||
|
||||
bool point_eq(t_point a, t_point b)
|
||||
{
|
||||
return (a.row == b.row && a.column == b.column);
|
||||
}
|
||||
|
||||
t_point point_min(t_point a, t_point b)
|
||||
{
|
||||
if (a.row < b.row || (a.row == b.row && a.column < b.column))
|
||||
return (a);
|
||||
else
|
||||
return (b);
|
||||
}
|
||||
|
||||
t_point point_max(t_point a, t_point b)
|
||||
{
|
||||
if (a.row > b.row || (a.row == b.row && a.column > b.column))
|
||||
return (a);
|
||||
else
|
||||
return (b);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:12:41 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:47:19 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_heredoc_start(t_heredoc *heredoc, t_lexer *lexer);
|
||||
bool scan_heredoc_end_identifier(t_heredoc *heredoc, t_lexer *lexer);
|
||||
bool scan_heredoc_content(t_scanner *scanner, t_lexer *lexer, \
|
||||
enum e_token_type middle_type, enum e_token_type end_type);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols)
|
||||
{
|
||||
return (valid_symbols[ERROR_RECOVERY]);
|
||||
}
|
||||
|
|
@ -1,82 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scan.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:09:30 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:48:40 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool scan_bare_dollar(t_lexer *lexer)
|
||||
{
|
||||
while (me_isspace(lexer->funcs.lookahead) && lexer->funcs.lookahead != '\n'
|
||||
&& !lexer->funcs.eof((void *)lexer))
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.result_symbol = BARE_DOLLAR;
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
return (me_isspace(lexer->funcs.lookahead) \
|
||||
|| lexer->funcs.eof((void *)lexer) || lexer->funcs.lookahead == '\"');
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
if (valid_symbols[IMMEDIATE_DOUBLE_HASH]
|
||||
&& !(valid_symbols[ERROR_RECOVERY]))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '#')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '#')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead != '}')
|
||||
{
|
||||
lexer->funcs.result_symbol = IMMEDIATE_DOUBLE_HASH;
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,301 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* scanner.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/10 15:41:11 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:51:57 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
/**
|
||||
* Consume a "word" in POSIX parlance, and returns it unquoted.
|
||||
*
|
||||
* This is an approximate implementation that doesn't deal with any
|
||||
* POSIX-mandated substitution, and assumes the default value for
|
||||
* IFS.
|
||||
*/
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
lexer->funcs.result_symbol = CONCAT;
|
||||
if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '"' || lexer->funcs.lookahead == '\''
|
||||
|| lexer->funcs.lookahead == '\\')
|
||||
return (true);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
return (false);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
bool advanced_once;
|
||||
bool advance_once_space;
|
||||
|
||||
advanced_once = false;
|
||||
advance_once_space = false;
|
||||
(void)(scanner);
|
||||
(void)(lexer);
|
||||
(void)(valid_symbols);
|
||||
while (true)
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\"')
|
||||
return (false);
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '{' || lexer->funcs.lookahead == '('
|
||||
|| lexer->funcs.lookahead == '\''
|
||||
|| me_isalnum(lexer->funcs.lookahead))
|
||||
{
|
||||
lexer->funcs.result_symbol = EXPANSION_WORD;
|
||||
return (advanced_once);
|
||||
}
|
||||
advanced_once = true;
|
||||
}
|
||||
if (lexer->funcs.lookahead == '}')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = EXPANSION_WORD;
|
||||
return (advanced_once || advance_once_space);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '(' && !(advanced_once
|
||||
|| advance_once_space))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
while (lexer->funcs.lookahead != ')'
|
||||
&& !lexer->funcs.eof((void *)lexer))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '$')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '{'
|
||||
|| lexer->funcs.lookahead == '('
|
||||
|| lexer->funcs.lookahead == '\''
|
||||
|| me_isalnum(lexer->funcs.lookahead))
|
||||
return (lexer->funcs.result_symbol = EXPANSION_WORD,
|
||||
advanced_once);
|
||||
advanced_once = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
advanced_once = advanced_once
|
||||
|| !me_isspace(lexer->funcs.lookahead);
|
||||
advance_once_space = advance_once_space
|
||||
|| me_isspace(lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
}
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
if (lexer->funcs.lookahead == ')')
|
||||
{
|
||||
advanced_once = true;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
if (lexer->funcs.lookahead == '}')
|
||||
return (false);
|
||||
}
|
||||
else
|
||||
return (false);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '\'')
|
||||
return (false);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
return (false);
|
||||
advanced_once = advanced_once || !me_isspace(lexer->funcs.lookahead);
|
||||
advance_once_space = advance_once_space
|
||||
|| me_isspace(lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
bool is_number;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if ((lexer->funcs.lookahead == ' ' || lexer->funcs.lookahead == '\t'
|
||||
|| lexer->funcs.lookahead == '\r'
|
||||
|| (lexer->funcs.lookahead == '\n' && !valid_symbols[NEWLINE]))
|
||||
&& !valid_symbols[EXPANSION_WORD])
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
else if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.eof((void *)lexer))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (true);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '\r')
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
if (lexer->funcs.lookahead == '\n')
|
||||
lexer->funcs.advance((void *)lexer, true);
|
||||
else
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\\'
|
||||
&& valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
else
|
||||
break ;
|
||||
}
|
||||
if (!valid_symbols[EXPANSION_WORD] && (lexer->funcs.lookahead == '*'
|
||||
|| lexer->funcs.lookahead == '@' || lexer->funcs.lookahead == '?'
|
||||
|| lexer->funcs.lookahead == '-' || lexer->funcs.lookahead == '0'
|
||||
|| lexer->funcs.lookahead == '_'))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == '['
|
||||
|| lexer->funcs.lookahead == ':' || lexer->funcs.lookahead == '-'
|
||||
|| lexer->funcs.lookahead == '%' || lexer->funcs.lookahead == '#'
|
||||
|| lexer->funcs.lookahead == '/')
|
||||
return (false);
|
||||
if (valid_symbols[EXTGLOB_PATTERN] && \
|
||||
me_isspace(lexer->funcs.lookahead))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = EXTGLOB_PATTERN;
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
is_number = true;
|
||||
if (me_isdigit(lexer->funcs.lookahead))
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
else if (me_isalpha(lexer->funcs.lookahead) || \
|
||||
lexer->funcs.lookahead == '_')
|
||||
{
|
||||
is_number = false;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lexer->funcs.lookahead == '{')
|
||||
return (false);
|
||||
if (valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
if (me_isdigit(lexer->funcs.lookahead))
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
else if (me_isalpha(lexer->funcs.lookahead)
|
||||
|| lexer->funcs.lookahead == '_')
|
||||
{
|
||||
is_number = false;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
else
|
||||
break ;
|
||||
}
|
||||
if (is_number && valid_symbols[FILE_DESCRIPTOR]
|
||||
&& (lexer->funcs.lookahead == '>' || lexer->funcs.lookahead == '<'))
|
||||
return (lexer->funcs.result_symbol = FILE_DESCRIPTOR, true);
|
||||
if (valid_symbols[VARIABLE_NAME])
|
||||
{
|
||||
if (lexer->funcs.lookahead == '+')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == ':')
|
||||
return (lexer->funcs.result_symbol = VARIABLE_NAME, true);
|
||||
return (false);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '/')
|
||||
return (false);
|
||||
if (lexer->funcs.lookahead == '=' || lexer->funcs.lookahead == '['
|
||||
|| (lexer->funcs.lookahead == ':' && !valid_symbols[OPENING_PAREN])
|
||||
|| lexer->funcs.lookahead == '%' || (lexer->funcs.lookahead == '#'
|
||||
&& !is_number) || lexer->funcs.lookahead == '@'
|
||||
|| (lexer->funcs.lookahead == '-'))
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (true);
|
||||
}
|
||||
if (lexer->funcs.lookahead == '?')
|
||||
{
|
||||
lexer->funcs.mark_end((void *)lexer);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
lexer->funcs.result_symbol = VARIABLE_NAME;
|
||||
return (me_isalpha(lexer->funcs.lookahead));
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols)
|
||||
{
|
||||
if (valid_symbols[CONCAT] && !(valid_symbols[ERROR_RECOVERY])
|
||||
&& (!(lexer->funcs.lookahead == 0 || me_isspace(lexer->funcs.lookahead) \
|
||||
|| lexer->funcs.lookahead == '>' || lexer->funcs.lookahead == '<' \
|
||||
|| lexer->funcs.lookahead == ')' || lexer->funcs.lookahead == '(' \
|
||||
|| lexer->funcs.lookahead == ';' || lexer->funcs.lookahead == '&' \
|
||||
|| lexer->funcs.lookahead == '|' || lexer->funcs.lookahead == '{' \
|
||||
|| lexer->funcs.lookahead == '}')))
|
||||
return (scan_concat(scanner, lexer, valid_symbols));
|
||||
if (scan_double_hash(scanner, lexer, valid_symbols))
|
||||
return (true);
|
||||
if (valid_symbols[EMPTY_VALUE] && (me_isspace(lexer->funcs.lookahead)
|
||||
|| lexer->funcs.eof((void *)lexer) || lexer->funcs.lookahead == ';'
|
||||
|| lexer->funcs.lookahead == '&'))
|
||||
return (lexer->funcs.result_symbol = EMPTY_VALUE, true);
|
||||
if ((valid_symbols[VARIABLE_NAME] || valid_symbols[FILE_DESCRIPTOR])
|
||||
&& !(valid_symbols[ERROR_RECOVERY]))
|
||||
return (scan_literals(scanner, lexer, valid_symbols));
|
||||
if (valid_symbols[BARE_DOLLAR] && !(valid_symbols[ERROR_RECOVERY])
|
||||
&& scan_bare_dollar(lexer))
|
||||
return (true);
|
||||
if (valid_symbols[EXPANSION_WORD])
|
||||
return (scan_advance_words(scanner, lexer, valid_symbols));
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* serialize.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:08:04 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:53:51 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/mem/mem.h"
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word)
|
||||
{
|
||||
bool empty;
|
||||
t_i32 quote;
|
||||
|
||||
empty = true;
|
||||
quote = 0;
|
||||
if (lexer->funcs.lookahead == '\'' || lexer->funcs.lookahead == '"')
|
||||
{
|
||||
quote = lexer->funcs.lookahead;
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
while (lexer->funcs.lookahead && !((quote && \
|
||||
(lexer->funcs.lookahead == quote \
|
||||
|| lexer->funcs.lookahead == '\r' \
|
||||
|| lexer->funcs.lookahead == '\n')) || (!quote \
|
||||
&& me_isspace(lexer->funcs.lookahead))))
|
||||
{
|
||||
if (lexer->funcs.lookahead == '\\')
|
||||
{
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
if (!lexer->funcs.lookahead)
|
||||
return (false);
|
||||
}
|
||||
empty = false;
|
||||
string_push_char(unquoted_word, lexer->funcs.lookahead);
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
}
|
||||
string_push_char(unquoted_word, '\0');
|
||||
if (quote && lexer->funcs.lookahead == quote)
|
||||
lexer->funcs.advance((void *)lexer, false);
|
||||
return (!empty);
|
||||
}
|
||||
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer)
|
||||
{
|
||||
t_u32 size;
|
||||
|
||||
size = 0;
|
||||
buffer[size++] = (char)scanner->last_glob_paren_depth;
|
||||
buffer[size++] = (char)scanner->ext_was_in_double_quote;
|
||||
buffer[size++] = (char)scanner->ext_saw_outside_quote;
|
||||
return (size);
|
||||
}
|
||||
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length)
|
||||
{
|
||||
t_u32 size;
|
||||
|
||||
if (length == 0)
|
||||
mem_set_zero(scanner, sizeof(*scanner));
|
||||
else
|
||||
{
|
||||
size = 0;
|
||||
scanner->last_glob_paren_depth = buffer[size++];
|
||||
scanner->ext_was_in_double_quote = buffer[size++];
|
||||
scanner->ext_saw_outside_quote = buffer[size++];
|
||||
if (!(size == length))
|
||||
me_abort("assertion failed: size == length");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* tree_sitter.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: rparodi <rparodi@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 16:10:31 by rparodi #+# #+# */
|
||||
/* Updated: 2024/09/19 23:54:39 by rparodi ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/scanner_inner.h"
|
||||
|
||||
bool in_error_recovery(const bool *valid_symbols);
|
||||
void reset(t_scanner *scanner);
|
||||
bool advance_word(t_lexer *lexer, t_string *unquoted_word);
|
||||
t_u32 serialize(t_scanner *scanner, t_u8 *buffer);
|
||||
void deserialize(t_scanner *scanner, const t_u8 *buffer, t_u32 length);
|
||||
bool scan_bare_dollar(t_lexer *lexer);
|
||||
bool scan_double_hash(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_concat(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_heredoc_end(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_advance_words(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan_literals(t_scanner *scanner, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
bool scan(t_scanner *scanner, t_lexer *lexer, const bool *valid_symbols);
|
||||
void *tree_sitter_sh_external_scanner_create(void);
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer, \
|
||||
const bool *valid_symbols);
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state);
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload, \
|
||||
const t_u8 *state, t_u32 length);
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload);
|
||||
|
||||
void *tree_sitter_sh_external_scanner_create(void)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = mem_alloc(sizeof(*scanner));
|
||||
return (scanner);
|
||||
}
|
||||
|
||||
bool tree_sitter_sh_external_scanner_scan(void *payload, t_lexer *lexer,
|
||||
const bool *valid_symbols)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
return (scan(scanner, lexer, valid_symbols));
|
||||
}
|
||||
|
||||
t_u32 tree_sitter_sh_external_scanner_serialize(void *payload, t_u8 *state)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
return (serialize(scanner, state));
|
||||
}
|
||||
|
||||
void tree_sitter_sh_external_scanner_deserialize(void *payload,
|
||||
const t_u8 *state, t_u32 length)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
deserialize(scanner, state, length);
|
||||
}
|
||||
|
||||
void tree_sitter_sh_external_scanner_destroy(void *payload)
|
||||
{
|
||||
t_scanner *scanner;
|
||||
|
||||
scanner = (t_scanner *)payload;
|
||||
mem_free(scanner);
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_add_link.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:52:46 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:49:32 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void _add_link_tail(t_stack_node *self, t_stack_link link)
|
||||
{
|
||||
t_i32 dynamic_precedence;
|
||||
t_u32 node_count;
|
||||
|
||||
if (self->link_count == MAX_LINK_COUNT)
|
||||
return ;
|
||||
stack_node_retain(link.node);
|
||||
node_count = link.node->node_count;
|
||||
dynamic_precedence = link.node->dynamic_precedence;
|
||||
self->links[self->link_count++] = link;
|
||||
if (link.subtree)
|
||||
{
|
||||
(link.subtree->ref_count++);
|
||||
node_count += stack__subtree_node_count(link.subtree);
|
||||
dynamic_precedence += ts_subtree_dynamic_precedence(link.subtree);
|
||||
}
|
||||
if (node_count > self->node_count)
|
||||
self->node_count = node_count;
|
||||
if (dynamic_precedence > self->dynamic_precedence)
|
||||
self->dynamic_precedence = dynamic_precedence;
|
||||
}
|
||||
|
||||
bool _is_link_node_similar(\
|
||||
t_stack_node *self, t_stack_link link, \
|
||||
t_stack_link *ext_link)
|
||||
{
|
||||
t_usize j;
|
||||
t_i32 dynamic_precedence;
|
||||
|
||||
if (ext_link->node->state == link.node->state \
|
||||
&& ext_link->node->position.bytes == link.node->position.bytes
|
||||
&& ext_link->node->error_cost == link.node->error_cost)
|
||||
{
|
||||
j = 0;
|
||||
while (j < link.node->link_count)
|
||||
stack_node_add_link(ext_link->node,
|
||||
link.node->links[j++]);
|
||||
dynamic_precedence = link.node->dynamic_precedence;
|
||||
if (link.subtree)
|
||||
dynamic_precedence
|
||||
+= ts_subtree_dynamic_precedence(link.subtree);
|
||||
if (dynamic_precedence > self->dynamic_precedence)
|
||||
self->dynamic_precedence = dynamic_precedence;
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
bool _is_link_same_node(\
|
||||
t_stack_node *self, t_stack_link link, \
|
||||
t_stack_link *ext_link)
|
||||
{
|
||||
if (ext_link->node == link.node)
|
||||
{
|
||||
if (ts_subtree_dynamic_precedence(\
|
||||
link.subtree) > ts_subtree_dynamic_precedence(ext_link->subtree))
|
||||
{
|
||||
link.subtree->ref_count++;
|
||||
ts_subtree_release(ext_link->subtree);
|
||||
ext_link->subtree = link.subtree;
|
||||
self->dynamic_precedence = link.node->dynamic_precedence
|
||||
+ ts_subtree_dynamic_precedence(link.subtree);
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
// In general,
|
||||
// we preserve ambiguities until they are removed from the stack
|
||||
// during a pop operation where multiple paths lead to the same node. But in
|
||||
// the special case where two links directly connect the same pair of nodes,
|
||||
// we can safely remove the ambiguity ahead of time without changing behavior.
|
||||
void stack_node_add_link(t_stack_node *self, t_stack_link link)
|
||||
{
|
||||
t_stack_link *ext_link;
|
||||
t_usize i;
|
||||
|
||||
if (link.node == self)
|
||||
return ;
|
||||
i = 0;
|
||||
while (i < self->link_count)
|
||||
{
|
||||
ext_link = &self->links[i];
|
||||
if (stack__subtree_is_equivalent(ext_link->subtree, link.subtree))
|
||||
{
|
||||
if (_is_link_same_node(self, link, ext_link) \
|
||||
|| _is_link_node_similar(self, link, ext_link))
|
||||
return ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
_add_link_tail(self, link);
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs1.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:52:03 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 18:06:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool ts_stack_is_active(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusActive);
|
||||
}
|
||||
|
||||
bool ts_stack_is_halted(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusHalted);
|
||||
}
|
||||
|
||||
bool ts_stack_is_paused(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->status == SStatusPaused);
|
||||
}
|
||||
|
||||
t_subtree ts_stack_resume(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_subtree result;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
assert(head->status == SStatusPaused);
|
||||
result = head->lookahead_when_paused;
|
||||
head->status = SStatusActive;
|
||||
head->lookahead_when_paused = NULL;
|
||||
return (result);
|
||||
}
|
||||
|
||||
void ts_stack_clear(t_stack *self)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
stack_node_retain(self->base_node);
|
||||
i = 0;
|
||||
while (i < self->heads.size)
|
||||
stack_head_delete(&self->heads.contents[i++]);
|
||||
array_clear(&self->heads);
|
||||
array_push(&self->heads, ((t_stack_head){.node = self->base_node, \
|
||||
.status = SStatusActive, .last_external_token = NULL, \
|
||||
.lookahead_when_paused = NULL, }));
|
||||
}
|
||||
|
|
@ -1,76 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:55:52 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:38:38 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_u32 ts_stack_error_cost(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_u32 result;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
result = head->node->error_cost;
|
||||
if (head->status == SStatusPaused || (head->node->state == ERROR_STATE
|
||||
&& !head->node->links[0].subtree))
|
||||
{
|
||||
result += ERROR_COST_PER_RECOVERY;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_u32 ts_stack_node_count_since_error(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
if (head->node->node_count < head->node_count_at_last_error)
|
||||
{
|
||||
head->node_count_at_last_error = head->node->node_count;
|
||||
}
|
||||
return (head->node->node_count - head->node_count_at_last_error);
|
||||
}
|
||||
|
||||
int ts_stack_dynamic_precedence(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->dynamic_precedence);
|
||||
}
|
||||
|
||||
bool ts_stack_has_advanced_since_error(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
const t_stack_head *head = array_get(&self->heads, version);
|
||||
const t_stack_node *node = head->node;
|
||||
t_subtree subtree;
|
||||
|
||||
if (node->error_cost == 0)
|
||||
return (true);
|
||||
while (node)
|
||||
{
|
||||
if (node->link_count == 0)
|
||||
break ;
|
||||
subtree = node->links[0].subtree;
|
||||
if (subtree)
|
||||
{
|
||||
if (ts_subtree_total_bytes(subtree) > 0)
|
||||
return (true);
|
||||
else if (node->node_count > head->node_count_at_last_error
|
||||
&& ts_subtree_error_cost(subtree) == 0)
|
||||
{
|
||||
node = node->links[0].node;
|
||||
continue ;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
|
@ -1,110 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:56:40 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:56:49 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool stack__subtree_is_equivalent(t_subtree left, t_subtree right)
|
||||
{
|
||||
if (left == right)
|
||||
return (true);
|
||||
if (!left || !right)
|
||||
return (false);
|
||||
if (ts_subtree_symbol(left) != ts_subtree_symbol(right))
|
||||
return (false);
|
||||
if (ts_subtree_error_cost(left) > 0 && ts_subtree_error_cost(right) > 0)
|
||||
return (true);
|
||||
return (ts_subtree_padding(left).bytes == ts_subtree_padding(right).bytes
|
||||
&& ts_subtree_size(left).bytes == ts_subtree_size(right).bytes
|
||||
&& ts_subtree_child_count(left) == ts_subtree_child_count(right)
|
||||
&& ts_subtree_extra(left) == ts_subtree_extra(right)
|
||||
&& ts_subtree_external_scanner_state_eq(left, right));
|
||||
}
|
||||
|
||||
void stack_head_delete(t_stack_head *self)
|
||||
{
|
||||
if (self->node)
|
||||
{
|
||||
if (self->last_external_token)
|
||||
{
|
||||
ts_subtree_release(self->last_external_token);
|
||||
}
|
||||
if (self->lookahead_when_paused)
|
||||
{
|
||||
ts_subtree_release(self->lookahead_when_paused);
|
||||
}
|
||||
if (self->summary)
|
||||
{
|
||||
array_delete(self->summary);
|
||||
mem_free(self->summary);
|
||||
}
|
||||
stack_node_release(self->node);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_version ts_stack__add_version(t_stack *self,
|
||||
t_stack_version original_version, t_stack_node *node)
|
||||
{
|
||||
t_stack_head head;
|
||||
|
||||
head = (t_stack_head){
|
||||
.node = node,
|
||||
.node_count_at_last_error = \
|
||||
self->heads.contents[original_version].node_count_at_last_error,
|
||||
.last_external_token = \
|
||||
self->heads.contents[original_version].last_external_token,
|
||||
.status = SStatusActive,
|
||||
.lookahead_when_paused = NULL,
|
||||
};
|
||||
array_push(&self->heads, head);
|
||||
stack_node_retain(node);
|
||||
if (head.last_external_token)
|
||||
(head.last_external_token->ref_count++);
|
||||
return ((t_stack_version)(self->heads.size - 1));
|
||||
}
|
||||
|
||||
void ts_stack__add_slice(t_stack *self, \
|
||||
t_stack_version original_version, t_stack_node *node, t_vec_subtree *subtrees)
|
||||
{
|
||||
t_u32 i;
|
||||
t_stack_version version;
|
||||
t_stack_slice slice;
|
||||
|
||||
i = self->slices.size - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
version = self->slices.contents[i].version;
|
||||
if (self->heads.contents[version].node == node)
|
||||
{
|
||||
slice = (t_stack_slice){.subtrees = *subtrees, .version = version};
|
||||
array_insert(&self->slices, i + 1, slice);
|
||||
return ;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
version = ts_stack__add_version(self, original_version, node);
|
||||
slice = (t_stack_slice){.subtrees = *subtrees, .version = version};
|
||||
array_push(&self->slices, slice);
|
||||
}
|
||||
|
||||
void ts_stack_set_last_external_token(t_stack *self, t_stack_version version,
|
||||
t_subtree token)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
if (token)
|
||||
(token->ref_count++);
|
||||
if (head->last_external_token)
|
||||
ts_subtree_release(head->last_external_token);
|
||||
head->last_external_token = token;
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_funcs4.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:58:39 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:37:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
t_u32 ts_stack_version_count(const t_stack *self)
|
||||
{
|
||||
return (self->heads.size);
|
||||
}
|
||||
|
||||
t_state_id ts_stack_state(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->state);
|
||||
}
|
||||
|
||||
t_length ts_stack_position(const t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->node->position);
|
||||
}
|
||||
|
||||
t_subtree ts_stack_last_external_token(const t_stack *self,
|
||||
t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->last_external_token);
|
||||
}
|
||||
|
||||
/// Get the number of nodes in the subtree, for the purpose of measuring
|
||||
/// how much progress has been made by a given version of the stack.
|
||||
//
|
||||
// Count intermediate error nodes even though they are not visible,
|
||||
// because a stack version's node count is used to check whether it
|
||||
// has made any progress since the last time it encountered an error.
|
||||
t_u32 stack__subtree_node_count(t_subtree subtree)
|
||||
{
|
||||
t_u32 count;
|
||||
|
||||
count = ts_subtree_visible_descendant_count(subtree);
|
||||
if (ts_subtree_visible(subtree))
|
||||
count++;
|
||||
if (ts_subtree_symbol(subtree) == ts_builtin_sym_error_repeat)
|
||||
count++;
|
||||
return (count);
|
||||
}
|
||||
|
|
@ -1,147 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_iter.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:46:43 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:57:31 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void _set_stack_iter_vars(\
|
||||
t_stack *self, struct s_stack_iter_args *args)
|
||||
{
|
||||
t_stack_iterator new_iterator;
|
||||
t_stack_head *head;
|
||||
|
||||
array_clear(&self->slices);
|
||||
array_clear(&self->iterators);
|
||||
head = array_get(&self->heads, args->version);
|
||||
new_iterator = (t_stack_iterator){
|
||||
.node = head->node,
|
||||
.subtrees = vec_subtree_new(16, NULL),
|
||||
.subtree_count = 0,
|
||||
.is_pending = true,
|
||||
};
|
||||
if (args->goal_subtree_count >= 0)
|
||||
vec_subtree_reserve(&new_iterator.subtrees, \
|
||||
ts_subtree_alloc_size(args->goal_subtree_count) / sizeof(t_subtree));
|
||||
array_push(&self->iterators, new_iterator);
|
||||
}
|
||||
|
||||
bool _handle_pop_stop(\
|
||||
t_stack *self, struct s_stack_iter_args *args, \
|
||||
struct s_stack_iter_indexes *idx, t_stack_node **node)
|
||||
{
|
||||
t_stack_action action;
|
||||
t_stack_iterator *iterator;
|
||||
t_vec_subtree subtrees;
|
||||
|
||||
iterator = &self->iterators.contents[idx->i];
|
||||
*node = iterator->node;
|
||||
action = args->callback(args->payload, iterator);
|
||||
if (action & SActionPop)
|
||||
{
|
||||
subtrees = iterator->subtrees;
|
||||
if (action & SActionStop || (*node)->link_count == 0)
|
||||
ts_subtree_array_copy(subtrees, &subtrees);
|
||||
vec_subtree_reverse(&subtrees);
|
||||
ts_stack__add_slice(self, args->version, *node, &subtrees);
|
||||
}
|
||||
if (action & SActionStop || (*node)->link_count == 0)
|
||||
{
|
||||
if (!(action & SActionPop))
|
||||
ts_subtree_array_delete(&iterator->subtrees);
|
||||
(array_erase(&self->iterators, idx->i), idx->size--);
|
||||
return (true);
|
||||
}
|
||||
return (false);
|
||||
}
|
||||
|
||||
void _stack_iter_misc(t_stack_link *link, t_stack_iterator **next_iterator, \
|
||||
struct s_stack_iter_args *args)
|
||||
{
|
||||
(*next_iterator)->node = link->node;
|
||||
if (link->subtree)
|
||||
{
|
||||
if (args->goal_subtree_count >= 0)
|
||||
{
|
||||
vec_subtree_push(&(*next_iterator)->subtrees, link->subtree);
|
||||
link->subtree->ref_count++;
|
||||
}
|
||||
if (!ts_subtree_extra(link->subtree))
|
||||
{
|
||||
(*next_iterator)->subtree_count++;
|
||||
if (!link->is_pending)
|
||||
(*next_iterator)->is_pending = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
(*next_iterator)->subtree_count++;
|
||||
(*next_iterator)->is_pending = false;
|
||||
}
|
||||
}
|
||||
|
||||
void _func(t_stack *self, \
|
||||
t_stack_link *link, \
|
||||
t_stack_iterator **next_iterator, \
|
||||
struct s_stack_iter_args *args, \
|
||||
t_stack_node **node, \
|
||||
struct s_stack_iter_indexes *idx)
|
||||
{
|
||||
t_stack_iterator current_iterator;
|
||||
|
||||
if (idx->j == (*node)->link_count)
|
||||
{
|
||||
*link = (*node)->links[0];
|
||||
*next_iterator = &self->iterators.contents[idx->i];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (self->iterators.size >= MAX_ITERATOR_COUNT)
|
||||
{
|
||||
idx->j++;
|
||||
return ;
|
||||
}
|
||||
*link = (*node)->links[idx->j];
|
||||
current_iterator = self->iterators.contents[idx->i];
|
||||
array_push(&self->iterators, current_iterator);
|
||||
*next_iterator = array_back(&self->iterators);
|
||||
ts_subtree_array_copy((*next_iterator)->subtrees,
|
||||
&(*next_iterator)->subtrees);
|
||||
}
|
||||
_stack_iter_misc(link, next_iterator, args);
|
||||
idx->j++;
|
||||
}
|
||||
|
||||
t_stack_slice_array stack__iter(t_stack *self, struct s_stack_iter_args args)
|
||||
{
|
||||
t_stack_iterator *next_iterator;
|
||||
t_stack_link link;
|
||||
t_stack_node *node;
|
||||
struct s_stack_iter_indexes idx;
|
||||
|
||||
_set_stack_iter_vars(self, &args);
|
||||
while (self->iterators.size > 0)
|
||||
{
|
||||
idx.i = 0;
|
||||
idx.size = self->iterators.size;
|
||||
while (idx.i < idx.size)
|
||||
{
|
||||
if (_handle_pop_stop(self, &args, &idx, &node))
|
||||
continue ;
|
||||
idx.j = 1;
|
||||
while (idx.j <= node->link_count)
|
||||
_func(self, &link, &next_iterator, &args, &node, &idx);
|
||||
idx.i++;
|
||||
}
|
||||
}
|
||||
return (self->slices);
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_lifetime.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:47:47 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:48:13 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack *ts_stack_new(void)
|
||||
{
|
||||
t_stack *self;
|
||||
|
||||
self = mem_alloc(sizeof(*self));
|
||||
array_init(&self->heads);
|
||||
array_init(&self->slices);
|
||||
array_init(&self->iterators);
|
||||
array_reserve(&self->heads, 4);
|
||||
array_reserve(&self->slices, 4);
|
||||
array_reserve(&self->iterators, 4);
|
||||
self->base_node = stack_node_new(NULL, NULL, false, 1);
|
||||
ts_stack_clear(self);
|
||||
return (self);
|
||||
}
|
||||
|
||||
void ts_stack_delete(t_stack *self)
|
||||
{
|
||||
t_usize i;
|
||||
|
||||
i = 0;
|
||||
if (self->slices.contents)
|
||||
array_delete(&self->slices);
|
||||
if (self->iterators.contents)
|
||||
array_delete(&self->iterators);
|
||||
stack_node_release(self->base_node);
|
||||
while (i < self->heads.size)
|
||||
stack_head_delete(&self->heads.contents[i++]);
|
||||
array_clear(&self->heads);
|
||||
array_delete(&self->heads);
|
||||
mem_free(self);
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:50:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 17:57:27 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
|
||||
void ts_stack_push(t_stack *self, struct s_stack_push_arg args)
|
||||
{
|
||||
t_stack_head *head;
|
||||
t_stack_node *new_node;
|
||||
|
||||
head = array_get(&self->heads, args.version);
|
||||
new_node = stack_node_new(\
|
||||
head->node, args.subtree, args.pending, args.state);
|
||||
if (!args.subtree)
|
||||
head->node_count_at_last_error = new_node->node_count;
|
||||
head->node = new_node;
|
||||
}
|
||||
|
||||
t_stack_action pop_count_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
t_u32 *goal_subtree_count;
|
||||
|
||||
goal_subtree_count = payload;
|
||||
if (iterator->subtree_count == *goal_subtree_count)
|
||||
{
|
||||
return (SActionPop | SActionStop);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (SActionNone);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_count(t_stack *self, t_stack_version version,
|
||||
t_u32 count)
|
||||
{
|
||||
return (stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_count_callback, \
|
||||
&count, (int)count}));
|
||||
}
|
||||
|
||||
t_stack_action pop_pending_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
(void)payload;
|
||||
if (iterator->subtree_count >= 1)
|
||||
{
|
||||
if (iterator->is_pending)
|
||||
return (SActionPop | SActionStop);
|
||||
else
|
||||
return (SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_pending(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_slice_array pop;
|
||||
|
||||
pop = stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_pending_callback, NULL, 0});
|
||||
if (pop.size > 0)
|
||||
{
|
||||
ts_stack_renumber_version(self, pop.contents[0].version, version);
|
||||
pop.contents[0].version = version;
|
||||
}
|
||||
return (pop);
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate2.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:54:26 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:59:43 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/types.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
bool ts_stack_merge(t_stack *self, t_stack_version version1,
|
||||
t_stack_version version2)
|
||||
{
|
||||
t_stack_head *head1;
|
||||
t_stack_head *head2;
|
||||
t_usize i;
|
||||
|
||||
if (!ts_stack_can_merge(self, version1, version2))
|
||||
return (false);
|
||||
head1 = &self->heads.contents[version1];
|
||||
head2 = &self->heads.contents[version2];
|
||||
i = 0;
|
||||
while (i < head2->node->link_count)
|
||||
stack_node_add_link(head1->node, head2->node->links[i++]);
|
||||
if (head1->node->state == ERROR_STATE)
|
||||
head1->node_count_at_last_error = head1->node->node_count;
|
||||
ts_stack_remove_version(self, version2);
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool ts_stack_can_merge(t_stack *self, t_stack_version version1,
|
||||
t_stack_version version2)
|
||||
{
|
||||
t_stack_head *head1;
|
||||
t_stack_head *head2;
|
||||
|
||||
head1 = &self->heads.contents[version1];
|
||||
head2 = &self->heads.contents[version2];
|
||||
return (head1->status == SStatusActive && head2->status == SStatusActive
|
||||
&& head1->node->state == head2->node->state
|
||||
&& head1->node->position.bytes == head2->node->position.bytes
|
||||
&& head1->node->error_cost == head2->node->error_cost
|
||||
&& ts_subtree_external_scanner_state_eq(head1->last_external_token,
|
||||
head2->last_external_token));
|
||||
}
|
||||
|
||||
void ts_stack_halt(t_stack *self, t_stack_version version)
|
||||
{
|
||||
array_get(&self->heads, version)->status = SStatusHalted;
|
||||
}
|
||||
|
||||
void ts_stack_pause(t_stack *self, t_stack_version version,
|
||||
t_subtree lookahead)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
head = array_get(&self->heads, version);
|
||||
head->status = SStatusPaused;
|
||||
head->lookahead_when_paused = lookahead;
|
||||
head->node_count_at_last_error = head->node->node_count;
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_manipulate3.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 17:00:07 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:26:48 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack_action pop_error_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
bool *found_error;
|
||||
|
||||
if (iterator->subtrees.len > 0)
|
||||
{
|
||||
found_error = payload;
|
||||
if (!*found_error
|
||||
&& ts_subtree_is_error(iterator->subtrees.buffer[0]))
|
||||
{
|
||||
*found_error = true;
|
||||
return (SActionPop | SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionStop);
|
||||
}
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_vec_subtree ts_stack_pop_error(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_node *n;
|
||||
bool found_error;
|
||||
t_stack_slice_array pop;
|
||||
t_usize i;
|
||||
|
||||
n = array_get(&self->heads, version)->node;
|
||||
i = 0;
|
||||
while (i < n->link_count)
|
||||
{
|
||||
if (n->links[i].subtree && ts_subtree_is_error(n->links[i].subtree))
|
||||
{
|
||||
found_error = false;
|
||||
pop = stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_error_callback, &found_error, 1});
|
||||
if (pop.size > 0)
|
||||
{
|
||||
ts_stack_renumber_version(\
|
||||
self, pop.contents[0].version, version);
|
||||
return (pop.contents[0].subtrees);
|
||||
}
|
||||
break ;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return ((t_vec_subtree){NULL, 0, 0, NULL});
|
||||
}
|
||||
|
||||
t_stack_action pop_all_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
(void)payload;
|
||||
if (iterator->node->link_count == 0)
|
||||
return (SActionPop);
|
||||
else
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
t_stack_slice_array ts_stack_pop_all(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, pop_all_callback, NULL, 0}));
|
||||
}
|
||||
|
|
@ -1,106 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_node.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:48:48 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:37:07 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/language.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void stack_node_retain(t_stack_node *self)
|
||||
{
|
||||
if (!self)
|
||||
return ;
|
||||
assert(self->ref_count > 0);
|
||||
self->ref_count++;
|
||||
assert(self->ref_count != 0);
|
||||
}
|
||||
|
||||
void _stack_node_release_inner(\
|
||||
t_stack_node **self, bool *continue_, t_stack_link *link)
|
||||
{
|
||||
t_stack_node *first_predecessor;
|
||||
t_usize i;
|
||||
|
||||
first_predecessor = NULL;
|
||||
if ((*self)->link_count > 0)
|
||||
{
|
||||
i = (*self)->link_count - 1;
|
||||
while (i > 0)
|
||||
{
|
||||
*link = (*self)->links[i];
|
||||
if (link->subtree)
|
||||
ts_subtree_release(link->subtree);
|
||||
stack_node_release(link->node);
|
||||
i--;
|
||||
}
|
||||
*link = (*self)->links[0];
|
||||
if (link->subtree)
|
||||
ts_subtree_release(link->subtree);
|
||||
first_predecessor = (*self)->links[0].node;
|
||||
}
|
||||
if (mem_free(*self), first_predecessor)
|
||||
{
|
||||
*self = first_predecessor;
|
||||
*continue_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void stack_node_release(t_stack_node *self)
|
||||
{
|
||||
t_stack_link link;
|
||||
bool continue_;
|
||||
|
||||
continue_ = true;
|
||||
while (continue_)
|
||||
{
|
||||
continue_ = false;
|
||||
self->ref_count--;
|
||||
if (self->ref_count > 0)
|
||||
return ;
|
||||
_stack_node_release_inner(&self, &continue_, &link);
|
||||
}
|
||||
}
|
||||
|
||||
void _node_new_from_previous(t_stack_node *node, t_stack_node *prev, \
|
||||
t_subtree subtree, bool is_pending)
|
||||
{
|
||||
node->link_count = prev != NULL;
|
||||
node->links[0] = (t_stack_link){prev, subtree, is_pending};
|
||||
node->position = prev->position;
|
||||
node->error_cost = prev->error_cost;
|
||||
node->dynamic_precedence = prev->dynamic_precedence;
|
||||
node->node_count = prev->node_count;
|
||||
if (subtree)
|
||||
{
|
||||
node->error_cost += ts_subtree_error_cost(subtree);
|
||||
node->position = length_add(node->position, ts_subtree_total_size(\
|
||||
subtree));
|
||||
node->node_count += stack__subtree_node_count(subtree);
|
||||
node->dynamic_precedence += ts_subtree_dynamic_precedence(subtree);
|
||||
}
|
||||
}
|
||||
|
||||
t_stack_node *stack_node_new(t_stack_node *prev,
|
||||
t_subtree subtree, bool is_pending, t_state_id state)
|
||||
{
|
||||
t_stack_node *node;
|
||||
|
||||
node = mem_alloc(sizeof(t_stack_node));
|
||||
*node = (typeof(*node)){.ref_count = 1, .link_count = 0, .state = state};
|
||||
if (prev != NULL)
|
||||
_node_new_from_previous(node, prev, subtree, is_pending);
|
||||
else
|
||||
{
|
||||
node->position = length_zero();
|
||||
node->error_cost = 0;
|
||||
}
|
||||
return (node);
|
||||
}
|
||||
|
|
@ -1,69 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_summary.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:50:56 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/19 18:25:51 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
t_stack_action summarize_stack_callback(void *payload,
|
||||
const t_stack_iterator *iterator)
|
||||
{
|
||||
t_summarize_stack_session *session;
|
||||
t_state_id state;
|
||||
t_u32 depth;
|
||||
t_stack_summary_entry entry;
|
||||
t_usize i;
|
||||
|
||||
session = payload;
|
||||
state = iterator->node->state;
|
||||
depth = iterator->subtree_count;
|
||||
if (depth > session->max_depth)
|
||||
return (SActionStop);
|
||||
i = session->summary->size - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
if (session->summary->contents == NULL)
|
||||
return (SActionNone);
|
||||
entry = session->summary->contents[i--];
|
||||
if (entry.depth < depth)
|
||||
break ;
|
||||
if (entry.depth == depth && entry.state == state)
|
||||
return (SActionNone);
|
||||
}
|
||||
array_push(session->summary, ((t_stack_summary_entry){\
|
||||
.position = iterator->node->position, .depth = depth, .state = state, }));
|
||||
return (SActionNone);
|
||||
}
|
||||
|
||||
void ts_stack_record_summary(t_stack *self, t_stack_version version,
|
||||
t_u32 max_depth)
|
||||
{
|
||||
t_summarize_stack_session sess;
|
||||
t_stack_head *head;
|
||||
|
||||
sess = (t_summarize_stack_session){.summary = \
|
||||
mem_alloc(sizeof(t_stack_summary)), .max_depth = max_depth};
|
||||
array_init(sess.summary);
|
||||
stack__iter(self, \
|
||||
(struct s_stack_iter_args){version, summarize_stack_callback, &sess, -1});
|
||||
head = &self->heads.contents[version];
|
||||
if (head->summary)
|
||||
{
|
||||
array_delete(head->summary);
|
||||
mem_free(head->summary);
|
||||
}
|
||||
head->summary = sess.summary;
|
||||
}
|
||||
|
||||
t_stack_summary *ts_stack_get_summary(t_stack *self, t_stack_version version)
|
||||
{
|
||||
return (array_get(&self->heads, version)->summary);
|
||||
}
|
||||
|
|
@ -1,66 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* stack_version.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/08/31 16:55:04 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/08/31 16:55:34 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/inner/stack_inner.h"
|
||||
#include "parser/inner/stack_inner.h"
|
||||
|
||||
void ts_stack_remove_version(t_stack *self, t_stack_version version)
|
||||
{
|
||||
stack_head_delete(array_get(&self->heads, version));
|
||||
array_erase(&self->heads, version);
|
||||
}
|
||||
|
||||
void ts_stack_renumber_version(t_stack *self, t_stack_version v1,
|
||||
t_stack_version v2)
|
||||
{
|
||||
t_stack_head *source_head;
|
||||
t_stack_head *target_head;
|
||||
|
||||
if (v1 == v2)
|
||||
return ;
|
||||
assert(v2 < v1);
|
||||
assert((t_u32)v1 < self->heads.size);
|
||||
source_head = &self->heads.contents[v1];
|
||||
target_head = &self->heads.contents[v2];
|
||||
if (target_head->summary && !source_head->summary)
|
||||
{
|
||||
source_head->summary = target_head->summary;
|
||||
target_head->summary = NULL;
|
||||
}
|
||||
stack_head_delete(target_head);
|
||||
*target_head = *source_head;
|
||||
array_erase(&self->heads, v1);
|
||||
}
|
||||
|
||||
void ts_stack_swap_versions(t_stack *self, t_stack_version v1,
|
||||
t_stack_version v2)
|
||||
{
|
||||
t_stack_head temporary_head;
|
||||
|
||||
temporary_head = self->heads.contents[v1];
|
||||
self->heads.contents[v1] = self->heads.contents[v2];
|
||||
self->heads.contents[v2] = temporary_head;
|
||||
}
|
||||
|
||||
t_stack_version ts_stack_copy_version(t_stack *self, t_stack_version version)
|
||||
{
|
||||
t_stack_head *head;
|
||||
|
||||
assert(version < self->heads.size);
|
||||
array_push(&self->heads, self->heads.contents[version]);
|
||||
head = array_back(&self->heads);
|
||||
stack_node_retain(head->node);
|
||||
if (head->last_external_token)
|
||||
(head->last_external_token->ref_count++);
|
||||
head->summary = NULL;
|
||||
return (self->heads.size - 1);
|
||||
}
|
||||
|
|
@ -1,123 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_balance.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/14 12:53:20 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:02:24 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/inner/ptypes.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
bool _subtree_compress_inner(\
|
||||
t_subtree *tree, t_symbol symbol, t_vec_subtree *stack)
|
||||
{
|
||||
t_subtree child[2];
|
||||
|
||||
if ((*tree)->ref_count > 1 || (*tree)->child_count < 2)
|
||||
return (true);
|
||||
child[0] = (ts_subtree_children(*tree)[0]);
|
||||
if (child[0]->child_count < 2 || child[0]->ref_count > 1
|
||||
|| child[0]->symbol != symbol)
|
||||
return (true);
|
||||
child[1] = (ts_subtree_children(child[0])[0]);
|
||||
if (child[1]->child_count < 2 || child[1]->ref_count > 1
|
||||
|| child[1]->symbol != symbol)
|
||||
return (true);
|
||||
ts_subtree_children(*tree)[0] = child[1];
|
||||
ts_subtree_children(child[0])[0] = ts_subtree_children(child[1])[\
|
||||
child[1]->child_count - 1];
|
||||
ts_subtree_children(child[1])[child[1]->child_count - 1] = (child[0]);
|
||||
vec_subtree_push(stack, *tree);
|
||||
*tree = child[1];
|
||||
return (false);
|
||||
}
|
||||
|
||||
void ts_subtree__compress(t_subtree self, t_u32 count,
|
||||
const t_language *language, t_vec_subtree *stack)
|
||||
{
|
||||
t_symbol symbol;
|
||||
t_subtree child[2];
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 initial_stack_size;
|
||||
|
||||
initial_stack_size = stack->len;
|
||||
tree = self;
|
||||
symbol = tree->symbol;
|
||||
i = 0;
|
||||
while (i++ < count)
|
||||
if (_subtree_compress_inner(&tree, symbol, stack))
|
||||
break ;
|
||||
while (stack->len > initial_stack_size)
|
||||
{
|
||||
vec_subtree_pop(stack, &tree);
|
||||
child[0] = (ts_subtree_children(tree)[0]);
|
||||
child[1] = (ts_subtree_children(child[0])[child[0]->child_count - 1]);
|
||||
ts_subtree_summarize_children(child[1], language);
|
||||
ts_subtree_summarize_children(child[0], language);
|
||||
ts_subtree_summarize_children(tree, language);
|
||||
}
|
||||
}
|
||||
|
||||
void _subtree_balance_repush(t_vec_subtree *tree_stack, t_subtree tree)
|
||||
{
|
||||
t_u32 i;
|
||||
t_subtree child;
|
||||
|
||||
i = 0;
|
||||
while (i < tree->child_count)
|
||||
{
|
||||
child = ts_subtree_children(tree)[i];
|
||||
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
|
||||
vec_subtree_push(tree_stack, child);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void _subtree_balance_inner(\
|
||||
const t_language *language, t_vec_subtree *tree_stack)
|
||||
{
|
||||
t_i64 repeat_delta;
|
||||
t_subtree child[2];
|
||||
t_subtree tree;
|
||||
t_u32 i;
|
||||
t_u32 n;
|
||||
|
||||
if (vec_subtree_pop(tree_stack, &tree) && tree->repeat_depth > 0)
|
||||
{
|
||||
child[0] = ts_subtree_children(tree)[0];
|
||||
child[1] = ts_subtree_children(tree)[tree->child_count - 1];
|
||||
repeat_delta = (t_i64)ts_subtree_repeat_depth(child[0])
|
||||
- (t_i64)ts_subtree_repeat_depth(child[1]);
|
||||
if (repeat_delta > 0)
|
||||
{
|
||||
n = (t_u32)repeat_delta;
|
||||
i = n / 2;
|
||||
while (i > 0)
|
||||
{
|
||||
ts_subtree__compress(tree, i, language, tree_stack);
|
||||
n -= i;
|
||||
i /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
_subtree_balance_repush(tree_stack, tree);
|
||||
}
|
||||
|
||||
void ts_subtree_balance(t_subtree self, const t_language *language)
|
||||
{
|
||||
t_vec_subtree tree_stack;
|
||||
|
||||
tree_stack = vec_subtree_new(16, NULL);
|
||||
if (ts_subtree_child_count(self) > 0 && self->ref_count == 1)
|
||||
vec_subtree_push(&tree_stack, self);
|
||||
while (tree_stack.len > 0)
|
||||
_subtree_balance_inner(language, &tree_stack);
|
||||
vec_subtree_free(tree_stack);
|
||||
}
|
||||
|
|
@ -1,121 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_funcs.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 20:36:10 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:06:16 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "me/vec/vec_subtree.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void _subtree_release_inner(t_vec_subtree *to_free)
|
||||
{
|
||||
t_usize i;
|
||||
t_subtree *children;
|
||||
t_subtree tree;
|
||||
|
||||
vec_subtree_pop(to_free, &tree);
|
||||
if (tree->child_count > 0)
|
||||
{
|
||||
children = ts_subtree_children(tree);
|
||||
i = 0;
|
||||
while (i < tree->child_count)
|
||||
{
|
||||
if (--(children[i])->ref_count == 0)
|
||||
vec_subtree_push(to_free, children[i]);
|
||||
i++;
|
||||
}
|
||||
mem_free(children);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (tree->has_external_tokens)
|
||||
ts_external_scanner_state_delete(&tree->external_scanner_state);
|
||||
mem_free(tree);
|
||||
}
|
||||
}
|
||||
|
||||
void ts_subtree_release(t_subtree self)
|
||||
{
|
||||
t_vec_subtree to_free;
|
||||
|
||||
to_free = vec_subtree_new(16, NULL);
|
||||
if (--self->ref_count == 0)
|
||||
vec_subtree_push(&to_free, self);
|
||||
while (to_free.len > 0)
|
||||
_subtree_release_inner(&to_free);
|
||||
vec_subtree_free(to_free);
|
||||
}
|
||||
|
||||
int subtree_compare_func(t_subtree left, t_subtree right)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = 0;
|
||||
if (ts_subtree_symbol(left) < ts_subtree_symbol(right))
|
||||
result = -1;
|
||||
else if (ts_subtree_symbol(right) < ts_subtree_symbol(left))
|
||||
result = 1;
|
||||
else if (ts_subtree_child_count(left) < ts_subtree_child_count(right))
|
||||
result = -1;
|
||||
else if (ts_subtree_child_count(right) < ts_subtree_child_count(left))
|
||||
result = 1;
|
||||
return (result);
|
||||
}
|
||||
|
||||
int ts_subtree_compare(t_subtree left, t_subtree right)
|
||||
{
|
||||
t_vec_subtree cmp_stack;
|
||||
t_i8 result;
|
||||
t_usize i;
|
||||
|
||||
result = 0;
|
||||
cmp_stack = vec_subtree_new(16, NULL);
|
||||
vec_subtree_push(&cmp_stack, (left));
|
||||
vec_subtree_push(&cmp_stack, (right));
|
||||
while (cmp_stack.len >= 2)
|
||||
{
|
||||
vec_subtree_pop(&cmp_stack, &left);
|
||||
vec_subtree_pop(&cmp_stack, &right);
|
||||
result = subtree_compare_func(left, right);
|
||||
if (result != 0)
|
||||
return (vec_subtree_free(cmp_stack), result);
|
||||
i = ts_subtree_child_count(left);
|
||||
while (i > 0)
|
||||
{
|
||||
vec_subtree_push(&cmp_stack, ts_subtree_children(left)[i - 1]);
|
||||
vec_subtree_push(&cmp_stack, ts_subtree_children(right)[i - 1]);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return (vec_subtree_free(cmp_stack), 0);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_last_external_token(t_subtree tree)
|
||||
{
|
||||
t_usize i;
|
||||
t_subtree child;
|
||||
|
||||
if (!ts_subtree_has_external_tokens(tree))
|
||||
return (NULL);
|
||||
while (tree->child_count > 0)
|
||||
{
|
||||
i = tree->child_count - 1;
|
||||
while (i + 1 > 0)
|
||||
{
|
||||
child = ts_subtree_children(tree)[i];
|
||||
if (ts_subtree_has_external_tokens(child))
|
||||
{
|
||||
tree = child;
|
||||
break ;
|
||||
}
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return (tree);
|
||||
}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_helper.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:34:30 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/02 21:39:19 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void ts_subtree_set_symbol(t_subtree *self, t_symbol symbol,
|
||||
const t_language *language)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
|
||||
metadata = ts_language_symbol_metadata(language, symbol);
|
||||
(*self)->symbol = symbol;
|
||||
(*self)->named = metadata.named;
|
||||
(*self)->visible = metadata.visible;
|
||||
}
|
||||
|
||||
// Clone a subtree.
|
||||
t_subtree ts_subtree_clone(t_subtree self)
|
||||
{
|
||||
t_usize alloc_size;
|
||||
t_usize i;
|
||||
t_subtree *new_children;
|
||||
t_subtree *old_children;
|
||||
t_subtree_data *result;
|
||||
|
||||
alloc_size = ts_subtree_alloc_size(self->child_count);
|
||||
new_children = mem_alloc(alloc_size);
|
||||
old_children = ts_subtree_children(self);
|
||||
mem_copy(new_children, old_children, alloc_size);
|
||||
result = (t_subtree_data *)&new_children[self->child_count];
|
||||
i = 0;
|
||||
if (self->child_count > 0)
|
||||
{
|
||||
while (i < self->child_count)
|
||||
{
|
||||
new_children[i]->ref_count++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else if (self->has_external_tokens)
|
||||
result->external_scanner_state = \
|
||||
ts_external_scanner_state_copy(&self->external_scanner_state);
|
||||
result->ref_count = 1;
|
||||
return ((t_subtree)result);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_ensure_owner(t_subtree self)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_clone(self);
|
||||
ts_subtree_release(self);
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_new.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:33:35 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:14:56 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
// Create a new parent node with the given children.
|
||||
//
|
||||
// This takes ownership of the children array.
|
||||
t_subtree ts_subtree_new_node(t_symbol symbol, t_vec_subtree *children, \
|
||||
t_u32 production_id, const t_language *language)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
bool fragile;
|
||||
t_subtree data;
|
||||
|
||||
metadata = ts_language_symbol_metadata(language, symbol);
|
||||
fragile = symbol == ts_builtin_sym_error
|
||||
|| symbol == ts_builtin_sym_error_repeat;
|
||||
vec_subtree_reserve(children, ts_subtree_alloc_size(children->len)
|
||||
/ sizeof(t_subtree));
|
||||
data = (void *)&children->buffer[children->len];
|
||||
*data = (t_subtree_data){.ref_count = 1, .symbol = symbol, .child_count = \
|
||||
children->len, .visible = metadata.visible, .named = metadata.named, \
|
||||
.has_changes = false, .has_external_scanner_state_change = false, \
|
||||
.fragile_left = fragile, .fragile_right = fragile, .is_keyword = false, \
|
||||
{{.visible_descendant_count = 0, .production_id = production_id, \
|
||||
.first_leaf = {.symbol = 0, .parse_state = 0}, }}};
|
||||
ts_subtree_summarize_children(data, language);
|
||||
return (data);
|
||||
}
|
||||
|
||||
// Create a new error node containing the given children.
|
||||
//
|
||||
// This node is treated as 'extra'. Its children are prevented from having
|
||||
// having any effect on the parse state.
|
||||
t_subtree ts_subtree_new_error_node(t_vec_subtree *children, bool extra,
|
||||
const t_language *language)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
|
||||
result->extra = extra;
|
||||
return (result);
|
||||
}
|
||||
|
||||
// Create a new 'missing leaf' node.
|
||||
//
|
||||
// This node is treated as 'extra'. Its children are prevented from having
|
||||
// having any effect on the parse state.
|
||||
t_subtree ts_subtree_new_missing_leaf(t_symbol symbol, t_length padding,
|
||||
t_u32 lookahead_bytes, const t_language *language)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_leaf((t_st_newleaf_args){\
|
||||
symbol, padding, length_zero(), lookahead_bytes, 0, \
|
||||
false, false, false, language});
|
||||
result->is_missing = true;
|
||||
return (result);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_new_leaf(t_st_newleaf_args args)
|
||||
{
|
||||
t_symbol_metadata metadata;
|
||||
bool extra;
|
||||
t_subtree_data *data;
|
||||
|
||||
extra = args.symbol == ts_builtin_sym_end;
|
||||
metadata = ts_language_symbol_metadata(args.language, args.symbol);
|
||||
data = mem_alloc(sizeof(*data));
|
||||
*data = (t_subtree_data){.ref_count = 1, .padding = args.padding,
|
||||
.size = args.size, .lookahead_bytes = args.lookahead_bytes,
|
||||
.error_cost = 0, .child_count = 0,
|
||||
.symbol = args.symbol, .parse_state = args.parse_state,
|
||||
.visible = metadata.visible, .named = metadata.named, .extra = extra,
|
||||
.fragile_left = false, .fragile_right = false, .has_changes = false,
|
||||
.has_external_tokens = args.has_external_tokens,
|
||||
.has_external_scanner_state_change = false,
|
||||
.depends_on_column = args.depends_on_column, .is_missing = false,
|
||||
.is_keyword = args.is_keyword, {{.first_leaf = {.symbol = 0,
|
||||
.parse_state = 0}}}};
|
||||
return ((t_subtree)data);
|
||||
}
|
||||
|
||||
t_subtree ts_subtree_new_error(t_st_newerr_args args)
|
||||
{
|
||||
t_subtree result;
|
||||
|
||||
result = ts_subtree_new_leaf(\
|
||||
(t_st_newleaf_args){ts_builtin_sym_error, args.padding, \
|
||||
args.size, args.bytes_scanned, \
|
||||
args.parse_state, false, false, false, args.language});
|
||||
result->fragile_left = true;
|
||||
result->fragile_right = true;
|
||||
result->lookahead_char = args.lookahead_char;
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/* ************************************************************************** */
|
||||
/* */
|
||||
/* ::: :::::::: */
|
||||
/* subtree_summarize.c :+: :+: :+: */
|
||||
/* +:+ +:+ +:+ */
|
||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||
/* +#+#+#+#+#+ +#+ */
|
||||
/* Created: 2024/09/02 21:35:24 by maiboyer #+# #+# */
|
||||
/* Updated: 2024/09/14 14:31:14 by maiboyer ### ########.fr */
|
||||
/* */
|
||||
/* ************************************************************************** */
|
||||
|
||||
#include "parser/language.h"
|
||||
#include "parser/subtree.h"
|
||||
|
||||
void _summarize_loop_inner1(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner2(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner3(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
void _summarize_loop_inner4(t_subtree self, \
|
||||
const t_language *language, struct s_summarize_state *s);
|
||||
|
||||
void _sumarize_end(t_subtree self, t_subtree *children)
|
||||
{
|
||||
t_subtree first_child;
|
||||
t_subtree last_child;
|
||||
|
||||
if (self->child_count > 0)
|
||||
{
|
||||
first_child = children[0];
|
||||
last_child = children[self->child_count - 1];
|
||||
self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
|
||||
self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
|
||||
if (ts_subtree_fragile_left(first_child))
|
||||
self->fragile_left = true;
|
||||
if (ts_subtree_fragile_right(last_child))
|
||||
self->fragile_right = true;
|
||||
if (self->child_count >= 2 && !self->visible && !self->named
|
||||
&& ts_subtree_symbol(first_child) == self->symbol)
|
||||
{
|
||||
if (ts_subtree_repeat_depth(first_child) > \
|
||||
ts_subtree_repeat_depth(last_child))
|
||||
self->repeat_depth = ts_subtree_repeat_depth(first_child) + 1;
|
||||
else
|
||||
self->repeat_depth = ts_subtree_repeat_depth(last_child) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct s_summarize_state _init_sumnarize_state(t_subtree self,
|
||||
const t_language *language)
|
||||
{
|
||||
struct s_summarize_state s;
|
||||
|
||||
s = (typeof(s)){};
|
||||
self->named_child_count = 0;
|
||||
self->visible_child_count = 0;
|
||||
self->error_cost = 0;
|
||||
self->repeat_depth = 0;
|
||||
self->visible_descendant_count = 0;
|
||||
self->has_external_tokens = false;
|
||||
self->depends_on_column = false;
|
||||
self->has_external_scanner_state_change = false;
|
||||
self->dynamic_precedence = 0;
|
||||
s.alias_sequence = \
|
||||
ts_language_alias_sequence(language, self->production_id);
|
||||
s.structural_index = 0;
|
||||
s.lookahead_end_byte = 0;
|
||||
s.children = ts_subtree_children(self);
|
||||
s.i = 0;
|
||||
return (s);
|
||||
}
|
||||
|
||||
// Assign all of the node's properties that depend on its children.
|
||||
void ts_subtree_summarize_children(t_subtree self,
|
||||
const t_language *language)
|
||||
{
|
||||
struct s_summarize_state s;
|
||||
|
||||
s = _init_sumnarize_state(self, language);
|
||||
while (s.i < self->child_count)
|
||||
{
|
||||
_summarize_loop_inner1(self, language, &s);
|
||||
_summarize_loop_inner2(self, language, &s);
|
||||
_summarize_loop_inner3(self, language, &s);
|
||||
_summarize_loop_inner4(self, language, &s);
|
||||
}
|
||||
self->lookahead_bytes = s.lookahead_end_byte - self->size.bytes
|
||||
- self->padding.bytes;
|
||||
if (self->symbol == ts_builtin_sym_error
|
||||
|| self->symbol == ts_builtin_sym_error_repeat)
|
||||
self->error_cost += ERROR_COST_PER_RECOVERY
|
||||
+ ERROR_COST_PER_SKIPPED_CHAR * self->size.bytes
|
||||
+ ERROR_COST_PER_SKIPPED_LINE * self->size.extent.row;
|
||||
_sumarize_end(self, s.children);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue