blob: a22e0db54f7d347416ded37a32fd88c5e242135e (
plain)
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
|
#include "cccl.h"
#include <assert.h>
#include <err.h>
#include <stdio.h>
#include <stddef.h>
size_t cccl_tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length)
{
size_t i = 0, tokeni = 0;
int comment = 0, mlcomment = 0;
do
{
switch (code[i])
{
#define X(name) \
{ \
if (comment || mlcomment) \
break; \
tokens[tokeni++] = (struct cccl_Token) \
{ \
.type = cccl_Token_##name, \
.value = code[i], \
}; \
} break
case '/':
{
if (mlcomment)
break;
comment = 1;
} break;
case '\n':
{
if (mlcomment)
break;
comment = 0;
} break;
case '\\':
{
if (comment)
break;
mlcomment = !mlcomment;
} break;
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g': case 'h': case 'i':
case 'j': case 'k': case 'l': case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I':
case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
case '_':
X(IDENTIFIER);
case '^': case '+': case '-': case '*': case '~': case '#': case ':':
X(COMMAND);
case '%': case '=': case '!': case '$':
case '&': case '<': case '>': case '@':
X(COMMANDWITHARG);
case '{': case '(': case '[': case '?':
X(BLOCKSTART);
case '}': case ')': case ']': case ';':
X(BLOCKEND);
case ' ': case '\t':
{ } break;
default:
{
if (comment || mlcomment)
break;
errx(1, "Illegal symbol in a code at byte %lu: [%d] %c", i, code[i], code[i]);
} break;
#undef X
}
assert(tokeni < tokens_length);
} while(++i < size);
return tokeni;
}
|