20 if (width ==
sizeof (
char))
22 o.
ws(
"unsigned char");
24 else if (width ==
sizeof (
short))
26 o.
ws(
"unsigned short");
28 else if (width ==
sizeof (
int))
32 else if (width ==
sizeof (
long))
34 o.
ws(
"unsigned long");
38 o.
ws(
"uint").
wu64 (width * 8).
ws(
"_t");
44 o.
ws(
"\n").
wind(ind).
ws(
"/* from little-endian to host-endian */");
45 o.
ws(
"\n").
wind(ind).
ws(
"unsigned char *p = (unsigned char*)&").
ws(expr).
ws(
";");
47 for (uint32_t i = 1; i < size; ++i)
56 o.
ws(
"\n#include <stdio.h>");
57 o.
ws(
"\n#include <stdlib.h> /* malloc, free */");
59 o.
ws(
"\nstatic void *read_file");
60 o.
ws(
"\n").
wind(1).
ws(
"( const char *fname");
61 o.
ws(
"\n").
wind(1).
ws(
", size_t unit");
62 o.
ws(
"\n").
wind(1).
ws(
", size_t padding");
63 o.
ws(
"\n").
wind(1).
ws(
", size_t *pfsize");
66 o.
ws(
"\n").
wind(1).
ws(
"void *buffer = NULL;");
67 o.
ws(
"\n").
wind(1).
ws(
"size_t fsize = 0;");
69 o.
ws(
"\n").
wind(1).
ws(
"/* open file */");
70 o.
ws(
"\n").
wind(1).
ws(
"FILE *f = fopen(fname, \"rb\");");
71 o.
ws(
"\n").
wind(1).
ws(
"if(f == NULL) {");
72 o.
ws(
"\n").
wind(2).
ws(
"goto error;");
75 o.
ws(
"\n").
wind(1).
ws(
"/* get file size */");
76 o.
ws(
"\n").
wind(1).
ws(
"fseek(f, 0, SEEK_END);");
77 o.
ws(
"\n").
wind(1).
ws(
"fsize = (size_t) ftell(f) / unit;");
78 o.
ws(
"\n").
wind(1).
ws(
"fseek(f, 0, SEEK_SET);");
80 o.
ws(
"\n").
wind(1).
ws(
"/* allocate memory for file and padding */");
81 o.
ws(
"\n").
wind(1).
ws(
"buffer = malloc(unit * (fsize + padding));");
82 o.
ws(
"\n").
wind(1).
ws(
"if (buffer == NULL) {");
83 o.
ws(
"\n").
wind(2).
ws(
"goto error;");
86 o.
ws(
"\n").
wind(1).
ws(
"/* read the whole file in memory */");
87 o.
ws(
"\n").
wind(1).
ws(
"if (fread(buffer, unit, fsize, f) != fsize) {");
88 o.
ws(
"\n").
wind(2).
ws(
"goto error;");
92 o.
ws(
"\n").
wind(1).
ws(
"*pfsize = fsize;");
93 o.
ws(
"\n").
wind(1).
ws(
"return buffer;");
96 o.
ws(
"\n").
wind(1).
ws(
"fprintf(stderr, \"error: cannot read file '%s'\\n\", fname);");
97 o.
ws(
"\n").
wind(1).
ws(
"free(buffer);");
98 o.
ws(
"\n").
wind(1).
ws(
"if (f != NULL) {");
101 o.
ws(
"\n").
wind(1).
ws(
"return NULL;");
117 o.
ws(
"\n#define YYCTYPE ");
119 o.
ws(
"\n#define YYKEYTYPE ");
121 o.
ws(
"\n#define YYPEEK() *cursor");
122 o.
ws(
"\n#define YYSKIP() ++cursor");
125 o.
ws(
"\n#define YYBACKUP() marker = cursor");
126 o.
ws(
"\n#define YYRESTORE() cursor = marker");
130 o.
ws(
"\n#define YYBACKUPCTX() ctxmarker = cursor");
131 o.
ws(
"\n#define YYRESTORECTX() cursor = ctxmarker");
133 o.
ws(
"\n#define YYLESSTHAN(n) (limit - cursor) < n");
134 o.
ws(
"\n#define YYFILL(n) { break; }");
136 o.
ws(
"\nstatic int action_").
wstring(name);
137 o.
ws(
"\n").
wind(1).
ws(
"( unsigned int i");
138 o.
ws(
"\n").
wind(1).
ws(
", const YYKEYTYPE *keys");
139 o.
ws(
"\n").
wind(1).
ws(
", const YYCTYPE *start");
140 o.
ws(
"\n").
wind(1).
ws(
", const YYCTYPE *token");
141 o.
ws(
"\n").
wind(1).
ws(
", const YYCTYPE **cursor");
142 o.
ws(
"\n").
wind(1).
ws(
", YYKEYTYPE rule_act");
145 o.
ws(
"\n").
wind(1).
ws(
"const long pos = token - start;");
146 o.
ws(
"\n").
wind(1).
ws(
"const long len_act = *cursor - token;");
147 o.
ws(
"\n").
wind(1).
ws(
"const long len_exp = (long) keys [3 * i + 1];");
148 o.
ws(
"\n").
wind(1).
ws(
"const YYKEYTYPE rule_exp = keys [3 * i + 2];");
149 o.
ws(
"\n").
wind(1).
ws(
"if (rule_exp == ").
wu32(default_rule).
ws(
") {");
152 o.
ws(
"\n").
wind(3).
ws(
", \"warning: lex_").
wstring(name).
ws(
": control flow is undefined for input\"");
153 o.
ws(
"\n").
wind(4).
ws(
"\" at position %ld, rerun re2c with '-W'\\n\"");
157 o.
ws(
"\n").
wind(1).
ws(
"if (len_act == len_exp && rule_act == rule_exp) {");
158 o.
ws(
"\n").
wind(2).
ws(
"const YYKEYTYPE offset = keys[3 * i];");
159 o.
ws(
"\n").
wind(2).
ws(
"*cursor = token + offset;");
164 o.
ws(
"\n").
wind(3).
ws(
", \"error: lex_").
wstring(name).
ws(
": at position %ld (iteration %u):\\n\"");
165 o.
ws(
"\n").
wind(4).
ws(
"\"\\texpected: match length %ld, rule %u\\n\"");
166 o.
ws(
"\n").
wind(4).
ws(
"\"\\tactual: match length %ld, rule %u\\n\"");
170 o.
ws(
"\n").
wind(3).
ws(
", rule_exp");
172 o.
ws(
"\n").
wind(3).
ws(
", rule_act");
180 o.
ws(
"\n").
wind(1).
ws(
"const size_t padding = ").
wu64(maxfill).
ws(
"; /* YYMAXFILL */");
181 o.
ws(
"\n").
wind(1).
ws(
"int status = 0;");
182 o.
ws(
"\n").
wind(1).
ws(
"size_t input_len = 0;");
183 o.
ws(
"\n").
wind(1).
ws(
"size_t keys_count = 0;");
184 o.
ws(
"\n").
wind(1).
ws(
"YYCTYPE *input = NULL;");
185 o.
ws(
"\n").
wind(1).
ws(
"YYKEYTYPE *keys = NULL;");
186 o.
ws(
"\n").
wind(1).
ws(
"const YYCTYPE *cursor = NULL;");
187 o.
ws(
"\n").
wind(1).
ws(
"const YYCTYPE *limit = NULL;");
188 o.
ws(
"\n").
wind(1).
ws(
"const YYCTYPE *token = NULL;");
189 o.
ws(
"\n").
wind(1).
ws(
"const YYCTYPE *eof = NULL;");
190 o.
ws(
"\n").
wind(1).
ws(
"unsigned int i = 0;");
192 o.
ws(
"\n").
wind(1).
ws(
"input = (YYCTYPE *) read_file");
194 o.
ws(
"\n").
wind(2).
ws(
", sizeof (YYCTYPE)");
196 o.
ws(
"\n").
wind(2).
ws(
", &input_len");
198 o.
ws(
"\n").
wind(1).
ws(
"if (input == NULL) {");
199 o.
ws(
"\n").
wind(2).
ws(
"status = 1;");
203 if (sizeof_cunit > 1)
205 o.
ws(
"\n").
wind(1).
ws(
"for (i = 0; i < input_len; ++i) {");
206 from_le(o, 2, sizeof_cunit,
"input[i]");
210 o.
ws(
"\n").
wind(1).
ws(
"keys = (YYKEYTYPE *) read_file");
212 o.
ws(
"\n").
wind(2).
ws(
", 3 * sizeof (YYKEYTYPE)");
214 o.
ws(
"\n").
wind(2).
ws(
", &keys_count");
216 o.
ws(
"\n").
wind(1).
ws(
"if (keys == NULL) {");
217 o.
ws(
"\n").
wind(2).
ws(
"status = 1;");
223 o.
ws(
"\n").
wind(1).
ws(
"for (i = 0; i < 3 * keys_count; ++i) {");
224 from_le(o, 2, sizeof_key,
"keys[i]");
228 o.
ws(
"\n").
wind(1).
ws(
"cursor = input;");
229 o.
ws(
"\n").
wind(1).
ws(
"limit = input + input_len + padding;");
230 o.
ws(
"\n").
wind(1).
ws(
"eof = input + input_len;");
232 o.
ws(
"\n").
wind(1).
ws(
"for (i = 0; status == 0 && i < keys_count; ++i) {");
233 o.
ws(
"\n").
wind(2).
ws(
"token = cursor;");
236 o.
ws(
"\n").
wind(2).
ws(
"const YYCTYPE *marker = NULL;");
240 o.
ws(
"\n").
wind(2).
ws(
"const YYCTYPE *ctxmarker = NULL;");
242 o.
ws(
"\n").
wind(2).
ws(
"YYCTYPE yych;");
245 o.
ws(
"\n").
wind(2).
ws(
"unsigned int yyaccept = 0;");
262 o.
ws(
"\n").
wind(1).
ws(
"if (status == 0) {");
263 o.
ws(
"\n").
wind(2).
ws(
"if (cursor != eof) {");
264 o.
ws(
"\n").
wind(3).
ws(
"status = 1;");
265 o.
ws(
"\n").
wind(3).
ws(
"const long pos = token - input;");
266 o.
ws(
"\n").
wind(3).
ws(
"fprintf(stderr, \"error: lex_").
wstring(name).
ws(
": unused input strings left at position %ld\\n\", pos);");
268 o.
ws(
"\n").
wind(2).
ws(
"if (i != keys_count) {");
269 o.
ws(
"\n").
wind(3).
ws(
"status = 1;");
270 o.
ws(
"\n").
wind(3).
ws(
"fprintf(stderr, \"error: lex_").
wstring(name).
ws(
": unused keys left after %u iterations\\n\", i);");
275 o.
ws(
"\n").
wind(1).
ws(
"free(input);");
276 o.
ws(
"\n").
wind(1).
ws(
"free(keys);");
278 o.
ws(
"\n").
wind(1).
ws(
"return status;");
281 o.
ws(
"\n#undef YYCTYPE");
282 o.
ws(
"\n#undef YYKEYTYPE");
283 o.
ws(
"\n#undef YYPEEK");
284 o.
ws(
"\n#undef YYSKIP");
287 o.
ws(
"\n#undef YYBACKUP");
288 o.
ws(
"\n#undef YYRESTORE");
292 o.
ws(
"\n#undef YYBACKUPCTX");
293 o.
ws(
"\n#undef YYRESTORECTX");
295 o.
ws(
"\n#undef YYLESSTHAN");
296 o.
ws(
"\n#undef YYFILL");
302 o.
ws(
"\n").
ws(
"int main()");
305 for (std::set<std::string>::const_iterator i = names.begin (); i != names.end (); ++i)
320 o.
wind(ind).
ws(
"continue;\n");
static void from_le(OutputFile &o, uint32_t ind, size_t size, const char *expr)
static key_t rule2key(rule_rank_t r)
static void gen(OutputFile &, uint32_t ind, uint32_t, uint32_t)
OutputFile & ws(const char *s)
OutputFile & wu32(uint32_t n)
void emit_end(OutputFile &o, bool backup, bool backupctx) const
static void exact_uint(OutputFile &o, size_t width)
OutputFile & wind(uint32_t ind)
void emit_start(OutputFile &o, size_t maxfill, bool backup, bool backupctx, bool accept) const
uint32_t szCodeUnit() const
OutputFile & wu64(uint64_t n)
static void emit_epilog(OutputFile &o, const std::set< std::string > &names)
uint32_t nCodeUnits() const
void emit_action(OutputFile &o, uint32_t ind, rule_rank_t rank) const
static rule_rank_t none()
static void emit_prolog(OutputFile &o)
OutputFile & wstring(const std::string &s)