001    package org.maltparser.parser;
002    
003    import java.util.HashMap;
004    
005    import org.maltparser.core.exception.MaltChainedException;
006    import org.maltparser.core.symbol.SymbolTable;
007    import org.maltparser.core.symbol.SymbolTableHandler;
008    import org.maltparser.core.symbol.TableHandler;
009    import org.maltparser.core.syntaxgraph.LabelSet;
010    import org.maltparser.core.syntaxgraph.edge.Edge;
011    import org.maltparser.parser.history.GuideUserHistory;
012    import org.maltparser.parser.history.action.GuideUserAction;
013    import org.maltparser.parser.history.container.ActionContainer;
014    import org.maltparser.parser.transition.TransitionTable;
015    import org.maltparser.parser.transition.TransitionTableHandler;
016    /**
017     * @author Johan Hall
018     *
019     */
020    public abstract class TransitionSystem {
021            protected HashMap<String, TableHandler> tableHandlers;
022            protected TransitionTableHandler transitionTableHandler;
023            protected ActionContainer[] actionContainers;
024            protected ActionContainer transActionContainer;
025            protected ActionContainer[] arcLabelActionContainers;
026            
027            public TransitionSystem() throws MaltChainedException { }
028            
029            public abstract void apply(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException;
030            public abstract boolean permissible(GuideUserAction currentAction, ParserConfiguration config) throws MaltChainedException;
031            public abstract GuideUserAction getDeterministicAction(GuideUserHistory history, ParserConfiguration config) throws MaltChainedException;
032            protected abstract void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException;
033            protected abstract void initWithDefaultTransitions(GuideUserHistory history) throws MaltChainedException;
034            public abstract String getName();
035            public abstract GuideUserAction defaultAction(GuideUserHistory history, ParserConfiguration configuration) throws MaltChainedException;
036            
037            protected GuideUserAction updateActionContainers(GuideUserHistory history, int transition, LabelSet arcLabels) throws MaltChainedException {    
038                    transActionContainer.setAction(transition);
039    
040                    if (arcLabels == null) {
041                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
042                                    arcLabelActionContainers[i].setAction(-1);      
043                            }
044                    } else {
045                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
046                                    arcLabelActionContainers[i].setAction(arcLabels.get(arcLabelActionContainers[i].getTable()).shortValue());
047                            }               
048                    }
049                    GuideUserAction oracleAction = history.getEmptyGuideUserAction();
050                    oracleAction.addAction(actionContainers);
051                    return oracleAction;
052            }
053            
054            protected boolean isActionContainersLabeled() {
055                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
056                            if (arcLabelActionContainers[i].getActionCode() < 0) {
057                                    return false;
058                            }
059                    }
060                    return true;
061            }
062            
063            protected void addEdgeLabels(Edge e) throws MaltChainedException {
064                    if (e != null) { 
065                            for (int i = 0; i < arcLabelActionContainers.length; i++) {
066                                    e.addLabel((SymbolTable)arcLabelActionContainers[i].getTable(), arcLabelActionContainers[i].getActionCode());
067                            }
068                    }
069            }
070            
071            public void initTransitionSystem(GuideUserHistory history) throws MaltChainedException {
072                    this.actionContainers = history.getActionContainerArray();
073                    if (actionContainers.length < 1) {
074                            throw new ParsingException("Problem when initialize the history (sequence of actions). There are no action containers. ");
075                    }
076                    int nLabels = 0;
077                    for (int i = 0; i < actionContainers.length; i++) {
078                            if (actionContainers[i].getTableContainerName().startsWith("A.")) {
079                                    nLabels++;
080                            }
081                    }
082                    int j = 0;
083                    for (int i = 0; i < actionContainers.length; i++) {
084                            if (actionContainers[i].getTableContainerName().equals("T.TRANS")) {
085                                    transActionContainer = actionContainers[i];
086                            } else if (actionContainers[i].getTableContainerName().startsWith("A.")) {
087                                    if (arcLabelActionContainers == null) {
088                                            arcLabelActionContainers = new ActionContainer[nLabels];
089                                    }
090                                    arcLabelActionContainers[j++] = actionContainers[i];
091                            }
092                    }
093                    initWithDefaultTransitions(history);
094            }
095            
096            public void initTableHandlers(String decisionSettings, SymbolTableHandler symbolTableHandler) throws MaltChainedException {
097                    transitionTableHandler = new TransitionTableHandler();
098                    tableHandlers = new HashMap<String, TableHandler>();
099                    
100                    final String[] decisionElements =  decisionSettings.split(",|#|;|\\+");
101                    
102                    int nTrans = 0;
103                    for (int i = 0; i < decisionElements.length; i++) {
104                            int index = decisionElements[i].indexOf('.');
105                            if (index == -1) {
106                                    throw new ParsingException("Decision settings '"+decisionSettings+"' contain an item '"+decisionElements[i]+"' that does not follow the format {TableHandler}.{Table}. ");
107                            }
108                            if (decisionElements[i].substring(0,index).equals("T")) {
109                                    if (!getTableHandlers().containsKey("T")) {
110                                            getTableHandlers().put("T", getTransitionTableHandler());
111                                    }
112                                    if (decisionElements[i].substring(index+1).equals("TRANS")) {
113                                            if (nTrans == 0) {
114                                                    TransitionTable ttable = (TransitionTable)getTransitionTableHandler().addSymbolTable("TRANS");
115                                                    addAvailableTransitionToTable(ttable);
116                                            } else {
117                                                    throw new ParsingException("Illegal decision settings '"+decisionSettings+"'");
118                                            }
119                                            nTrans++;
120                                    }  
121                            } else if (decisionElements[i].substring(0,index).equals("A")) {
122                                    if (!getTableHandlers().containsKey("A")) {
123                                            getTableHandlers().put("A", symbolTableHandler);
124                                    }
125                            } else {
126                                    throw new ParsingException("The decision settings '"+decisionSettings+"' contains an unknown table handler '"+decisionElements[i].substring(0,index)+"'. " +
127                                                    "Only T (Transition table handler) and A (ArcLabel table handler) is allowed. ");
128                            }
129                    }
130            }
131            
132            public void copyAction(GuideUserAction source, GuideUserAction target) throws MaltChainedException {
133                    source.getAction(actionContainers);
134                    target.addAction(actionContainers);
135            }
136            
137            public HashMap<String, TableHandler> getTableHandlers() {
138                    return tableHandlers;
139            }
140    
141            public TransitionTableHandler getTransitionTableHandler() {
142                    return transitionTableHandler;
143            }
144            
145            public String getActionString(GuideUserAction action) throws MaltChainedException {
146                    StringBuilder sb = new StringBuilder();
147                    action.getAction(actionContainers);
148                    TransitionTable ttable = (TransitionTable)getTransitionTableHandler().getSymbolTable("TRANS");
149                    sb.append(ttable.getSymbolCodeToString(transActionContainer.getActionCode()));
150                    for (int i = 0; i < arcLabelActionContainers.length; i++) {
151                            if (arcLabelActionContainers[i].getActionCode() != -1) {
152                                    sb.append(' ');
153                                    sb.append(arcLabelActionContainers[i].getTable().getSymbolCodeToString(arcLabelActionContainers[i].getActionCode()));
154                            }
155                    }
156                    return sb.toString();
157            }
158    }