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