-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParsing.cpp
124 lines (100 loc) · 2.47 KB
/
Parsing.cpp
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
#include "Parsing.h"
#include "Containers/Array.h"
#include "Math/Base.h"
u64 parse_cid(const Str& s, u64 i, Str& out)
{
const char* begin = &s[i++];
while (i < s.len && is_valid_cid(s[i])) {
i++;
}
i = min(i, s.len - 1);
const char* end = &s[i];
out = Str(begin, u64(end - begin));
return i;
}
Str parse_cid(ReadTape* tape, Allocator& alloc)
{
TArray<char> result(&alloc);
char c;
while ((c = tape->read_char()) != EOF) {
if (is_valid_cid(c)) {
result.add(c);
} else {
break;
}
}
tape->seek(-1);
if (result.size == 0) {
return Str::NullStr;
} else {
return Str(result.data, result.size);
}
}
Str parse_string(ReadTape* tape, Allocator& alloc, ProcCharClassIs* predicate)
{
int32 i = 0;
char c;
TArray<char> result(&alloc);
while ((c = tape->read_char()) != EOF) {
if (predicate(c)) {
result.add(c);
} else {
break;
}
}
if (c != EOF) tape->seek(-1);
return Str(result.data, result.size);
}
bool parse_escaped_string(ReadTape* tape, Str& result, Allocator& allocator)
{
ParseReadTape pt(*tape);
TArray<char> array(&allocator);
char c = pt.read_char();
if (c != '\"') {
goto PARSE_FAIL;
}
c = pt.read_char();
while ((c != '\"') && c != EOF) {
if (c == '\\') {
char escape = pt.read_char();
switch (escape) {
case '\\':
array.add('\\');
break;
case '\"':
array.add('\"');
break;
case 't':
array.add('\t');
break;
case 'r':
array.add('\r');
break;
case 'f':
array.add('\f');
break;
case 'n':
array.add('\n');
break;
case 'b':
array.add('\b');
break;
default: {
array.add(c);
array.add(escape);
} break;
}
} else {
array.add(c);
}
c = pt.read_char();
}
if (c == EOF) {
goto PARSE_FAIL;
}
result = Str((char*)array.data, array.size);
return true;
PARSE_FAIL:
pt.restore();
return false;
}