 		
 		// CYK-Algorithm
 		
-		var cykTable = Array<[[Tree<NonTerminal, String>]]>(repeating: [], count: tokenization.count)
+		var cykTable = Array<[[Tree<NonTerminal, Range<String.Index>>]]>(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
+			cykTable[row] = (0..<upperBound).map { column -> [Tree<NonTerminal, Range<String.Index>>] in
+				(1...row).flatMap { offset -> [Tree<NonTerminal, Range<String.Index>>] 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
+					return crossProduct(cykTable[ref1Row][column], cykTable[ref2Row][ref2Col]).flatMap { nonTerminals -> [Tree<NonTerminal, Range<String.Index>>] 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
+						return possibleProductions.map { pattern -> Tree<NonTerminal, Range<String.Index>> in
 							Tree(key: pattern, children: [leftNonTerminal, rightNonTerminal])
 						}
 					}


enum SyntaxError: Error {
	case unknownSequence(from: String)
	case unmatchedPattern(pattern: Tree<NonTerminal, String>, location: Int)
	case emptyWordNotAllowed
}


			if productions.contains(where: { production -> Bool in
				production.pattern == start && production.generatedTerminals.isEmpty
			}) {
				return Tree.node(key: start, children: [Tree.leaf(word.startIndex..<word.endIndex)])
			} else {
				throw SyntaxError.emptyWordNotAllowed
			}
