-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathjson.rl
More file actions
137 lines (112 loc) · 3.62 KB
/
json.rl
File metadata and controls
137 lines (112 loc) · 3.62 KB
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
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <stddef.h>
%%{
machine json;
alphtype unsigned char;
# ACME guarantees UTF-8, although JSON might be encoded in UTF-16
# or UTF-32, which requires guessing analyzing the first four
# octets.
# https://datatracker.ietf.org/doc/html/rfc8555/#section-5
include unicode "unicode.rl";
ws = (0x20 | 0xA | 0xD | 0x9)*;
#ws = zlen;
character = utf8 -- 0..31 -- '"' -- '\\'
| '\\' (["\\/bfnrt] | 'u' xdigit{4});
characters = character*;
#characters = 'a'*;
string = '"' characters '"';
#string = 's';
onenine = '1'..'9';
integer = '-'? (digit | onenine digit+);
fraction = ('.' digit+)?;
exponent = ('E'i [\-+]? digit+)?;
number = integer fraction exponent;
#number = '1'+;
# Gay colon
gc = ws ':' ws;
# !in_object means "in array"
action in_obj { 1 == (le_stack & 1) }
#action in_array { }
action deepen
{
if (le_stack > (1 << 30))
DIE(11);
le_stack = (le_stack << 1) | ('{' == fc);
}
action pop {
if (is_debug)
printf("pop(%b->%b)",le_stack, le_stack >> 1);
assert(le_stack != 0);
if (1 == le_stack)
DIE(12);
le_stack >>= 1;
}
action overridden { 2 == le_stack || 3 == le_stack }
#action fix { }
action save { } # TODO what did I mean by this
value4 = string | number | "true" | "false" | "null";
value2 = start: ( '{' @deepen -> object_member
| '[' @deepen -> array_element
| value4 >(pri,1) -> cont
)
, cont: ( ws ( ',' when in_obj ws string gc -> start
| ',' when !in_obj ws -> start
| '}' when in_obj when !overridden @pop -> cont
| ']' when !in_obj when !overridden @pop -> cont
| '}' when in_obj when overridden @pop -> final
| ']' when !in_obj when overridden @pop -> final
)
)
, object_member: (ws ( '}' when !overridden @pop -> cont
| '}' when overridden @pop -> final
| string gc -> start
)
)
, array_element: (ws ( ']' when !overridden @pop -> cont
| ']' when overridden @pop -> final
| zlen -> start
)
)
;
value6 = value4 >(pri,2) | value2;
}%%
#ifdef IS_JSON_MAIN
#include <stdbool.h>
#include <stdint.h>
#include <assert.h>
#include <stdio.h>
static bool is_debug = false;
int main(int argc, char *argv[])
{
if (argc < 2)
return 3;
unsigned char *p;
unsigned char *pe;
{
FILE *file = fopen(argv[1], "rb");
static unsigned char text[50000];
pe = text + fread(p = text, 1, sizeof text, file);
bool die = ferror(file) || !feof(file);
(void)fclose(file);
if (die)
return 2;
}
unsigned char *eof = pe;
uint_least32_t le_stack = 1;
long usv;
#define DIE(X) return (X)
#define PARSE(...)
int cs;
%%{
machine json_generic;
alphtype unsigned char;
include json;
action die { { if (is_debug) printf("die(%d)", fcurs); DIE(10); } }
action idiocy { if (is_debug) printf("%d(%c)", fcurs, fc); }
main := (ws value6 ws) $idiocy $!die;
write data noerror nofinal noentry;
write init;
write exec;
}%%
return 0;
}
#endif