librdesc
Loading...
Searching...
No Matches
exblex.h
Go to the documentation of this file.
1
6#ifndef EXBLEX_H
7#define EXBLEX_H
8
9#include "../../src/common.h"
10
11#include <ctype.h>
12#include <stdbool.h>
13#include <stdint.h>
14#include <stdlib.h>
15#include <string.h>
16
17
37struct exblex {
39 const char *buf;
40
42 const char *tokens;
43
46
47 /* --- Fields from now on should be zero-initialized. --- */
48
50 size_t cur /* (current) Index lexing continues on. */;
51
53 char pushback_char /* A character that was part of the input stream but
54 * not consumed by the previous token (e.g., the `+`
55 * in `abc+def`). */;
56
57 char *current_seminfo /* Holds semantic information pointer of the last
58 * token and returns it in
59 * `exblex_current_seminfo`. */;
61};
62
64static inline uint16_t _exblex_priv_tokenid(const struct exblex *l, char tk)
65{
66 for (uint16_t i = 1; i <= l->token_count; i++)
67 if (l->tokens[i] == tk)
68 return i;
69
70 return 0;
71}
82static inline void exblex_init(struct exblex *l,
83 const char *buf,
84 const char *tokens)
85{
86 rdesc_assert(tokens[0] == '\0', "first element of tokens (tokens[0]) "
87 "should be '\\0'");
88
89 *l = (struct exblex) {
90 .buf = buf,
91 .tokens = tokens,
92 .token_count = strlen(tokens + 1),
93 .cur = 0, .current_seminfo = NULL,
94 .pushback_char = '\0',
95 };
96}
97
107static inline char *exblex_current_seminfo(struct exblex *l)
108{
109 return l->current_seminfo;
110}
111
122static inline uint16_t exblex_next(struct exblex *l)
123{
124 while (l->buf[l->cur] && isspace(l->buf[l->cur]))
125 l->cur++;
126
127 char c = l->buf[l->cur++];
128 char *seminfo = NULL;
129 size_t seminfo_len = 0;
130
131 bool is_num = true;
132 while (isalnum(c) || c == '_') {
133 if (seminfo == NULL) {
134 rdesc_assert(seminfo = malloc(sizeof(char) * 2),
135 "malloc failed");
136 seminfo_len++;
137 } else {
138 rdesc_assert(seminfo = realloc(seminfo, sizeof(char) * (++seminfo_len + 1)),
139 "realloc failed");
140 }
141
142 if (!isdigit(c))
143 is_num = false;
144
145 seminfo[seminfo_len - 1] = c;
146
147 c = l->buf[l->cur++];
148 }
149
150 if (seminfo) {
151 seminfo[seminfo_len] = '\0';
152
153 l->cur--;
154 int id = 0;
155
156 if (is_num)
157 id = _exblex_priv_tokenid(l, 'd');
158 else if (!isdigit(seminfo[0]))
159 id = _exblex_priv_tokenid(l, 'w');
160
161 if (id) {
162 l->current_seminfo = seminfo;
163
164 return id;
165 } else {
166 if (seminfo_len > 1)
167 c = '\0';
168 else
169 c = seminfo[0];
170
171 free(seminfo);
172 }
173 }
174
175 return _exblex_priv_tokenid(l, c);
176}
177
178
179#endif
static char * exblex_current_seminfo(struct exblex *l)
Retrieves the semantic information for the last token.
Definition exblex.h:107
static uint16_t exblex_next(struct exblex *l)
Fetches the next token.
Definition exblex.h:122
static void exblex_init(struct exblex *l, const char *buf, const char *tokens)
Initializes the basic lexer with a null-terminated list of chars.
Definition exblex.h:82
EXtremely Basic LEXer.
Definition exblex.h:37
const char * tokens
Array of token characters.
Definition exblex.h:42
const char * buf
Underlying null-terminated input buffer.
Definition exblex.h:39
size_t cur
(current) Position in the buffer.
Definition exblex.h:50
size_t token_count
Number of tokens in provided array.
Definition exblex.h:45