// Code generated by re2go, DO NOT EDIT.
//line "codegen/go/recursive_functions/advanced.re":1
//go:generate re2go $INPUT -o $OUTPUT -cf --recursive-functions -Wno-nondeterministic-tags
package main

import (
	"fmt"
	"os"
)

//line "codegen/go/recursive_functions/advanced.go":12
const (
	yycmedia_type = 1
	yycheader = 23
)
//line "codegen/go/recursive_functions/advanced.re":9


const debug bool = false

// Intentionally small to trigger buffer refill.
const SIZE int = 4095

const (
	mtagRoot int = -1
	tagNone int = -1
)

// An m-tag tree is a way to store histories with an O(1) copy operation.
// Histories naturally form a tree, as they have common start and fork at some
// point. The tree is stored as an array of pairs (tag value, link to parent).
// An m-tag is represented with a single link in the tree (array index).
type mtagElem struct {
	elem int
	pred int
}
type mtagTrie = []mtagElem

// Append a single value to an m-tag history.
func add_mtag(trie *mtagTrie, mtag int, value int) int {
	*trie = append(*trie, mtagElem{value, mtag})
	return len(*trie) - 1
}

// Recursively unwind tag histories and collect version components.
func unwind(trie mtagTrie, x int, y int, str []byte) []string {
	// Reached the root of the m-tag tree, stop recursion.
	if x == mtagRoot && y == mtagRoot {
		return []string{}
	}

	// Unwind history further.
	result := unwind(trie, trie[x].pred, trie[y].pred, str)

	// Get tag values. Tag histories must have equal length.
	if x == mtagRoot || y == mtagRoot {
		panic("tag histories have different length")
	}
	ex := trie[x].elem
	ey := trie[y].elem

	if ex != tagNone && ey != tagNone {
		// Both tags are valid string indices, extract component.
		result = append(result, string(str[ex:ey]))
	} else if !(ex == tagNone && ey == tagNone) {
		panic("both tags should be tagNone")
	}
	return result
}

type State struct {
	file     *os.File
	yyinput  []byte
	yycursor int
	yymarker int
	yylimit  int
	token    int
	yyc      int
	yyst     int
	trie     mtagTrie
	
//line "codegen/go/recursive_functions/advanced.go":83

	yyt1 int
	yyt2 int
//line "codegen/go/recursive_functions/advanced.re":73

	
//line "codegen/go/recursive_functions/advanced.go":90

	yytm1 int
	yytm10 int
	yytm2 int
	yytm3 int
	yytm4 int
	yytm5 int
	yytm6 int
	yytm7 int
	yytm8 int
	yytm9 int
//line "codegen/go/recursive_functions/advanced.re":74

	l1, l2   int
	f1, f2   int
	p1, p2   int
	p3, p4   int
	yyaccept int
}

const (
	lexEnd = iota
	lexReady
	lexWaiting
	lexBadPacket
	lexBigPacket
)

func fill(st *State) int {
	shift := st.token
	used := st.yylimit - st.token
	free := SIZE - used

	// Error: no space. In real life can reallocate a larger buffer.
	if free < 1 { return lexBigPacket }

	// Shift buffer contents (discard already processed data).
	copy(st.yyinput[0:], st.yyinput[shift:shift+used])
	st.yycursor -= shift
	st.yymarker -= shift
	st.yylimit -= shift
	st.token -= shift
	
//line "codegen/go/recursive_functions/advanced.go":134

	st.yyt1 -= shift
	st.yyt2 -= shift
//line "codegen/go/recursive_functions/advanced.re":104


	// Fill free space at the end of buffer with new data.
	n, _ := st.file.Read(st.yyinput[st.yylimit:SIZE])
	st.yylimit += n
	st.yyinput[st.yylimit] = 0 // append sentinel symbol

	return lexReady
}


//line "codegen/go/recursive_functions/advanced.go":150
func yy1(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yyt1 = st.yycursor
		st.yycursor += 1
		return yy4(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 0
			return lexWaiting
		} else {
			st.yycursor += 1
			return yy2(st)
		}
	}
}

func yy2(st *State) int {
	return yy3(st)
}

func yy3(st *State) int {
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":177
	return lexBadPacket
//line "codegen/go/recursive_functions/advanced.go":193
}

func yy4(st *State) int {
	st.yymarker = st.yycursor
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.','/','0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		return yy6(st, yych)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 1
			return lexWaiting
		} else {
			return yy3(st)
		}
	}
}

func yy5(st *State) int {
	yych := st.yyinput[st.yycursor]
	return yy6(st, yych)
}

func yy6(st *State, yych byte) int {
	switch (yych) {
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yycursor += 1
		return yy5(st)
	case '/':
		st.yycursor += 1
		return yy8(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 2
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy7(st *State) int {
	st.yycursor = st.yymarker
	return yy3(st)
}

func yy8(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case '\t':
		fallthrough
	case '\r':
		fallthrough
	case ' ':
		fallthrough
	case ';':
		if (st.yylimit <= st.yycursor) {
			st.yyst = 3
			return lexWaiting
		} else {
			return yy7(st)
		}
	default:
		return yy10(st, yych)
	}
}

func yy9(st *State) int {
	yych := st.yyinput[st.yycursor]
	return yy10(st, yych)
}

func yy10(st *State, yych byte) int {
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yytm6 = st.yytm10
		st.yytm6 = add_mtag(&st.trie, st.yytm6, tagNone)
		st.yytm5 = st.yytm9
		st.yytm5 = add_mtag(&st.trie, st.yytm5, tagNone)
		st.yytm4 = st.yytm8
		st.yytm4 = add_mtag(&st.trie, st.yytm4, tagNone)
		st.yytm3 = st.yytm7
		st.yytm3 = add_mtag(&st.trie, st.yytm3, tagNone)
		st.yyt2 = st.yycursor
		st.yycursor += 1
		return yy11(st)
	case '\r':
		st.yytm6 = st.yytm10
		st.yytm6 = add_mtag(&st.trie, st.yytm6, tagNone)
		st.yytm5 = st.yytm9
		st.yytm5 = add_mtag(&st.trie, st.yytm5, tagNone)
		st.yytm4 = st.yytm8
		st.yytm4 = add_mtag(&st.trie, st.yytm4, tagNone)
		st.yytm3 = st.yytm7
		st.yytm3 = add_mtag(&st.trie, st.yytm3, tagNone)
		st.yyt2 = st.yycursor
		st.yycursor += 1
		return yy12(st)
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yycursor += 1
		return yy9(st)
	case ';':
		st.yyt2 = st.yycursor
		st.yycursor += 1
		return yy13(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 4
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy11(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy11(st)
	case '\r':
		st.yycursor += 1
		return yy12(st)
	case ';':
		st.yycursor += 1
		return yy13(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 5
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy12(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\n':
		st.yycursor += 1
		return yy14(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 6
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy13(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy13(st)
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yytm7 = add_mtag(&st.trie, st.yytm7, st.yycursor)
		st.yycursor += 1
		return yy15(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 7
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy14(st *State) int {
	st.l1 = st.yyt1
	st.l2 = st.yyt2
	st.p1 = st.yytm3
	st.p2 = st.yytm4
	st.p3 = st.yytm5
	st.p4 = st.yytm6
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":155
	
		if debug {fmt.Printf("media type: %v\n", string(st.yyinput[st.l1:st.l2]))}

		pnames := unwind(st.trie, st.p1, st.p2, st.yyinput)
		if debug {fmt.Printf("pnames: %v\n", pnames)}

		pvals := unwind(st.trie, st.p3, st.p4, st.yyinput)
		if debug {fmt.Printf("pvals: %v\n", pvals)}

		st.token = st.yycursor
		return lex(st)

//line "codegen/go/recursive_functions/advanced.go":458
}

func yy15(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yycursor += 1
		return yy15(st)
	case '=':
		st.yytm8 = add_mtag(&st.trie, st.yytm8, st.yycursor)
		st.yycursor += 1
		return yy16(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 8
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy16(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yytm9 = add_mtag(&st.trie, st.yytm9, st.yycursor)
		st.yycursor += 1
		return yy17(st)
	case '"':
		st.yytm9 = add_mtag(&st.trie, st.yytm9, st.yycursor)
		st.yycursor += 1
		return yy18(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 9
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy17(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yytm10 = add_mtag(&st.trie, st.yytm10, st.yycursor)
		st.yycursor += 1
		return yy19(st)
	case '\r':
		st.yytm3 = st.yytm7
		st.yytm4 = st.yytm8
		st.yytm5 = st.yytm9
		st.yytm6 = st.yytm10
		st.yytm6 = add_mtag(&st.trie, st.yytm6, st.yycursor)
		st.yycursor += 1
		return yy12(st)
	case '!':
		fallthrough
	case '#','$','%','&','\'':
		fallthrough
	case '*','+':
		fallthrough
	case '-','.':
		fallthrough
	case '0','1','2','3','4','5','6','7','8','9':
		fallthrough
	case 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z':
		fallthrough
	case '^','_','`','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z':
		fallthrough
	case '|':
		fallthrough
	case '~':
		st.yycursor += 1
		return yy17(st)
	case ';':
		st.yytm10 = add_mtag(&st.trie, st.yytm10, st.yycursor)
		st.yycursor += 1
		return yy13(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 10
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy18(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f','\r',0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 11
			return lexWaiting
		} else {
			return yy7(st)
		}
	case '"':
		st.yycursor += 1
		return yy20(st)
	case '\\':
		st.yycursor += 1
		return yy21(st)
	default:
		st.yycursor += 1
		return yy18(st)
	}
}

func yy19(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy19(st)
	case '\r':
		st.yytm3 = st.yytm7
		st.yytm4 = st.yytm8
		st.yytm5 = st.yytm9
		st.yytm6 = st.yytm10
		st.yycursor += 1
		return yy12(st)
	case ';':
		st.yycursor += 1
		return yy13(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 12
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy20(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yytm10 = add_mtag(&st.trie, st.yytm10, st.yycursor)
		st.yycursor += 1
		return yy19(st)
	case '\r':
		st.yytm3 = st.yytm7
		st.yytm4 = st.yytm8
		st.yytm5 = st.yytm9
		st.yytm6 = st.yytm10
		st.yytm6 = add_mtag(&st.trie, st.yytm6, st.yycursor)
		st.yycursor += 1
		return yy12(st)
	case ';':
		st.yytm10 = add_mtag(&st.trie, st.yytm10, st.yycursor)
		st.yycursor += 1
		return yy13(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 13
			return lexWaiting
		} else {
			return yy7(st)
		}
	}
}

func yy21(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f','\r',0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 14
			return lexWaiting
		} else {
			return yy7(st)
		}
	default:
		st.yycursor += 1
		return yy18(st)
	}
}

func yy22(st *State) int {
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":176
	return lexEnd
//line "codegen/go/recursive_functions/advanced.go":697
}

func yyfnmedia_type(st *State) int {
	return yy1(st)
}

func yy23(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,'\t','\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 15
			return lexWaiting
		} else {
			st.yycursor += 1
			return yy24(st)
		}
	case '\r':
		st.yytm3 = add_mtag(&st.trie, st.yytm3, st.yycursor)
		st.yycursor += 1
		return yy26(st)
	default:
		st.yycursor += 1
		return yy27(st)
	}
}

func yy24(st *State) int {
	return yy25(st)
}

func yy25(st *State) int {
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":177
	return lexBadPacket
//line "codegen/go/recursive_functions/advanced.go":739
}

func yy26(st *State) int {
	st.yyaccept = 0
	st.yymarker = st.yycursor
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\n':
		st.yycursor += 1
		return yy28(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 16
			return lexWaiting
		} else {
			return yy25(st)
		}
	}
}

func yy27(st *State) int {
	st.yyaccept = 0
	st.yymarker = st.yycursor
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 17
			return lexWaiting
		} else {
			return yy25(st)
		}
	case '\t':
		st.yycursor += 1
		return yy30(st)
	case '\r':
		st.yytm3 = add_mtag(&st.trie, st.yytm3, st.yycursor)
		st.yycursor += 1
		return yy31(st)
	default:
		st.yycursor += 1
		return yy32(st)
	}
}

func yy28(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy33(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 18
			return lexWaiting
		} else {
			return yy29(st)
		}
	}
}

func yy29(st *State) int {
	st.yycursor = st.yymarker
	if (st.yyaccept == 0) {
		return yy25(st)
	} else {
		return yy38(st)
	}
}

func yy30(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f','\r',0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 19
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		st.yycursor += 1
		return yy30(st)
	case ' ':
		st.yycursor += 1
		return yy32(st)
	default:
		st.yycursor += 1
		return yy34(st)
	}
}

func yy31(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\n':
		st.yycursor += 1
		return yy28(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 20
			return lexWaiting
		} else {
			return yy29(st)
		}
	}
}

func yy32(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 21
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		st.yycursor += 1
		return yy30(st)
	case '\r':
		st.yytm3 = add_mtag(&st.trie, st.yytm3, st.yycursor)
		st.yycursor += 1
		return yy31(st)
	default:
		st.yycursor += 1
		return yy32(st)
	}
}

func yy33(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 22
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy33(st)
	case '\r':
		st.yytm5 = add_mtag(&st.trie, st.yytm5, st.yycursor)
		st.yytm4 = st.yytm3
		st.yytm4 = add_mtag(&st.trie, st.yytm4, st.yycursor)
		st.yycursor += 1
		return yy35(st)
	default:
		st.yytm5 = add_mtag(&st.trie, st.yytm5, st.yycursor)
		st.yycursor += 1
		return yy36(st)
	}
}

func yy34(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,'\t','\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 23
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\r':
		st.yytm3 = add_mtag(&st.trie, st.yytm3, st.yycursor)
		st.yycursor += 1
		return yy31(st)
	default:
		st.yycursor += 1
		return yy32(st)
	}
}

func yy35(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\n':
		st.yycursor += 1
		return yy37(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 24
			return lexWaiting
		} else {
			return yy29(st)
		}
	}
}

func yy36(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 25
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		st.yycursor += 1
		return yy39(st)
	case '\r':
		st.yytm4 = st.yytm3
		st.yytm4 = add_mtag(&st.trie, st.yytm4, st.yycursor)
		st.yycursor += 1
		return yy35(st)
	default:
		st.yycursor += 1
		return yy36(st)
	}
}

func yy37(st *State) int {
	st.yyaccept = 1
	st.yymarker = st.yycursor
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yytm1 = st.yytm3
		st.yytm2 = st.yytm5
		st.yytm3 = st.yytm4
		st.yycursor += 1
		return yy33(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 26
			return lexWaiting
		} else {
			st.yytm1 = st.yytm3
			st.yytm2 = st.yytm5
			return yy38(st)
		}
	}
}

func yy38(st *State) int {
	st.f1 = st.yytm1
	st.f2 = st.yytm2
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":168
	
		folds := unwind(st.trie, st.f1, st.f2, st.yyinput)
		if debug {fmt.Printf("folds: %v\n", folds)}

		st.token = st.yycursor
		return lex(st)

//line "codegen/go/recursive_functions/advanced.go":1042
}

func yy39(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 27
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		st.yycursor += 1
		return yy39(st)
	case '\r':
		st.yycursor += 1
		return yy40(st)
	case ' ':
		st.yycursor += 1
		return yy36(st)
	default:
		st.yycursor += 1
		return yy41(st)
	}
}

func yy40(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\n':
		st.yycursor += 1
		return yy42(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 28
			return lexWaiting
		} else {
			return yy29(st)
		}
	}
}

func yy41(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case 0x00:
		fallthrough
	case 0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08:
		fallthrough
	case '\n','\v','\f':
		fallthrough
	case 0x0E,0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E:
		fallthrough
	case 0x7F:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 29
			return lexWaiting
		} else {
			return yy29(st)
		}
	case '\t':
		st.yycursor += 1
		return yy43(st)
	case '\r':
		st.yytm4 = st.yytm3
		st.yytm4 = add_mtag(&st.trie, st.yytm4, st.yycursor)
		st.yycursor += 1
		return yy35(st)
	default:
		st.yycursor += 1
		return yy36(st)
	}
}

func yy42(st *State) int {
	st.yytm1 = st.yytm3
	st.yytm2 = st.yytm5
	return yy38(st)
}

func yy43(st *State) int {
	yych := st.yyinput[st.yycursor]
	switch (yych) {
	case '\t':
		fallthrough
	case ' ':
		st.yycursor += 1
		return yy43(st)
	case '\r':
		st.yycursor += 1
		return yy40(st)
	default:
		if (st.yylimit <= st.yycursor) {
			st.yyst = 30
			return lexWaiting
		} else {
			return yy29(st)
		}
	}
}

func yy44(st *State) int {
	st.yyst = -1
//line "codegen/go/recursive_functions/advanced.re":176
	return lexEnd
//line "codegen/go/recursive_functions/advanced.go":1157
}

func yyfnheader(st *State) int {
	return yy23(st)
}

func yy0(st *State) int {
	switch (st.yyc) {
	case yycmedia_type:
		return yyfnmedia_type(st)
	case yycheader:
		return yyfnheader(st)
	default:
		panic("internal lexer error")
	}
}

func lex(st *State) int {
	switch (st.yyst) {
	case -1:
		return yy0(st)
	case 0:
		if (st.yylimit <= st.yycursor) {
			return yy22(st)
		} else {
			return yy1(st)
		}
	case 1:
		if (st.yylimit <= st.yycursor) {
			return yy3(st)
		} else {
			return yy4(st)
		}
	case 2:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy5(st)
		}
	case 3:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy8(st)
		}
	case 4:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy9(st)
		}
	case 5:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy11(st)
		}
	case 6:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy12(st)
		}
	case 7:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy13(st)
		}
	case 8:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy15(st)
		}
	case 9:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy16(st)
		}
	case 10:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy17(st)
		}
	case 11:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy18(st)
		}
	case 12:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy19(st)
		}
	case 13:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy20(st)
		}
	case 14:
		if (st.yylimit <= st.yycursor) {
			return yy7(st)
		} else {
			return yy21(st)
		}
	case 15:
		if (st.yylimit <= st.yycursor) {
			return yy44(st)
		} else {
			return yy23(st)
		}
	case 16:
		if (st.yylimit <= st.yycursor) {
			return yy25(st)
		} else {
			return yy26(st)
		}
	case 17:
		if (st.yylimit <= st.yycursor) {
			return yy25(st)
		} else {
			return yy27(st)
		}
	case 18:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy28(st)
		}
	case 19:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy30(st)
		}
	case 20:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy31(st)
		}
	case 21:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy32(st)
		}
	case 22:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy33(st)
		}
	case 23:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy34(st)
		}
	case 24:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy35(st)
		}
	case 25:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy36(st)
		}
	case 26:
		if (st.yylimit <= st.yycursor) {
			st.yytm1 = st.yytm3
			st.yytm2 = st.yytm5
			return yy38(st)
		} else {
			return yy37(st)
		}
	case 27:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy39(st)
		}
	case 28:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy40(st)
		}
	case 29:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy41(st)
		}
	case 30:
		if (st.yylimit <= st.yycursor) {
			return yy29(st)
		} else {
			return yy43(st)
		}
	default:
		panic("internal lexer error")
	}
}

//line "codegen/go/recursive_functions/advanced.re":178


func test(packets []string) int {
	fname := "pipe"
	fw, _ := os.Create(fname);
	fr, _ := os.Open(fname);

	st := &State{
		file:     fr,
		yyinput:  make([]byte, SIZE+1),
		yycursor: SIZE,
		yymarker: SIZE,
		yylimit:  SIZE,
		token:    SIZE,
		yyc:      yycmedia_type,
		yyst:     -1,
		trie:     make([]mtagElem, 0),
		
//line "codegen/go/recursive_functions/advanced.go":1391

		yyt1: tagNone,
		yyt2: tagNone,
//line "codegen/go/recursive_functions/advanced.re":195

		
//line "codegen/go/recursive_functions/advanced.go":1398

		yytm1: mtagRoot,
		yytm10: mtagRoot,
		yytm2: mtagRoot,
		yytm3: mtagRoot,
		yytm4: mtagRoot,
		yytm5: mtagRoot,
		yytm6: mtagRoot,
		yytm7: mtagRoot,
		yytm8: mtagRoot,
		yytm9: mtagRoot,
//line "codegen/go/recursive_functions/advanced.re":196

		l1:       0,
		l2:       0,
		f1:       0,
		f2:       0,
		p1:       0,
		p2:       0,
		p3:       0,
		p4:       0,
		yyaccept: 0,
	}
	// yyinput is zero-initialized, no need to write sentinel

	var status int
	send := 0
loop:
	for {
		status = lex(st)
		if status == lexEnd {
			//fmt.Printf("ok, done\n")
			break loop
		} else if status == lexWaiting {
			//fmt.Printf("need more input\n")
			if send < len(packets) {
				//fmt.Printf("sending %d-th packet '%s'\n", send, packets[send])
				fw.WriteString(packets[send])
				send += 1
			}
			status = fill(st)
			if status != lexReady {
				break loop
			}
			//fmt.Printf("refilled buffer, ready to continue\n")
		} else if status == lexBadPacket {
			//fmt.Printf("bad packet\n")
			break loop
		} else {
			panic("unexpected status")
		}
	}

	fr.Close()
	fw.Close()
	os.Remove(fname)

	return status
}

func main() {
	packets := []string{"ap", "plication/j", "son;", " charset=\"", "utf\\\"-8\"\r", "\n", ""}
	if test(packets) != lexEnd { panic("error") }
}
