did stuff, done stuff
This commit is contained in:
parent
4a8fb259dc
commit
62a4f377a1
37 changed files with 325 additions and 399 deletions
|
|
@ -20,7 +20,7 @@
|
||||||
typedef struct s_node_child_iterator NodeChildIterator;
|
typedef struct s_node_child_iterator NodeChildIterator;
|
||||||
struct s_node_child_iterator
|
struct s_node_child_iterator
|
||||||
{
|
{
|
||||||
Subtree parent;
|
t_subtree parent;
|
||||||
const TSTree *tree;
|
const TSTree *tree;
|
||||||
Length position;
|
Length position;
|
||||||
t_u32 child_index;
|
t_u32 child_index;
|
||||||
|
|
@ -37,7 +37,7 @@ bool ts_node_child_iterator_done(NodeChildIterator *self);
|
||||||
bool ts_node_child_iterator_next(NodeChildIterator *self, TSNode *result);
|
bool ts_node_child_iterator_next(NodeChildIterator *self, TSNode *result);
|
||||||
t_const_str ts_node__field_name_from_language(TSNode self, t_u32 structural_child_index);
|
t_const_str ts_node__field_name_from_language(TSNode self, t_u32 structural_child_index);
|
||||||
t_u32 ts_node__relevant_child_count(TSNode self, bool include_anonymous);
|
t_u32 ts_node__relevant_child_count(TSNode self, bool include_anonymous);
|
||||||
Subtree ts_node__subtree(TSNode self);
|
t_subtree ts_node__subtree(TSNode self);
|
||||||
t_u32 ts_node__alias(const TSNode *self);
|
t_u32 ts_node__alias(const TSNode *self);
|
||||||
|
|
||||||
#endif /* NODE_H */
|
#endif /* NODE_H */
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 16:37:50 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 16:37:50 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 16:53:40 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:36:27 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ typedef t_stack_action (*t_stack_callback)(void *,
|
||||||
struct s_stack_link
|
struct s_stack_link
|
||||||
{
|
{
|
||||||
t_stack_node *node;
|
t_stack_node *node;
|
||||||
Subtree subtree;
|
t_subtree subtree;
|
||||||
bool is_pending;
|
bool is_pending;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -71,8 +71,8 @@ struct s_stack_head
|
||||||
t_stack_node *node;
|
t_stack_node *node;
|
||||||
t_stack_summary *summary;
|
t_stack_summary *summary;
|
||||||
t_u32 node_count_at_last_error;
|
t_u32 node_count_at_last_error;
|
||||||
Subtree last_external_token;
|
t_subtree last_external_token;
|
||||||
Subtree lookahead_when_paused;
|
t_subtree lookahead_when_paused;
|
||||||
t_stack_status status;
|
t_stack_status status;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -97,11 +97,11 @@ struct s_summarize_stack_session
|
||||||
t_u32 max_depth;
|
t_u32 max_depth;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool stack__subtree_is_equivalent(Subtree left, Subtree right);
|
bool stack__subtree_is_equivalent(t_subtree left, t_subtree right);
|
||||||
t_stack_node *stack_node_new(t_stack_node *previous_node, Subtree subtree, bool is_pending, TSStateId state);
|
t_stack_node *stack_node_new(t_stack_node *previous_node, t_subtree subtree, bool is_pending, TSStateId state);
|
||||||
t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_callback callback, void *payload, int goal_subtree_count);
|
t_stack_slice_array stack__iter(t_stack *self, t_stack_version version, t_stack_callback callback, void *payload, int goal_subtree_count);
|
||||||
t_stack_version ts_stack__add_version(t_stack *self, t_stack_version original_version, t_stack_node *node);
|
t_stack_version ts_stack__add_version(t_stack *self, t_stack_version original_version, t_stack_node *node);
|
||||||
t_u32 stack__subtree_node_count(Subtree subtree);
|
t_u32 stack__subtree_node_count(t_subtree subtree);
|
||||||
void stack_head_delete(t_stack_head *self);
|
void stack_head_delete(t_stack_head *self);
|
||||||
void stack_node_add_link(t_stack_node *self, t_stack_link link);
|
void stack_node_add_link(t_stack_node *self, t_stack_link link);
|
||||||
void stack_node_release(t_stack_node *self);
|
void stack_node_release(t_stack_node *self);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/24 13:56:34 by maiboyer #+# #+# */
|
/* Created: 2024/08/24 13:56:34 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/24 14:00:11 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:34:46 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -15,21 +15,21 @@
|
||||||
|
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
|
|
||||||
struct ExternalScannerState
|
struct s_external_scanner_state
|
||||||
{
|
{
|
||||||
char *long_data;
|
char *long_data;
|
||||||
t_u32 length;
|
t_u32 length;
|
||||||
};
|
};
|
||||||
typedef struct ExternalScannerState ExternalScannerState;
|
typedef struct s_external_scanner_state t_external_scanner_state;
|
||||||
typedef struct SubtreeHeapData SubtreeHeapData;
|
typedef struct s_subtree_data t_subtree_data;
|
||||||
typedef const SubtreeHeapData *Subtree;
|
typedef const t_subtree_data *t_subtree;
|
||||||
|
|
||||||
void ts_external_scanner_state_init(ExternalScannerState *self, const t_u8 *data, t_u32 length);
|
void ts_external_scanner_state_init(t_external_scanner_state *self, const t_u8 *data, t_u32 length);
|
||||||
ExternalScannerState ts_external_scanner_state_copy(const ExternalScannerState *self);
|
t_external_scanner_state ts_external_scanner_state_copy(const t_external_scanner_state *self);
|
||||||
void ts_external_scanner_state_delete(ExternalScannerState *self);
|
void ts_external_scanner_state_delete(t_external_scanner_state *self);
|
||||||
const t_u8 *ts_external_scanner_state_data(const ExternalScannerState *self);
|
const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *self);
|
||||||
bool ts_external_scanner_state_eq(const ExternalScannerState *self, const t_u8 *buffer, t_u32 length);
|
bool ts_external_scanner_state_eq(const t_external_scanner_state *self, const t_u8 *buffer, t_u32 length);
|
||||||
const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self);
|
const t_external_scanner_state *ts_subtree_external_scanner_state(t_subtree self);
|
||||||
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other);
|
bool ts_subtree_external_scanner_state_eq(t_subtree self, t_subtree other);
|
||||||
|
|
||||||
#endif /* EXTERNAL_SCANNER_STATE_H */
|
#endif /* EXTERNAL_SCANNER_STATE_H */
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:16 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:16 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:30:26 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -16,13 +16,13 @@
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
|
|
||||||
struct Length
|
struct s_length
|
||||||
{
|
{
|
||||||
t_u32 bytes;
|
t_u32 bytes;
|
||||||
TSPoint extent;
|
TSPoint extent;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Length Length;
|
typedef struct s_length Length;
|
||||||
|
|
||||||
static const Length LENGTH_UNDEFINED = {0, {0, 1}};
|
static const Length LENGTH_UNDEFINED = {0, {0, 1}};
|
||||||
static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
|
static const Length LENGTH_MAX = {UINT32_MAX, {UINT32_MAX, UINT32_MAX}};
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:15 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:15 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:39:28 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
#include "parser/parser.h"
|
#include "parser/parser.h"
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
|
|
||||||
struct Lexer
|
struct s_lexer
|
||||||
{
|
{
|
||||||
TSLexer data;
|
TSLexer data;
|
||||||
Length current_position;
|
Length current_position;
|
||||||
|
|
@ -37,17 +37,17 @@ struct Lexer
|
||||||
t_u8 debug_buffer[TREE_SITTER_SERIALIZATION_BUFFER_SIZE];
|
t_u8 debug_buffer[TREE_SITTER_SERIALIZATION_BUFFER_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Lexer Lexer;
|
typedef struct s_lexer t_lexer;
|
||||||
|
|
||||||
void ts_lexer_init(Lexer *self);
|
void ts_lexer_init(t_lexer *self);
|
||||||
void ts_lexer_delete(Lexer *self);
|
void ts_lexer_delete(t_lexer *self);
|
||||||
void ts_lexer_set_input(Lexer *self, TSInput input);
|
void ts_lexer_set_input(t_lexer *self, TSInput input);
|
||||||
void ts_lexer_reset(Lexer *self, Length length);
|
void ts_lexer_reset(t_lexer *self, Length length);
|
||||||
void ts_lexer_start(Lexer *self);
|
void ts_lexer_start(t_lexer *self);
|
||||||
void ts_lexer_finish(Lexer *self, t_u32 *lookahead);
|
void ts_lexer_finish(t_lexer *self, t_u32 *lookahead);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_mark_end(Lexer *self);
|
void ts_lexer_mark_end(t_lexer *self);
|
||||||
bool ts_lexer_set_included_ranges(Lexer *self, const TSRange *ranges, t_u32 count);
|
bool ts_lexer_set_included_ranges(t_lexer *self, const TSRange *ranges, t_u32 count);
|
||||||
TSRange *ts_lexer_included_ranges(const Lexer *self, t_u32 *count);
|
TSRange *ts_lexer_included_ranges(const t_lexer *self, t_u32 *count);
|
||||||
|
|
||||||
#endif // LEXER_H
|
#endif // LEXER_H
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:13 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:13 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:45:04 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -46,9 +46,9 @@ typedef struct TSSymbolMetadata
|
||||||
bool supertype;
|
bool supertype;
|
||||||
} TSSymbolMetadata;
|
} TSSymbolMetadata;
|
||||||
|
|
||||||
typedef struct TSLexer TSLexer;
|
typedef struct s_lexer_functions TSLexer;
|
||||||
|
|
||||||
struct TSLexer
|
struct s_lexer_functions
|
||||||
{
|
{
|
||||||
t_i32 lookahead;
|
t_i32 lookahead;
|
||||||
TSSymbol result_symbol;
|
TSSymbol result_symbol;
|
||||||
|
|
@ -184,10 +184,10 @@ static inline bool set_contains(TSCharacterRange *ranges, t_u32 len, t_i32 looka
|
||||||
t_i32 lookahead; \
|
t_i32 lookahead; \
|
||||||
goto start; \
|
goto start; \
|
||||||
next_state: \
|
next_state: \
|
||||||
lexer->advance(lexer, skip); \
|
lexer->data.advance((void *)lexer, skip); \
|
||||||
start: \
|
start: \
|
||||||
skip = false; \
|
skip = false; \
|
||||||
lookahead = lexer->lookahead;
|
lookahead = lexer->data.lookahead;
|
||||||
|
|
||||||
#define ADVANCE(state_value) \
|
#define ADVANCE(state_value) \
|
||||||
{ \
|
{ \
|
||||||
|
|
@ -217,8 +217,8 @@ start:
|
||||||
|
|
||||||
#define ACCEPT_TOKEN(symbol_value) \
|
#define ACCEPT_TOKEN(symbol_value) \
|
||||||
result = true; \
|
result = true; \
|
||||||
lexer->result_symbol = symbol_value; \
|
lexer->data.result_symbol = symbol_value; \
|
||||||
lexer->mark_end(lexer);
|
lexer->data.mark_end((void *)lexer);
|
||||||
|
|
||||||
#define END_STATE() return result;
|
#define END_STATE() return result;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:09 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:09 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:03:29 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:31:33 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#include "parser/array.h"
|
#include "parser/array.h"
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
|
|
||||||
struct ReduceAction
|
struct s_reduce_action
|
||||||
{
|
{
|
||||||
t_u32 count;
|
t_u32 count;
|
||||||
TSSymbol symbol;
|
TSSymbol symbol;
|
||||||
|
|
@ -25,7 +25,7 @@ struct ReduceAction
|
||||||
t_u16 production_id;
|
t_u16 production_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ReduceAction ReduceAction;
|
typedef struct s_reduce_action ReduceAction;
|
||||||
typedef Array(ReduceAction) ReduceActionSet;
|
typedef Array(ReduceAction) ReduceActionSet;
|
||||||
|
|
||||||
void ts_reduce_action_set_add(ReduceActionSet *self, ReduceAction new_action);
|
void ts_reduce_action_set_add(ReduceActionSet *self, ReduceAction new_action);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:07 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:07 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 15:27:32 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:34:46 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -39,98 +39,36 @@ struct s_stack_summary_entry
|
||||||
TSStateId state;
|
TSStateId state;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a stack.
|
t_stack *ts_stack_new(void);
|
||||||
t_stack *ts_stack_new(/*SubtreePool **/);
|
|
||||||
|
|
||||||
// Release the memory reserved for a given stack.
|
|
||||||
void ts_stack_delete(t_stack *);
|
void ts_stack_delete(t_stack *);
|
||||||
|
|
||||||
// Get the stack's current number of versions.
|
|
||||||
t_u32 ts_stack_version_count(const t_stack *);
|
t_u32 ts_stack_version_count(const t_stack *);
|
||||||
|
|
||||||
// Get the state at the top of the given version of the stack. If the stack is
|
|
||||||
// empty, this returns the initial state, 0.
|
|
||||||
TSStateId ts_stack_state(const t_stack *, t_stack_version);
|
TSStateId ts_stack_state(const t_stack *, t_stack_version);
|
||||||
|
t_subtree ts_stack_last_external_token(const t_stack *, t_stack_version);
|
||||||
// Get the last external token associated with a given version of the stack.
|
void ts_stack_set_last_external_token(t_stack *, t_stack_version, t_subtree);
|
||||||
Subtree ts_stack_last_external_token(const t_stack *, t_stack_version);
|
|
||||||
|
|
||||||
// Set the last external token associated with a given version of the stack.
|
|
||||||
void ts_stack_set_last_external_token(t_stack *, t_stack_version, Subtree);
|
|
||||||
|
|
||||||
// Get the position of the given version of the stack within the document.
|
|
||||||
Length ts_stack_position(const t_stack *, t_stack_version);
|
Length ts_stack_position(const t_stack *, t_stack_version);
|
||||||
|
void ts_stack_push(t_stack *, t_stack_version, t_subtree, bool, TSStateId);
|
||||||
// Push a tree and state onto the given version of the stack.
|
|
||||||
//
|
|
||||||
// This transfers ownership of the tree to the t_stack. Callers that
|
|
||||||
// need to retain ownership of the tree for their own purposes should
|
|
||||||
// first retain the tree.
|
|
||||||
void ts_stack_push(t_stack *, t_stack_version, Subtree, bool, TSStateId);
|
|
||||||
|
|
||||||
// Pop the given number of entries from the given version of the stack. This
|
|
||||||
// operation can increase the number of stack versions by revealing multiple
|
|
||||||
// versions which had previously been merged. It returns an array that
|
|
||||||
// specifies the index of each revealed version and the trees that were
|
|
||||||
// removed from that version.
|
|
||||||
t_stack_slice_array ts_stack_pop_count(t_stack *, t_stack_version, t_u32 count);
|
t_stack_slice_array ts_stack_pop_count(t_stack *, t_stack_version, t_u32 count);
|
||||||
|
|
||||||
// Remove an error at the top of the given version of the stack.
|
|
||||||
SubtreeArray ts_stack_pop_error(t_stack *, t_stack_version);
|
SubtreeArray ts_stack_pop_error(t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Remove any pending trees from the top of the given version of the stack.
|
|
||||||
t_stack_slice_array ts_stack_pop_pending(t_stack *, t_stack_version);
|
t_stack_slice_array ts_stack_pop_pending(t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Remove any all trees from the given version of the stack.
|
|
||||||
t_stack_slice_array ts_stack_pop_all(t_stack *, t_stack_version);
|
t_stack_slice_array ts_stack_pop_all(t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Get the maximum number of tree nodes reachable from this version of the stack
|
|
||||||
// since the last error was detected.
|
|
||||||
t_u32 ts_stack_node_count_since_error(const t_stack *, t_stack_version);
|
t_u32 ts_stack_node_count_since_error(const t_stack *, t_stack_version);
|
||||||
|
|
||||||
int ts_stack_dynamic_precedence(t_stack *, t_stack_version);
|
int ts_stack_dynamic_precedence(t_stack *, t_stack_version);
|
||||||
|
|
||||||
bool ts_stack_has_advanced_since_error(const t_stack *, t_stack_version);
|
bool ts_stack_has_advanced_since_error(const t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Compute a summary of all the parse states near the top of the given
|
|
||||||
// version of the stack and store the summary for later retrieval.
|
|
||||||
void ts_stack_record_summary(t_stack *, t_stack_version, t_u32 max_depth);
|
void ts_stack_record_summary(t_stack *, t_stack_version, t_u32 max_depth);
|
||||||
|
|
||||||
// Retrieve a summary of all the parse states near the top of the
|
|
||||||
// given version of the stack.
|
|
||||||
t_stack_summary *ts_stack_get_summary(t_stack *, t_stack_version);
|
t_stack_summary *ts_stack_get_summary(t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Get the total cost of all errors on the given version of the stack.
|
|
||||||
t_u32 ts_stack_error_cost(const t_stack *, t_stack_version version);
|
t_u32 ts_stack_error_cost(const t_stack *, t_stack_version version);
|
||||||
|
|
||||||
// Merge the given two stack versions if possible, returning true
|
|
||||||
// if they were successfully merged and false otherwise.
|
|
||||||
bool ts_stack_merge(t_stack *, t_stack_version, t_stack_version);
|
bool ts_stack_merge(t_stack *, t_stack_version, t_stack_version);
|
||||||
|
|
||||||
// Determine whether the given two stack versions can be merged.
|
|
||||||
bool ts_stack_can_merge(t_stack *, t_stack_version, t_stack_version);
|
bool ts_stack_can_merge(t_stack *, t_stack_version, t_stack_version);
|
||||||
|
t_subtree ts_stack_resume(t_stack *, t_stack_version);
|
||||||
Subtree ts_stack_resume(t_stack *, t_stack_version);
|
void ts_stack_pause(t_stack *, t_stack_version, t_subtree);
|
||||||
|
|
||||||
void ts_stack_pause(t_stack *, t_stack_version, Subtree);
|
|
||||||
|
|
||||||
void ts_stack_halt(t_stack *, t_stack_version);
|
void ts_stack_halt(t_stack *, t_stack_version);
|
||||||
|
|
||||||
bool ts_stack_is_active(const t_stack *, t_stack_version);
|
bool ts_stack_is_active(const t_stack *, t_stack_version);
|
||||||
|
|
||||||
bool ts_stack_is_paused(const t_stack *, t_stack_version);
|
bool ts_stack_is_paused(const t_stack *, t_stack_version);
|
||||||
|
|
||||||
bool ts_stack_is_halted(const t_stack *, t_stack_version);
|
bool ts_stack_is_halted(const t_stack *, t_stack_version);
|
||||||
|
|
||||||
void ts_stack_renumber_version(t_stack *, t_stack_version, t_stack_version);
|
void ts_stack_renumber_version(t_stack *, t_stack_version, t_stack_version);
|
||||||
|
|
||||||
void ts_stack_swap_versions(t_stack *, t_stack_version, t_stack_version);
|
void ts_stack_swap_versions(t_stack *, t_stack_version, t_stack_version);
|
||||||
|
|
||||||
t_stack_version ts_stack_copy_version(t_stack *, t_stack_version);
|
t_stack_version ts_stack_copy_version(t_stack *, t_stack_version);
|
||||||
|
|
||||||
// Remove the given version from the stack.
|
|
||||||
void ts_stack_remove_version(t_stack *, t_stack_version);
|
void ts_stack_remove_version(t_stack *, t_stack_version);
|
||||||
|
|
||||||
void ts_stack_clear(t_stack *);
|
void ts_stack_clear(t_stack *);
|
||||||
|
|
||||||
#endif // PARSE_STACK_H
|
#endif // PARSE_STACK_H
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:06 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:03:06 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:37:26 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -26,16 +26,16 @@
|
||||||
#define TS_BIG_ENDIAN 0
|
#define TS_BIG_ENDIAN 0
|
||||||
#define TS_PTR_SIZE 64
|
#define TS_PTR_SIZE 64
|
||||||
#define TS_TREE_STATE_NONE USHRT_MAX
|
#define TS_TREE_STATE_NONE USHRT_MAX
|
||||||
#define NULL_SUBTREE ((Subtree)NULL)
|
#define NULL_SUBTREE ((t_subtree)NULL)
|
||||||
|
|
||||||
// A heap-allocated representation of a subtree.
|
// A heap-allocated representation of a subtree.
|
||||||
//
|
//
|
||||||
// This representation is used for parent nodes, external tokens,
|
// This representation is used for parent nodes, external tokens,
|
||||||
// errors, and other leaf nodes whose data is too large to fit into
|
// errors, and other leaf nodes whose data is too large to fit into
|
||||||
// the inline representation.
|
// the inline representation.
|
||||||
typedef struct SubtreeHeapData SubtreeHeapData;
|
typedef struct s_subtree_data t_subtree_data;
|
||||||
|
|
||||||
struct SubtreeHeapData
|
struct s_subtree_data
|
||||||
{
|
{
|
||||||
t_u32 ref_count;
|
t_u32 ref_count;
|
||||||
Length padding;
|
Length padding;
|
||||||
|
|
@ -76,7 +76,7 @@ struct SubtreeHeapData
|
||||||
};
|
};
|
||||||
|
|
||||||
// External terminal subtrees (`child_count == 0 && has_external_tokens`)
|
// External terminal subtrees (`child_count == 0 && has_external_tokens`)
|
||||||
ExternalScannerState external_scanner_state;
|
t_external_scanner_state external_scanner_state;
|
||||||
|
|
||||||
// Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)
|
// Error terminal subtrees (`child_count == 0 && symbol == ts_builtin_sym_error`)
|
||||||
t_i32 lookahead_char;
|
t_i32 lookahead_char;
|
||||||
|
|
@ -84,18 +84,18 @@ struct SubtreeHeapData
|
||||||
};
|
};
|
||||||
|
|
||||||
// The fundamental building block of a syntax tree.
|
// The fundamental building block of a syntax tree.
|
||||||
typedef const SubtreeHeapData *Subtree;
|
typedef const t_subtree_data *t_subtree;
|
||||||
|
|
||||||
// Like Subtree, but mutable.
|
// Like t_subtree, but mutable.
|
||||||
typedef SubtreeHeapData *MutableSubtree;
|
typedef t_subtree_data *t_mut_subtree;
|
||||||
|
|
||||||
typedef Array(Subtree) SubtreeArray;
|
typedef Array(t_subtree) SubtreeArray;
|
||||||
typedef Array(MutableSubtree) MutableSubtreeArray;
|
typedef Array(t_mut_subtree) MutableSubtreeArray;
|
||||||
|
|
||||||
void ts_external_scanner_state_init(ExternalScannerState *, const t_u8 *, t_u32);
|
void ts_external_scanner_state_init(t_external_scanner_state *, const t_u8 *, t_u32);
|
||||||
const t_u8 *ts_external_scanner_state_data(const ExternalScannerState *);
|
const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *);
|
||||||
bool ts_external_scanner_state_eq(const ExternalScannerState *self, const t_u8 *, t_u32);
|
bool ts_external_scanner_state_eq(const t_external_scanner_state *self, const t_u8 *, t_u32);
|
||||||
void ts_external_scanner_state_delete(ExternalScannerState *self);
|
void ts_external_scanner_state_delete(t_external_scanner_state *self);
|
||||||
|
|
||||||
void ts_subtree_array_copy(SubtreeArray, SubtreeArray *);
|
void ts_subtree_array_copy(SubtreeArray, SubtreeArray *);
|
||||||
void ts_subtree_array_clear(SubtreeArray *);
|
void ts_subtree_array_clear(SubtreeArray *);
|
||||||
|
|
@ -103,59 +103,59 @@ void ts_subtree_array_delete(SubtreeArray *);
|
||||||
void ts_subtree_array_remove_trailing_extras(SubtreeArray *, SubtreeArray *);
|
void ts_subtree_array_remove_trailing_extras(SubtreeArray *, SubtreeArray *);
|
||||||
void ts_subtree_array_reverse(SubtreeArray *);
|
void ts_subtree_array_reverse(SubtreeArray *);
|
||||||
|
|
||||||
Subtree ts_subtree_new_leaf(TSSymbol, Length, Length, t_u32, TSStateId, bool, bool, bool, const TSLanguage *);
|
t_subtree ts_subtree_new_leaf(TSSymbol, Length, Length, t_u32, TSStateId, bool, bool, bool, const TSLanguage *);
|
||||||
Subtree ts_subtree_new_error(t_i32, Length, Length, t_u32, TSStateId, const TSLanguage *);
|
t_subtree ts_subtree_new_error(t_i32, Length, Length, t_u32, TSStateId, const TSLanguage *);
|
||||||
MutableSubtree ts_subtree_new_node(TSSymbol, SubtreeArray *, t_u32, const TSLanguage *);
|
t_mut_subtree ts_subtree_new_node(TSSymbol, SubtreeArray *, t_u32, const TSLanguage *);
|
||||||
Subtree ts_subtree_new_error_node(SubtreeArray *, bool, const TSLanguage *);
|
t_subtree ts_subtree_new_error_node(SubtreeArray *, bool, const TSLanguage *);
|
||||||
Subtree ts_subtree_new_missing_leaf(TSSymbol, Length, t_u32, const TSLanguage *);
|
t_subtree ts_subtree_new_missing_leaf(TSSymbol, Length, t_u32, const TSLanguage *);
|
||||||
MutableSubtree ts_subtree_make_mut(Subtree);
|
t_mut_subtree ts_subtree_make_mut(t_subtree);
|
||||||
void ts_subtree_retain(Subtree);
|
void ts_subtree_retain(t_subtree);
|
||||||
void ts_subtree_release(Subtree);
|
void ts_subtree_release(t_subtree);
|
||||||
int ts_subtree_compare(Subtree, Subtree);
|
int ts_subtree_compare(t_subtree, t_subtree);
|
||||||
void ts_subtree_set_symbol(MutableSubtree *, TSSymbol, const TSLanguage *);
|
void ts_subtree_set_symbol(t_mut_subtree *, TSSymbol, const TSLanguage *);
|
||||||
void ts_subtree_summarize(MutableSubtree, const Subtree *, t_u32, const TSLanguage *);
|
void ts_subtree_summarize(t_mut_subtree, const t_subtree *, t_u32, const TSLanguage *);
|
||||||
void ts_subtree_summarize_children(MutableSubtree, const TSLanguage *);
|
void ts_subtree_summarize_children(t_mut_subtree, const TSLanguage *);
|
||||||
void ts_subtree_balance(Subtree, const TSLanguage *);
|
void ts_subtree_balance(t_subtree, const TSLanguage *);
|
||||||
Subtree ts_subtree_edit(Subtree, const TSInputEdit *edit);
|
t_subtree ts_subtree_edit(t_subtree, const TSInputEdit *edit);
|
||||||
char *ts_subtree_string(Subtree, TSSymbol, bool, const TSLanguage *, bool include_all);
|
char *ts_subtree_string(t_subtree, TSSymbol, bool, const TSLanguage *, bool include_all);
|
||||||
void ts_subtree_print_dot_graph(Subtree, const TSLanguage *, FILE *);
|
void ts_subtree_print_dot_graph(t_subtree, const TSLanguage *, FILE *);
|
||||||
Subtree ts_subtree_last_external_token(Subtree);
|
t_subtree ts_subtree_last_external_token(t_subtree);
|
||||||
const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self);
|
const t_external_scanner_state *ts_subtree_external_scanner_state(t_subtree self);
|
||||||
bool ts_subtree_external_scanner_state_eq(Subtree, Subtree);
|
bool ts_subtree_external_scanner_state_eq(t_subtree, t_subtree);
|
||||||
|
|
||||||
static inline TSSymbol ts_subtree_symbol(Subtree self)
|
static inline TSSymbol ts_subtree_symbol(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->symbol);
|
return ((self)->symbol);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_visible(Subtree self)
|
static inline bool ts_subtree_visible(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->visible);
|
return ((self)->visible);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_named(Subtree self)
|
static inline bool ts_subtree_named(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->named);
|
return ((self)->named);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_extra(Subtree self)
|
static inline bool ts_subtree_extra(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->extra);
|
return ((self)->extra);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_has_changes(Subtree self)
|
static inline bool ts_subtree_has_changes(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->has_changes);
|
return ((self)->has_changes);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_missing(Subtree self)
|
static inline bool ts_subtree_missing(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->is_missing);
|
return ((self)->is_missing);
|
||||||
}
|
}
|
||||||
static inline bool ts_subtree_is_keyword(Subtree self)
|
static inline bool ts_subtree_is_keyword(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->is_keyword);
|
return ((self)->is_keyword);
|
||||||
}
|
}
|
||||||
static inline TSStateId ts_subtree_parse_state(Subtree self)
|
static inline TSStateId ts_subtree_parse_state(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->parse_state);
|
return ((self)->parse_state);
|
||||||
}
|
}
|
||||||
static inline t_u32 ts_subtree_lookahead_bytes(Subtree self)
|
static inline t_u32 ts_subtree_lookahead_bytes(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self)->lookahead_bytes);
|
return ((self)->lookahead_bytes);
|
||||||
}
|
}
|
||||||
|
|
@ -164,68 +164,68 @@ static inline t_u32 ts_subtree_lookahead_bytes(Subtree self)
|
||||||
// number of children.
|
// number of children.
|
||||||
static inline size_t ts_subtree_alloc_size(t_u32 child_count)
|
static inline size_t ts_subtree_alloc_size(t_u32 child_count)
|
||||||
{
|
{
|
||||||
return child_count * sizeof(Subtree) + sizeof(SubtreeHeapData);
|
return child_count * sizeof(t_subtree) + sizeof(t_subtree_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a subtree's children, which are allocated immediately before the
|
// Get a subtree's children, which are allocated immediately before the
|
||||||
// tree's own heap data.
|
// tree's own heap data.
|
||||||
#define ts_subtree_children(self) ((Subtree *)((self)) - (self)->child_count)
|
#define ts_subtree_children(self) ((t_subtree *)((self)) - (self)->child_count)
|
||||||
|
|
||||||
static inline void ts_subtree_set_extra(MutableSubtree *self, bool is_extra)
|
static inline void ts_subtree_set_extra(t_mut_subtree *self, bool is_extra)
|
||||||
{
|
{
|
||||||
(*self)->extra = is_extra;
|
(*self)->extra = is_extra;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline TSSymbol ts_subtree_leaf_symbol(Subtree self)
|
static inline TSSymbol ts_subtree_leaf_symbol(t_subtree self)
|
||||||
{
|
{
|
||||||
if (self->child_count == 0)
|
if (self->child_count == 0)
|
||||||
return self->symbol;
|
return self->symbol;
|
||||||
return self->first_leaf.symbol;
|
return self->first_leaf.symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline TSStateId ts_subtree_leaf_parse_state(Subtree self)
|
static inline TSStateId ts_subtree_leaf_parse_state(t_subtree self)
|
||||||
{
|
{
|
||||||
if (self->child_count == 0)
|
if (self->child_count == 0)
|
||||||
return self->parse_state;
|
return self->parse_state;
|
||||||
return self->first_leaf.parse_state;
|
return self->first_leaf.parse_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_padding(Subtree self)
|
static inline Length ts_subtree_padding(t_subtree self)
|
||||||
{
|
{
|
||||||
return self->padding;
|
return self->padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_size(Subtree self)
|
static inline Length ts_subtree_size(t_subtree self)
|
||||||
{
|
{
|
||||||
return self->size;
|
return self->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Length ts_subtree_total_size(Subtree self)
|
static inline Length ts_subtree_total_size(t_subtree self)
|
||||||
{
|
{
|
||||||
return (length_add(ts_subtree_padding(self), ts_subtree_size(self)));
|
return (length_add(ts_subtree_padding(self), ts_subtree_size(self)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_u32 ts_subtree_total_bytes(Subtree self)
|
static inline t_u32 ts_subtree_total_bytes(t_subtree self)
|
||||||
{
|
{
|
||||||
return (ts_subtree_total_size(self).bytes);
|
return (ts_subtree_total_size(self).bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_u32 ts_subtree_child_count(Subtree self)
|
static inline t_u32 ts_subtree_child_count(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->child_count);
|
return (self->child_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_u32 ts_subtree_repeat_depth(Subtree self)
|
static inline t_u32 ts_subtree_repeat_depth(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->repeat_depth);
|
return (self->repeat_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_u32 ts_subtree_visible_descendant_count(Subtree self)
|
static inline t_u32 ts_subtree_visible_descendant_count(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self->child_count == 0) ? 0 : self->visible_descendant_count);
|
return ((self->child_count == 0) ? 0 : self->visible_descendant_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_u32 ts_subtree_error_cost(Subtree self)
|
static inline t_u32 ts_subtree_error_cost(t_subtree self)
|
||||||
{
|
{
|
||||||
if (ts_subtree_missing(self))
|
if (ts_subtree_missing(self))
|
||||||
return (ERROR_COST_PER_MISSING_TREE + ERROR_COST_PER_RECOVERY);
|
return (ERROR_COST_PER_MISSING_TREE + ERROR_COST_PER_RECOVERY);
|
||||||
|
|
@ -233,54 +233,54 @@ static inline t_u32 ts_subtree_error_cost(Subtree self)
|
||||||
return (self->error_cost);
|
return (self->error_cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline t_i32 ts_subtree_dynamic_precedence(Subtree self)
|
static inline t_i32 ts_subtree_dynamic_precedence(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((self->child_count == 0) ? 0 : self->dynamic_precedence);
|
return ((self->child_count == 0) ? 0 : self->dynamic_precedence);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_fragile_left(Subtree self)
|
static inline bool ts_subtree_fragile_left(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->fragile_left);
|
return (self->fragile_left);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_fragile_right(Subtree self)
|
static inline bool ts_subtree_fragile_right(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->fragile_right);
|
return (self->fragile_right);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_has_external_tokens(Subtree self)
|
static inline bool ts_subtree_has_external_tokens(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->has_external_tokens);
|
return (self->has_external_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_has_external_scanner_state_change(Subtree self)
|
static inline bool ts_subtree_has_external_scanner_state_change(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->has_external_scanner_state_change);
|
return (self->has_external_scanner_state_change);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_depends_on_column(Subtree self)
|
static inline bool ts_subtree_depends_on_column(t_subtree self)
|
||||||
{
|
{
|
||||||
return (self->depends_on_column);
|
return (self->depends_on_column);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_is_error(Subtree self)
|
static inline bool ts_subtree_is_error(t_subtree self)
|
||||||
{
|
{
|
||||||
return (ts_subtree_symbol(self) == ts_builtin_sym_error);
|
return (ts_subtree_symbol(self) == ts_builtin_sym_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool ts_subtree_is_eof(Subtree self)
|
static inline bool ts_subtree_is_eof(t_subtree self)
|
||||||
{
|
{
|
||||||
return (ts_subtree_symbol(self) == ts_builtin_sym_end);
|
return (ts_subtree_symbol(self) == ts_builtin_sym_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Subtree ts_subtree_from_mut(MutableSubtree self)
|
static inline t_subtree ts_subtree_from_mut(t_mut_subtree self)
|
||||||
{
|
{
|
||||||
return (self);
|
return (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline MutableSubtree ts_subtree_to_mut_unsafe(Subtree self)
|
static inline t_mut_subtree ts_subtree_to_mut_unsafe(t_subtree self)
|
||||||
{
|
{
|
||||||
return ((MutableSubtree)self);
|
return ((t_mut_subtree)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SUBTREE_H
|
#endif // SUBTREE_H
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 12:03:04 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 12:03:04 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 12:04:05 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:38:49 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -16,23 +16,13 @@
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
#include "parser/subtree.h"
|
#include "parser/subtree.h"
|
||||||
|
|
||||||
typedef struct ParentCacheEntry ParentCacheEntry;
|
|
||||||
|
|
||||||
struct TSTree
|
struct TSTree
|
||||||
{
|
{
|
||||||
Subtree root;
|
t_subtree root;
|
||||||
const TSLanguage *language;
|
const TSLanguage *language;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ParentCacheEntry
|
TSTree *ts_tree_new(t_subtree root, const TSLanguage *language);
|
||||||
{
|
TSNode ts_node_new(const TSTree *, const t_subtree *, Length, TSSymbol);
|
||||||
const Subtree *child;
|
|
||||||
const Subtree *parent;
|
|
||||||
Length position;
|
|
||||||
TSSymbol alias_symbol;
|
|
||||||
};
|
|
||||||
|
|
||||||
TSTree *ts_tree_new(Subtree root, const TSLanguage *language);
|
|
||||||
TSNode ts_node_new(const TSTree *, const Subtree *, Length, TSSymbol);
|
|
||||||
|
|
||||||
#endif // TREE_H
|
#endif // TREE_H
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/04/24 23:01:45 by maiboyer #+# #+# */
|
/* Created: 2024/04/24 23:01:45 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/07/11 18:50:48 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:41:24 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -25,7 +25,7 @@ typedef TSSymbolMetadata t_symbol_metadata;
|
||||||
typedef TSSymbol t_symbol;
|
typedef TSSymbol t_symbol;
|
||||||
typedef TSStateId t_state_id;
|
typedef TSStateId t_state_id;
|
||||||
typedef TSFieldId t_field_id;
|
typedef TSFieldId t_field_id;
|
||||||
typedef TSLexer t_lexer;
|
typedef TSLexer t_lexer_funcs;
|
||||||
typedef TSFieldMapSlice t_field_map_slice;
|
typedef TSFieldMapSlice t_field_map_slice;
|
||||||
typedef TSFieldMapEntry t_field_map_entry;
|
typedef TSFieldMapEntry t_field_map_entry;
|
||||||
typedef TSParseActionEntry t_parse_action_entry;
|
typedef TSParseActionEntry t_parse_action_entry;
|
||||||
|
|
@ -53,7 +53,7 @@ typedef struct s_lexer_state t_lexer_state;
|
||||||
# define inline __inline__
|
# define inline __inline__
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline bool lex_skip(t_state_id state_value, t_lexer *lexer, t_lexer_state *s)
|
static inline bool lex_skip(t_state_id state_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||||
{
|
{
|
||||||
(void)(lexer);
|
(void)(lexer);
|
||||||
s->skip = true;
|
s->skip = true;
|
||||||
|
|
@ -61,14 +61,14 @@ static inline bool lex_skip(t_state_id state_value, t_lexer *lexer, t_lexer_stat
|
||||||
return (true);
|
return (true);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool lex_advance(t_state_id state_value, t_lexer *lexer, t_lexer_state *s)
|
static inline bool lex_advance(t_state_id state_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||||
{
|
{
|
||||||
(void)(lexer);
|
(void)(lexer);
|
||||||
s->state = state_value;
|
s->state = state_value;
|
||||||
return (true);
|
return (true);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool lex_accept_token(t_symbol symbol_value, t_lexer *lexer, t_lexer_state *s)
|
static inline bool lex_accept_token(t_symbol symbol_value, t_lexer_funcs *lexer, t_lexer_state *s)
|
||||||
{
|
{
|
||||||
s->result = true;
|
s->result = true;
|
||||||
lexer->result_symbol = symbol_value;
|
lexer->result_symbol = symbol_value;
|
||||||
|
|
@ -76,7 +76,7 @@ static inline bool lex_accept_token(t_symbol symbol_value, t_lexer *lexer, t_lex
|
||||||
return (true);
|
return (true);
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool lex_end_state(t_lexer *lexer, t_lexer_state *s)
|
static inline bool lex_end_state(t_lexer_funcs *lexer, t_lexer_state *s)
|
||||||
{
|
{
|
||||||
(void)(lexer);
|
(void)(lexer);
|
||||||
(void)(s);
|
(void)(s);
|
||||||
|
|
@ -180,7 +180,7 @@ static inline bool set_contains(t_char_range *ranges, t_u32 len, int32_t lookahe
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline bool advance_map_inner(t_u32 *map, t_u32 elems, t_lexer *l, t_lexer_state *s)
|
static inline bool advance_map_inner(t_u32 *map, t_u32 elems, t_lexer_funcs *l, t_lexer_state *s)
|
||||||
{
|
{
|
||||||
t_u32 i;
|
t_u32 i;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
bool ts_lex(t_lexer *lexer, t_state_id state)
|
bool ts_lex(t_lexer *lexer, t_state_id state)
|
||||||
{
|
{
|
||||||
START_LEXER();
|
START_LEXER();
|
||||||
eof = lexer->eof(lexer);
|
eof = lexer->data.eof((void *)lexer);
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|
@ -3460,7 +3460,7 @@ bool ts_lex(t_lexer *lexer, t_state_id state)
|
||||||
bool ts_lex_keywords(t_lexer *lexer, t_state_id state)
|
bool ts_lex_keywords(t_lexer *lexer, t_state_id state)
|
||||||
{
|
{
|
||||||
START_LEXER();
|
START_LEXER();
|
||||||
eof = lexer->eof(lexer);
|
eof = lexer->data.eof((void *)lexer);
|
||||||
switch (state)
|
switch (state)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,19 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
bool ts_lexer__do_advance_loop(Lexer *self, const TSRange **current_range);
|
bool ts_lexer__do_advance_loop(t_lexer *self, const TSRange **current_range);
|
||||||
void ts_lexer__do_advance_after_loop(Lexer *self, bool skip,
|
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||||
const TSRange *cur);
|
const TSRange *cur);
|
||||||
|
|
||||||
// Intended to be called only from functions that control logging.
|
// Intended to be called only from functions that control logging.
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip)
|
void ts_lexer__do_advance(t_lexer *self, bool skip)
|
||||||
{
|
{
|
||||||
const TSRange *cur = \
|
const TSRange *cur = \
|
||||||
&self->included_ranges[self->current_included_range_index];
|
&self->included_ranges[self->current_included_range_index];
|
||||||
|
|
@ -55,15 +55,15 @@ void ts_lexer__do_advance(Lexer *self, bool skip)
|
||||||
// chunk of source code if needed.
|
// chunk of source code if needed.
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip)
|
void ts_lexer__advance(TSLexer *_self, bool skip)
|
||||||
{
|
{
|
||||||
Lexer *self;
|
t_lexer *self;
|
||||||
|
|
||||||
self = (Lexer *)_self;
|
self = (t_lexer *)_self;
|
||||||
if (!self->chunk)
|
if (!self->chunk)
|
||||||
return ;
|
return ;
|
||||||
ts_lexer__do_advance(self, skip);
|
ts_lexer__do_advance(self, skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_lexer__do_advance_loop(Lexer *self, const TSRange **current_range)
|
bool ts_lexer__do_advance_loop(t_lexer *self, const TSRange **current_range)
|
||||||
{
|
{
|
||||||
if (self->current_included_range_index < self->included_range_count)
|
if (self->current_included_range_index < self->included_range_count)
|
||||||
self->current_included_range_index++;
|
self->current_included_range_index++;
|
||||||
|
|
@ -83,7 +83,7 @@ bool ts_lexer__do_advance_loop(Lexer *self, const TSRange **current_range)
|
||||||
return (false);
|
return (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer__do_advance_after_loop(Lexer *self, bool skip,
|
void ts_lexer__do_advance_after_loop(t_lexer *self, bool skip,
|
||||||
const TSRange *cur)
|
const TSRange *cur)
|
||||||
{
|
{
|
||||||
if (skip)
|
if (skip)
|
||||||
|
|
|
||||||
|
|
@ -16,17 +16,17 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip);
|
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
// Clear the currently stored chunk of source code, because the lexer's
|
// Clear the currently stored chunk of source code, because the lexer's
|
||||||
// position has changed.
|
// position has changed.
|
||||||
void ts_lexer__clear_chunk(Lexer *self)
|
void ts_lexer__clear_chunk(t_lexer *self)
|
||||||
{
|
{
|
||||||
self->chunk = NULL;
|
self->chunk = NULL;
|
||||||
self->chunk_size = 0;
|
self->chunk_size = 0;
|
||||||
|
|
@ -35,7 +35,7 @@ void ts_lexer__clear_chunk(Lexer *self)
|
||||||
|
|
||||||
// Call the lexer's input callback to obtain a new chunk of source code
|
// Call the lexer's input callback to obtain a new chunk of source code
|
||||||
// for the current position.
|
// for the current position.
|
||||||
void ts_lexer__get_chunk(Lexer *self)
|
void ts_lexer__get_chunk(t_lexer *self)
|
||||||
{
|
{
|
||||||
self->chunk_start = self->current_position.bytes;
|
self->chunk_start = self->current_position.bytes;
|
||||||
self->chunk = self->input.read(self->input.payload,
|
self->chunk = self->input.read(self->input.payload,
|
||||||
|
|
|
||||||
|
|
@ -16,22 +16,22 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip);
|
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
// Check if the lexer has reached EOF. This state is stored
|
// Check if the lexer has reached EOF. This state is stored
|
||||||
// by setting the lexer's `current_included_range_index` such that
|
// by setting the lexer's `current_included_range_index` such that
|
||||||
// it has consumed all of its available ranges.
|
// it has consumed all of its available ranges.
|
||||||
bool ts_lexer__eof(const TSLexer *_self)
|
bool ts_lexer__eof(const TSLexer *_self)
|
||||||
{
|
{
|
||||||
Lexer *self;
|
t_lexer *self;
|
||||||
|
|
||||||
self = (Lexer *)_self;
|
self = (t_lexer *)_self;
|
||||||
return (self->current_included_range_index == self->included_range_count);
|
return (self->current_included_range_index == self->included_range_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -39,11 +39,11 @@ bool ts_lexer__eof(const TSLexer *_self)
|
||||||
// times if a longer match is found later.
|
// times if a longer match is found later.
|
||||||
void ts_lexer__mark_end(TSLexer *_self)
|
void ts_lexer__mark_end(TSLexer *_self)
|
||||||
{
|
{
|
||||||
Lexer *self;
|
t_lexer *self;
|
||||||
TSRange *current_included_range;
|
TSRange *current_included_range;
|
||||||
TSRange *previous_included_range;
|
TSRange *previous_included_range;
|
||||||
|
|
||||||
self = (Lexer *)_self;
|
self = (t_lexer *)_self;
|
||||||
if (!ts_lexer__eof(&self->data))
|
if (!ts_lexer__eof(&self->data))
|
||||||
{
|
{
|
||||||
current_included_range = \
|
current_included_range = \
|
||||||
|
|
@ -62,7 +62,7 @@ void ts_lexer__mark_end(TSLexer *_self)
|
||||||
self->token_end_position = self->current_position;
|
self->token_end_position = self->current_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_advance_to_end(Lexer *self)
|
void ts_lexer_advance_to_end(t_lexer *self)
|
||||||
{
|
{
|
||||||
while (self->chunk)
|
while (self->chunk)
|
||||||
ts_lexer__advance(&self->data, false);
|
ts_lexer__advance(&self->data, false);
|
||||||
|
|
|
||||||
|
|
@ -16,21 +16,21 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip);
|
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self)
|
t_u32 ts_lexer__get_column(TSLexer *_self)
|
||||||
{
|
{
|
||||||
Lexer *self;
|
t_lexer *self;
|
||||||
t_u32 goal_byte;
|
t_u32 goal_byte;
|
||||||
t_u32 result;
|
t_u32 result;
|
||||||
|
|
||||||
self = (Lexer *)_self;
|
self = (t_lexer *)_self;
|
||||||
goal_byte = self->current_position.bytes;
|
goal_byte = self->current_position.bytes;
|
||||||
self->did_get_column = true;
|
self->did_get_column = true;
|
||||||
self->current_position.bytes -= self->current_position.extent.column;
|
self->current_position.bytes -= self->current_position.extent.column;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
/* By: maiboyer <maiboyer@student.42.fr> +#+ +:+ +#+ */
|
||||||
/* +#+#+#+#+#+ +#+ */
|
/* +#+#+#+#+#+ +#+ */
|
||||||
/* Created: 2024/08/31 18:08:11 by maiboyer #+# #+# */
|
/* Created: 2024/08/31 18:08:11 by maiboyer #+# #+# */
|
||||||
/* Updated: 2024/08/31 18:25:58 by maiboyer ### ########.fr */
|
/* Updated: 2024/08/31 18:39:32 by maiboyer ### ########.fr */
|
||||||
/* */
|
/* */
|
||||||
/* ************************************************************************** */
|
/* ************************************************************************** */
|
||||||
|
|
||||||
|
|
@ -16,19 +16,19 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip);
|
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
void ts_lexer_goto_inside_loop(Lexer *self, bool *found_included_range,
|
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||||
TSRange *included_range, t_usize i);
|
TSRange *included_range, t_usize i);
|
||||||
void ts_lexer_goto_after_loop(Lexer *self, bool found_included_range);
|
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range);
|
||||||
|
|
||||||
void ts_lexer_goto(Lexer *self, Length position)
|
void ts_lexer_goto(t_lexer *self, Length position)
|
||||||
{
|
{
|
||||||
bool found_included_range;
|
bool found_included_range;
|
||||||
TSRange *included_range;
|
TSRange *included_range;
|
||||||
|
|
@ -53,7 +53,7 @@ void ts_lexer_goto(Lexer *self, Length position)
|
||||||
ts_lexer_goto_after_loop(self, found_included_range);
|
ts_lexer_goto_after_loop(self, found_included_range);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_goto_inside_loop(Lexer *self, bool *found_included_range,
|
void ts_lexer_goto_inside_loop(t_lexer *self, bool *found_included_range,
|
||||||
TSRange *included_range, t_usize i)
|
TSRange *included_range, t_usize i)
|
||||||
{
|
{
|
||||||
if (included_range->start_byte >= self->current_position.bytes)
|
if (included_range->start_byte >= self->current_position.bytes)
|
||||||
|
|
@ -67,7 +67,7 @@ void ts_lexer_goto_inside_loop(Lexer *self, bool *found_included_range,
|
||||||
*found_included_range = true;
|
*found_included_range = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_goto_after_loop(Lexer *self, bool found_included_range)
|
void ts_lexer_goto_after_loop(t_lexer *self, bool found_included_range)
|
||||||
{
|
{
|
||||||
TSRange *last_included_range;
|
TSRange *last_included_range;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,20 +18,20 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
void ts_lexer_init(Lexer *self)
|
void ts_lexer_init(t_lexer *self)
|
||||||
{
|
{
|
||||||
static TSRange default_range = {.start_point = {\
|
static TSRange default_range = {.start_point = {\
|
||||||
.row = 0, .column = 0, }, .end_point = {.row = UINT32_MAX, \
|
.row = 0, .column = 0, }, .end_point = {.row = UINT32_MAX, \
|
||||||
.column = UINT32_MAX, }, .start_byte = 0, .end_byte = UINT32_MAX};
|
.column = UINT32_MAX, }, .start_byte = 0, .end_byte = UINT32_MAX};
|
||||||
|
|
||||||
*self = (Lexer){
|
*self = (t_lexer){
|
||||||
.data = {
|
.data = {
|
||||||
.advance = ts_lexer__advance,
|
.advance = ts_lexer__advance,
|
||||||
.mark_end = ts_lexer__mark_end,
|
.mark_end = ts_lexer__mark_end,
|
||||||
|
|
@ -49,20 +49,20 @@ void ts_lexer_init(Lexer *self)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_set_input(Lexer *self, TSInput input)
|
void ts_lexer_set_input(t_lexer *self, TSInput input)
|
||||||
{
|
{
|
||||||
self->input = input;
|
self->input = input;
|
||||||
ts_lexer__clear_chunk(self);
|
ts_lexer__clear_chunk(self);
|
||||||
ts_lexer_goto(self, self->current_position);
|
ts_lexer_goto(self, self->current_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_reset(Lexer *self, Length position)
|
void ts_lexer_reset(t_lexer *self, Length position)
|
||||||
{
|
{
|
||||||
if (position.bytes != self->current_position.bytes)
|
if (position.bytes != self->current_position.bytes)
|
||||||
ts_lexer_goto(self, position);
|
ts_lexer_goto(self, position);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_start(Lexer *self)
|
void ts_lexer_start(t_lexer *self)
|
||||||
{
|
{
|
||||||
self->token_start_position = self->current_position;
|
self->token_start_position = self->current_position;
|
||||||
self->token_end_position = LENGTH_UNDEFINED;
|
self->token_end_position = LENGTH_UNDEFINED;
|
||||||
|
|
@ -80,7 +80,7 @@ void ts_lexer_start(Lexer *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_lexer_finish(Lexer *self, t_u32 *lookahead_end_byte)
|
void ts_lexer_finish(t_lexer *self, t_u32 *lookahead_end_byte)
|
||||||
{
|
{
|
||||||
if (length_is_undefined(self->token_end_position))
|
if (length_is_undefined(self->token_end_position))
|
||||||
ts_lexer__mark_end(&self->data);
|
ts_lexer__mark_end(&self->data);
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,15 @@
|
||||||
bool ts_lexer__eof(const TSLexer *_self);
|
bool ts_lexer__eof(const TSLexer *_self);
|
||||||
t_u32 ts_lexer__get_column(TSLexer *_self);
|
t_u32 ts_lexer__get_column(TSLexer *_self);
|
||||||
void ts_lexer__advance(TSLexer *_self, bool skip);
|
void ts_lexer__advance(TSLexer *_self, bool skip);
|
||||||
void ts_lexer__do_advance(Lexer *self, bool skip);
|
void ts_lexer__do_advance(t_lexer *self, bool skip);
|
||||||
void ts_lexer__clear_chunk(Lexer *self);
|
void ts_lexer__clear_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_chunk(Lexer *self);
|
void ts_lexer__get_chunk(t_lexer *self);
|
||||||
void ts_lexer__get_lookahead(Lexer *self);
|
void ts_lexer__get_lookahead(t_lexer *self);
|
||||||
void ts_lexer__mark_end(TSLexer *_self);
|
void ts_lexer__mark_end(TSLexer *_self);
|
||||||
void ts_lexer_advance_to_end(Lexer *self);
|
void ts_lexer_advance_to_end(t_lexer *self);
|
||||||
void ts_lexer_goto(Lexer *self, Length position);
|
void ts_lexer_goto(t_lexer *self, Length position);
|
||||||
|
|
||||||
void ts_lexer__get_lookahead(Lexer *self)
|
void ts_lexer__get_lookahead(t_lexer *self)
|
||||||
{
|
{
|
||||||
t_u32 position_in_chunk;
|
t_u32 position_in_chunk;
|
||||||
t_u32 size;
|
t_u32 size;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include "parser/external_scanner_state.h"
|
#include "parser/external_scanner_state.h"
|
||||||
#include "parser/subtree.h"
|
#include "parser/subtree.h"
|
||||||
|
|
||||||
void ts_external_scanner_state_init(ExternalScannerState *self,
|
void ts_external_scanner_state_init(t_external_scanner_state *self,
|
||||||
const t_u8 *data, t_u32 length)
|
const t_u8 *data, t_u32 length)
|
||||||
{
|
{
|
||||||
self->length = length;
|
self->length = length;
|
||||||
|
|
@ -21,10 +21,10 @@ void ts_external_scanner_state_init(ExternalScannerState *self,
|
||||||
mem_copy(self->long_data, data, length);
|
mem_copy(self->long_data, data, length);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExternalScannerState ts_external_scanner_state_copy(\
|
t_external_scanner_state ts_external_scanner_state_copy(\
|
||||||
const ExternalScannerState *self)
|
const t_external_scanner_state *self)
|
||||||
{
|
{
|
||||||
ExternalScannerState result;
|
t_external_scanner_state result;
|
||||||
|
|
||||||
result = *self;
|
result = *self;
|
||||||
result.long_data = mem_alloc(self->length);
|
result.long_data = mem_alloc(self->length);
|
||||||
|
|
@ -32,17 +32,17 @@ ExternalScannerState ts_external_scanner_state_copy(\
|
||||||
return (result);
|
return (result);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_external_scanner_state_delete(ExternalScannerState *self)
|
void ts_external_scanner_state_delete(t_external_scanner_state *self)
|
||||||
{
|
{
|
||||||
mem_free(self->long_data);
|
mem_free(self->long_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
const t_u8 *ts_external_scanner_state_data(const ExternalScannerState *self)
|
const t_u8 *ts_external_scanner_state_data(const t_external_scanner_state *self)
|
||||||
{
|
{
|
||||||
return ((const t_u8 *)self->long_data);
|
return ((const t_u8 *)self->long_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_external_scanner_state_eq(const ExternalScannerState *self,
|
bool ts_external_scanner_state_eq(const t_external_scanner_state *self,
|
||||||
const t_u8 *buffer, t_u32 length)
|
const t_u8 *buffer, t_u32 length)
|
||||||
{
|
{
|
||||||
return (self->length == length
|
return (self->length == length
|
||||||
|
|
|
||||||
|
|
@ -13,9 +13,9 @@
|
||||||
#include "parser/external_scanner_state.h"
|
#include "parser/external_scanner_state.h"
|
||||||
#include "parser/subtree.h"
|
#include "parser/subtree.h"
|
||||||
|
|
||||||
const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self)
|
const t_external_scanner_state *ts_subtree_external_scanner_state(t_subtree self)
|
||||||
{
|
{
|
||||||
static const ExternalScannerState empty_state = {NULL, .length = 0};
|
static const t_external_scanner_state empty_state = {NULL, .length = 0};
|
||||||
|
|
||||||
if (self && self->has_external_tokens && self->child_count == 0)
|
if (self && self->has_external_tokens && self->child_count == 0)
|
||||||
return (&self->external_scanner_state);
|
return (&self->external_scanner_state);
|
||||||
|
|
@ -23,11 +23,11 @@ const ExternalScannerState *ts_subtree_external_scanner_state(Subtree self)
|
||||||
return (&empty_state);
|
return (&empty_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ts_subtree_external_scanner_state_eq(Subtree self, Subtree other)
|
bool ts_subtree_external_scanner_state_eq(t_subtree self, t_subtree other)
|
||||||
{
|
{
|
||||||
const ExternalScannerState *state_self = \
|
const t_external_scanner_state *state_self = \
|
||||||
ts_subtree_external_scanner_state(self);
|
ts_subtree_external_scanner_state(self);
|
||||||
const ExternalScannerState *state_other = \
|
const t_external_scanner_state *state_other = \
|
||||||
ts_subtree_external_scanner_state(other);
|
ts_subtree_external_scanner_state(other);
|
||||||
|
|
||||||
return (ts_external_scanner_state_eq(state_self,
|
return (ts_external_scanner_state_eq(state_self,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
t_u32 ts_node_child_count(TSNode self)
|
t_u32 ts_node_child_count(TSNode self)
|
||||||
{
|
{
|
||||||
Subtree tree;
|
t_subtree tree;
|
||||||
|
|
||||||
tree = ts_node__subtree(self);
|
tree = ts_node__subtree(self);
|
||||||
if (ts_subtree_child_count(tree) > 0)
|
if (ts_subtree_child_count(tree) > 0)
|
||||||
|
|
@ -25,7 +25,7 @@ t_u32 ts_node_child_count(TSNode self)
|
||||||
|
|
||||||
t_u32 ts_node_named_child_count(TSNode self)
|
t_u32 ts_node_named_child_count(TSNode self)
|
||||||
{
|
{
|
||||||
Subtree tree;
|
t_subtree tree;
|
||||||
|
|
||||||
tree = ts_node__subtree(self);
|
tree = ts_node__subtree(self);
|
||||||
if (ts_subtree_child_count(tree) > 0)
|
if (ts_subtree_child_count(tree) > 0)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
#include "parser/length.h"
|
#include "parser/length.h"
|
||||||
#include "parser/subtree.h"
|
#include "parser/subtree.h"
|
||||||
|
|
||||||
TSNode ts_node_new(const TSTree *tree, const Subtree *subtree, \
|
TSNode ts_node_new(const TSTree *tree, const t_subtree *subtree, \
|
||||||
Length position, TSSymbol alias)
|
Length position, TSSymbol alias)
|
||||||
{
|
{
|
||||||
return ((TSNode){
|
return ((TSNode){
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ t_u32 ts_node__alias(const TSNode *self)
|
||||||
return (self->alias);
|
return (self->alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_node__subtree(TSNode self)
|
t_subtree ts_node__subtree(TSNode self)
|
||||||
{
|
{
|
||||||
return (*(const Subtree *)self.id);
|
return (*(const t_subtree *)self.id);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
NodeChildIterator ts_node_iterate_children(const TSNode *node)
|
NodeChildIterator ts_node_iterate_children(const TSNode *node)
|
||||||
{
|
{
|
||||||
Subtree subtree;
|
t_subtree subtree;
|
||||||
const TSSymbol *alias_sequence;
|
const TSSymbol *alias_sequence;
|
||||||
|
|
||||||
subtree = ts_node__subtree(*node);
|
subtree = ts_node__subtree(*node);
|
||||||
|
|
@ -42,7 +42,7 @@ bool ts_node_child_iterator_done(NodeChildIterator *self)
|
||||||
|
|
||||||
bool ts_node_child_iterator_next(NodeChildIterator *self, TSNode *result)
|
bool ts_node_child_iterator_next(NodeChildIterator *self, TSNode *result)
|
||||||
{
|
{
|
||||||
const Subtree *child;
|
const t_subtree *child;
|
||||||
TSSymbol alias_symbol;
|
TSSymbol alias_symbol;
|
||||||
|
|
||||||
if (!self->parent || ts_node_child_iterator_done(self))
|
if (!self->parent || ts_node_child_iterator_done(self))
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
bool ts_node__is_relevant(TSNode self, bool include_anonymous)
|
bool ts_node__is_relevant(TSNode self, bool include_anonymous)
|
||||||
{
|
{
|
||||||
TSSymbol alias;
|
TSSymbol alias;
|
||||||
Subtree tree;
|
t_subtree tree;
|
||||||
|
|
||||||
tree = ts_node__subtree(self);
|
tree = ts_node__subtree(self);
|
||||||
if (include_anonymous)
|
if (include_anonymous)
|
||||||
|
|
@ -31,7 +31,7 @@ bool ts_node__is_relevant(TSNode self, bool include_anonymous)
|
||||||
|
|
||||||
t_u32 ts_node__relevant_child_count(TSNode self, bool include_anonymous)
|
t_u32 ts_node__relevant_child_count(TSNode self, bool include_anonymous)
|
||||||
{
|
{
|
||||||
Subtree tree;
|
t_subtree tree;
|
||||||
|
|
||||||
tree = ts_node__subtree(self);
|
tree = ts_node__subtree(self);
|
||||||
if (ts_subtree_child_count(tree) > 0)
|
if (ts_subtree_child_count(tree) > 0)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
#define _POSIX_C_SOURCE 200112L
|
|
||||||
|
|
||||||
#include "me/mem/mem.h"
|
#include "me/mem/mem.h"
|
||||||
#include "me/types.h"
|
#include "me/types.h"
|
||||||
#include "parser/api.h"
|
#include "parser/api.h"
|
||||||
|
|
@ -25,11 +23,11 @@ typedef struct s_string_input t_string_input;
|
||||||
|
|
||||||
struct TSParser
|
struct TSParser
|
||||||
{
|
{
|
||||||
Lexer lexer;
|
t_lexer lexer;
|
||||||
t_stack *stack;
|
t_stack *stack;
|
||||||
const TSLanguage *language;
|
const TSLanguage *language;
|
||||||
ReduceActionSet reduce_actions;
|
ReduceActionSet reduce_actions;
|
||||||
Subtree finished_tree;
|
t_subtree finished_tree;
|
||||||
SubtreeArray trailing_extras;
|
SubtreeArray trailing_extras;
|
||||||
SubtreeArray trailing_extras2;
|
SubtreeArray trailing_extras2;
|
||||||
SubtreeArray scratch_trees;
|
SubtreeArray scratch_trees;
|
||||||
|
|
@ -101,11 +99,11 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve
|
||||||
{
|
{
|
||||||
t_stack_slice slice = pop.contents[i];
|
t_stack_slice slice = pop.contents[i];
|
||||||
TSStateId state = ts_stack_state(self->stack, slice.version);
|
TSStateId state = ts_stack_state(self->stack, slice.version);
|
||||||
Subtree parent = *array_front(&slice.subtrees);
|
t_subtree parent = *array_front(&slice.subtrees);
|
||||||
|
|
||||||
for (t_u32 j = 0, n = ts_subtree_child_count(parent); j < n; j++)
|
for (t_u32 j = 0, n = ts_subtree_child_count(parent); j < n; j++)
|
||||||
{
|
{
|
||||||
Subtree child = ts_subtree_children(parent)[j];
|
t_subtree child = ts_subtree_children(parent)[j];
|
||||||
pending = ts_subtree_child_count(child) > 0;
|
pending = ts_subtree_child_count(child) > 0;
|
||||||
|
|
||||||
if (ts_subtree_is_error(child))
|
if (ts_subtree_is_error(child))
|
||||||
|
|
@ -123,7 +121,7 @@ static bool ts_parser__breakdown_top_of_stack(TSParser *self, t_stack_version ve
|
||||||
|
|
||||||
for (t_u32 j = 1; j < slice.subtrees.size; j++)
|
for (t_u32 j = 1; j < slice.subtrees.size; j++)
|
||||||
{
|
{
|
||||||
Subtree tree = slice.subtrees.contents[j];
|
t_subtree tree = slice.subtrees.contents[j];
|
||||||
ts_stack_push(self->stack, slice.version, tree, false, state);
|
ts_stack_push(self->stack, slice.version, tree, false, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -283,7 +281,7 @@ static t_u32 ts_parser__external_scanner_serialize(TSParser *self)
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_parser__external_scanner_deserialize(TSParser *self, Subtree external_token)
|
static void ts_parser__external_scanner_deserialize(TSParser *self, t_subtree external_token)
|
||||||
{
|
{
|
||||||
const t_u8 *data = NULL;
|
const t_u8 *data = NULL;
|
||||||
t_u32 length = 0;
|
t_u32 length = 0;
|
||||||
|
|
@ -302,14 +300,14 @@ static bool ts_parser__external_scanner_scan(TSParser *self, TSStateId external_
|
||||||
return self->language->external_scanner.scan(self->external_scanner_payload, &self->lexer.data, valid_external_tokens);
|
return self->language->external_scanner.scan(self->external_scanner_payload, &self->lexer.data, valid_external_tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Subtree ts_parser__lex(TSParser *self, t_stack_version version, TSStateId parse_state)
|
static t_subtree ts_parser__lex(TSParser *self, t_stack_version version, TSStateId parse_state)
|
||||||
{
|
{
|
||||||
TSLexMode lex_mode = self->language->lex_modes[parse_state];
|
TSLexMode lex_mode = self->language->lex_modes[parse_state];
|
||||||
if (lex_mode.lex_state == (t_u16)-1)
|
if (lex_mode.lex_state == (t_u16)-1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
const Length start_position = ts_stack_position(self->stack, version);
|
const Length start_position = ts_stack_position(self->stack, version);
|
||||||
const Subtree external_token = ts_stack_last_external_token(self->stack, version);
|
const t_subtree external_token = ts_stack_last_external_token(self->stack, version);
|
||||||
|
|
||||||
bool found_external_token = false;
|
bool found_external_token = false;
|
||||||
bool error_mode = parse_state == ERROR_STATE;
|
bool error_mode = parse_state == ERROR_STATE;
|
||||||
|
|
@ -406,7 +404,7 @@ static Subtree ts_parser__lex(TSParser *self, t_stack_version version, TSStateId
|
||||||
error_end_position = self->lexer.current_position;
|
error_end_position = self->lexer.current_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree result;
|
t_subtree result;
|
||||||
if (skipped_error)
|
if (skipped_error)
|
||||||
{
|
{
|
||||||
Length padding = length_sub(error_start_position, start_position);
|
Length padding = length_sub(error_start_position, start_position);
|
||||||
|
|
@ -447,7 +445,7 @@ static Subtree ts_parser__lex(TSParser *self, t_stack_version version, TSStateId
|
||||||
|
|
||||||
if (found_external_token)
|
if (found_external_token)
|
||||||
{
|
{
|
||||||
MutableSubtree mut_result = ts_subtree_to_mut_unsafe(result);
|
t_mut_subtree mut_result = ts_subtree_to_mut_unsafe(result);
|
||||||
ts_external_scanner_state_init(&mut_result->external_scanner_state, self->lexer.debug_buffer, external_scanner_state_len);
|
ts_external_scanner_state_init(&mut_result->external_scanner_state, self->lexer.debug_buffer, external_scanner_state_len);
|
||||||
mut_result->has_external_scanner_state_change = external_scanner_state_changed;
|
mut_result->has_external_scanner_state_change = external_scanner_state_changed;
|
||||||
}
|
}
|
||||||
|
|
@ -460,7 +458,7 @@ static Subtree ts_parser__lex(TSParser *self, t_stack_version version, TSStateId
|
||||||
//
|
//
|
||||||
// The decision is based on the trees' error costs (if any), their dynamic precedence,
|
// 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.
|
// and finally, as a default, by a recursive comparison of the trees' symbols.
|
||||||
static bool ts_parser__select_tree(TSParser *self, Subtree left, Subtree right)
|
static bool ts_parser__select_tree(TSParser *self, t_subtree left, t_subtree right)
|
||||||
{
|
{
|
||||||
(void)(self);
|
(void)(self);
|
||||||
if (!left)
|
if (!left)
|
||||||
|
|
@ -505,7 +503,7 @@ static bool ts_parser__select_tree(TSParser *self, Subtree left, Subtree right)
|
||||||
|
|
||||||
// Determine if a given tree's children should be replaced by an alternative
|
// Determine if a given tree's children should be replaced by an alternative
|
||||||
// array of children.
|
// array of children.
|
||||||
static bool ts_parser__select_children(TSParser *self, Subtree left, const SubtreeArray *children)
|
static bool ts_parser__select_children(TSParser *self, t_subtree left, const SubtreeArray *children)
|
||||||
{
|
{
|
||||||
array_assign(&self->scratch_trees, children);
|
array_assign(&self->scratch_trees, children);
|
||||||
|
|
||||||
|
|
@ -513,18 +511,18 @@ static bool ts_parser__select_children(TSParser *self, Subtree left, const Subtr
|
||||||
// not perform any allocation except for possibly growing the array to make
|
// not perform any allocation except for possibly growing the array to make
|
||||||
// room for its own heap data. The scratch tree is never explicitly released,
|
// room for its own heap data. The scratch tree is never explicitly released,
|
||||||
// so the same 'scratch trees' array can be reused again later.
|
// so the same 'scratch trees' array can be reused again later.
|
||||||
MutableSubtree scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language);
|
t_mut_subtree scratch_tree = ts_subtree_new_node(ts_subtree_symbol(left), &self->scratch_trees, 0, self->language);
|
||||||
|
|
||||||
return ts_parser__select_tree(self, left, ts_subtree_from_mut(scratch_tree));
|
return ts_parser__select_tree(self, left, ts_subtree_from_mut(scratch_tree));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId state, Subtree lookahead, bool extra)
|
static void ts_parser__shift(TSParser *self, t_stack_version version, TSStateId state, t_subtree lookahead, bool extra)
|
||||||
{
|
{
|
||||||
bool is_leaf = ts_subtree_child_count(lookahead) == 0;
|
bool is_leaf = ts_subtree_child_count(lookahead) == 0;
|
||||||
Subtree subtree_to_push = lookahead;
|
t_subtree subtree_to_push = lookahead;
|
||||||
if (extra != ts_subtree_extra(lookahead) && is_leaf)
|
if (extra != ts_subtree_extra(lookahead) && is_leaf)
|
||||||
{
|
{
|
||||||
MutableSubtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
t_mut_subtree result = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
||||||
ts_subtree_set_extra(&result, extra);
|
ts_subtree_set_extra(&result, extra);
|
||||||
subtree_to_push = ts_subtree_from_mut(result);
|
subtree_to_push = ts_subtree_from_mut(result);
|
||||||
}
|
}
|
||||||
|
|
@ -579,7 +577,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
|
||||||
SubtreeArray children = slice.subtrees;
|
SubtreeArray children = slice.subtrees;
|
||||||
ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);
|
ts_subtree_array_remove_trailing_extras(&children, &self->trailing_extras);
|
||||||
|
|
||||||
MutableSubtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language);
|
t_mut_subtree parent = ts_subtree_new_node(symbol, &children, production_id, self->language);
|
||||||
|
|
||||||
// This pop operation may have caused multiple stack versions to collapse
|
// This pop operation may have caused multiple stack versions to collapse
|
||||||
// into one, because they all diverged from a common state. In that case,
|
// into one, because they all diverged from a common state. In that case,
|
||||||
|
|
@ -651,7 +649,7 @@ static t_stack_version ts_parser__reduce(TSParser *self, t_stack_version version
|
||||||
return ts_stack_version_count(self->stack) > initial_version_count ? initial_version_count : STACK_VERSION_NONE;
|
return ts_stack_version_count(self->stack) > initial_version_count ? initial_version_count : STACK_VERSION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_parser__accept(TSParser *self, t_stack_version version, Subtree lookahead)
|
static void ts_parser__accept(TSParser *self, t_stack_version version, t_subtree lookahead)
|
||||||
{
|
{
|
||||||
assert(ts_subtree_is_eof(lookahead));
|
assert(ts_subtree_is_eof(lookahead));
|
||||||
ts_stack_push(self->stack, version, lookahead, false, 1);
|
ts_stack_push(self->stack, version, lookahead, false, 1);
|
||||||
|
|
@ -661,14 +659,14 @@ static void ts_parser__accept(TSParser *self, t_stack_version version, Subtree l
|
||||||
{
|
{
|
||||||
SubtreeArray trees = pop.contents[i].subtrees;
|
SubtreeArray trees = pop.contents[i].subtrees;
|
||||||
|
|
||||||
Subtree root = NULL;
|
t_subtree root = NULL;
|
||||||
for (t_u32 j = trees.size - 1; j + 1 > 0; j--)
|
for (t_u32 j = trees.size - 1; j + 1 > 0; j--)
|
||||||
{
|
{
|
||||||
Subtree tree = trees.contents[j];
|
t_subtree tree = trees.contents[j];
|
||||||
if (!ts_subtree_extra(tree))
|
if (!ts_subtree_extra(tree))
|
||||||
{
|
{
|
||||||
t_u32 child_count = ts_subtree_child_count(tree);
|
t_u32 child_count = ts_subtree_child_count(tree);
|
||||||
const Subtree *children = ts_subtree_children(tree);
|
const t_subtree *children = ts_subtree_children(tree);
|
||||||
for (t_u32 k = 0; k < child_count; k++)
|
for (t_u32 k = 0; k < child_count; k++)
|
||||||
{
|
{
|
||||||
ts_subtree_retain(children[k]);
|
ts_subtree_retain(children[k]);
|
||||||
|
|
@ -838,7 +836,7 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
|
||||||
if (error_trees.size > 0)
|
if (error_trees.size > 0)
|
||||||
{
|
{
|
||||||
assert(error_trees.size == 1);
|
assert(error_trees.size == 1);
|
||||||
Subtree error_tree = error_trees.contents[0];
|
t_subtree error_tree = error_trees.contents[0];
|
||||||
t_u32 error_child_count = ts_subtree_child_count(error_tree);
|
t_u32 error_child_count = ts_subtree_child_count(error_tree);
|
||||||
if (error_child_count > 0)
|
if (error_child_count > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -855,7 +853,7 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
|
||||||
|
|
||||||
if (slice.subtrees.size > 0)
|
if (slice.subtrees.size > 0)
|
||||||
{
|
{
|
||||||
Subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
|
t_subtree error = ts_subtree_new_error_node(&slice.subtrees, true, self->language);
|
||||||
ts_stack_push(self->stack, slice.version, error, false, goal_state);
|
ts_stack_push(self->stack, slice.version, error, false, goal_state);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -865,7 +863,7 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
|
||||||
|
|
||||||
for (t_u32 j = 0; j < self->trailing_extras.size; j++)
|
for (t_u32 j = 0; j < self->trailing_extras.size; j++)
|
||||||
{
|
{
|
||||||
Subtree tree = self->trailing_extras.contents[j];
|
t_subtree tree = self->trailing_extras.contents[j];
|
||||||
ts_stack_push(self->stack, slice.version, tree, false, goal_state);
|
ts_stack_push(self->stack, slice.version, tree, false, goal_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -875,7 +873,7 @@ static bool ts_parser__recover_to_state(TSParser *self, t_stack_version version,
|
||||||
return previous_version != STACK_VERSION_NONE;
|
return previous_version != STACK_VERSION_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_parser__recover(TSParser *self, t_stack_version version, Subtree lookahead)
|
static void ts_parser__recover(TSParser *self, t_stack_version version, t_subtree lookahead)
|
||||||
{
|
{
|
||||||
bool did_recover = false;
|
bool did_recover = false;
|
||||||
t_u32 previous_version_count = ts_stack_version_count(self->stack);
|
t_u32 previous_version_count = ts_stack_version_count(self->stack);
|
||||||
|
|
@ -977,7 +975,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, Subtree
|
||||||
if (ts_subtree_is_eof(lookahead))
|
if (ts_subtree_is_eof(lookahead))
|
||||||
{
|
{
|
||||||
SubtreeArray children = array_new();
|
SubtreeArray children = array_new();
|
||||||
Subtree parent = ts_subtree_new_error_node(&children, false, self->language);
|
t_subtree parent = ts_subtree_new_error_node(&children, false, self->language);
|
||||||
ts_stack_push(self->stack, version, parent, false, 1);
|
ts_stack_push(self->stack, version, parent, false, 1);
|
||||||
ts_parser__accept(self, version, lookahead);
|
ts_parser__accept(self, version, lookahead);
|
||||||
return;
|
return;
|
||||||
|
|
@ -999,7 +997,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, Subtree
|
||||||
const TSParseAction *actions = ts_language_actions(self->language, 1, ts_subtree_symbol(lookahead), &n);
|
const TSParseAction *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)
|
if (n > 0 && actions[n - 1].type == TSParseActionTypeShift && actions[n - 1].shift.extra)
|
||||||
{
|
{
|
||||||
MutableSubtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
t_mut_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
||||||
ts_subtree_set_extra(&mutable_lookahead, true);
|
ts_subtree_set_extra(&mutable_lookahead, true);
|
||||||
lookahead = ts_subtree_from_mut(mutable_lookahead);
|
lookahead = ts_subtree_from_mut(mutable_lookahead);
|
||||||
}
|
}
|
||||||
|
|
@ -1008,7 +1006,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, Subtree
|
||||||
SubtreeArray children = array_new();
|
SubtreeArray children = array_new();
|
||||||
array_reserve(&children, 1);
|
array_reserve(&children, 1);
|
||||||
array_push(&children, lookahead);
|
array_push(&children, lookahead);
|
||||||
MutableSubtree error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children, 0, self->language);
|
t_mut_subtree error_repeat = ts_subtree_new_node(ts_builtin_sym_error_repeat, &children, 0, self->language);
|
||||||
|
|
||||||
// If other tokens have already been skipped, so there is already an ERROR at the top of the
|
// If other tokens have already been skipped, so there is already an ERROR at the top of the
|
||||||
// stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger
|
// stack, then pop that ERROR off the stack and wrap the two ERRORs together into one larger
|
||||||
|
|
@ -1046,7 +1044,7 @@ static void ts_parser__recover(TSParser *self, t_stack_version version, Subtree
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_parser__handle_error(TSParser *self, t_stack_version version, Subtree lookahead)
|
static void ts_parser__handle_error(TSParser *self, t_stack_version version, t_subtree lookahead)
|
||||||
{
|
{
|
||||||
t_u32 previous_version_count = ts_stack_version_count(self->stack);
|
t_u32 previous_version_count = ts_stack_version_count(self->stack);
|
||||||
|
|
||||||
|
|
@ -1084,7 +1082,7 @@ static void ts_parser__handle_error(TSParser *self, t_stack_version version, Sub
|
||||||
t_u32 lookahead_bytes = ts_subtree_total_bytes(lookahead) + ts_subtree_lookahead_bytes(lookahead);
|
t_u32 lookahead_bytes = ts_subtree_total_bytes(lookahead) + ts_subtree_lookahead_bytes(lookahead);
|
||||||
|
|
||||||
t_stack_version version_with_missing_tree = ts_stack_copy_version(self->stack, v);
|
t_stack_version version_with_missing_tree = ts_stack_copy_version(self->stack, v);
|
||||||
Subtree missing_tree =
|
t_subtree missing_tree =
|
||||||
ts_subtree_new_missing_leaf(/*&self->tree_pool,*/ missing_symbol, padding, lookahead_bytes, self->language);
|
ts_subtree_new_missing_leaf(/*&self->tree_pool,*/ missing_symbol, padding, lookahead_bytes, self->language);
|
||||||
ts_stack_push(self->stack, version_with_missing_tree, missing_tree, false, state_after_missing_symbol);
|
ts_stack_push(self->stack, version_with_missing_tree, missing_tree, false, state_after_missing_symbol);
|
||||||
|
|
||||||
|
|
@ -1123,7 +1121,7 @@ static bool ts_parser__advance(TSParser *self, t_stack_version version, bool all
|
||||||
(void)(allow_node_reuse);
|
(void)(allow_node_reuse);
|
||||||
TSStateId state = ts_stack_state(self->stack, version);
|
TSStateId state = ts_stack_state(self->stack, version);
|
||||||
|
|
||||||
Subtree lookahead = NULL;
|
t_subtree lookahead = NULL;
|
||||||
TableEntry table_entry = {.action_count = 0};
|
TableEntry table_entry = {.action_count = 0};
|
||||||
|
|
||||||
bool needs_lex = true;
|
bool needs_lex = true;
|
||||||
|
|
@ -1248,7 +1246,7 @@ static bool ts_parser__advance(TSParser *self, t_stack_version version, bool all
|
||||||
ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);
|
ts_language_table_entry(self->language, state, self->language->keyword_capture_token, &table_entry);
|
||||||
if (table_entry.action_count > 0)
|
if (table_entry.action_count > 0)
|
||||||
{
|
{
|
||||||
MutableSubtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
t_mut_subtree mutable_lookahead = ts_subtree_make_mut(/*&self->tree_pool,*/ lookahead);
|
||||||
ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);
|
ts_subtree_set_symbol(&mutable_lookahead, self->language->keyword_capture_token, self->language);
|
||||||
lookahead = ts_subtree_from_mut(mutable_lookahead);
|
lookahead = ts_subtree_from_mut(mutable_lookahead);
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -1373,7 +1371,7 @@ static t_u32 ts_parser__condense_stack(TSParser *self)
|
||||||
if (!has_unpaused_version && self->accept_count < MAX_VERSION_COUNT)
|
if (!has_unpaused_version && self->accept_count < MAX_VERSION_COUNT)
|
||||||
{
|
{
|
||||||
min_error_cost = ts_stack_error_cost(self->stack, i);
|
min_error_cost = ts_stack_error_cost(self->stack, i);
|
||||||
Subtree lookahead = ts_stack_resume(self->stack, i);
|
t_subtree lookahead = ts_stack_resume(self->stack, i);
|
||||||
ts_parser__handle_error(self, i, lookahead);
|
ts_parser__handle_error(self, i, lookahead);
|
||||||
has_unpaused_version = true;
|
has_unpaused_version = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,10 +28,10 @@ bool ts_stack_is_paused(const t_stack *self, t_stack_version version)
|
||||||
return (array_get(&self->heads, version)->status == SStatusPaused);
|
return (array_get(&self->heads, version)->status == SStatusPaused);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_stack_resume(t_stack *self, t_stack_version version)
|
t_subtree ts_stack_resume(t_stack *self, t_stack_version version)
|
||||||
{
|
{
|
||||||
t_stack_head *head;
|
t_stack_head *head;
|
||||||
Subtree result;
|
t_subtree result;
|
||||||
|
|
||||||
head = array_get(&self->heads, version);
|
head = array_get(&self->heads, version);
|
||||||
assert(head->status == SStatusPaused);
|
assert(head->status == SStatusPaused);
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ bool ts_stack_has_advanced_since_error(const t_stack *self,
|
||||||
{
|
{
|
||||||
const t_stack_head *head = array_get(&self->heads, version);
|
const t_stack_head *head = array_get(&self->heads, version);
|
||||||
const t_stack_node *node = head->node;
|
const t_stack_node *node = head->node;
|
||||||
Subtree subtree;
|
t_subtree subtree;
|
||||||
|
|
||||||
if (node->error_cost == 0)
|
if (node->error_cost == 0)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include "parser/stack.h"
|
#include "parser/stack.h"
|
||||||
#include "parser/_inner/stack.h"
|
#include "parser/_inner/stack.h"
|
||||||
|
|
||||||
bool stack__subtree_is_equivalent(Subtree left, Subtree right)
|
bool stack__subtree_is_equivalent(t_subtree left, t_subtree right)
|
||||||
{
|
{
|
||||||
if (left == right)
|
if (left == right)
|
||||||
return (true);
|
return (true);
|
||||||
|
|
@ -97,7 +97,7 @@ t_stack_version original_version, t_stack_node *node, SubtreeArray *subtrees)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_set_last_external_token(t_stack *self, t_stack_version version,
|
void ts_stack_set_last_external_token(t_stack *self, t_stack_version version,
|
||||||
Subtree token)
|
t_subtree token)
|
||||||
{
|
{
|
||||||
t_stack_head *head;
|
t_stack_head *head;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ Length ts_stack_position(const t_stack *self, t_stack_version version)
|
||||||
return (array_get(&self->heads, version)->node->position);
|
return (array_get(&self->heads, version)->node->position);
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_stack_last_external_token(const t_stack *self,
|
t_subtree ts_stack_last_external_token(const t_stack *self,
|
||||||
t_stack_version version)
|
t_stack_version version)
|
||||||
{
|
{
|
||||||
return (array_get(&self->heads, version)->last_external_token);
|
return (array_get(&self->heads, version)->last_external_token);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ t_stack_slice_array stack__iter(t_stack *self, t_stack_version version,
|
||||||
{
|
{
|
||||||
include_subtrees = true;
|
include_subtrees = true;
|
||||||
array_reserve(&new_iterator.subtrees,
|
array_reserve(&new_iterator.subtrees,
|
||||||
(t_u32)ts_subtree_alloc_size(goal_subtree_count) / sizeof(Subtree));
|
(t_u32)ts_subtree_alloc_size(goal_subtree_count) / sizeof(t_subtree));
|
||||||
}
|
}
|
||||||
array_push(&self->iterators, new_iterator);
|
array_push(&self->iterators, new_iterator);
|
||||||
while (self->iterators.size > 0)
|
while (self->iterators.size > 0)
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
#include "parser/_inner/stack.h"
|
#include "parser/_inner/stack.h"
|
||||||
#include "parser/language.h"
|
#include "parser/language.h"
|
||||||
|
|
||||||
void ts_stack_push(t_stack *self, t_stack_version version, Subtree subtree,
|
void ts_stack_push(t_stack *self, t_stack_version version, t_subtree subtree,
|
||||||
bool pending, TSStateId state)
|
bool pending, TSStateId state)
|
||||||
{
|
{
|
||||||
t_stack_head *head;
|
t_stack_head *head;
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ void ts_stack_halt(t_stack *self, t_stack_version version)
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_stack_pause(t_stack *self, t_stack_version version,
|
void ts_stack_pause(t_stack *self, t_stack_version version,
|
||||||
Subtree lookahead)
|
t_subtree lookahead)
|
||||||
{
|
{
|
||||||
t_stack_head *head;
|
t_stack_head *head;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -70,7 +70,7 @@ void stack_node_release(t_stack_node *self)
|
||||||
// Count intermediate error nodes even though they are not visible,
|
// Count intermediate error nodes even though they are not visible,
|
||||||
// because a stack version's node count is used to check whether it
|
// 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.
|
// has made any progress since the last time it encountered an error.
|
||||||
t_u32 stack__subtree_node_count(Subtree subtree)
|
t_u32 stack__subtree_node_count(t_subtree subtree)
|
||||||
{
|
{
|
||||||
t_u32 count;
|
t_u32 count;
|
||||||
|
|
||||||
|
|
@ -83,7 +83,7 @@ t_u32 stack__subtree_node_count(Subtree subtree)
|
||||||
}
|
}
|
||||||
|
|
||||||
t_stack_node *stack_node_new(t_stack_node *previous_node,
|
t_stack_node *stack_node_new(t_stack_node *previous_node,
|
||||||
Subtree subtree, bool is_pending, TSStateId state)
|
t_subtree subtree, bool is_pending, TSStateId state)
|
||||||
{
|
{
|
||||||
t_stack_node *node;
|
t_stack_node *node;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,8 @@ void ts_subtree_array_copy(SubtreeArray self, SubtreeArray *dest)
|
||||||
dest->contents = self.contents;
|
dest->contents = self.contents;
|
||||||
if (self.capacity > 0)
|
if (self.capacity > 0)
|
||||||
{
|
{
|
||||||
dest->contents = mem_alloc_array(self.capacity, sizeof(Subtree));
|
dest->contents = mem_alloc_array(self.capacity, sizeof(t_subtree));
|
||||||
mem_copy(dest->contents, self.contents, self.size * sizeof(Subtree));
|
mem_copy(dest->contents, self.contents, self.size * sizeof(t_subtree));
|
||||||
for (t_u32 i = 0; i < self.size; i++)
|
for (t_u32 i = 0; i < self.size; i++)
|
||||||
{
|
{
|
||||||
ts_subtree_retain(dest->contents[i]);
|
ts_subtree_retain(dest->contents[i]);
|
||||||
|
|
@ -50,7 +50,7 @@ void ts_subtree_array_remove_trailing_extras(SubtreeArray *self, SubtreeArray *d
|
||||||
array_clear(destination);
|
array_clear(destination);
|
||||||
while (self->size > 0)
|
while (self->size > 0)
|
||||||
{
|
{
|
||||||
Subtree last = self->contents[self->size - 1];
|
t_subtree last = self->contents[self->size - 1];
|
||||||
if (ts_subtree_extra(last))
|
if (ts_subtree_extra(last))
|
||||||
{
|
{
|
||||||
self->size--;
|
self->size--;
|
||||||
|
|
@ -69,21 +69,21 @@ void ts_subtree_array_reverse(SubtreeArray *self)
|
||||||
for (t_u32 i = 0, limit = self->size / 2; i < limit; i++)
|
for (t_u32 i = 0, limit = self->size / 2; i < limit; i++)
|
||||||
{
|
{
|
||||||
size_t reverse_index = self->size - 1 - i;
|
size_t reverse_index = self->size - 1 - i;
|
||||||
Subtree swap = self->contents[i];
|
t_subtree swap = self->contents[i];
|
||||||
self->contents[i] = self->contents[reverse_index];
|
self->contents[i] = self->contents[reverse_index];
|
||||||
self->contents[reverse_index] = swap;
|
self->contents[reverse_index] = swap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u32 lookahead_bytes, TSStateId parse_state,
|
t_subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u32 lookahead_bytes, TSStateId parse_state,
|
||||||
bool has_external_tokens, bool depends_on_column, bool is_keyword, const TSLanguage *language)
|
bool has_external_tokens, bool depends_on_column, bool is_keyword, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
||||||
bool extra = symbol == ts_builtin_sym_end;
|
bool extra = symbol == ts_builtin_sym_end;
|
||||||
|
|
||||||
{
|
{
|
||||||
SubtreeHeapData *data = mem_alloc(sizeof(*data));
|
t_subtree_data *data = mem_alloc(sizeof(*data));
|
||||||
*data = (SubtreeHeapData){.ref_count = 1,
|
*data = (t_subtree_data){.ref_count = 1,
|
||||||
.padding = padding,
|
.padding = padding,
|
||||||
.size = size,
|
.size = size,
|
||||||
.lookahead_bytes = lookahead_bytes,
|
.lookahead_bytes = lookahead_bytes,
|
||||||
|
|
@ -103,11 +103,11 @@ Subtree ts_subtree_new_leaf(TSSymbol symbol, Length padding, Length size, t_u32
|
||||||
.is_missing = false,
|
.is_missing = false,
|
||||||
.is_keyword = is_keyword,
|
.is_keyword = is_keyword,
|
||||||
{{.first_leaf = {.symbol = 0, .parse_state = 0}}}};
|
{{.first_leaf = {.symbol = 0, .parse_state = 0}}}};
|
||||||
return (Subtree)data;
|
return (t_subtree)data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_subtree_set_symbol(MutableSubtree *self, TSSymbol symbol, const TSLanguage *language)
|
void ts_subtree_set_symbol(t_mut_subtree *self, TSSymbol symbol, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
||||||
{
|
{
|
||||||
|
|
@ -117,11 +117,11 @@ void ts_subtree_set_symbol(MutableSubtree *self, TSSymbol symbol, const TSLangua
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size, t_u32 bytes_scanned, TSStateId parse_state,
|
t_subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size, t_u32 bytes_scanned, TSStateId parse_state,
|
||||||
const TSLanguage *language)
|
const TSLanguage *language)
|
||||||
{
|
{
|
||||||
Subtree result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, bytes_scanned, parse_state, false, false, false, language);
|
t_subtree result = ts_subtree_new_leaf(ts_builtin_sym_error, padding, size, bytes_scanned, parse_state, false, false, false, language);
|
||||||
SubtreeHeapData *data = (SubtreeHeapData *)result;
|
t_subtree_data *data = (t_subtree_data *)result;
|
||||||
data->fragile_left = true;
|
data->fragile_left = true;
|
||||||
data->fragile_right = true;
|
data->fragile_right = true;
|
||||||
data->lookahead_char = lookahead_char;
|
data->lookahead_char = lookahead_char;
|
||||||
|
|
@ -129,13 +129,13 @@ Subtree ts_subtree_new_error(t_i32 lookahead_char, Length padding, Length size,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clone a subtree.
|
// Clone a subtree.
|
||||||
MutableSubtree ts_subtree_clone(Subtree self)
|
t_mut_subtree ts_subtree_clone(t_subtree self)
|
||||||
{
|
{
|
||||||
size_t alloc_size = ts_subtree_alloc_size(self->child_count);
|
size_t alloc_size = ts_subtree_alloc_size(self->child_count);
|
||||||
Subtree *new_children = mem_alloc(alloc_size);
|
t_subtree *new_children = mem_alloc(alloc_size);
|
||||||
Subtree *old_children = ts_subtree_children(self);
|
t_subtree *old_children = ts_subtree_children(self);
|
||||||
mem_copy(new_children, old_children, alloc_size);
|
mem_copy(new_children, old_children, alloc_size);
|
||||||
SubtreeHeapData *result = (SubtreeHeapData *)&new_children[self->child_count];
|
t_subtree_data *result = (t_subtree_data *)&new_children[self->child_count];
|
||||||
if (self->child_count > 0)
|
if (self->child_count > 0)
|
||||||
{
|
{
|
||||||
for (t_u32 i = 0; i < self->child_count; i++)
|
for (t_u32 i = 0; i < self->child_count; i++)
|
||||||
|
|
@ -148,7 +148,7 @@ MutableSubtree ts_subtree_clone(Subtree self)
|
||||||
result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state);
|
result->external_scanner_state = ts_external_scanner_state_copy(&self->external_scanner_state);
|
||||||
}
|
}
|
||||||
result->ref_count = 1;
|
result->ref_count = 1;
|
||||||
return (MutableSubtree)result;
|
return (t_mut_subtree)result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get mutable version of a subtree.
|
// Get mutable version of a subtree.
|
||||||
|
|
@ -156,31 +156,31 @@ MutableSubtree ts_subtree_clone(Subtree self)
|
||||||
// This takes ownership of the subtree. If the subtree has only one owner,
|
// This takes ownership of the subtree. If the subtree has only one owner,
|
||||||
// this will directly convert it into a mutable version. Otherwise, it will
|
// this will directly convert it into a mutable version. Otherwise, it will
|
||||||
// perform a copy.
|
// perform a copy.
|
||||||
MutableSubtree ts_subtree_make_mut(Subtree self)
|
t_mut_subtree ts_subtree_make_mut(t_subtree self)
|
||||||
{
|
{
|
||||||
if (self->ref_count == 1)
|
if (self->ref_count == 1)
|
||||||
return ts_subtree_to_mut_unsafe(self);
|
return ts_subtree_to_mut_unsafe(self);
|
||||||
MutableSubtree result = ts_subtree_clone(self);
|
t_mut_subtree result = ts_subtree_clone(self);
|
||||||
ts_subtree_release(self);
|
ts_subtree_release(self);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ts_subtree__compress(MutableSubtree self, t_u32 count, const TSLanguage *language, MutableSubtreeArray *stack)
|
static void ts_subtree__compress(t_mut_subtree self, t_u32 count, const TSLanguage *language, MutableSubtreeArray *stack)
|
||||||
{
|
{
|
||||||
t_u32 initial_stack_size = stack->size;
|
t_u32 initial_stack_size = stack->size;
|
||||||
|
|
||||||
MutableSubtree tree = self;
|
t_mut_subtree tree = self;
|
||||||
TSSymbol symbol = tree->symbol;
|
TSSymbol symbol = tree->symbol;
|
||||||
for (t_u32 i = 0; i < count; i++)
|
for (t_u32 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (tree->ref_count > 1 || tree->child_count < 2)
|
if (tree->ref_count > 1 || tree->child_count < 2)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
|
t_mut_subtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
|
||||||
if (child->child_count < 2 || child->ref_count > 1 || child->symbol != symbol)
|
if (child->child_count < 2 || child->ref_count > 1 || child->symbol != symbol)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[0]);
|
t_mut_subtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[0]);
|
||||||
if (grandchild->child_count < 2 || grandchild->ref_count > 1 || grandchild->symbol != symbol)
|
if (grandchild->child_count < 2 || grandchild->ref_count > 1 || grandchild->symbol != symbol)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -194,15 +194,15 @@ static void ts_subtree__compress(MutableSubtree self, t_u32 count, const TSLangu
|
||||||
while (stack->size > initial_stack_size)
|
while (stack->size > initial_stack_size)
|
||||||
{
|
{
|
||||||
tree = array_pop(stack);
|
tree = array_pop(stack);
|
||||||
MutableSubtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
|
t_mut_subtree child = ts_subtree_to_mut_unsafe(ts_subtree_children(tree)[0]);
|
||||||
MutableSubtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[child->child_count - 1]);
|
t_mut_subtree grandchild = ts_subtree_to_mut_unsafe(ts_subtree_children(child)[child->child_count - 1]);
|
||||||
ts_subtree_summarize_children(grandchild, language);
|
ts_subtree_summarize_children(grandchild, language);
|
||||||
ts_subtree_summarize_children(child, language);
|
ts_subtree_summarize_children(child, language);
|
||||||
ts_subtree_summarize_children(tree, language);
|
ts_subtree_summarize_children(tree, language);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_subtree_balance(Subtree self, const TSLanguage *language)
|
void ts_subtree_balance(t_subtree self, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
|
|
||||||
MutableSubtreeArray balance_stack = array_new();
|
MutableSubtreeArray balance_stack = array_new();
|
||||||
|
|
@ -215,12 +215,12 @@ void ts_subtree_balance(Subtree self, const TSLanguage *language)
|
||||||
|
|
||||||
while (balance_stack.size > 0)
|
while (balance_stack.size > 0)
|
||||||
{
|
{
|
||||||
MutableSubtree tree = array_pop(&balance_stack);
|
t_mut_subtree tree = array_pop(&balance_stack);
|
||||||
|
|
||||||
if (tree->repeat_depth > 0)
|
if (tree->repeat_depth > 0)
|
||||||
{
|
{
|
||||||
Subtree child1 = ts_subtree_children(tree)[0];
|
t_subtree child1 = ts_subtree_children(tree)[0];
|
||||||
Subtree child2 = ts_subtree_children(tree)[tree->child_count - 1];
|
t_subtree child2 = ts_subtree_children(tree)[tree->child_count - 1];
|
||||||
long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
|
long repeat_delta = (long)ts_subtree_repeat_depth(child1) - (long)ts_subtree_repeat_depth(child2);
|
||||||
if (repeat_delta > 0)
|
if (repeat_delta > 0)
|
||||||
{
|
{
|
||||||
|
|
@ -235,7 +235,7 @@ void ts_subtree_balance(Subtree self, const TSLanguage *language)
|
||||||
|
|
||||||
for (t_u32 i = 0; i < tree->child_count; i++)
|
for (t_u32 i = 0; i < tree->child_count; i++)
|
||||||
{
|
{
|
||||||
Subtree child = ts_subtree_children(tree)[i];
|
t_subtree child = ts_subtree_children(tree)[i];
|
||||||
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
|
if (ts_subtree_child_count(child) > 0 && child->ref_count == 1)
|
||||||
{
|
{
|
||||||
array_push(&balance_stack, ts_subtree_to_mut_unsafe(child));
|
array_push(&balance_stack, ts_subtree_to_mut_unsafe(child));
|
||||||
|
|
@ -246,7 +246,7 @@ void ts_subtree_balance(Subtree self, const TSLanguage *language)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign all of the node's properties that depend on its children.
|
// Assign all of the node's properties that depend on its children.
|
||||||
void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *language)
|
void ts_subtree_summarize_children(t_mut_subtree self, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
self->named_child_count = 0;
|
self->named_child_count = 0;
|
||||||
self->visible_child_count = 0;
|
self->visible_child_count = 0;
|
||||||
|
|
@ -262,10 +262,10 @@ void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *langua
|
||||||
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->production_id);
|
const TSSymbol *alias_sequence = ts_language_alias_sequence(language, self->production_id);
|
||||||
t_u32 lookahead_end_byte = 0;
|
t_u32 lookahead_end_byte = 0;
|
||||||
|
|
||||||
const Subtree *children = ts_subtree_children(self);
|
const t_subtree *children = ts_subtree_children(self);
|
||||||
for (t_u32 i = 0; i < self->child_count; i++)
|
for (t_u32 i = 0; i < self->child_count; i++)
|
||||||
{
|
{
|
||||||
Subtree child = children[i];
|
t_subtree child = children[i];
|
||||||
|
|
||||||
if (self->size.extent.row == 0 && ts_subtree_depends_on_column(child))
|
if (self->size.extent.row == 0 && ts_subtree_depends_on_column(child))
|
||||||
{
|
{
|
||||||
|
|
@ -362,8 +362,8 @@ void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *langua
|
||||||
|
|
||||||
if (self->child_count > 0)
|
if (self->child_count > 0)
|
||||||
{
|
{
|
||||||
Subtree first_child = children[0];
|
t_subtree first_child = children[0];
|
||||||
Subtree last_child = children[self->child_count - 1];
|
t_subtree last_child = children[self->child_count - 1];
|
||||||
|
|
||||||
self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
|
self->first_leaf.symbol = ts_subtree_leaf_symbol(first_child);
|
||||||
self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
|
self->first_leaf.parse_state = ts_subtree_leaf_parse_state(first_child);
|
||||||
|
|
@ -390,21 +390,21 @@ void ts_subtree_summarize_children(MutableSubtree self, const TSLanguage *langua
|
||||||
// Create a new parent node with the given children.
|
// Create a new parent node with the given children.
|
||||||
//
|
//
|
||||||
// This takes ownership of the children array.
|
// This takes ownership of the children array.
|
||||||
MutableSubtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language)
|
t_mut_subtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u32 production_id, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
TSSymbolMetadata metadata = ts_language_symbol_metadata(language, symbol);
|
||||||
bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
|
bool fragile = symbol == ts_builtin_sym_error || symbol == ts_builtin_sym_error_repeat;
|
||||||
|
|
||||||
// Allocate the node's data at the end of the array of children.
|
// Allocate the node's data at the end of the array of children.
|
||||||
size_t new_byte_size = ts_subtree_alloc_size(children->size);
|
size_t new_byte_size = ts_subtree_alloc_size(children->size);
|
||||||
if (children->capacity * sizeof(Subtree) < new_byte_size)
|
if (children->capacity * sizeof(t_subtree) < new_byte_size)
|
||||||
{
|
{
|
||||||
children->contents = mem_realloc(children->contents, new_byte_size);
|
children->contents = mem_realloc(children->contents, new_byte_size);
|
||||||
children->capacity = (t_u32)(new_byte_size / sizeof(Subtree));
|
children->capacity = (t_u32)(new_byte_size / sizeof(t_subtree));
|
||||||
}
|
}
|
||||||
SubtreeHeapData *data = (SubtreeHeapData *)&children->contents[children->size];
|
t_subtree_data *data = (t_subtree_data *)&children->contents[children->size];
|
||||||
|
|
||||||
*data = (SubtreeHeapData){.ref_count = 1,
|
*data = (t_subtree_data){.ref_count = 1,
|
||||||
.symbol = symbol,
|
.symbol = symbol,
|
||||||
.child_count = children->size,
|
.child_count = children->size,
|
||||||
.visible = metadata.visible,
|
.visible = metadata.visible,
|
||||||
|
|
@ -419,7 +419,7 @@ MutableSubtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u3
|
||||||
.production_id = production_id,
|
.production_id = production_id,
|
||||||
.first_leaf = {.symbol = 0, .parse_state = 0},
|
.first_leaf = {.symbol = 0, .parse_state = 0},
|
||||||
}}};
|
}}};
|
||||||
MutableSubtree result = data;
|
t_mut_subtree result = data;
|
||||||
ts_subtree_summarize_children(result, language);
|
ts_subtree_summarize_children(result, language);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -428,9 +428,9 @@ MutableSubtree ts_subtree_new_node(TSSymbol symbol, SubtreeArray *children, t_u3
|
||||||
//
|
//
|
||||||
// This node is treated as 'extra'. Its children are prevented from having
|
// This node is treated as 'extra'. Its children are prevented from having
|
||||||
// having any effect on the parse state.
|
// having any effect on the parse state.
|
||||||
Subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLanguage *language)
|
t_subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
MutableSubtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
|
t_mut_subtree result = ts_subtree_new_node(ts_builtin_sym_error, children, 0, language);
|
||||||
result->extra = extra;
|
result->extra = extra;
|
||||||
return ts_subtree_from_mut(result);
|
return ts_subtree_from_mut(result);
|
||||||
}
|
}
|
||||||
|
|
@ -439,21 +439,21 @@ Subtree ts_subtree_new_error_node(SubtreeArray *children, bool extra, const TSLa
|
||||||
//
|
//
|
||||||
// This node is treated as 'extra'. Its children are prevented from having
|
// This node is treated as 'extra'. Its children are prevented from having
|
||||||
// having any effect on the parse state.
|
// having any effect on the parse state.
|
||||||
Subtree ts_subtree_new_missing_leaf(TSSymbol symbol, Length padding, t_u32 lookahead_bytes, const TSLanguage *language)
|
t_subtree ts_subtree_new_missing_leaf(TSSymbol symbol, Length padding, t_u32 lookahead_bytes, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
Subtree result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language);
|
t_subtree result = ts_subtree_new_leaf(symbol, padding, length_zero(), lookahead_bytes, 0, false, false, false, language);
|
||||||
((SubtreeHeapData *)result)->is_missing = true;
|
((t_subtree_data *)result)->is_missing = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_subtree_retain(Subtree self)
|
void ts_subtree_retain(t_subtree self)
|
||||||
{
|
{
|
||||||
assert(self->ref_count > 0);
|
assert(self->ref_count > 0);
|
||||||
(*(t_u32 *)(&self->ref_count))++;
|
(*(t_u32 *)(&self->ref_count))++;
|
||||||
assert(self->ref_count != 0);
|
assert(self->ref_count != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ts_subtree_release(Subtree self)
|
void ts_subtree_release(t_subtree self)
|
||||||
{
|
{
|
||||||
MutableSubtreeArray to_free;
|
MutableSubtreeArray to_free;
|
||||||
|
|
||||||
|
|
@ -469,13 +469,13 @@ void ts_subtree_release(Subtree self)
|
||||||
|
|
||||||
while (to_free.size > 0)
|
while (to_free.size > 0)
|
||||||
{
|
{
|
||||||
MutableSubtree tree = array_pop(&to_free);
|
t_mut_subtree tree = array_pop(&to_free);
|
||||||
if (tree->child_count > 0)
|
if (tree->child_count > 0)
|
||||||
{
|
{
|
||||||
Subtree *children = ts_subtree_children(tree);
|
t_subtree *children = ts_subtree_children(tree);
|
||||||
for (t_u32 i = 0; i < tree->child_count; i++)
|
for (t_u32 i = 0; i < tree->child_count; i++)
|
||||||
{
|
{
|
||||||
Subtree child = children[i];
|
t_subtree child = children[i];
|
||||||
assert(child->ref_count > 0);
|
assert(child->ref_count > 0);
|
||||||
if (--(*(t_u32 *)(&child->ref_count)) == 0)
|
if (--(*(t_u32 *)(&child->ref_count)) == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -494,7 +494,7 @@ void ts_subtree_release(Subtree self)
|
||||||
array_delete(&to_free);
|
array_delete(&to_free);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ts_subtree_compare(Subtree left, Subtree right)
|
int ts_subtree_compare(t_subtree left, t_subtree right)
|
||||||
{
|
{
|
||||||
MutableSubtreeArray compare_stack = array_new();
|
MutableSubtreeArray compare_stack = array_new();
|
||||||
|
|
||||||
|
|
@ -524,8 +524,8 @@ int ts_subtree_compare(Subtree left, Subtree right)
|
||||||
|
|
||||||
for (t_u32 i = ts_subtree_child_count(left); i > 0; i--)
|
for (t_u32 i = ts_subtree_child_count(left); i > 0; i--)
|
||||||
{
|
{
|
||||||
Subtree left_child = ts_subtree_children(left)[i - 1];
|
t_subtree left_child = ts_subtree_children(left)[i - 1];
|
||||||
Subtree right_child = ts_subtree_children(right)[i - 1];
|
t_subtree right_child = ts_subtree_children(right)[i - 1];
|
||||||
array_push(&compare_stack, ts_subtree_to_mut_unsafe(left_child));
|
array_push(&compare_stack, ts_subtree_to_mut_unsafe(left_child));
|
||||||
array_push(&compare_stack, ts_subtree_to_mut_unsafe(right_child));
|
array_push(&compare_stack, ts_subtree_to_mut_unsafe(right_child));
|
||||||
}
|
}
|
||||||
|
|
@ -535,7 +535,7 @@ int ts_subtree_compare(Subtree left, Subtree right)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Subtree ts_subtree_last_external_token(Subtree tree)
|
t_subtree ts_subtree_last_external_token(t_subtree tree)
|
||||||
{
|
{
|
||||||
if (!ts_subtree_has_external_tokens(tree))
|
if (!ts_subtree_has_external_tokens(tree))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -543,7 +543,7 @@ Subtree ts_subtree_last_external_token(Subtree tree)
|
||||||
{
|
{
|
||||||
for (t_u32 i = tree->child_count - 1; i + 1 > 0; i--)
|
for (t_u32 i = tree->child_count - 1; i + 1 > 0; i--)
|
||||||
{
|
{
|
||||||
Subtree child = ts_subtree_children(tree)[i];
|
t_subtree child = ts_subtree_children(tree)[i];
|
||||||
if (ts_subtree_has_external_tokens(child))
|
if (ts_subtree_has_external_tokens(child))
|
||||||
{
|
{
|
||||||
tree = child;
|
tree = child;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
#include "parser/subtree.h"
|
#include "parser/subtree.h"
|
||||||
#include "parser/tree.h"
|
#include "parser/tree.h"
|
||||||
|
|
||||||
TSTree *ts_tree_new(Subtree root, const TSLanguage *language)
|
TSTree *ts_tree_new(t_subtree root, const TSLanguage *language)
|
||||||
{
|
{
|
||||||
TSTree *result;
|
TSTree *result;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue