1// re2c $INPUT -o $OUTPUT -s
2#include <stdlib.h>
3#include <stdio.h>
4#include <string.h>
5
6#define RET(n) return n
7
8size_t scan(const char *s, int l, char *r)
9{
10	const char *p = s;
11	const char *q;
12	#define YYCTYPE         char
13	#define YYCURSOR        p
14	#define YYLIMIT         (s+l)
15	#define YYMARKER        q
16	#define YYFILL(n)
17
18	while(1)
19	{
20/*!re2c
21	ALNUM = [0-9a-zA-Z];
22	ANY = [\000-\377];
23
24	"?!" ALNUM* {
25		*r++ = '1';
26		continue;
27	}
28
29	"?" ALNUM+ {
30		*r++ = '2';
31		continue;
32	}
33
34	(ANY\"?") {
35		*r++ = '0';
36		*r++ = '\0';
37		return p - s;
38	}
39*/
40	}
41}
42
43void _do_scan(const char * str, size_t str_len, size_t scn_len, const char * exp, size_t exp_len)
44{
45	char res[32], sp[32];
46	size_t res_len, inp_len;
47
48	inp_len = scan(str, str_len, res);
49	res_len = strlen(res);
50
51	memset(sp, ' ', sizeof(sp));
52	sp[15 - str_len] = '\0';
53
54	printf("[%s](%2d/%2d)%s: %8s(%d) %s %8s(%d)\n", str, inp_len, scn_len, sp,
55			exp, exp_len,
56			inp_len != scn_len || exp_len != res_len || strncmp(exp, res, exp_len) ? "!=" : "==",
57			res, res_len);
58}
59
60#define do_scan(str, scn_len, exp) _do_scan(str, sizeof(str) - 1, scn_len, exp, sizeof(exp) - 1)
61
62main()
63{
64	do_scan("?1??",         4, "20");
65	do_scan("#",            1, "0");
66	do_scan("##",           1, "0");
67	do_scan("##?",          1, "0");
68	do_scan("##|",          1, "0");
69	do_scan("?!|",          3, "10");
70	do_scan("?!?1|",        5, "120");
71	do_scan("?!?a+",        5, "120");
72	do_scan("?2!1?2??",     3, "20");
73	do_scan("?1?2!1?2??",   5, "220");
74	do_scan("?1?2?!1?2??", 11, "22120");
75	do_scan("?1?2?!1?2?!", 12, "221210");
76	do_scan("?1?123?45??", 11, "2220");
77	do_scan("?1?123?45?!", 12, "22210");
78}
79