source: buchla-68k/ram/cminit.c@ 2340de6

Last change on this file since 2340de6 was 2340de6, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Keep macros in external declarations.

  • Property mode set to 100644
File size: 6.2 KB
Line 
1/*
2 =============================================================================
3 cminit.c -- C-Meta parser functions
4 Version 5 -- 1987-07-10 -- D.N. Lynx Crowe
5
6 Some parser functions in C, modelled after HyperMeta(tm).
7 Designed for, but not dedicated to, LR(k), top-down, recursive parsing.
8 =============================================================================
9*/
10
11#include "ram.h"
12
13#define CM_DBLK if (!QQanch) while (*QQip EQ ' ') ++QQip
14
15int16_t QQsw; /* parser result switch */
16int16_t QQanch; /* parser anchored match switch */
17
18int8_t *QQin; /* parser initial input pointer */
19int8_t *QQip; /* parser current input pointer */
20int8_t *QQop; /* parser string output pointer */
21
22int32_t QQnum; /* parser numeric result */
23int16_t QQlnum; /* parser list element number result */
24int8_t QQdig; /* parser digit result */
25int8_t QQchr; /* parser character result */
26
27int8_t QQstr[CM_MXSTR]; /* parser string result */
28
29/*
30
31*/
32
33/*
34 =============================================================================
35 CMinit(ip) -- initialize the parser to work on the string at 'ip'.
36 =============================================================================
37*/
38
39void CMinit(int8_t *ip)
40{
41 register int16_t i;
42 register int8_t *t;
43
44 QQip = ip;
45 QQin = ip;
46 QQsw = TRUE;
47 QQanch = FALSE;
48 QQdig = '?';
49 QQchr = '?';
50 QQnum = 0;
51 QQop = QQstr;
52 t = QQstr;
53
54 for (i = 0; i < CM_MXSTR; i++)
55 *t++ = '\0';
56}
57
58/*
59
60*/
61
62/*
63 =============================================================================
64 CMchr(c) -- attempt to match character 'c' in the input.
65 =============================================================================
66*/
67
68int16_t CMchr(int8_t c)
69{
70 CM_DBLK;
71
72 if (c NE *QQip)
73 return(QQsw = FALSE);
74
75 QQchr = *QQip++;
76 return(QQsw = TRUE);
77}
78
79/*
80
81*/
82
83/*
84 =============================================================================
85 CMuchr(c) -- attempt to match character 'c' in the input, ignoring case.
86 =============================================================================
87*/
88
89int16_t CMuchr(int8_t c)
90{
91 register int8_t t;
92
93 CM_DBLK;
94
95 t = *QQip;
96
97 if (isascii(c))
98 if (isupper(c))
99 c = _tolower(c);
100
101 if (isascii(t))
102 if (isupper(t))
103 t = _tolower(t);
104
105 if (c NE t)
106 return(QQsw = FALSE);
107
108 QQchr = *QQip++;
109 return(QQsw = TRUE);
110}
111
112/*
113
114*/
115
116/*
117 =============================================================================
118 CMstr(s) -- attempt to match string at 's' in the input.
119 =============================================================================
120*/
121
122int16_t CMstr(int8_t *s)
123{
124 register int8_t *t;
125 int8_t *q;
126
127 CM_DBLK;
128
129 t = QQip;
130 q = s;
131
132 while (*s) {
133
134 if (*t++ NE *s++)
135 return(QQsw = FALSE);
136 }
137
138 QQop = QQstr;
139
140 while (*QQop++ = *q++) ;
141
142 QQip = t;
143 return(QQsw = TRUE);
144}
145
146/*
147
148*/
149
150/*
151 =============================================================================
152 CMustr(s) -- attempt to match string 's' in the input, ignoring case.
153 =============================================================================
154*/
155
156int16_t CMustr(int8_t *s)
157{
158 register int8_t *t, t1, t2;
159 int8_t *q;
160
161 CM_DBLK;
162
163 t = QQip;
164 q = s;
165
166 while (*s) {
167
168 t1 = *t++;
169 t2 = *s++;
170
171 if (isascii(t1))
172 if (isupper(t1))
173 t1 = _tolower(t1);
174
175 if (isascii(t2))
176 if (isupper(t2))
177 t2 = _tolower(t2);
178
179 if (t1 NE t2)
180 return(QQsw = FALSE);
181 }
182
183 QQop = QQstr;
184
185 while (*QQop++ = *q++) ;
186
187 QQip = t;
188 return(QQsw = TRUE);
189}
190
191/*
192
193*/
194
195/*
196 =============================================================================
197 CMlong() -- attempt to parse a digit string in the input as a long.
198 =============================================================================
199*/
200
201int16_t CMlong(void)
202{
203 register int8_t *p;
204 register int32_t n;
205 register int8_t c;
206
207 CM_DBLK;
208
209 p = QQip;
210 n = 0L;
211 c = *p++;
212
213 if (!isascii(c))
214 return(QQsw = FALSE);
215
216 if (!isdigit(c))
217 return(QQsw = FALSE);
218
219 n = c - '0';
220
221 while (c = *p) {
222
223 if (!isascii(c))
224 break;
225
226 if (!isdigit(c))
227 break;
228
229 n = (n * 10) + (c - '0');
230 ++p;
231 }
232
233 QQip = p;
234 QQnum = n;
235 return(QQsw = TRUE);
236}
237
238/*
239
240*/
241
242/*
243 =============================================================================
244 CMdig() -- attempt to match a digit in the input string.
245 =============================================================================
246*/
247
248int16_t CMdig(void)
249{
250 register int8_t c;
251
252 CM_DBLK;
253
254 c = *QQip;
255
256 if (!isascii(c))
257 return(QQsw = FALSE);
258
259 if (!isdigit(c))
260 return(QQsw = FALSE);
261
262 QQdig = c;
263 ++QQip;
264 return(QQsw = TRUE);
265}
266
267/*
268
269*/
270
271/*
272 =============================================================================
273 CMlist(l) -- attempt to match a string from the list 'l' in the input.
274 =============================================================================
275*/
276
277int16_t CMlist(int8_t *l[])
278{
279 register int16_t n;
280 register int8_t *p, *q;
281
282 CM_DBLK;
283
284 n = 0;
285
286 while (p = *l++) {
287
288 q = p;
289
290 if (CMstr(p)) {
291
292 QQop = QQstr;
293
294 while (*QQop++ = *q++) ;
295
296 QQlnum = n;
297 return(QQsw = TRUE);
298 }
299
300 ++n;
301 }
302
303 return(QQsw = FALSE);
304}
305
306/*
307
308*/
309
310/*
311 =============================================================================
312 CMulist(l) -- attempt to match a string from the list 'l' in the input
313 ignoring case in both the list and the input string.
314 =============================================================================
315*/
316
317int16_t CMulist(int8_t *l[])
318{
319 register int16_t n;
320 register int8_t *p, *q;
321
322 CM_DBLK;
323
324 n = 0;
325
326 while (p = *l++) {
327
328 q = p;
329
330 if (CMustr(p)) {
331
332 QQop = QQstr;
333
334 while (*QQop++ = *q++) ;
335
336 QQlnum = n;
337 return(QQsw = TRUE);
338 }
339
340 ++n;
341 }
342
343 return(QQsw = FALSE);
344}
345
346/*
347
348*/
349
350/*
351 =============================================================================
352 CMstat(msg) -- output 'msg and dump parser status. Returns QQsw.
353 =============================================================================
354*/
355
356int16_t CMstat(int8_t *msg)
357{
358 register int8_t *tp;
359
360 tp = QQin;
361 printf("%s\r\n", msg);
362 printf(" QQsw: %s, QQanch: %s, QQchr: 0x%02x <%c>, QQdig: %c\r\n",
363 (QQsw ? "OK" : "NOGO"), (QQanch ? "anchored" : "deblanked"),
364 QQchr, (isascii(QQchr) ? (isprint(QQchr) ? QQchr : ' ') : ' '),
365 QQdig);
366 printf(" QQnum: %ld, QQlnum: %d\r\n", QQnum, QQlnum);
367 printf(" QQstr: %s\r\n", QQstr);
368 printf(" {%s}\r\n", QQin);
369 printf(" ");
370
371 while (tp++ NE QQip)
372 printf(" ");
373
374 printf("^\r\n");
375 return(QQsw);
376}
377
Note: See TracBrowser for help on using the repository browser.