<commit_before>/*
 * Created on 04.des.2005
 *
 * Copyright (c) 2005, <NAME> <<EMAIL> near strategoxt.org>
 *
 * Licensed under the GNU Lesser General Public License, v2.1
 */
package org.spoofax.jsglr.client;

import static java.util.Arrays.asList;
import static org.spoofax.terms.Term.*;
import static org.spoofax.terms.util.TermUtils.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.*;

import org.apache.commons.vfs2.FileObject;
import org.metaborg.parsetable.IParseTable;
import org.metaborg.parsetable.IParseTableGenerator;
import org.metaborg.util.log.ILogger;
import org.metaborg.util.log.LoggerUtils;
import org.spoofax.interpreter.terms.*;
import org.spoofax.jsglr.client.imploder.ProductionAttributeReader;
import org.spoofax.jsglr.client.imploder.TreeBuilder;
import org.spoofax.jsglr.io.ParseTableManager;
import org.spoofax.jsglr.io.SGLR;
import org.spoofax.jsglr.shared.SGLRException;
import org.spoofax.terms.ParseError;
import org.spoofax.terms.Term;
import org.spoofax.terms.TermFactory;
import org.spoofax.terms.util.NotImplementedException;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;

/**
 * A parse table.
 * 
 * Can (should!) be shared by multiple parser instances.
 */
public class ParseTable implements Serializable {

    public static final int LABEL_BASE = 257;

    private static final ILogger logger = LoggerUtils.logger(ParseTable.class);

    private static final long serialVersionUID = -3372429249660900093L;

    private final IParseTableGenerator ptGenerator;

    private static SGLR layoutParser;

    private int version;

    private State[] states;

    private int startState;

    private Label[] labels;

    private Priority[] priorities;

    private Associativity[] associativities;

    private final SetMultimap<Integer, Integer> nonAssocProductionLabels = HashMultimap.create();
    private final SetMultimap<Integer, Integer> nonNestedProductionLabels = HashMultimap.create();
    private final SetMultimap<String, String> nonAssocProductions = HashMultimap.create();
    private final SetMultimap<String, String> nonNestedProductions = HashMultimap.create();

    private boolean hasRejects;

    private boolean hasAvoids;

    private boolean hasPrefers;

    private boolean hasRecovers;

    transient private ITermFactory factory;

    transient public IStrategoConstructor applIStrategoConstructor;

    transient public IStrategoConstructor ambIStrategoConstructor;

    private Label[] injections;

    // TODO: allocate prototypes to avoid measurable GC overhead in ParseTable construction
    // (especially when using the CMS garbage collector, those gotos and stuff
    // introduce a lot of overhead)

    private transient HashMap<Goto, Goto> gotoCache = new HashMap<Goto, Goto>();

    private transient HashMap<Shift, Shift> shiftCache = new HashMap<Shift, Shift>();

    private transient HashMap<Reduce, Reduce> reduceCache = new HashMap<Reduce, Reduce>();

    private transient HashMap<RangeList, RangeList> rangesCache = new HashMap<RangeList, RangeList>();

    private transient Map<Label, List<Priority>> priorityCache;

    private transient IKeywordRecognizer keywords;

    private boolean dynamicPTgeneration = false;

    public ParseTable(IStrategoTerm pt, ITermFactory factory) throws InvalidParseTableException {
        initTransientData(factory);
        parse(pt);
        ptGenerator = null;

        if(states.length == 0) {
            throw new InvalidParseTableException(
                "Parse table does not contain any state and normalized grammar is null");
        }
    }

    public ParseTable(IStrategoTerm pt, ITermFactory factory, FileObject persistedTable,
        IParseTableGenerator ptGenerator) throws Exception {
        // N.B. This is _not_ code duplication with the InputStream variant constructor, because that
        //      variant doesn't _close_ the stream. So opening it here and calling the other constructor
        //      will lead to a dangling open stream!
        initTransientData(factory);
        parse(pt);
        if(states.length == 0) {
            dynamicPTgeneration = true;
        }

        if(dynamicPTgeneration && persistedTable != null) {
            this.ptGenerator = ptGenerator;
            gotoCache = new HashMap<Goto, Goto>();
            shiftCache = new HashMap<Shift, Shift>();
            reduceCache = new HashMap<Reduce, Reduce>();
            rangesCache = new HashMap<RangeList, RangeList>();
        } else {
            this.ptGenerator = null;
        }

        if(dynamicPTgeneration && persistedTable == null) {
            throw new InvalidParseTableException(
                "Parse table does not contain any state and normalized grammar is null");
        }
    }

    public ParseTable(IStrategoTerm pt, ITermFactory factory, InputStream persistedTable,
        IParseTableGenerator ptGenerator) throws Exception {
        initTransientData(factory);
        parse(pt);
        if(states.length == 0) {
            dynamicPTgeneration = true;
        }

        if(dynamicPTgeneration && persistedTable != null) {
            this.ptGenerator = ptGenerator;
            gotoCache = new HashMap<Goto, Goto>();
            shiftCache = new HashMap<Shift, Shift>();
            reduceCache = new HashMap<Reduce, Reduce>();
            rangesCache = new HashMap<RangeList, RangeList>();

        } else {
            this.ptGenerator = null;
        }

        if(dynamicPTgeneration && persistedTable == null) {
            throw new InvalidParseTableException(
                "Parse table does not contain any state and normalized grammar is null");
        }
    }

    public ParseTable(IStrategoTerm pt, ITermFactory factory, FileObject persistedTable, IParseTable referencePt,
        IParseTableGenerator ptGenerator, IStrategoTerm parseTableAterm) throws Exception {
        initTransientData(factory);<commit_msg>Remove superfluous FileObject parameter to ParseTable constructor<commit_after>/*
 * Created on 04.des.2005
 *
 * Copyright (c) 2005, <NAME> <karltk near strategoxt.org>
 *
 * Licensed under the GNU Lesser General Public License, v2.1
 */
package org.spoofax.jsglr.client;

import static java.util.Arrays.asList;
import static org.spoofax.terms.Term.*;
import static org.spoofax.terms.util.TermUtils.*;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.*;

import org.apache.commons.vfs2.FileObject;
import org.metaborg.parsetable.IParseTable;
import org.metaborg.parsetable.IParseTableGenerator;
import org.metaborg.util.log.ILogger;
import org.metaborg.util.log.LoggerUtils;
import org.spoofax.interpreter.terms.*;
import org.spoofax.jsglr.client.imploder.ProductionAttributeReader;
import org.spoofax.jsglr.client.imploder.TreeBuilder;
import org.spoofax.jsglr.io.ParseTableManager;
import org.spoofax.jsglr.io.SGLR;
import org.spoofax.jsglr.shared.SGLRException;
import org.spoofax.terms.ParseError;
import org.spoofax.terms.Term;
import org.spoofax.terms.TermFactory;
import org.spoofax.terms.util.NotImplementedException;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.SetMultimap;

/**
 * A parse table.
 * 
 * Can (should!) be shared by multiple parser instances.
 */
public class ParseTable implements Serializable {

    public static final int LABEL_BASE = 257;

    private static final ILogger logger = LoggerUtils.logger(ParseTable.class);

    private static final long serialVersionUID = -3372429249660900093L;

    private final IParseTableGenerator ptGenerator;

    private static SGLR layoutParser;

    private int version;

    private State[] states;

    private int startState;

    private Label[] labels;

    private Priority[] priorities;

    private Associativity[] associativities;

    private final SetMultimap<Integer, Integer> nonAssocProductionLabels = HashMultimap.create();
    private final SetMultimap<Integer, Integer> nonNestedProductionLabels = HashMultimap.create();
    private final SetMultimap<String, String> nonAssocProductions = HashMultimap.create();
    private final SetMultimap<String, String> nonNestedProductions = HashMultimap.create();

    private boolean hasRejects;

    private boolean hasAvoids;

    private boolean hasPrefers;

    private boolean hasRecovers;

    transient private ITermFactory factory;

    transient public IStrategoConstructor applIStrategoConstructor;

    transient public IStrategoConstructor ambIStrategoConstructor;

    private Label[] injections;

    // TODO: allocate prototypes to avoid measurable GC overhead in ParseTable construction
    // (especially when using the CMS garbage collector, those gotos and stuff
    // introduce a lot of overhead)

    private transient HashMap<Goto, Goto> gotoCache = new HashMap<Goto, Goto>();

    private transient HashMap<Shift, Shift> shiftCache = new HashMap<Shift, Shift>();

    private transient HashMap<Reduce, Reduce> reduceCache = new HashMap<Reduce, Reduce>();

    private transient HashMap<RangeList, RangeList> rangesCache = new HashMap<RangeList, RangeList>();

    private transient Map<Label, List<Priority>> priorityCache;

    private transient IKeywordRecognizer keywords;

    private boolean dynamicPTgeneration = false;

    public ParseTable(IStrategoTerm pt, ITermFactory factory) throws InvalidParseTableException {
        initTransientData(factory);
        parse(pt);
        ptGenerator = null;

        if(states.length == 0) {
            throw new InvalidParseTableException(
                "Parse table does not contain any state and normalized grammar is null");
        }
    }

    public ParseTable(IStrategoTerm pt, ITermFactory factory, IParseTableGenerator ptGenerator)
        throws InvalidParseTableException {
        initTransientData(factory);
        parse(pt);
        if(states.length == 0) {
            dynamicPTgeneration = true;
        }

        if(dynamicPTgeneration) {
            this.ptGenerator = ptGenerator;
            gotoCache = new HashMap<Goto, Goto>();
            shiftCache = new HashMap<Shift, Shift>();
            reduceCache = new HashMap<Reduce, Reduce>();
            rangesCache = new HashMap<RangeList, RangeList>();
        } else {
            this.ptGenerator = null;
        }
    }

    public ParseTable(IStrategoTerm pt, ITermFactory factory, FileObject persistedTable, IParseTable referencePt,
        IParseTableGenerator ptGenerator, IStrategoTerm parseTableAterm) throws Exception {
        initTransientData(factory);
{'fraction_non_alphanumeric': 0.08215218202163371, 'fraction_numerical': 0.006993659082431929, 'mean_word_length': 3.606958762886598, 'pattern_counts': {'":': 0, '<': 48, '<?xml version=': 0, '>': 48, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5562384', 'n_tokens_mistral': 3092, 'n_tokens_neox': 2862, 'n_words': 798}