001    package org.maltparser.parser.algorithm.nivre.malt04;
002    
003    
004    
005    import org.maltparser.core.exception.MaltChainedException;
006    import org.maltparser.core.syntaxgraph.DependencyStructure;
007    import org.maltparser.core.syntaxgraph.LabelSet;
008    import org.maltparser.core.syntaxgraph.edge.Edge;
009    
010    import org.maltparser.parser.SingleMalt;
011    import org.maltparser.parser.algorithm.helper.TransitionTable;
012    import org.maltparser.parser.history.container.ActionContainer;
013    
014    /**
015     * 
016     * @author Joakim Nivre
017     * @author Johan Hall
018     * @since 1.0
019    */
020    public class NivreStandardMalt04 extends NivreMalt04 {
021            protected static final int REDUCE = 2;
022            protected static final int RIGHTARC = 3;
023            protected static final int LEFTARC = 4;
024            
025            public NivreStandardMalt04(SingleMalt configuration) throws MaltChainedException {
026                    super(configuration);
027            }
028            
029            protected void transition(DependencyStructure parseDependencyGraph) throws MaltChainedException {
030                    currentAction.getAction(actionContainers);
031                    if (checkParserAction(parseDependencyGraph) == false) {
032                            updateActionContainers(SHIFT, null); // default parser action
033                    }
034                    Edge e = null;
035                    switch (transActionContainer.getActionCode()) {
036                    case LEFTARC:
037                            e = parseDependencyGraph.addDependencyEdge(input.peek().getIndex(), stack.peek().getIndex());
038                            addEdgeLabels(e);
039                            stack.pop();
040                            break;
041                    case RIGHTARC:
042                            e = parseDependencyGraph.addDependencyEdge(stack.peek().getIndex(), input.peek().getIndex());
043                            addEdgeLabels(e);
044                            input.pop();
045                            if (!stack.peek().isRoot()) {
046                                    input.push(stack.pop());        
047                            }
048                            break;
049                    default:
050                            stack.push(input.pop()); // SHIFT
051                            break;
052                    }
053            }
054            
055            protected boolean checkParserAction(DependencyStructure parseDependencyGraph) throws MaltChainedException {
056                    int trans = transActionContainer.getActionCode();
057                    if ((trans == LEFTARC || trans == RIGHTARC) && !isActionContainersLabeled()) {
058                            // Label code is null for transitions LEFTARC and RIGHTARC
059                            return false;
060                    }
061                    /* if (trans == SHIFT && parserAction.getLastLabelCode() != null) {
062                            // Label code is not null for transition SHIFT
063                    }*/
064                    if (trans == LEFTARC && stack.peek().isRoot()) { 
065                            // The token on top of the stack is root for transition LEFTARC
066                            return false;
067                    }
068                    return true;
069            }
070    
071            
072            protected void oraclePredict(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException {
073                    if (!stack.peek().isRoot() && gold.getTokenNode(stack.peek().getIndex()).getHead().getIndex() == input.peek().getIndex()) {
074                            updateActionContainers(LEFTARC, gold.getTokenNode(stack.peek().getIndex()).getHeadEdge().getLabelSet());
075                    } else if (gold.getTokenNode(input.peek().getIndex()).getHead().getIndex() == stack.peek().getIndex() && checkRightDependent(gold, parseDependencyGraph)) {
076                            updateActionContainers(RIGHTARC, gold.getTokenNode(input.peek().getIndex()).getHeadEdge().getLabelSet());
077                    } else {
078                            updateActionContainers(SHIFT, null);
079                    }
080            }
081    
082            private boolean checkRightDependent(DependencyStructure gold, DependencyStructure parseDependencyGraph) throws MaltChainedException {
083                    if (gold.getTokenNode(input.peek().getIndex()).getRightmostDependent() == null) {
084                            return true;
085                    } else if (parseDependencyGraph.getTokenNode(input.peek().getIndex()).getRightmostDependent() != null) {
086                            if (gold.getTokenNode(input.peek().getIndex()).getRightmostDependent().getIndex() == parseDependencyGraph.getTokenNode(input.peek().getIndex()).getRightmostDependent().getIndex()) {
087                                    return true;
088                            }
089                    }
090                    return false;
091            }
092            
093            protected int getTransition() {
094                    return transActionContainer.getActionCode();
095            }
096            
097            protected void updateActionContainers(int transition, LabelSet arcLabels) throws MaltChainedException {
098                    transActionContainer.setAction(transition);
099                    if (arcLabels == null) {
100                            for (ActionContainer container : arcLabelActionContainers) {
101                                    container.setAction(-1);
102                            }
103                    } else {
104                            for (ActionContainer container : arcLabelActionContainers) {
105                                    container.setAction(arcLabels.get(container.getTable()).shortValue());
106                            }               
107                    }
108                    currentAction.addAction(actionContainers);
109            }
110            
111            public String getName() {
112                    return "nivrestandard";
113            }
114            
115            protected void addAvailableTransitionToTable(TransitionTable ttable) throws MaltChainedException {
116                    ttable.addTransition(SHIFT, "SH", false, null);
117                    ttable.addTransition(REDUCE, "RE", false, null);
118                    ttable.addTransition(RIGHTARC, "RA", true, null);
119                    ttable.addTransition(LEFTARC, "LA", true, null);
120            }
121            
122            protected void initWithDefaultTransitions() throws MaltChainedException {
123                    addTransition(transActionContainer, currentAction, SHIFT);
124                    addTransition(transActionContainer, currentAction, REDUCE);
125                    deprel = configuration.getSymbolTables().getSymbolTable("DEPREL");
126                    for (int i = 1; i < deprel.getValueCounter(); i++) {
127                            if (!getConfiguration().getOptionValue("graph", "root_label").toString().equals(deprel.getSymbolCodeToString(i))) {
128                                    actionContainers.get(0).setAction(RIGHTARC);
129                                    actionContainers.get(1).setAction(i);
130                                    currentAction.addAction(actionContainers);
131                            }
132                    }
133                    for (int i = 1; i < deprel.getValueCounter(); i++) {
134                            if (!getConfiguration().getOptionValue("graph", "root_label").toString().equals(deprel.getSymbolCodeToString(i))) {
135                                    actionContainers.get(0).setAction(LEFTARC);
136                                    actionContainers.get(1).setAction(i);
137                                    currentAction.addAction(actionContainers);
138                            }
139                    }
140            }
141    }