// This file is part of AceWiki. // Copyright 2008-2013, AceWiki developers. // // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU // Lesser General Public License as published by the Free Software Foundation, either version 3 of // the License, or (at your option) any later version. // // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If // not, see http://www.gnu.org/licenses/. package ch.uzh.ifi.attempto.chartparser; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import ch.uzh.ifi.attempto.base.NextTokenOptions; /** * This class represents a set of options that describe how a partial text can be continued * according to a given grammar, and contains specific code for its use in the chart parser. * * @author Tobias Kuhn */ public class CPNextTokenOptions implements NextTokenOptions { private Set<CPAbstractOption> aOptions; private Set<CPConcreteOption> cOptions; private Map<String,Set<CPAbstractOption>> categoryMap; private Set<String> tokens; /** * Generates a new object with the given abstract and concrete options. * * @param aOptions The set of abstract options. * @param cOptions The set of concrete options. */ CPNextTokenOptions(Set<CPAbstractOption> aOptions, Set<CPConcreteOption> cOptions) { this.aOptions = aOptions; this.cOptions = cOptions; } public Set<CPAbstractOption> getAbstractOptions() { return aOptions; } /** * Returns the abstract options that have a pre-terminal category with the specified name. * * @param categoryName The name of the category. * @return The set of abstract options with the respective category name. */ public Set<CPAbstractOption> getAbstractOptions(String categoryName) { createCategoryCache(); Set<CPAbstractOption> s = categoryMap.get(categoryName); if (s == null) { s = new HashSet<CPAbstractOption>(); categoryMap.put(categoryName, s); } return s; } public Set<CPConcreteOption> getConcreteOptions() { return cOptions; } public boolean containsToken(String token) { createTokenCache(); return tokens.contains(token); } public boolean containsCategory(String categoryName) { createCategoryCache(); return categoryMap.containsKey(categoryName); } /** * Returns true if the given pre-terminal category represents a possible next token. * * @param c The pre-terminal category. * @return true if it represents a possible next token. */ public boolean containsCategory(Preterminal c) { createCategoryCache(); if (!categoryMap.containsKey(c.getName())) return false; for (CPAbstractOption o : getAbstractOptions(c.getName())) { if (o.isFulfilledBy(c)) { return true; } } return false; } private void createTokenCache() { if (tokens != null) return; tokens = new HashSet<String>(); for (CPConcreteOption o : cOptions) { tokens.add(o.getWord()); } } private void createCategoryCache() { if (categoryMap != null) return; categoryMap = new HashMap<String, Set<CPAbstractOption>>(); for (CPAbstractOption o : aOptions) { if (o.getCategory() instanceof Preterminal) { String n = o.getCategory().getName(); Set<CPAbstractOption> s = categoryMap.get(n); if (s == null) { s = new HashSet<CPAbstractOption>(); categoryMap.put(n, s); } s.add(o); } } } }