13447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/*
23447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein [The "BSD license"]
33447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein Copyright (c) 2005-2009 Terence Parr
43447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein All rights reserved.
53447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
63447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein Redistribution and use in source and binary forms, with or without
73447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein modification, are permitted provided that the following conditions
83447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein are met:
93447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 1. Redistributions of source code must retain the above copyright
103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     notice, this list of conditions and the following disclaimer.
113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 2. Redistributions in binary form must reproduce the above copyright
123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     notice, this list of conditions and the following disclaimer in the
133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     documentation and/or other materials provided with the distribution.
143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein 3. The name of the author may not be used to endorse or promote products
153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein     derived from this software without specific prior written permission.
163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinpackage org.antlr.runtime.debug;
293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport org.antlr.runtime.*;
313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport org.antlr.runtime.misc.DoubleKeyMap;
323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinimport java.util.*;
343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein/** Using the debug event interface, track what is happening in the parser
363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein *  and record statistics about the runtime.
373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein */
383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sappersteinpublic class Profiler extends BlankDebugEventListener {
393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final String DATA_SEP = "\t";
403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final String newline = System.getProperty("line.separator");
413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	static boolean dump = false;
433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static class ProfileStats {
453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public String Version;
463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public String name;
473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numRuleInvocations;
483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numUniqueRulesInvoked;
493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numDecisionEvents;
503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numDecisionsCovered;
513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numDecisionsThatPotentiallyBacktrack;
523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numDecisionsThatDoBacktrack;
533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int maxRuleInvocationDepth;
543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public float avgkPerDecisionEvent;
553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public float avgkPerBacktrackingDecisionEvent;
563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public float averageDecisionPercentBacktracks;
573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numBacktrackOccurrences; // doesn't count gated DFA edges
583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numFixedDecisions;
603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int minDecisionMaxFixedLookaheads;
613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int maxDecisionMaxFixedLookaheads;
623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int avgDecisionMaxFixedLookaheads;
633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int stddevDecisionMaxFixedLookaheads;
643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numCyclicDecisions;
653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int minDecisionMaxCyclicLookaheads;
663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int maxDecisionMaxCyclicLookaheads;
673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int avgDecisionMaxCyclicLookaheads;
683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int stddevDecisionMaxCyclicLookaheads;
693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		int Stats.min(toArray(decisionMaxSynPredLookaheads);
703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		int Stats.max(toArray(decisionMaxSynPredLookaheads);
713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		int Stats.avg(toArray(decisionMaxSynPredLookaheads);
723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		int Stats.stddev(toArray(decisionMaxSynPredLookaheads);
733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numSemanticPredicates;
743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numTokens;
753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numHiddenTokens;
763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numCharsMatched;
773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numHiddenCharsMatched;
783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numReportedErrors;
793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numMemoizationCacheHits;
803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numMemoizationCacheMisses;
813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numGuessingRuleInvocations;
823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numMemoizationCacheEntries;
833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static class DecisionDescriptor {
863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int decision;
873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public String fileName;
883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public String ruleName;
893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int line;
903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int pos;
913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public boolean couldBacktrack;
923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int n;
943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public float avgk; // avg across all decision events
953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int maxk;
963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numBacktrackOccurrences;
973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numSemPredEvals;
983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// all about a specific exec of a single decision
1013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static class DecisionEvent {
1023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public DecisionDescriptor decision;
1033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int startIndex;
1043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int k;
1053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public boolean backtracks; // doesn't count gated DFA edges
1063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public boolean evalSemPred;
1073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public long startTime;
1083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public long stopTime;
1093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numMemoizationCacheHits;
1103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		public int numMemoizationCacheMisses;
1113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Because I may change the stats, I need to track that for later
1143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  computations to be consistent.
1153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final String Version = "3";
1173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static final String RUNTIME_STATS_FILENAME = "runtime.stats";
1183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Ack, should not store parser; can't do remote stuff.  Well, we pass
1203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  input stream around too so I guess it's ok.
1213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public DebugParser parser = null;
1233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// working variables
1253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int ruleLevel = 0;
1273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	//protected int decisionLevel = 0;
1283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Token lastRealTokenTouchedInDecision;
1293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Set<String> uniqueRules = new HashSet<String>();
1303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Stack<String> currentGrammarFileName = new Stack();
1313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Stack<String> currentRuleName = new Stack();
1323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Stack<Integer> currentLine = new Stack();
1333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Stack<Integer> currentPos = new Stack();
1343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// Vector<DecisionStats>
1363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	//protected Vector decisions = new Vector(200); // need setSize
1373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected DoubleKeyMap<String,Integer, DecisionDescriptor> decisions =
1383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		new DoubleKeyMap<String,Integer, DecisionDescriptor>();
1393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// Record a DecisionData for each decision we hit while parsing
1413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected List<DecisionEvent> decisionEvents = new ArrayList<DecisionEvent>();
1423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected Stack<DecisionEvent> decisionStack = new Stack<DecisionEvent>();
1433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int backtrackDepth;
1453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	ProfileStats stats = new ProfileStats();
1473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Profiler() {
1493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public Profiler(DebugParser parser) {
1523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.parser = parser;
1533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void enterRule(String grammarFileName, String ruleName) {
1563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		System.out.println("enterRule "+grammarFileName+":"+ruleName);
1573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		ruleLevel++;
1583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numRuleInvocations++;
1593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		uniqueRules.add(grammarFileName+":"+ruleName);
1603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.maxRuleInvocationDepth = Math.max(stats.maxRuleInvocationDepth, ruleLevel);
1613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentGrammarFileName.push( grammarFileName );
1623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentRuleName.push( ruleName );
1633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void exitRule(String grammarFileName, String ruleName) {
1663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		ruleLevel--;
1673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentGrammarFileName.pop();
1683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentRuleName.pop();
1693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Track memoization; this is not part of standard debug interface
1723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  but is triggered by profiling.  Code gen inserts an override
1733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  for this method in the recognizer, which triggers this method.
1743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  Called from alreadyParsedRule().
1753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
1763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void examineRuleMemoization(IntStream input,
1773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein									   int ruleIndex,
1783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein									   int stopIndex, // index or MEMO_RULE_UNKNOWN...
1793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein									   String ruleName)
1803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	{
1813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("examine memo "+ruleName+" at "+input.index()+": "+stopIndex);
1823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( stopIndex==BaseRecognizer.MEMO_RULE_UNKNOWN ) {
1833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			//System.out.println("rule "+ruleIndex+" missed @ "+input.index());
1843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numMemoizationCacheMisses++;
1853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numGuessingRuleInvocations++; // we'll have to enter
1863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentDecision().numMemoizationCacheMisses++;
1873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		else {
1893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			// regardless of rule success/failure, if in cache, we have a cache hit
1903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			//System.out.println("rule "+ruleIndex+" hit @ "+input.index());
1913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numMemoizationCacheHits++;
1923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentDecision().numMemoizationCacheHits++;
1933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
1943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
1953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
1963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Warning: doesn't track success/failure, just unique recording event */
1973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void memoize(IntStream input,
1983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						int ruleIndex,
1993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						int ruleStartIndex,
2003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						String ruleName)
2013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	{
2023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// count how many entries go into table
2033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("memoize "+ruleName);
2043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numMemoizationCacheEntries++;
2053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	@Override
2083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void location(int line, int pos) {
2093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentLine.push(line);
2103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		currentPos.push(pos);
2113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void enterDecision(int decisionNumber, boolean couldBacktrack) {
2143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		lastRealTokenTouchedInDecision = null;
2153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numDecisionEvents++;
2163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int startingLookaheadIndex = parser.getTokenStream().index();
2173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		TokenStream input = parser.getTokenStream();
2183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( dump ) System.out.println("enterDecision canBacktrack="+couldBacktrack+" "+ decisionNumber +
2193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						   " backtrack depth " + backtrackDepth +
2203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						   " @ " + input.get(input.index()) +
2213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						   " rule " +locationDescription());
2223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		String g = (String) currentGrammarFileName.peek();
2233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		DecisionDescriptor descriptor = decisions.get(g, decisionNumber);
2243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( descriptor == null ) {
2253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor = new DecisionDescriptor();
2263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			decisions.put(g, decisionNumber, descriptor);
2273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.decision = decisionNumber;
2283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.fileName = (String)currentGrammarFileName.peek();
2293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.ruleName = (String)currentRuleName.peek();
2303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.line = (Integer)currentLine.peek();
2313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.pos = (Integer)currentPos.peek();
2323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			descriptor.couldBacktrack = couldBacktrack;
2333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		descriptor.n++;
2353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		DecisionEvent d = new DecisionEvent();
2373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		decisionStack.push(d);
2383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.decision = descriptor;
2393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.startTime = System.currentTimeMillis();
2403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.startIndex = startingLookaheadIndex;
2413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void exitDecision(int decisionNumber) {
2443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		DecisionEvent d = decisionStack.pop();
2453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.stopTime = System.currentTimeMillis();
2463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int lastTokenIndex = lastRealTokenTouchedInDecision.getTokenIndex();
2483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int numHidden = getNumberOfHiddenTokens(d.startIndex, lastTokenIndex);
2493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int depth = lastTokenIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
2503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.k = depth;
2513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		d.decision.maxk = Math.max(d.decision.maxk, depth);
2523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("exitDecision "+decisionNumber+" in "+d.decision.ruleName+
2543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						   " lookahead "+d.k +" max token "+lastRealTokenTouchedInDecision);
2553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		decisionEvents.add(d); // done with decision; track all
2563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void consumeToken(Token token) {
2593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("consume token "+token);
2603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( !inDecision() ) {
2613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numTokens++;
2623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			return;
2633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( lastRealTokenTouchedInDecision==null ||
2653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			 lastRealTokenTouchedInDecision.getTokenIndex() < token.getTokenIndex() )
2663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		{
2673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			lastRealTokenTouchedInDecision = token;
2683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
2693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		DecisionEvent d = currentDecision();
2703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		// compute lookahead depth
2713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int thisRefIndex = token.getTokenIndex();
2723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int numHidden = getNumberOfHiddenTokens(d.startIndex, thisRefIndex);
2733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int depth = thisRefIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
2743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//d.maxk = Math.max(d.maxk, depth);
2753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("consume "+thisRefIndex+" "+depth+" tokens ahead in "+
2763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein						   d.decision.ruleName+"-"+d.decision.decision+" start index "+d.startIndex);
2773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** The parser is in a decision if the decision depth > 0.  This
2803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  works for backtracking also, which can have nested decisions.
2813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
2823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public boolean inDecision() {
2833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return decisionStack.size()>0;
2843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void consumeHiddenToken(Token token) {
2873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//System.out.println("consume hidden token "+token);
2883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( !inDecision() ) stats.numHiddenTokens++;
2893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
2903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
2913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Track refs to lookahead if in a fixed/nonfixed decision.
2923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
2933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void LT(int i, Token t) {
2943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( inDecision() && i>0 ) {
2953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			DecisionEvent d = currentDecision();
2963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if (dump) System.out.println("LT("+i+")="+t+" index "+t.getTokenIndex()+" relative to "+d.decision.ruleName+"-"+
2973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein							   d.decision.decision+" start index "+d.startIndex);
2983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( lastRealTokenTouchedInDecision==null ||
2993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				 lastRealTokenTouchedInDecision.getTokenIndex() < t.getTokenIndex() )
3003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			{
3013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				lastRealTokenTouchedInDecision = t;
3023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				if (dump) System.out.println("set last token "+lastRealTokenTouchedInDecision);
3033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
3043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			// get starting index off stack
3053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			int stackTop = lookaheadStack.size()-1;
3063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			Integer startingIndex = (Integer)lookaheadStack.get(stackTop);
3073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			// compute lookahead depth
3083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			int thisRefIndex = parser.getTokenStream().index();
3093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			int numHidden =
3103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//				getNumberOfHiddenTokens(startingIndex.intValue(), thisRefIndex);
3113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			int depth = i + thisRefIndex - startingIndex.intValue() - numHidden;
3123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			/*
3133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			System.out.println("LT("+i+") @ index "+thisRefIndex+" is depth "+depth+
3143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//				" max is "+maxLookaheadInCurrentDecision);
3153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			*/
3163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			if ( depth>maxLookaheadInCurrentDecision ) {
3173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//				maxLookaheadInCurrentDecision = depth;
3183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			}
3193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			d.maxk = currentDecision()/
3203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Track backtracking decisions.  You'll see a fixed or cyclic decision
3243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *  and then a backtrack.
3253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 *
3263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		enter rule
3273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		...
3283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		enter decision
3293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		LA and possibly consumes (for cyclic DFAs)
3303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		begin backtrack level
3313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		mark m
3323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		rewind m
3333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		end backtrack level, success
3343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		exit decision
3353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		...
3363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 * 		exit rule
3373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	 */
3383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void beginBacktrack(int level) {
3393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("enter backtrack "+level);
3403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		backtrackDepth++;
3413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		DecisionEvent e = currentDecision();
3423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( e.decision.couldBacktrack ) {
3433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numBacktrackOccurrences++;
3443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			e.decision.numBacktrackOccurrences++;
3453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			e.backtracks = true;
3463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Successful or not, track how much lookahead synpreds use */
3503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void endBacktrack(int level, boolean successful) {
3513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("exit backtrack "+level+": "+successful);
3523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		backtrackDepth--;
3533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	@Override
3563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void mark(int i) {
3573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("mark "+i);
3583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	@Override
3613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void rewind(int i) {
3623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("rewind "+i);
3633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	@Override
3663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void rewind() {
3673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if (dump) System.out.println("rewind");
3683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected DecisionEvent currentDecision() {
3733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return decisionStack.peek();
3743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void recognitionException(RecognitionException e) {
3773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numReportedErrors++;
3783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void semanticPredicate(boolean result, String predicate) {
3813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numSemanticPredicates++;
3823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( inDecision() ) {
3833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			DecisionEvent d = currentDecision();
3843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			d.evalSemPred = true;
3853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			d.decision.numSemPredEvals++;
3863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if (dump) System.out.println("eval "+predicate+" in "+d.decision.ruleName+"-"+
3873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein							   d.decision.decision);
3883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
3893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
3903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
3913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void terminate() {
3923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (DecisionEvent e : decisionEvents) {
3933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			//System.out.println("decision "+e.decision.decision+": k="+e.k);
3943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			e.decision.avgk += e.k;
3953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.avgkPerDecisionEvent += e.k;
3963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( e.backtracks ) { // doesn't count gated syn preds on DFA edges
3973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				stats.avgkPerBacktrackingDecisionEvent += e.k;
3983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
3993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.averageDecisionPercentBacktracks = 0.0f;
4013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (DecisionDescriptor d : decisions.values()) {
4023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			stats.numDecisionsCovered++;
4033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			d.avgk /= (double)d.n;
4043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( d.couldBacktrack ) {
4053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				stats.numDecisionsThatPotentiallyBacktrack++;
4063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				float percentBacktracks = d.numBacktrackOccurrences / (float)d.n;
4073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				//System.out.println("dec "+d.decision+" backtracks "+percentBacktracks*100+"%");
4083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				stats.averageDecisionPercentBacktracks += percentBacktracks;
4093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			// ignore rules that backtrack along gated DFA edges
4113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( d.numBacktrackOccurrences > 0 ) {
4123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				stats.numDecisionsThatDoBacktrack++;
4133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
4143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
4153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.averageDecisionPercentBacktracks /= stats.numDecisionsThatPotentiallyBacktrack;
4163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.averageDecisionPercentBacktracks *= 100; // it's a percentage
4173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.avgkPerDecisionEvent /= stats.numDecisionEvents;
4183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.avgkPerBacktrackingDecisionEvent /= (double)stats.numBacktrackOccurrences;
4193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		System.err.println(toString());
4213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		System.err.println(getDecisionStatsDump());
4223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		String stats = toNotifyString();
4243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		try {
4253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			Stats.writeReport(RUNTIME_STATS_FILENAME,stats);
4263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		}
4273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		catch (IOException ioe) {
4283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			System.err.println(ioe);
4293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			ioe.printStackTrace(System.err);
4303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		}
4313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
4323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public void setParser(DebugParser parser) {
4343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		this.parser = parser;
4353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
4363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	// R E P O R T I N G
4383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
4393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String toNotifyString() {
4403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		StringBuffer buf = new StringBuffer();
4413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(Version);
4423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append('\t');
4433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(parser.getClass().getName());
4443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numRuleInvocations);
4463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(maxRuleInvocationDepth);
4483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numFixedDecisions);
4503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.min(decisionMaxFixedLookaheads));
4523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.max(decisionMaxFixedLookaheads));
4543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.avg(decisionMaxFixedLookaheads));
4563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.stddev(decisionMaxFixedLookaheads));
4583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numCyclicDecisions);
4603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.min(decisionMaxCyclicLookaheads));
4623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.max(decisionMaxCyclicLookaheads));
4643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.avg(decisionMaxCyclicLookaheads));
4663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.stddev(decisionMaxCyclicLookaheads));
4683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numBacktrackDecisions);
4703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.min(toArray(decisionMaxSynPredLookaheads)));
4723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.max(toArray(decisionMaxSynPredLookaheads)));
4743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.avg(toArray(decisionMaxSynPredLookaheads)));
4763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(Stats.stddev(toArray(decisionMaxSynPredLookaheads)));
4783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numSemanticPredicates);
4803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(parser.getTokenStream().size());
4823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numHiddenTokens);
4843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numCharsMatched);
4863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numHiddenCharsMatched);
4883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numberReportedErrors);
4903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numMemoizationCacheHits);
4923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numMemoizationCacheMisses);
4943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numGuessingRuleInvocations);
4963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\t');
4973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(numMemoizationCacheEntries);
4983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
4993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
5003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String toString() {
5023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return toString(getReport());
5033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
5043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public ProfileStats getReport() {
5063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		TokenStream input = parser.getTokenStream();
5073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		for (int i=0; i<input.size()&& lastRealTokenTouchedInDecision !=null&&i<= lastRealTokenTouchedInDecision.getTokenIndex(); i++) {
5083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			Token t = input.get(i);
5093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
5103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//				stats.numHiddenTokens++;
5113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//				stats.numHiddenCharsMatched += t.getText().length();
5123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//			}
5133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		}
5143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.Version = Version;
5153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.name = parser.getClass().getName();
5163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		stats.numUniqueRulesInvoked = uniqueRules.size();
5173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		//stats.numCharsMatched = lastTokenConsumed.getStopIndex() + 1;
5183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return stats;
5193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
5203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public DoubleKeyMap getDecisionStats() {
5223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return decisions;
5233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
5243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public List getDecisionEvents() {
5263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return decisionEvents;
5273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
5283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public static String toString(ProfileStats stats) {
5303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		StringBuffer buf = new StringBuffer();
5313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("ANTLR Runtime Report; Profile Version ");
5323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.Version);
5333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("parser name ");
5353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.name);
5363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Number of rule invocations ");
5383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numRuleInvocations);
5393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Number of unique rules visited ");
5413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numUniqueRulesInvoked);
5423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Number of decision events ");
5443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numDecisionEvents);
5453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Overall average k per decision event ");
5473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.avgkPerDecisionEvent);
5483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Number of backtracking occurrences (can be multiple per decision) ");
5503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numBacktrackOccurrences);
5513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Overall average k per decision event that backtracks ");
5533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.avgkPerBacktrackingDecisionEvent);
5543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("Number of rule invocations while backtracking ");
5563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numGuessingRuleInvocations);
5573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("num decisions that potentially backtrack ");
5593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numDecisionsThatPotentiallyBacktrack);
5603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("num decisions that do backtrack ");
5623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numDecisionsThatDoBacktrack);
5633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("num decisions that potentially backtrack but don't ");
5653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numDecisionsThatPotentiallyBacktrack - stats.numDecisionsThatDoBacktrack);
5663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("average % of time a potentially backtracking decision backtracks ");
5683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.averageDecisionPercentBacktracks);
5693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("num unique decisions covered ");
5713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numDecisionsCovered);
5723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("max rule invocation nesting depth ");
5743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.maxRuleInvocationDepth);
5753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
5763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
5773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("number of fixed lookahead decisions ");
5783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("min lookahead used in a fixed lookahead decision ");
5813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("max lookahead used in a fixed lookahead decision ");
5843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("average lookahead depth used in fixed lookahead decisions ");
5873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("standard deviation of depth used in fixed lookahead decisions ");
5903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("number of arbitrary lookahead decisions ");
5933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("min lookahead used in an arbitrary lookahead decision ");
5963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
5973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
5983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("max lookahead used in an arbitrary lookahead decision ");
5993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("average lookahead depth used in arbitrary lookahead decisions ");
6023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("standard deviation of depth used in arbitrary lookahead decisions ");
6053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("number of evaluated syntactic predicates ");
6083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("min lookahead used in a syntactic predicate ");
6113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("max lookahead used in a syntactic predicate ");
6143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("average lookahead depth used in syntactic predicates ");
6173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("standard deviation of depth used in syntactic predicates ");
6203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append('\n');
6223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("rule memoization cache size ");
6233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numMemoizationCacheEntries);
6243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of rule memoization cache hits ");
6263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numMemoizationCacheHits);
6273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of rule memoization cache misses ");
6293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numMemoizationCacheMisses);
6303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append("number of evaluated semantic predicates ");
6323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append();
6333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein//		buf.append(newline);
6343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of tokens ");
6353447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numTokens);
6363447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6373447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of hidden tokens ");
6383447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numHiddenTokens);
6393447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6403447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of char ");
6413447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numCharsMatched);
6423447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6433447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of hidden char ");
6443447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numHiddenCharsMatched);
6453447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6463447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("number of syntax errors ");
6473447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(stats.numReportedErrors);
6483447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(newline);
6493447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
6503447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
6513447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
6523447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public String getDecisionStatsDump() {
6533447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		StringBuffer buf = new StringBuffer();
6543447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("location");
6553447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6563447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("n");
6573447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6583447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("avgk");
6593447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6603447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("maxk");
6613447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6623447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("synpred");
6633447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6643447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("sempred");
6653447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append(DATA_SEP);
6663447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("canbacktrack");
6673447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		buf.append("\n");
6683447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (String fileName : decisions.keySet()) {
6693447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			for (int d : decisions.keySet(fileName)) {
6703447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				DecisionDescriptor s = decisions.get(fileName, d);
6713447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.decision);
6723447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append("@");
6733447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(locationDescription(s.fileName,s.ruleName,s.line,s.pos)); // decision number
6743447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6753447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.n);
6763447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6773447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(String.format("%.2f",s.avgk));
6783447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6793447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.maxk);
6803447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6813447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.numBacktrackOccurrences);
6823447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6833447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.numSemPredEvals);
6843447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(DATA_SEP);
6853447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(s.couldBacktrack ?"1":"0");
6863447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				buf.append(newline);
6873447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
6883447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
6893447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return buf.toString();
6903447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
6913447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
6923447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int[] trim(int[] X, int n) {
6933447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		if ( n<X.length ) {
6943447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			int[] trimmed = new int[n];
6953447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			System.arraycopy(X,0,trimmed,0,n);
6963447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			X = trimmed;
6973447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
6983447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return X;
6993447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
7003447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
7013447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected int[] toArray(List a) {
7023447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int[] x = new int[a.size()];
7033447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int i = 0; i < a.size(); i++) {
7043447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Integer I = (Integer) a.get(i);
7053447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			x[i] = I.intValue();
7063447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
7073447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return x;
7083447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
7093447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
7103447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	/** Get num hidden tokens between i..j inclusive */
7113447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	public int getNumberOfHiddenTokens(int i, int j) {
7123447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		int n = 0;
7133447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		TokenStream input = parser.getTokenStream();
7143447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		for (int ti = i; ti<input.size() && ti <= j; ti++) {
7153447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			Token t = input.get(ti);
7163447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
7173447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein				n++;
7183447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			}
7193447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		}
7203447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return n;
7213447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
7223447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
7233447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected String locationDescription() {
7243447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return locationDescription(
7253447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentGrammarFileName.peek(),
7263447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentRuleName.peek(),
7273447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentLine.peek(),
7283447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein			currentPos.peek());
7293447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
7303447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein
7313447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	protected String locationDescription(String file, String rule, int line, int pos) {
7323447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein		return file+":"+line+":"+pos+"(" + rule + ")";
7333447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein	}
7343447a5916aa62f44de24cc441fc9987116ddff52Andrew Sapperstein}
735