001 package org.maltparser.core.syntaxgraph.headrules;
002
003 import java.util.ArrayList;
004
005 import org.apache.log4j.Logger;
006 import org.maltparser.core.exception.MaltChainedException;
007 import org.maltparser.core.io.dataformat.ColumnDescription;
008 import org.maltparser.core.symbol.SymbolTable;
009 import org.maltparser.core.syntaxgraph.headrules.PrioSetMember.RelationToPrevMember;
010 import org.maltparser.core.syntaxgraph.node.NonTerminalNode;
011 import org.maltparser.core.syntaxgraph.node.PhraseStructureNode;
012 import org.maltparser.core.syntaxgraph.node.TokenNode;
013 /**
014 *
015 *
016 * @author Johan Hall
017 */
018 public class PrioSet extends ArrayList<PrioSetMember> {
019 public static final long serialVersionUID = 8045568022124816313L;
020 protected PrioList prioList;
021 protected PrioSetMember cache;
022
023 public PrioSet(PrioList prioList) {
024 setPrioList(prioList);
025 cache = new PrioSetMember(this, null, null, -1, RelationToPrevMember.START);
026 }
027
028 public PrioSet(PrioList prioList, String setSpec) throws MaltChainedException {
029 setPrioList(prioList);
030 cache = new PrioSetMember(this, null, null, -1, RelationToPrevMember.START);
031 init(setSpec);
032 }
033
034 public void init(String setSpec) throws MaltChainedException {
035 String spec = setSpec.trim();
036 String[] disItems = spec.split("\\|");
037 for (int i = 0; i < disItems.length; i++) {
038 String[] conItems = spec.split("\\&");
039 for (int j = 0; j < conItems.length; j++) {
040 int index = conItems[j].indexOf(':');
041 if (index != -1) {
042 SymbolTable table = prioList.getDataFormatInstance().getSymbolTables().getSymbolTable(conItems[j].substring(0, index));
043 ColumnDescription column = prioList.getDataFormatInstance().getColumnDescriptionByName(conItems[j].substring(0, index));
044 if (i == 0 && j == 0) {
045 addPrioSetMember(table, column, conItems[j].substring(index+1), RelationToPrevMember.START);
046 } else if (j == 0) {
047 addPrioSetMember(table, column, conItems[j].substring(index+1), RelationToPrevMember.DISJUNCTION);
048 } else {
049 addPrioSetMember(table, column, conItems[j].substring(index+1), RelationToPrevMember.CONJUNCTION);
050 }
051 } else {
052 throw new HeadRuleException("The specification of the priority list is not correct '"+setSpec+"'. ");
053 }
054 }
055 }
056 }
057
058 public PrioSetMember addPrioSetMember(SymbolTable table, ColumnDescription column, String symbolString, RelationToPrevMember relationToPrevMember) throws MaltChainedException {
059 if (table == null) {
060 throw new HeadRuleException("Could add a member to priority set because the symbol table could be found. ");
061 }
062 return this.addPrioSetMember(table, column, table.addSymbol(symbolString), relationToPrevMember);
063 }
064
065 public PrioSetMember addPrioSetMember(SymbolTable table, ColumnDescription column, int symbolCode, RelationToPrevMember relationToPrevMember) throws MaltChainedException {
066 cache.setTable(table);
067 cache.setSymbolCode(symbolCode);
068 if (!contains(cache)) {
069 PrioSetMember newItem = new PrioSetMember(this, table, column, symbolCode, relationToPrevMember);
070 add(newItem);
071 return newItem;
072 }
073 return cache;
074 }
075
076 public PhraseStructureNode getHeadChild(NonTerminalNode nt, Direction direction) throws MaltChainedException {
077 boolean match = false;
078 if (direction == Direction.LEFT) {
079 for (PhraseStructureNode child : nt.getChildren()) {
080 for (int j = 0; j < size(); j++) {
081 match = matchHeadChild(child, get(j));
082 if (match == true) {
083 if (j+1 >= size()) {
084 return child;
085 } else if (get(j).getRelationToPrevMember() != RelationToPrevMember.CONJUNCTION) {
086 return child;
087 }
088 }
089 }
090 }
091 } else if (direction == Direction.RIGHT) {
092 for (int i = nt.nChildren()-1; i >= 0; i--) {
093 PhraseStructureNode child = nt.getChild(i);
094 for (int j = 0; j < size(); j++) {
095 match = matchHeadChild(child, get(j));
096 if (match == true) {
097 if (j+1 >= size()) {
098 return child;
099 } else if (get(j).getRelationToPrevMember() != RelationToPrevMember.CONJUNCTION) {
100 return child;
101 }
102 }
103 }
104 }
105 }
106 return null;
107 }
108
109 private boolean matchHeadChild(PhraseStructureNode child, PrioSetMember member) throws MaltChainedException {
110 if (child instanceof NonTerminalNode && member.getTable().getName().equals("CAT") && member.getSymbolCode() == child.getLabelCode(member.getTable())) {
111 return true;
112 } else if (member.getTable().getName().equals("LABEL") && member.getSymbolCode() == child.getParentEdgeLabelCode(member.getTable())) {
113 return true;
114 } else if (child instanceof TokenNode && member.getColumn().getCategory() == ColumnDescription.INPUT && member.getSymbolCode() == child.getLabelCode(member.getTable())) {
115 return true;
116 }
117 return false;
118 }
119
120 public Logger getLogger() {
121 return prioList.getLogger();
122 }
123
124 public PrioList getPrioList() {
125 return prioList;
126 }
127
128 protected void setPrioList(PrioList prioList) {
129 this.prioList = prioList;
130 }
131
132 public boolean equals(Object obj) {
133 if (this == obj)
134 return true;
135 if (obj == null)
136 return false;
137 if (getClass() != obj.getClass())
138 return false;
139 return super.equals(obj);
140 }
141
142 public int hashCode() {
143 return super.hashCode();
144 }
145
146 public String toString() {
147 final StringBuilder sb = new StringBuilder();
148 for (int i = 0; i < size(); i++) {
149 if (i != 0) {
150 if (get(i).getRelationToPrevMember() == RelationToPrevMember.CONJUNCTION) {
151 sb.append('&');
152 } else if (get(i).getRelationToPrevMember() == RelationToPrevMember.DISJUNCTION) {
153 sb.append('|');
154 }
155 }
156 sb.append(get(i));
157 }
158 return sb.toString();
159 }
160 }