001package org.maltparser.core.syntaxgraph.headrules; 002 003import java.util.ArrayList; 004 005import org.apache.log4j.Logger; 006import org.maltparser.core.exception.MaltChainedException; 007import org.maltparser.core.io.dataformat.ColumnDescription; 008import org.maltparser.core.symbol.SymbolTable; 009import org.maltparser.core.syntaxgraph.headrules.PrioSetMember.RelationToPrevMember; 010import org.maltparser.core.syntaxgraph.node.NonTerminalNode; 011import org.maltparser.core.syntaxgraph.node.PhraseStructureNode; 012import org.maltparser.core.syntaxgraph.node.TokenNode; 013/** 014* 015* 016* @author Johan Hall 017*/ 018public 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.getSymbolTableHandler().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}