 //			}()
 			
 			let restTokenization = try tokenize(word: word, from: firstMatchRange.upperBound)
-			let matchTrees = matches.flatMap { production -> Tree<NonTerminal, String>? in
-				Tree(key: production.pattern, children: [Tree(value: firstMatchString)])
+			let matchTrees = matches.flatMap { production -> Tree<NonTerminal, Range<String.Index>>? in
+				Tree(key: production.pattern, children: [Tree(value: firstMatchRange)])
 			}
 			//TODO: Make this method tail recursive
 			return [matchTrees] + restTokenization

		
		// CYK-Algorithm
		
		var cykTable = Array<[[Tree<NonTerminal, String>]]>(repeating: [], count: tokenization.count)
		cykTable[0] = tokenization
		
		for row in 1 ..< cykTable.count {
			let upperBound = cykTable.count - row
			
			cykTable[row] = (0..<upperBound).map { column -> [Tree<NonTerminal, String>] in
				(1...row).flatMap { offset -> [Tree<NonTerminal, String>] in
					let ref1Row = row - offset
					let ref2Col = column + row - offset + 1
					let ref2Row = offset - 1
					
					return crossProduct(cykTable[ref1Row][column], cykTable[ref2Row][ref2Col]).flatMap { nonTerminals -> [Tree<NonTerminal, String>] in
						let (leftNonTerminal, rightNonTerminal) = nonTerminals
						let combinedString = NonTerminalString(characters: [leftNonTerminal.root!, rightNonTerminal.root!])
						let possibleProductions = nonTerminalProductions[combinedString, default: []].map(\Production.pattern)
						return possibleProductions.map { pattern -> Tree<NonTerminal, String> in
							Tree(key: pattern, children: [leftNonTerminal, rightNonTerminal])
						}
					}

				throw SyntaxError.unknownSequence(from: String(word[startIndex...]))
			}
			
			//let firstMatchString = String(word[firstMatchRange])
			
			//TODO: Do not cut string, just instruct subsequent calls to only search after match range
			// This would also improve performance
