commit 4e72e5c
uint
·
2026-10-23 20:55:20 +0000 UTC
parent 03db476
Parse strings
M
expl.c
+65,
-21
1@@ -5,7 +5,8 @@
2
3 #include "expl.h"
4
5-#define parser_current_char(p, c) ((p)->src[(p)->pos] == (c))
6+#define current_char(p, c) ((p)->src[(p)->pos] == (c))
7+#define advance(p) ((p)->pos++) /* XXX */
8
9 typedef struct {
10 const char* src;
11@@ -14,10 +15,11 @@ typedef struct {
12 } parser;
13
14 static expl_node* atom(parser* p);
15-static char* _strndup(const char* src, size_t len);
16 static expl_node* node_new(expl_type type);
17 static void node_free(expl_node* node);
18 static void skip_whitespace(parser* p);
19+static expl_node* string(parser* p);
20+static char* _strndup(const char* src, size_t len);
21
22 static expl_node*
23 atom(parser* p)
24@@ -25,11 +27,11 @@ atom(parser* p)
25 size_t start = p->pos;
26 expl_node* node = NULL;
27
28- while (!parser_current_char(p, '(') &&
29- !parser_current_char(p, ')') &&
30- !parser_current_char(p, '"') &&
31- !parser_current_char(p, ';') &&
32- !parser_current_char(p, '\0') &&
33+ while (!current_char(p, '(') &&
34+ !current_char(p, ')') &&
35+ !current_char(p, '"') &&
36+ !current_char(p, ';') &&
37+ !current_char(p, '\0') &&
38 !isspace((unsigned char)p->src[p->pos]))
39 p->pos++;
40
41@@ -54,19 +56,6 @@ atom(parser* p)
42 return node;
43 }
44
45-static char*
46-_strndup(const char* src, size_t len)
47-{
48- char* str = malloc(len + 1);
49- if (!str)
50- return NULL;
51-
52- memcpy(str, src, len);
53- str[len] = '\0';
54-
55- return str;
56-}
57-
58 static expl_node*
59 node_new(expl_type type)
60 {
61@@ -100,7 +89,7 @@ node_free(expl_node* node)
62 static void
63 skip_whitespace(parser* p)
64 {
65- while (isspace((unsigned char)p->src[p->pos]) || parser_current_char(p, ';')) {
66+ while (isspace((unsigned char)p->src[p->pos]) || current_char(p, ';')) {
67 /* comment */
68 if (parser_current_char(p, ';')) {
69 while (!parser_current_char(p, '\n') && !parser_current_char(p, '\0'))
70@@ -113,6 +102,61 @@ skip_whitespace(parser* p)
71 }
72 }
73
74+static expl_node*
75+string(parser* p)
76+{
77+ expl_node* node = NULL;
78+ size_t start = 0;
79+
80+ if (!current_char(p, '"')) {
81+ p->err = EXPL_ERR_EXPECTED_STRING;
82+ return NULL;
83+ }
84+
85+ start = p->pos;
86+ advance(p); /* skip opening " */
87+
88+ while (!current_char(p, '"') && !current_char(p, '\0')) {
89+ if (current_char(p, '\\') && p->src[p->pos + 1])
90+ p->pos++;
91+ p->pos++;
92+ }
93+
94+ if (current_char(p, '\0')) {
95+ p->err = EXPL_ERR_EXPECTED_STRING;
96+ return NULL;
97+ }
98+
99+ node = node_new(EXPL_STRING);
100+ if (!node) {
101+ p->err = EXPL_ERR_OUT_OF_MEMORY;
102+ return NULL;
103+ }
104+
105+ node->value = _strndup(p->src + start, p->pos - start);
106+ advance(p); /* skip closing " */
107+ if (!node->value) {
108+ node_free(node);
109+ p->err = EXPL_ERR_OUT_OF_MEMORY;
110+ return NULL;
111+ }
112+
113+ return node;
114+}
115+
116+static char*
117+_strndup(const char* src, size_t len)
118+{
119+ char* str = malloc(len + 1);
120+ if (!str)
121+ return NULL;
122+
123+ memcpy(str, src, len);
124+ str[len] = '\0';
125+
126+ return str;
127+}
128+
129 int
130 main(void)
131 {
M
expl.h
+1,
-0
1@@ -12,6 +12,7 @@ typedef enum {
2 typedef enum {
3 EXPL_ERR_NONE,
4 EXPL_ERR_EXPECTED_ATOM,
5+ EXPL_ERR_EXPECTED_STRING,
6 EXPL_ERR_OUT_OF_MEMORY,
7
8 EXPL_ERR_COUNT