1#ifndef TREE_SITTER_PARSER_H_
  2#define TREE_SITTER_PARSER_H_
  3
  4#ifdef __cplusplus
  5extern "C" {
  6#endif
  7
  8#include <stdbool.h>
  9#include <stdint.h>
 10#include <stdlib.h>
 11
 12#define ts_builtin_sym_error ((TSSymbol)-1)
 13#define ts_builtin_sym_end 0
 14#define TREE_SITTER_SERIALIZATION_BUFFER_SIZE 1024
 15
 16#ifndef TREE_SITTER_API_H_
 17typedef uint16_t TSStateId;
 18typedef uint16_t TSSymbol;
 19typedef uint16_t TSFieldId;
 20typedef struct TSLanguage TSLanguage;
 21#endif
 22
 23typedef struct {
 24  TSFieldId field_id;
 25  uint8_t child_index;
 26  bool inherited;
 27} TSFieldMapEntry;
 28
 29typedef struct {
 30  uint16_t index;
 31  uint16_t length;
 32} TSFieldMapSlice;
 33
 34typedef struct {
 35  bool visible;
 36  bool named;
 37  bool supertype;
 38} TSSymbolMetadata;
 39
 40typedef struct TSLexer TSLexer;
 41
 42struct TSLexer {
 43  int32_t lookahead;
 44  TSSymbol result_symbol;
 45  void (*advance)(TSLexer *, bool);
 46  void (*mark_end)(TSLexer *);
 47  uint32_t (*get_column)(TSLexer *);
 48  bool (*is_at_included_range_start)(const TSLexer *);
 49  bool (*eof)(const TSLexer *);
 50  void (*log)(const TSLexer *, const char *, ...);
 51};
 52
 53typedef enum {
 54  TSParseActionTypeShift,
 55  TSParseActionTypeReduce,
 56  TSParseActionTypeAccept,
 57  TSParseActionTypeRecover,
 58} TSParseActionType;
 59
 60typedef union {
 61  struct {
 62    uint8_t type;
 63    TSStateId state;
 64    bool extra;
 65    bool repetition;
 66  } shift;
 67  struct {
 68    uint8_t type;
 69    uint8_t child_count;
 70    TSSymbol symbol;
 71    int16_t dynamic_precedence;
 72    uint16_t production_id;
 73  } reduce;
 74  uint8_t type;
 75} TSParseAction;
 76
 77typedef struct {
 78  uint16_t lex_state;
 79  uint16_t external_lex_state;
 80} TSLexMode;
 81
 82typedef union {
 83  TSParseAction action;
 84  struct {
 85    uint8_t count;
 86    bool reusable;
 87  } entry;
 88} TSParseActionEntry;
 89
 90typedef struct {
 91  int32_t start;
 92  int32_t end;
 93} TSCharacterRange;
 94
 95struct TSLanguage {
 96  uint32_t version;
 97  uint32_t symbol_count;
 98  uint32_t alias_count;
 99  uint32_t token_count;
100  uint32_t external_token_count;
101  uint32_t state_count;
102  uint32_t large_state_count;
103  uint32_t production_id_count;
104  uint32_t field_count;
105  uint16_t max_alias_sequence_length;
106  const uint16_t *parse_table;
107  const uint16_t *small_parse_table;
108  const uint32_t *small_parse_table_map;
109  const TSParseActionEntry *parse_actions;
110  const char * const *symbol_names;
111  const char * const *field_names;
112  const TSFieldMapSlice *field_map_slices;
113  const TSFieldMapEntry *field_map_entries;
114  const TSSymbolMetadata *symbol_metadata;
115  const TSSymbol *public_symbol_map;
116  const uint16_t *alias_map;
117  const TSSymbol *alias_sequences;
118  const TSLexMode *lex_modes;
119  bool (*lex_fn)(TSLexer *, TSStateId);
120  bool (*keyword_lex_fn)(TSLexer *, TSStateId);
121  TSSymbol keyword_capture_token;
122  struct {
123    const bool *states;
124    const TSSymbol *symbol_map;
125    void *(*create)(void);
126    void (*destroy)(void *);
127    bool (*scan)(void *, TSLexer *, const bool *symbol_whitelist);
128    unsigned (*serialize)(void *, char *);
129    void (*deserialize)(void *, const char *, unsigned);
130  } external_scanner;
131  const TSStateId *primary_state_ids;
132};
133
134static inline bool set_contains(TSCharacterRange *ranges, uint32_t len, int32_t lookahead) {
135  uint32_t index = 0;
136  uint32_t size = len - index;
137  while (size > 1) {
138    uint32_t half_size = size / 2;
139    uint32_t mid_index = index + half_size;
140    TSCharacterRange *range = &ranges[mid_index];
141    if (lookahead >= range->start && lookahead <= range->end) {
142      return true;
143    } else if (lookahead > range->end) {
144      index = mid_index;
145    }
146    size -= half_size;
147  }
148  TSCharacterRange *range = &ranges[index];
149  return (lookahead >= range->start && lookahead <= range->end);
150}
151
152/*
153 *  Lexer Macros
154 */
155
156#ifdef _MSC_VER
157#define UNUSED __pragma(warning(suppress : 4101))
158#else
159#define UNUSED __attribute__((unused))
160#endif
161
162#define START_LEXER()           \
163  bool result = false;          \
164  bool skip = false;            \
165  UNUSED                        \
166  bool eof = false;             \
167  int32_t lookahead;            \
168  goto start;                   \
169  next_state:                   \
170  lexer->advance(lexer, skip);  \
171  start:                        \
172  skip = false;                 \
173  lookahead = lexer->lookahead;
174
175#define ADVANCE(state_value) \
176  {                          \
177    state = state_value;     \
178    goto next_state;         \
179  }
180
181#define ADVANCE_MAP(...)                                              \
182  {                                                                   \
183    static const uint16_t map[] = { __VA_ARGS__ };                    \
184    for (uint32_t i = 0; i < sizeof(map) / sizeof(map[0]); i += 2) {  \
185      if (map[i] == lookahead) {                                      \
186        state = map[i + 1];                                           \
187        goto next_state;                                              \
188      }                                                               \
189    }                                                                 \
190  }
191
192#define SKIP(state_value) \
193  {                       \
194    skip = true;          \
195    state = state_value;  \
196    goto next_state;      \
197  }
198
199#define ACCEPT_TOKEN(symbol_value)     \
200  result = true;                       \
201  lexer->result_symbol = symbol_value; \
202  lexer->mark_end(lexer);
203
204#define END_STATE() return result;
205
206/*
207 *  Parse Table Macros
208 */
209
210#define SMALL_STATE(id) ((id) - LARGE_STATE_COUNT)
211
212#define STATE(id) id
213
214#define ACTIONS(id) id
215
216#define SHIFT(state_value)            \
217  {{                                  \
218    .shift = {                        \
219      .type = TSParseActionTypeShift, \
220      .state = (state_value)          \
221    }                                 \
222  }}
223
224#define SHIFT_REPEAT(state_value)     \
225  {{                                  \
226    .shift = {                        \
227      .type = TSParseActionTypeShift, \
228      .state = (state_value),         \
229      .repetition = true              \
230    }                                 \
231  }}
232
233#define SHIFT_EXTRA()                 \
234  {{                                  \
235    .shift = {                        \
236      .type = TSParseActionTypeShift, \
237      .extra = true                   \
238    }                                 \
239  }}
240
241#define REDUCE(symbol_name, children, precedence, prod_id) \
242  {{                                                       \
243    .reduce = {                                            \
244      .type = TSParseActionTypeReduce,                     \
245      .symbol = symbol_name,                               \
246      .child_count = children,                             \
247      .dynamic_precedence = precedence,                    \
248      .production_id = prod_id                             \
249    },                                                     \
250  }}
251
252#define RECOVER()                    \
253  {{                                 \
254    .type = TSParseActionTypeRecover \
255  }}
256
257#define ACCEPT_INPUT()              \
258  {{                                \
259    .type = TSParseActionTypeAccept \
260  }}
261
262#ifdef __cplusplus
263}
264#endif
265
266#endif  // TREE_SITTER_PARSER_H_