001 // This file is part of AceWiki. 002 // Copyright 2008-2012, AceWiki developers. 003 // 004 // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU 005 // Lesser General Public License as published by the Free Software Foundation, either version 3 of 006 // the License, or (at your option) any later version. 007 // 008 // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 010 // Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If 013 // not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.chartparser; 016 017 import java.util.HashMap; 018 import java.util.HashSet; 019 import java.util.Map; 020 import java.util.Set; 021 022 import ch.uzh.ifi.attempto.base.NextTokenOptions; 023 024 /** 025 * This class represents a set of options that describe how a partial text can be continued 026 * according to a given grammar, and contains specific code for its use in the chart parser. 027 * 028 * @author Tobias Kuhn 029 */ 030 public class CPNextTokenOptions implements NextTokenOptions { 031 032 private Set<CPAbstractOption> aOptions; 033 private Set<CPConcreteOption> cOptions; 034 private Map<String,Set<CPAbstractOption>> categoryMap; 035 private Set<String> tokens; 036 037 /** 038 * Generates a new object with the given abstract and concrete options. 039 * 040 * @param aOptions The set of abstract options. 041 * @param cOptions The set of concrete options. 042 */ 043 CPNextTokenOptions(Set<CPAbstractOption> aOptions, Set<CPConcreteOption> cOptions) { 044 this.aOptions = aOptions; 045 this.cOptions = cOptions; 046 } 047 048 public Set<CPAbstractOption> getAbstractOptions() { 049 return aOptions; 050 } 051 052 /** 053 * Returns the abstract options that have a pre-terminal category with the specified name. 054 * 055 * @param categoryName The name of the category. 056 * @return The set of abstract options with the respective category name. 057 */ 058 public Set<CPAbstractOption> getAbstractOptions(String categoryName) { 059 createCategoryCache(); 060 Set<CPAbstractOption> s = categoryMap.get(categoryName); 061 if (s == null) { 062 s = new HashSet<CPAbstractOption>(); 063 categoryMap.put(categoryName, s); 064 } 065 return s; 066 } 067 068 public Set<CPConcreteOption> getConcreteOptions() { 069 return cOptions; 070 } 071 072 public boolean containsToken(String token) { 073 createTokenCache(); 074 return tokens.contains(token); 075 } 076 077 public boolean containsCategory(String categoryName) { 078 createCategoryCache(); 079 return categoryMap.containsKey(categoryName); 080 } 081 082 /** 083 * Returns true if the given pre-terminal category represents a possible next token. 084 * 085 * @param c The pre-terminal category. 086 * @return true if it represents a possible next token. 087 */ 088 public boolean containsCategory(Preterminal c) { 089 createCategoryCache(); 090 if (!categoryMap.containsKey(c.getName())) return false; 091 for (CPAbstractOption o : getAbstractOptions(c.getName())) { 092 if (o.isFulfilledBy(c)) { 093 return true; 094 } 095 } 096 return false; 097 } 098 099 private void createTokenCache() { 100 if (tokens != null) return; 101 102 tokens = new HashSet<String>(); 103 for (CPConcreteOption o : cOptions) { 104 tokens.add(o.getWord()); 105 } 106 } 107 108 private void createCategoryCache() { 109 if (categoryMap != null) return; 110 111 categoryMap = new HashMap<String, Set<CPAbstractOption>>(); 112 for (CPAbstractOption o : aOptions) { 113 if (o.getCategory() instanceof Preterminal) { 114 String n = o.getCategory().getName(); 115 Set<CPAbstractOption> s = categoryMap.get(n); 116 if (s == null) { 117 s = new HashSet<CPAbstractOption>(); 118 categoryMap.put(n, s); 119 } 120 s.add(o); 121 } 122 } 123 } 124 125 }