/* * [The "BSD license"] * Copyright (c) 2010 Terence Parr * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package org.antlr.analysis; import org.antlr.misc.OrderedHashSet; import org.antlr.misc.Utils; import org.antlr.runtime.Token; import org.antlr.tool.ErrorManager; import java.util.*; /** Code that embodies the NFA conversion to DFA. A new object is needed * per DFA (also required for thread safety if multiple conversions * launched). */ public class NFAToDFAConverter { /** A list of DFA states we still need to process during NFA conversion */ protected List work = new LinkedList(); /** While converting NFA, we must track states that * reference other rule's NFAs so we know what to do * at the end of a rule. We need to know what context invoked * this rule so we can know where to continue looking for NFA * states. I'm tracking a context tree (record of rule invocation * stack trace) for each alternative that could be predicted. */ protected NFAContext[] contextTrees; /** We are converting which DFA? */ protected DFA dfa; public static boolean debug = false; /** Should ANTLR launch multiple threads to convert NFAs to DFAs? * With a 2-CPU box, I note that it's about the same single or * multithreaded. Both CPU meters are going even when single-threaded * so I assume the GC is killing us. Could be the compiler. When I * run java -Xint mode, I get about 15% speed improvement with multiple * threads. */ public static boolean SINGLE_THREADED_NFA_CONVERSION = true; protected boolean computingStartState = false; public NFAToDFAConverter(DFA dfa) { this.dfa = dfa; int nAlts = dfa.getNumberOfAlts(); initContextTrees(nAlts); } public void convert() { //dfa.conversionStartTime = System.currentTimeMillis(); // create the DFA start state dfa.startState = computeStartState(); // while more DFA states to check, process them while ( work.size()>0 && !dfa.nfa.grammar.NFAToDFAConversionExternallyAborted() ) { DFAState d = (DFAState) work.get(0); if ( dfa.nfa.grammar.composite.watchNFAConversion ) { System.out.println("convert DFA state "+d.stateNumber+ " ("+d.nfaConfigurations.size()+" nfa states)"); } int k = dfa.getUserMaxLookahead(); if ( k>0 && k==d.getLookaheadDepth() ) { // we've hit max lookahead, make this a stop state //System.out.println("stop state @k="+k+" (terminated early)"); /* List