/* Generated by re2c */
#line 1 "c/submatch/02_mtags.re"
// re2c $INPUT -o $OUTPUT
#include <assert.h>
#include <vector>
#include <string>

static const int ROOT = -1;

struct Mtag {
    int pred;
    const char *tag;
};

typedef std::vector<Mtag> MtagTree;
typedef std::vector<std::string> Words;

static void mtag(int *pt, const char *t, MtagTree *tree)
{
    Mtag m = {*pt, t};
    *pt = (int)tree->size();
    tree->push_back(m);
}

static void unfold(const MtagTree &tree, int x, int y, Words &words)
{
    if (x == ROOT) return;
    unfold(tree, tree[x].pred, tree[y].pred, words);
    const char *px = tree[x].tag, *py = tree[y].tag;
    words.push_back(std::string(px, py - px));
}

#define YYMTAGP(t) mtag(&t, YYCURSOR, &tree)
#define YYMTAGN(t) mtag(&t, NULL,     &tree)
static bool lex(const char *YYCURSOR, Words &words)
{
    const char *YYMARKER;
    
#line 40 "c/submatch/02_mtags.c"
int yyt1 = ROOT;
int yyt2 = ROOT;
int yyt3 = ROOT;
#line 36 "c/submatch/02_mtags.re"

    MtagTree tree;
    int x, y;

    
#line 50 "c/submatch/02_mtags.c"
{
	char yych;
	unsigned int yyaccept = 0;
	yych = *YYCURSOR;
	switch (yych) {
	case 'a':
	case 'b':
	case 'c':
	case 'd':
	case 'e':
	case 'f':
	case 'g':
	case 'h':
	case 'i':
	case 'j':
	case 'k':
	case 'l':
	case 'm':
	case 'n':
	case 'o':
	case 'p':
	case 'q':
	case 'r':
	case 's':
	case 't':
	case 'u':
	case 'v':
	case 'w':
	case 'x':
	case 'y':
	case 'z':
		YYMTAGP(yyt2);
		goto yy4;
	default:	goto yy2;
	}
yy2:
	++YYCURSOR;
yy3:
#line 50 "c/submatch/02_mtags.re"
	{ return false; }
#line 91 "c/submatch/02_mtags.c"
yy4:
	yyaccept = 0;
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
	case ';':
		YYMTAGP(yyt3);
		goto yy5;
	case 'a':
	case 'b':
	case 'c':
	case 'd':
	case 'e':
	case 'f':
	case 'g':
	case 'h':
	case 'i':
	case 'j':
	case 'k':
	case 'l':
	case 'm':
	case 'n':
	case 'o':
	case 'p':
	case 'q':
	case 'r':
	case 's':
	case 't':
	case 'u':
	case 'v':
	case 'w':
	case 'x':
	case 'y':
	case 'z':	goto yy7;
	default:	goto yy3;
	}
yy5:
	yyaccept = 1;
	yych = *(YYMARKER = ++YYCURSOR);
	switch (yych) {
	case 'a':
	case 'b':
	case 'c':
	case 'd':
	case 'e':
	case 'f':
	case 'g':
	case 'h':
	case 'i':
	case 'j':
	case 'k':
	case 'l':
	case 'm':
	case 'n':
	case 'o':
	case 'p':
	case 'q':
	case 'r':
	case 's':
	case 't':
	case 'u':
	case 'v':
	case 'w':
	case 'x':
	case 'y':
	case 'z':
		yyt1 = yyt2;
		YYMTAGP(yyt2);
		goto yy7;
	default:
		yyt1 = yyt2;
		goto yy6;
	}
yy6:
	x = yyt1;
	y = yyt3;
#line 45 "c/submatch/02_mtags.re"
	{
        words.clear();
        unfold(tree, x, y, words);
        return true;
    }
#line 173 "c/submatch/02_mtags.c"
yy7:
	yych = *++YYCURSOR;
	switch (yych) {
	case ';':
		YYMTAGP(yyt3);
		goto yy5;
	case 'a':
	case 'b':
	case 'c':
	case 'd':
	case 'e':
	case 'f':
	case 'g':
	case 'h':
	case 'i':
	case 'j':
	case 'k':
	case 'l':
	case 'm':
	case 'n':
	case 'o':
	case 'p':
	case 'q':
	case 'r':
	case 's':
	case 't':
	case 'u':
	case 'v':
	case 'w':
	case 'x':
	case 'y':
	case 'z':	goto yy7;
	default:	goto yy9;
	}
yy9:
	YYCURSOR = YYMARKER;
	if (yyaccept == 0) {
		goto yy3;
	} else {
		goto yy6;
	}
}
#line 51 "c/submatch/02_mtags.re"

}

int main()
{
    Words w;
    assert(lex("one;two;three;", w) && w == Words({"one", "two", "three"}));
    return 0;
}
