    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    }