-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlexer.c
161 lines (120 loc) · 3.45 KB
/
lexer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include "lexer.h"
int token_is_of_type(sql_token_type type, const struct token *token) {
return token->type == type;
}
struct token token_new(sql_token_type type, const char *value, size_t len, size_t position) {
return (struct token) {
.type = type,
.value = value,
.len = len,
.position = position
};
}
size_t token_position(const struct token *token) {
return token->position;
}
size_t token_length(const struct token *token) {
return token->len;
}
sql_token_type token_type(const struct token *token) {
return token->type;
}
static void lexer_ensure_have_current(struct lexer *lexer);
static void lexer_ensure_have_next(struct lexer *lexer);
extern void lexer_use_buffer(const char *buff, size_t len);
#define READ_NEXT_TOKEN(token) \
do { \
do { \
token = lexer_lex(); \
} while (token_is_of_type(T_WHITE_SPACE, &token)); \
\
if (token_is_of_type(T_UNKNOWN, &token)) { \
lexer->is_done = 1; \
} \
\
if (token_is_of_type(T_EOF, &token)) { \
lexer->is_done = 1; \
} \
} while (0)
static void lexer_ensure_have_current(struct lexer *lexer) {
if (lexer->has_current || lexer->is_done) {
return;
}
struct token token;
READ_NEXT_TOKEN(token);
lexer->current = token;
lexer->has_current = 1;
}
static void lexer_ensure_have_next(struct lexer *lexer) {
if (lexer->has_next || lexer->is_done) {
return;
}
lexer_ensure_have_current(lexer);
struct token token;
READ_NEXT_TOKEN(token);
lexer->next = token;
lexer->has_next = 1;
}
struct lexer lexer_new(const char *buff, size_t len) {
lexer_use_buffer(buff, len);
struct lexer lexer = (struct lexer) {
.current = token_new(T_UNKNOWN, NULL, 0, 0),
.has_current = 0,
.previous = token_new(T_UNKNOWN, NULL, 0, 0),
.has_previous = 0,
.next = token_new(T_UNKNOWN, NULL, 0, 0),
.has_next = 0,
.is_done = 0,
.context = {
.buff = buff,
.len = len
},
.tokens_consumed = 0
};
return lexer;
}
const char *lexer_buffer(const struct lexer *lexer) {
return lexer->context.buff;
}
extern void lexer_clear_buffer();
void lexer_destroy(struct lexer *lexer) {
lexer_clear_buffer();
}
size_t lexer_tokens_consumed(const struct lexer *lexer) {
return lexer->tokens_consumed;
}
int lexer_has(struct lexer *lexer) {
lexer_ensure_have_current(lexer);
return lexer_peek(lexer)->type != T_EOF;
}
const struct token *lexer_peek(struct lexer *lexer) {
lexer_ensure_have_current(lexer);
return &lexer->current;
}
const struct token *lexer_peek_next(struct lexer *lexer) {
lexer_ensure_have_next(lexer);
return &lexer->next;
}
int lexer_has_previous(const struct lexer *lexer) {
return lexer->has_previous;
}
int lexer_has_next(struct lexer *lexer) {
return lexer->has_next;
}
const struct token *lexer_peek_previous(const struct lexer *lexer) {
return &lexer->previous;
}
struct token lexer_consume(struct lexer *lexer) {
lexer_ensure_have_current(lexer);
struct token token = lexer->current;
lexer->has_current = 0;
lexer->tokens_consumed++;
lexer->previous = token;
lexer->has_previous = 1;
if (lexer->has_next) {
lexer->current = lexer->next;
lexer->has_next = 0;
lexer->has_current = 1;
}
return token;
}