tttm

git clone https://orangeshoelaces.net/git/tttm.git

fb36521539f03bc5f9857b436e7e3b5ff547f6dd

Author: Vasily Kolobkov on 04/25/2016

Committer: Vasily Kolobkov on 04/25/2016

Draft parse tree

Stats

imap.c | 240 +++++---
1 file changed, 152 insertions(+), 88 deletions(-)

Patch

diff --git a/imap.c b/imap.c
index 4f7e62c..1cd9315 100644
--- a/imap.c
+++ b/imap.c
@@ -1,8 +1,7 @@
 /*
-  Be warned! All the parse_* functions bear unconventional call
-  semantics. They return 1 on success and 0 otherwise. Specific
-  error code or 0 when all went smooth will be dispensed to the
-  parse context.
+  Be warned! All the parse_* functions and associates bear unconventional
+  call semantics returning 1 on success and 0 otherwise. Where applicable
+  specific error code or 0 is dispensed to the parse context.
 */
 
 #include <stdarg.h>
@@ -58,46 +57,97 @@ static struct literal {
 	{ UNSEEN, "UNSEEN", 6 },
 };
 
-static struct parse_cur {
-	char  *ntok;
-	struct semact *nact;
+struct parse_cur {
+	const char   *tok;
+	union marker *pt;
 };
 
-static struct parse_ctx {
-	char  *tokens;
-	char  *tokend;
-	size_t toklen;
-	struct semaction *acts;
-	struct semaction *actend;
-	size_t actlen;
+enum { MK_INT, MK_LEAF, MK_ATOM, ... };
+
+union marker {
+	struct {
+		int    type;
+		size_t len;
+	} hdr;
+	struct {
+		char  *tok;
+		size_t len;
+	} str;
+};
+
+enum { PE_OK, PE_PARSE, PE_NOTENMK };
+
+struct parse_ctx {
+	const char      *tok;
+	const char      *tokend;
+	size_t           toklen;
+	union marker    *pt;
+	union marker    *ptend;
+	size_t           ptlen;
 	struct parse_cur cur;
-	int    e;
+	int              e;
 };
 
-static typedef int parsefn(struct parse_ctx *);
+typedef int parsefn(struct parse_ctx *);
 
 int
-read_respln(struct semaction *acts, size_t actlen)
+read_respln(struct imap_ctx imap, union marker *pt, size_t ptlen)
 {
 	char *resp;
 	size_t resplen;
-	prepare_resp(con, &resp, &resplen);
+	prepare_resp(imap, &resp, &resplen);
 	struct parse_ctx p = { resp, resplen, acts, actlen, { resp, acts } };
 	return parse_respln(&p);
 }
 
 int
-mark(struct parse_ctx *p, struct parse_cur *cur)
+imap_resptype(union marker *pt)
+{
+	return pt[0].hdr.type ^ MK_INT;
+}
+
+/*
+  Combinators and misc meta critters
+*/
+
+int
+chkpoint(struct parse_ctx *p, struct parse_cur *cp)
 {
-	*cur = p->cur;
+	*cp = p->cur;
 	return 1;
 }
 
 int
-rollback(struct parse_ctx *p, struct parse_cur *cur)
+markhdr(struct parse_ctx *p, int type)
 {
-	if (p->e == EPARSE)
-		p->cur = *cur;
+	if (p->cur.pt == p->ptend) {
+		p->e = ENOTENMK;
+		return 0;
+	}
+	p->cur.pt.hdr.type = type;
+	p->cur.pt++;
+	return 1;
+}
+
+int
+intbeg(struct parse_ctx *p, struct parse_cur *beg, int type)
+{
+	return chkpoint(p, beg) && markhdr(p, MK_INT | type);
+}
+
+int
+intend(struct parse_ctx *p, struct parse_cur *beg)
+{
+	beg->len = p->cur.mark - beg->mark;
+	return 1;
+}
+
+int
+rollback(struct parse_ctx *p, struct parse_cur *cp)
+{
+	p->cur = *cp;
+	if (!p->e)
+		p->e = EPARSE;
 
 	return 0;
 }
@@ -111,10 +161,6 @@ opt(struct parse_ctx *p)
 	return !p->e;
 }
 
-/*
-  Combinators and misc meta critters
-*/
-
 /* prod *(SP prod) */
 int
 parse_list(struct parse_ctx *p, parsefn *prod)
@@ -141,42 +187,56 @@ parse_rep(struct parse_ctx *p, parsefn *prod)
 
 /* 1*<any char except those in `except'> */
 int
-parse_repchr(struct parse_ctx *p, char *except)
+parse_repchr(struct parse_ctx *p, const char *except, int type)
 {
-	int res;
 	char *t;
+	union marker *pt;
 
-	t = p->cur.ntok;
+	t = p->cur.tok;
+	pt = p->cur.pt;
 
 	while (t != p->tokend && binsearch(except, *t) == -1)
 		t++;
 
-	res = t > p->cur.ntok;
-	if (res) {
-		p->cur.ntok = t;
-	} else {
-		p->e = 1;
+	if (!(t > p->cur.tok)) {
+		p->e = PE_PARSE;
+		goto exit;
+	} else if (p->ptlen < 2 || p->ptend - p->cur.pt < 2) {
+		p->e = PE_NOTENMK;
+		goto exit;
 	}
 
-	return res;
+	pt->hdr.type = MK_LEAF | type;
+	pt->hdr.len = 2;
+	pt++;
+	pt->str.tok = p->cur.tok;
+	pt->str.len = t - p->cur.tok;
+	pt++;
+
+	p->cur.tok = t;
+	p->cur.mark = m;
+	p->e = PE_OK;
+
+ exit:
+	return !p->e;
 }
 
 int
 parse_2xcombo(struct parse_ctx *p, int ilit, parsefn *prod)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, ilit) &&
-	    prod(p) || rollback(p, &s);
+	return chkpoint(p, &b) && parse_lit(p, ilit) &&
+	    prod(p) || rollback(p, &b);
 }
 
 int
 parse_3xcombo(struct parse_ctx *p, int ilit1, int ilit2, parsefn *prod)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, ilit1) &&
-	    parse_lit(p, ilit2) && prod(p) || rollback(p, &s);
+	return chkpoint(p, &b) && parse_lit(p, ilit1) &&
+	    parse_lit(p, ilit2) && prod(p) || rollback(p, &b);
 }
 
 /*
@@ -186,7 +246,7 @@ parse_3xcombo(struct parse_ctx *p, int ilit1, int ilit2, parsefn *prod)
 int
 parse_atom(struct parse_ctx *p)
 {
-	return parse_repchr(p, atom_specials);
+	return parse_repchr(p, atom_specials, MK_ATOM);
 }
 
 int
@@ -198,17 +258,21 @@ parse_authtype(struct parse_ctx *p)
 int
 parse_badcscode(struct parse_ctx *p)
 {
-	return parse_lit(p, BADCS) && (parse_badcsopt(p) || opt(p));
+	struct parse_cur b;
+
+	return intbeg(p, &b, MK_BADCSCODE) &&
+	    parse_lit(p, BADCS) && (parse_badcsopt(p) || opt(p)) &&
+	    intend(p, &b) || rollback(p, &b);
 }
 
 int
 parse_badcsopt(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, SP) &&
+	return chkpoint(p, &b) && parse_lit(p, SP) &&
 	    parse_lit(p, OPAR) && parse_list(p, parse_astring) &&
-	    parse_lit(p, CPAR) || rollback(p, &s);
+	    parse_lit(p, CPAR) || rollback(p, &b);
 }
 
 int
@@ -220,51 +284,51 @@ parse_base64(struct parse_ctx *p)
 int
 parse_cap(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, SP) &&
+	return chkpoint(p, &b) && parse_lit(p, SP) &&
 	    (parse_2xcombo(AUTHEQ, parse_authtype, p) || parse_atom(p)) ||
-	    rollback(p, &s);
+	    rollback(p, &b);
 }
 
 int
 parse_capdata(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, CAP) &&
-	    parse_rep(p, parse_cap) || rollback(p, &s);
+	return chkpoint(p, &b) && parse_lit(p, CAP) &&
+	    parse_rep(p, parse_cap) || rollback(p, &b);
 }
 
 int
 parse_contreq(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) &&
+	return chkpoint(p, &b) &&
 	    parse_lit(p, PLUS) && parse_lit(p, SP) &&
 	    (parse_resptext(p) || parse_base64(p)) &&
-	    parse_lit(p, EOL) || rollback(p, &s);
+	    parse_lit(p, EOL) || rollback(p, &b);
 }
 
 int
 parse_dquotedchar(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, DQUOTE) &&
+	return chkpoint(p, &b) && parse_lit(p, DQUOTE) &&
 	    parse_quotedchar(p) && parse_lit(p, DQUOTE) ||
-	    rollback(p, &s);
+	    rollback(p, &b);
 }
 
 int
 parse_escqspec(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, BSLASH) &&
+	return chkpoint(p, &b) && parse_lit(p, BSLASH) &&
 	    (parse_lit(p, DQUOTE) || parse_lit(p, BSLASH)) ||
-	    rollback(p, &s);
+	    rollback(p, &b);
 }
 
 int
@@ -279,10 +343,10 @@ parse_flag(struct parse_ctx *p)
 int
 parse_flext(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, BSLASH) &&
-	    parse_atom(p) || rollback(p, &s);
+	return chkpoint(p, &b) && parse_lit(p, BSLASH) &&
+	    parse_atom(p) || rollback(p, &b);
 }
 
 int
@@ -296,7 +360,7 @@ parse_gencode(struct parse_ctx *p)
 {
 	struct parse_cur opt;
 
-	return parse_atom(p) && (mark(p, &opt) &&
+	return parse_atom(p) && (chkpoint(p, &opt) &&
 	    parse_lit(p, SP) && parse_genctext(p) ||
 	    rollback(p, &opt) || opt(p));
 }
@@ -339,20 +403,20 @@ parse_mbdata(struct parse_ctx *p)
 int
 parse_mbflags(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	rerurn mark(p, &s) && parse_lit(p, FLAGS) &&
+	rerurn chkpoint(p, &b) && parse_lit(p, FLAGS) &&
 	    parse_lit(p, SP) && parse_lit(p, OPAR) &&
 	    (parse_list(p, parse_flag) || opt(p)) &&
-	    parse_lit(p, CPAR) || rollback(p, &s);
+	    parse_lit(p, CPAR) || rollback(p, &b);
 }
 
 int
 parse_mblist(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, LIST) &&
+	return chkpoint(p, &b) && parse_lit(p, LIST) &&
 	    parse_lit(p, SP) && parse_lit(p, OPAR) &&
 	    (parse_list(p, parse_mblistfl) || opt(p)) &&
 	    parse_list(p, CPAR) && parse_lit(p, SP) &&
@@ -398,12 +462,12 @@ parse_permfl(struct parse_ctx *p)
 int
 parse_permflcode(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, PERMFL) &&
+	return chkpoint(p, &b) && parse_lit(p, PERMFL) &&
 	    parse_lit(p, SP) && parse_lit(p, OPAR) &&
 	    (parse_list(p, parse_permfl) || opt(p)) &&
-	    parse_lit(p, CPAR) || rollback(p, &s);
+	    parse_lit(p, CPAR) || rollback(p, &b);
 }
 
 int
@@ -428,18 +492,18 @@ parse_quotedcharclean(struct parse_ctx *p)
 int
 parse_respbye(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, BYE) && parse_lit(p, SP) &&
-	    parse_resptext(p) || rollback(p, &s);
+	return chkpoint(p, &b) && parse_lit(p, BYE) && parse_lit(p, SP) &&
+	    parse_resptext(p) || rollback(p, &b);
 }
 
 int
 parse_respdata(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_lit(p, ASTERISK) &&
+	return chkpoint(p, &b) && parse_lit(p, ASTERISK) &&
 	    parse_lit(p, SP) && (parse_respstate(p) ||
 	    parse_respbye(p) || parse_mbdata(p) || parse_msgdata(p) ||
 	    parse_capdata(p)) && parse_eol(p) || rollback(p &s);
@@ -456,22 +520,22 @@ parse_respln(struct parse_ctx *p)
 int
 parse_respstate(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && (parse_lit(p, OK) ||
+	return chkpoint(p, &b) && (parse_lit(p, OK) ||
 	    parse_lit(p, NO) || parse_lit(p, BAD)) &&
 	    parse_lit(p, SP) && parse_resptext(p) ||
-	    rollback(p, &s);
+	    rollback(p, &b);
 }
 
 int
 parse_resptext(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	mark(p, &s) && parse_lit(p, OBR) &&
+	chkpoint(p, &b) && parse_lit(p, OBR) &&
 	    parse_resptextcode(p) && parse_lit(p, CBR) &&
-	    parse_lit(p, SP) || rollback(p, &s) || opt(p);
+	    parse_lit(p, SP) || rollback(p, &b) || opt(p);
 
 	return parse_text(p);
 }
@@ -496,11 +560,11 @@ parse_tag(struct parse_ctx *p)
 int
 parse_taggedresp(struct parse_ctx *p)
 {
-	struct parse_cur s;
+	struct parse_cur b;
 
-	return mark(p, &s) && parse_tag(p) && parse_lit(p, SP) &&
+	return chkpoint(p, &b) && parse_tag(p) && parse_lit(p, SP) &&
 	    parse_respstate(p) && parse_eol(p) ||
-	    rollback(p, &s);
+	    rollback(p, &b);
 }
 
 int