parser.h
Go to the documentation of this file.
1 #ifndef NVIM_VIML_PARSER_PARSER_H
2 #define NVIM_VIML_PARSER_PARSER_H
3 
4 #include <assert.h>
5 #include <stdbool.h>
6 #include <stddef.h>
7 
8 #include "nvim/func_attr.h"
9 #include "nvim/lib/kvec.h"
10 #include "nvim/mbyte.h"
11 #include "nvim/memory.h"
12 
14 typedef struct {
15  const char *data;
16  size_t size;
17  bool allocated;
18 } ParserLine;
19 
23 typedef void (*ParserLineGetter)(void *cookie, ParserLine *ret_pline);
24 
26 typedef struct {
27  size_t line;
28  size_t col;
30 
32 typedef struct {
33  enum {
34  kPTopStateParsingCommand = 0,
36  } type;
37  union {
38  struct {
39  enum {
40  kExprUnknown = 0,
41  } type;
42  } expr;
43  } data;
45 
47 typedef struct {
51  void *cookie;
53  kvec_withinit_t(ParserLine, 4) lines;
55  vimconv_T conv;
57 
61 typedef struct {
63  size_t end_col;
64  const char *group;
66 
68 typedef kvec_withinit_t(ParserHighlightChunk, 16) ParserHighlight;
69 
71 typedef struct {
79  ParserHighlight *colors;
81  bool can_continuate;
82 } ParserState;
83 
84 static inline void viml_parser_init(
85  ParserState *const ret_pstate,
86  const ParserLineGetter get_line, void *const cookie,
87  ParserHighlight *const colors)
89 
97 static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line,
98  void *const cookie, ParserHighlight *const colors)
99 {
100  *ret_pstate = (ParserState) {
101  .reader = {
102  .get_line = get_line,
103  .cookie = cookie,
104  .conv = MBYTE_NONE_CONV,
105  },
106  .pos = { 0, 0 },
107  .colors = colors,
108  .can_continuate = false,
109  };
110  kvi_init(ret_pstate->reader.lines);
111  kvi_init(ret_pstate->stack);
112 }
113 
114 static inline void viml_parser_destroy(ParserState *const pstate)
116 
120 static inline void viml_parser_destroy(ParserState *const pstate)
121 {
122  for (size_t i = 0; i < kv_size(pstate->reader.lines); i++) {
123  ParserLine pline = kv_A(pstate->reader.lines, i);
124  if (pline.allocated) {
125  xfree((void *)pline.data);
126  }
127  }
128  kvi_destroy(pstate->reader.lines);
129  kvi_destroy(pstate->stack);
130 }
131 
132 static inline void viml_preader_get_line(ParserInputReader *const preader,
133  ParserLine *const ret_pline)
135 
137 static inline void viml_preader_get_line(ParserInputReader *const preader,
138  ParserLine *const ret_pline)
139 {
140  ParserLine pline;
141  preader->get_line(preader->cookie, &pline);
142  if (preader->conv.vc_type != CONV_NONE && pline.size) {
143  ParserLine cpline = {
144  .allocated = true,
145  .size = pline.size,
146  };
147  cpline.data = (char *)string_convert(&preader->conv,
148  (char_u *)pline.data,
149  &cpline.size);
150  if (pline.allocated) {
151  xfree((void *)pline.data);
152  }
153  pline = cpline;
154  }
155  kvi_push(preader->lines, pline);
156  *ret_pline = pline;
157 }
158 
159 static inline bool viml_parser_get_remaining_line(ParserState *const pstate,
160  ParserLine *const ret_pline)
162 
168 static inline bool viml_parser_get_remaining_line(ParserState *const pstate,
169  ParserLine *const ret_pline)
170 {
171  const size_t num_lines = kv_size(pstate->reader.lines);
172  if (pstate->pos.line == num_lines) {
173  viml_preader_get_line(&pstate->reader, ret_pline);
174  } else {
175  *ret_pline = kv_last(pstate->reader.lines);
176  }
177  assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
178  if (ret_pline->data != NULL) {
179  ret_pline->data += pstate->pos.col;
180  ret_pline->size -= pstate->pos.col;
181  }
182  return ret_pline->data != NULL;
183 }
184 
185 static inline void viml_parser_advance(ParserState *const pstate,
186  const size_t len)
188 
195 static inline void viml_parser_advance(ParserState *const pstate, const size_t len)
196 {
197  assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
198  const ParserLine pline = kv_last(pstate->reader.lines);
199  if (pstate->pos.col + len >= pline.size) {
200  pstate->pos.line++;
201  pstate->pos.col = 0;
202  } else {
203  pstate->pos.col += len;
204  }
205 }
206 
207 static inline void viml_parser_highlight(ParserState *const pstate,
208  const ParserPosition start,
209  const size_t end_col,
210  const char *const group)
212 
219 static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start,
220  const size_t len, const char *const group)
221 {
222  if (pstate->colors == NULL || len == 0) {
223  return;
224  }
225  assert(kv_size(*pstate->colors) == 0
226  || kv_Z(*pstate->colors, 0).start.line < start.line
227  || kv_Z(*pstate->colors, 0).end_col <= start.col);
228  kvi_push(*pstate->colors, ((ParserHighlightChunk) {
229  .start = start,
230  .end_col = start.col + len,
231  .group = group,
232  }));
233 }
234 
235 #ifdef INCLUDE_GENERATED_DECLARATIONS
236 # include "viml/parser/parser.h.generated.h"
237 #endif
238 
239 #endif // NVIM_VIML_PARSER_PARSER_H
ParserLine
One parsed line.
Definition: parser.h:14
ParserPosition::col
size_t col
Byte index in the line.
Definition: parser.h:28
i
static void int i
Definition: edit.c:2997
kv_Z
#define kv_Z(v, i)
Definition: kvec.h:70
kvec_withinit_t
typedef kvec_withinit_t(ParserHighlightChunk, 16) ParserHighlight
Highlighting defined by a parser.
type
err type
Definition: helpers.c:1043
ParserInputReader::conv
vimconv_T conv
Conversion, for :scriptencoding.
Definition: parser.h:55
assert.h
ParserPosition::line
size_t line
Line index in ParserInputReader.lines.
Definition: parser.h:27
ParserLine::size
size_t size
Parsed line size.
Definition: parser.h:16
kvi_push
#define kvi_push(v, x)
Definition: kvec.h:210
ParserStateItem::kPTopStateParsingExpression
@ kPTopStateParsingExpression
Definition: parser.h:35
ParserPosition
Parser position in the input.
Definition: parser.h:26
void
void(WINAPI *pClosePseudoConsole)(HPCON)
vimconv_T
Structure used for string conversions.
Definition: mbyte.h:58
kvi_init
#define kvi_init(v)
Definition: kvec.h:145
kvi_destroy
#define kvi_destroy(v)
Definition: kvec.h:216
ParserHighlightChunk::start
ParserPosition start
Start of the highlight: line and column.
Definition: parser.h:62
REAL_FATTR_NONNULL_ALL
#define REAL_FATTR_NONNULL_ALL
Definition: func_attr.h:183
mbyte.h
ParserLine::data
const char * data
Parsed line pointer.
Definition: parser.h:15
ParserLineGetter
void(* ParserLineGetter)(void *cookie, ParserLine *ret_pline)
Definition: parser.h:23
ParserHighlightChunk
Definition: parser.h:61
ParserState
Structure defining parser state.
Definition: parser.h:71
kv_A
#define kv_A(v, i)
Definition: kvec.h:66
ParserState::reader
ParserInputReader reader
Line reader.
Definition: parser.h:73
CONV_NONE
@ CONV_NONE
Definition: mbyte.h:43
kvec.h
ParserHighlightChunk::end_col
size_t end_col
End column, points to the start of the next character.
Definition: parser.h:63
ParserLine::allocated
bool allocated
True if line may be freed.
Definition: parser.h:17
assert
assert(len >=0)
REAL_FATTR_NONNULL_ARG
#define REAL_FATTR_NONNULL_ARG(...)
Definition: func_attr.h:187
ParserInputReader
Structure defining input reader.
Definition: parser.h:47
vimconv_T::vc_type
int vc_type
Zero or more ConvFlags.
Definition: mbyte.h:59
kv_last
#define kv_last(v)
Definition: kvec.h:71
ParserInputReader::cookie
void * cookie
Data for get_line function.
Definition: parser.h:51
ParserState::colors
ParserHighlight * colors
Highlighting support.
Definition: parser.h:79
char_u
unsigned char char_u
Definition: types.h:12
ParserState::pos
ParserPosition pos
Position up to which input was parsed.
Definition: parser.h:75
kv_size
#define kv_size(v)
Definition: kvec.h:68
ParserStateItem
Parser state item.
Definition: parser.h:32
func_attr.h
REAL_FATTR_ALWAYS_INLINE
static int REAL_FATTR_WARN_UNUSED_RESULT REAL_FATTR_ALWAYS_INLINE
Definition: typval_encode.c.h:265
ParserHighlightChunk::group
const char * group
Highlight group.
Definition: parser.h:64
ParserInputReader::get_line
ParserLineGetter get_line
Function used to get next line.
Definition: parser.h:49
memory.h
NULL
return NULL
Definition: eval.c:10355
REAL_FATTR_WARN_UNUSED_RESULT
static int REAL_FATTR_WARN_UNUSED_RESULT
Definition: typval_encode.c.h:300
MBYTE_NONE_CONV
#define MBYTE_NONE_CONV
Definition: mbyte.h:51
xfree
xfree(pat2)
len
int len
Definition: helpers.c:1034
string_convert
char_u * string_convert(const vimconv_T *const vcp, char_u *ptr, size_t *lenp)
Definition: mbyte.c:2522