/* * Created on 04.des.2005 * * Copyright (c) 2005, Karl Trygve Kalleberg * * Licensed under the GNU Lesser General Public License, v2.1 */ package org.spoofax.jsglr; import java.io.Serializable; import java.util.ArrayList; import java.util.List; public class State implements Serializable { static final long serialVersionUID = 3383369639779986307L; private static final int CHAR_RANGE = -1; private static final int FULL_RANGE = -2; public final int stateNumber; private final Goto[] gotos; private final int[] gotoDescriptors; private final Action[] actions; public State(int stateNumber, Goto[] gotos, Action[] actions) { this.stateNumber = stateNumber; this.gotos = gotos; this.actions = actions; this.gotoDescriptors = createGotoDescriptor(gotos); } private static final int[] createGotoDescriptor(Goto[] gotos) { int[] results = new int[gotos.length]; for (int i = 0; i < gotos.length; i++) { RangeList range = gotos[i].getRanges(); if (range.getSingularRange() >= 0) { results[i] = range.getSingularRange(); } else if (range.getLastRangeElement() < ParseTable.NUM_CHARS) { results[i] = CHAR_RANGE; } else { results[i] = FULL_RANGE; } } return results; } /** * @deprecated Use getActions() instead. */ @Deprecated public List getActionItems(int currentToken) { List ret = new ArrayList(); for(Action a : actions) { if(a.accepts(currentToken)) for(ActionItem it : a.getActionItems()) ret.add(it); } return ret; } public Action[] getActions() { return actions; } /** * @return The single action associated with this state, or null if not applicable. */ public Action getSingularAction() { return actions.length == 1 ? actions[0] : null; } public int go(int labelNumber) { int[] descriptors = gotoDescriptors; for (int i = 0; i < descriptors.length; i++) { int descriptor = descriptors[i]; switch (descriptor) { case CHAR_RANGE: if (labelNumber >= ParseTable.NUM_CHARS) break; case FULL_RANGE: Goto go = gotos[i]; if (go.hasProd(labelNumber)) return go.nextState; break; default: if (descriptor == labelNumber) return gotos[i].nextState; } } return -1; } public boolean rejectable() { for(Action a : actions) { if(a.rejectable()) return true; } return false; } public int getActionItemCount() { int total = 0; for(Action a : actions) { total += a.getActionItems().length; } return total; } public int getGotoCount() { return gotos.length; } public int getActionCount() { return actions.length; } public boolean hasPrefer() { for(Action a : actions) { if (a.hasPrefer()) return true; } return false; } public boolean hasAvoid() { for(Action a : actions) { if (a.hasAvoid()) return true; } return false; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("State("); sb.append(stateNumber); sb.append(", #"); sb.append(actions.length); sb.append(" actions, #"); sb.append(gotos.length); sb.append(" gotos)"); sb.append("\n - ["); for(int i=0;i