All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.xbib.jacc.grammar.Machine Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
package org.xbib.jacc.grammar;

import org.xbib.jacc.util.BitSet;
import org.xbib.jacc.util.IntSet;
import org.xbib.jacc.util.Interator;

import java.io.IOException;
import java.io.Writer;

/**
 *
 */
public class Machine {

    private final IntSet acceptItems = IntSet.singleton(-1);
    protected Grammar grammar;
    protected int numNTs;
    protected int numTs;
    protected Left left;
    LR0Items items;
    int numStates;
    int[] entry;
    int[][] succState;
    private int numSyms;
    private IntSet[] stateSets;
    private IntSet[] nullReds;
    private int[][] gotos;
    private int[][] shifts;
    private int[][] reduceOffsets;

    Machine(Grammar grammar) {
        this.grammar = grammar;
        numSyms = grammar.getNumSyms();
        numNTs = grammar.getNumNTs();
        numTs = grammar.getNumTs();
        left = grammar.getLeft();
        items = new LR0Items(grammar);
        calcLR0states();
        calcGotosShifts();
        calcReduceOffsets();
    }

    public Grammar getGrammar() {
        return grammar;
    }

    public int getNumStates() {
        return numStates;
    }

    public LR0Items getItems() {
        return items;
    }

    public LR0Items.Item reduceItem(int i, int j) {
        return items.getItem(stateSets[i].at(j));
    }

    public int getEntry(int i) {
        return i >= 0 ? entry[i] : numSyms - 1;
    }

    public IntSet getItemsAt(int i) {
        return stateSets[i];
    }

    public int[] getGotosAt(int i) {
        return gotos[i];
    }

    public int[] getShiftsAt(int i) {
        return shifts[i];
    }

    int[] getReducesAt(int i) {
        return reduceOffsets[i];
    }

    private void calcLR0states() {
        stateSets = new IntSet[16];
        succState = new int[16][];
        entry = new int[16];
        nullReds = new IntSet[16];
        stateSets[0] = IntSet.singleton(items.getStartItem());
        numStates = 1;
        IntSet[] aintset = new IntSet[numSyms];
        int i = 0;
        int[] ai = BitSet.make(numNTs);
        for (int j = 0; j < numStates; j++) {
            IntSet intset = stateSets[j];
            BitSet.clear(ai);
            Interator interator = intset.interator();
            do {
                if (!interator.hasNext()) {
                    break;
                }
                LR0Items.Item item = items.getItem(interator.next());
                if (item.canGoto()) {
                    int k = item.getNextSym();
                    int i1 = item.getNextItem();
                    if (grammar.isNonterminal(k)) {
                        BitSet.addTo(ai, left.at(k));
                    }
                    if (addValue(aintset, k, i1)) {
                        i++;
                    }
                }
            } while (true);
            if (!BitSet.isEmpty(ai)) {
                for (Interator interator1 = BitSet.interator(ai, 0); interator1.hasNext(); ) {
                    int l = interator1.next();
                    Grammar.Prod[] aprod = grammar.getProds(l);
                    int k1 = 0;
                    while (k1 < aprod.length) {
                        int[] ai3 = aprod[k1].getRhs();
                        int i2 = items.getFirstKernel(l, k1);
                        if (ai3.length != 0) {
                            if (addValue(aintset, ai3[0], i2)) {
                                i++;
                            }
                        } else {
                            addValue(nullReds, j, i2);
                        }
                        k1++;
                    }
                }
            }
            int[] ai1 = new int[i];
            int j1 = 0;
            int l1 = 0;
            while (j1 < i) {
                if (aintset[l1] != null) {
                    ai1[j1] = addState(l1, aintset[l1]);
                    aintset[l1] = null;
                    j1++;
                }
                l1++;
            }
            i = 0;
            succState[j] = ai1;
        }
        mergeNullReds();
    }

    private boolean addValue(IntSet[] aintset, int i, int j) {
        if (aintset[i] == null) {
            aintset[i] = IntSet.singleton(j);
            return true;
        } else {
            aintset[i].add(j);
            return false;
        }
    }

    private int addState(int i, IntSet intset) {
        for (int j = 0; j < numStates; j++) {
            if (stateSets[j].equals(intset)) {
                return j;
            }
        }
        if (acceptItems.equals(intset)) {
            return -1;
        }
        if (numStates >= stateSets.length) {
            int k = 2 * stateSets.length;
            IntSet[] aintset = new IntSet[k];
            int[][] ai = new int[k][];
            IntSet[] aintset1 = new IntSet[k];
            int[] ai1 = new int[k];
            for (int l = 0; l < numStates; l++) {
                aintset[l] = stateSets[l];
                ai[l] = succState[l];
                ai1[l] = entry[l];
                aintset1[l] = nullReds[l];
            }
            stateSets = aintset;
            succState = ai;
            entry = ai1;
            nullReds = aintset1;
        }
        stateSets[numStates] = intset;
        entry[numStates] = i;
        return numStates++;
    }

    private void mergeNullReds() {
        for (int i = 0; i < numStates; i++) {
            if (nullReds[i] == null) {
                continue;
            }
            Interator interator = nullReds[i].interator();
            while (interator.hasNext()) {
                stateSets[i].add(interator.next());
            }
            nullReds[i] = null;
        }
    }

    private void calcGotosShifts() {
        gotos = new int[numStates][];
        shifts = new int[numStates][];
        for (int i = 0; i < numStates; i++) {
            int j = 0;
            int k = 0;
            for (int l = 0; l < succState[i].length; l++) {
                int j1 = succState[i][l];
                if (grammar.isTerminal(entry[j1])) {
                    k++;
                } else {
                    j++;
                }
            }
            if (stateSets[i].contains(items.getEndItem())) {
                k++;
            }
            gotos[i] = new int[j];
            shifts[i] = new int[k];
            for (int i1 = succState[i].length; 0 < i1--; ) {
                int k1 = succState[i][i1];
                if (grammar.isTerminal(entry[k1])) {
                    shifts[i][--k] = k1;
                } else {
                    gotos[i][--j] = k1;
                }
            }
            if (k > 0) {
                shifts[i][0] = -1;
            }
        }
    }

    private void calcReduceOffsets() {
        reduceOffsets = new int[numStates][];
        for (int i = 0; i < numStates; i++) {
            int j = 0;
            IntSet intset = stateSets[i];
            int k = intset.size();
            for (int l = 0; l < k; l++) {
                if (items.getItem(intset.at(l)).canReduce()) {
                    j++;
                }
            }
            reduceOffsets[i] = new int[j];
            int i1 = 0;
            for (int j1 = 0; j1 < k; j1++) {
                if (items.getItem(intset.at(j1)).canReduce()) {
                    reduceOffsets[i][i1++] = j1;
                }
            }
        }
    }

    public void display(Writer writer) throws IOException {
        for (int i = 0; i < numStates; i++) {
            writer.write("state " + i + "\n");
            for (Interator interator = stateSets[i].interator(); interator.hasNext(); writer.write("\n")) {
                writer.write("\t");
                items.getItem(interator.next()).display(writer);
            }
            writer.write("\n");
            if (succState[i].length <= 0) {
                continue;
            }
            for (int j = 0; j < succState[i].length; j++) {
                int k = succState[i][j];
                writer.write("\t" + grammar.getSymbol(entry[k]) + " goto " + succState[i][j] + "\n");
            }
            writer.write("\n");
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy