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.ArrayList; 018 import java.util.List; 019 020 import ch.uzh.ifi.attempto.base.AbstractOption; 021 022 /** 023 * This class represents an abstract option for the chart parser. Such an abstract option consists 024 * of a category that represents possible next tokens and of a set of zero or more exceptions, also 025 * in the form of categories. The categories can be terminal or pre-terminal, but not non-terminal. 026 * 027 * @author Tobias Kuhn 028 */ 029 public class CPAbstractOption implements AbstractOption { 030 031 private final Category category; 032 private final Category[] exceptions; 033 private final String identifier; 034 035 CPAbstractOption(Grammar grammar, Category category, Category[] exceptions) { 036 this.category = category; 037 if (exceptions != null) { 038 this.exceptions = exceptions; 039 } else { 040 this.exceptions = new Category[] {}; 041 } 042 identifier = calculateIdentifier(grammar.getFeatureNamesArray()); 043 } 044 045 CPAbstractOption(Grammar grammar, Category category, List<Category> exceptions) { 046 this(grammar, category, exceptions.toArray(new Category[] {})); 047 } 048 049 CPAbstractOption(Grammar grammar, Category category) { 050 this(grammar, category, (Category[]) null); 051 } 052 053 /** 054 * Returns the terminal or pre-terminal category that represents possible next tokens. 055 * 056 * @return The terminal or pre-terminal category. 057 */ 058 public Category getCategory() { 059 return category; 060 } 061 062 public String getCategoryName() { 063 return category.getName(); 064 } 065 066 /** 067 * This method returns the exceptions. 068 * 069 * @return The exceptions in the form of categories. 070 */ 071 public Category[] getExceptions() { 072 return exceptions; 073 } 074 075 /** 076 * Returns true if the given category is fulfilled by this option. 077 * 078 * @param c The category. 079 * @return true if it is fulfilled by this option. 080 */ 081 public boolean isFulfilledBy(Category c) { 082 if (!category.subsumes(c)) return false; 083 if (exceptions == null) return true; 084 for (Category x : exceptions) { 085 if (x.subsumes(c)) return false; 086 } 087 return true; 088 } 089 090 String calculateIdentifier(String[] usedFeatureNames) { 091 List<Integer> vars = new ArrayList<Integer>(); 092 List<Integer> mvars = new ArrayList<Integer>(); 093 String id = ""; 094 095 vars.clear(); 096 mvars.clear(); 097 category.collectVars(vars, mvars); 098 id += category.getIdentifier(mvars, usedFeatureNames) + " / "; 099 100 if (exceptions != null) { 101 for (Category x : exceptions) { 102 vars.clear(); 103 mvars.clear(); 104 x.collectVars(vars, mvars); 105 id += x.getIdentifier(mvars, usedFeatureNames) + " "; 106 } 107 } 108 return id; 109 } 110 111 public boolean equals(Object obj) { 112 if (!(obj instanceof CPAbstractOption)) return false; 113 CPAbstractOption other = (CPAbstractOption) obj; 114 return this.identifier.equals(other.identifier); 115 } 116 117 public int hashCode() { 118 return identifier.hashCode(); 119 } 120 121 public String toString() { 122 String s = ""; 123 s += category + ""; 124 if (exceptions.length > 0) { 125 s += " except"; 126 for (Category x : exceptions) { 127 s += " " + x; 128 } 129 } 130 return s; 131 } 132 133 }