commit - c64af147da5a26f0586e7d201175c5f9864ab478
commit + e3cbf911592479fbaa8b6f9edaf54328d9cee629
blob - f1b6210ea9098ef2ec08b8495cbc6a9af114776b
blob + dd835e84fec59008d7c3219a6d67879906247244
--- ini_a.c
+++ ini_a.c
DEF_(rightbr, CHAR(']'))
DEF_(eol, CHOICE(nl, end))
-DEF_(bra, SEQ(wss, leftbr))
+DEF_(bra, TRY(wss, leftbr))
DEF_(ket, SEQ(rightbr, wss))
DEF_(comment, OPT(semi, lchars))
DEF_(sname, MANY1(schar))
DEF_(key, MANY1(kchar))
DEF_(value, MANY1(lchar))
-DEF_(empties, MANY(wss, comment, nl))
-DEF_(header, SEQ(empties, bra, sname, ket, eol))
-DEF_(entries, MANY(empties, key, eq, value, eol))
+DEF_(empty, TRY(wss, comment, nl))
+DEF_(empties, MANY(empty))
+DEF_(header, TRY(empties, bra, sname, ket, eol))
+DEF_(entry, TRY(empties, key, eq, value, eol))
+DEF_(entries, MANY(entry))
-DEF_(tail, OPT(eof, wss, eol, anys))
+DEF_(tail, TRY(eof, wss, eol, anys) || EPSILON)
DEF_(sects, MANY(header, entries))
DEF_(inifile, SEQ(sects, empties, wss, tail))
const char *begin = env;
size_t pos;
+ if (env == NULL)
+ return true;
+
pos = s - begin;
printf("%4zx: %4zu byte %s\n", pos, len, nt);
return true;
blob - 465924eae396069cc11288010225f6cdc0a46c65
blob + 7fb3f05287cc2fe0e730c1507bd28fd0e841c444
--- minip_a.h
+++ minip_a.h
typedef bool action(void *, void *, const char *, size_t);
#define ACTION(F, C) (F)((C), env_, inp_, p_ - inp_)
+/*
+ * to avoid premature execution of actions, TRY(...) can be used in place of
+ * SEQ on any sequence where actions could execute before a later nonterminal
+ * fails. note:
+ *
+ * - single-element sequences do not need TRY.
+ * - multi-argument calls of MANY, MANY1, OPT may need to be replaced.
+ * - OPT(...) can be replaced with TRY(...) || EPSILON.
+ *
+ * in any case, beware of the overhead. since TRY executes the sequence twice,
+ * it can easily lead to a substantial increase in recognition time.
+ */
+#define MATCH(...) seq_(inp_, endp_, NULL, PARGS(__VA_ARGS__))
+#define TRY(...) (env_ == NULL || MATCH(__VA_ARGS__)) && SEQ(__VA_ARGS__)
+
static inline stream
anychar_(stream p, const stream endp)
{