 		}
 	}
 
-	public func syntaxTree(for string: String) throws -> SyntaxTree<NonTerminal, Range<String.Index>> {
+	private func syntaxTree(for string: String, ignoreAmbiguousItems: Bool) throws -> [SyntaxTree<NonTerminal, Range<String.Index>>] {
 		let tokens = try self.tokenizer.tokenize(string)
 		if tokens.isEmpty {
 			if normalizedGrammar.productions.contains(where: { production -> Bool in
 				production.pattern == normalizedGrammar.start
 					&& production.generatesEmpty(in: normalizedGrammar)
 			}) {
-				return SyntaxTree.node(key: normalizedGrammar.start, children: [SyntaxTree.leaf("".startIndex ..< "".endIndex)])
+				return [SyntaxTree.node(key: normalizedGrammar.start, children: [SyntaxTree.leaf(string.startIndex ..< string.endIndex)])]
 			} else {
 				throw SyntaxError(range: string.startIndex ..< string.endIndex, in: string, reason: .emptyNotAllowed)
 			}

							return SyntaxTree(key: pattern, children: [leftTree, rightTree])
						}
					}
					}.unique(by: {$0.root!.pattern}).collect(Array.init)
			}
		}
		
		// If a given word is not a member of the language generated by this grammar
		// an error will be computed that returns the first and largest structure
		// in the syntax tree that the parser was unable to process.
		guard let syntaxTree = cykTable[cykTable.count-1][0].first(where: { tree -> Bool in
			tree.root?.pattern == normalizedGrammar.start
		}) else {
			throw generateError(cykTable, string: string)
		}
		return unfoldChainProductions(syntaxTree).explode(normalizedGrammar.normalizationNonTerminals.contains)[0]
	}
}

			let upperBound = cykTable.count - row
			
			cykTable[row] = (0..<upperBound).map { column -> [SyntaxTree<Production, Range<String.Index>>] in
				let cell = (1...row).flatMap { offset -> [SyntaxTree<Production, Range<String.Index>>] in
					let ref1Row = row - offset
					let ref2Col = column + row - offset + 1
					let ref2Row = offset - 1
