/*
 [The "BSD license"]
 Copyright (c) 2005-2009 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.runtime.debug;

import org.antlr.runtime.*;
import org.antlr.runtime.misc.DoubleKeyMap;

import java.util.*;

/** Using the debug event interface, track what is happening in the parser
 *  and record statistics about the runtime.
 */
public class Profiler extends BlankDebugEventListener {
	public static final String DATA_SEP = "\t";
	public static final String newline = System.getProperty("line.separator");

	static boolean dump = false;

	public static class ProfileStats {
		public String Version;
		public String name;
		public int numRuleInvocations;
		public int numUniqueRulesInvoked;
		public int numDecisionEvents;
		public int numDecisionsCovered;
		public int numDecisionsThatPotentiallyBacktrack;
		public int numDecisionsThatDoBacktrack;
		public int maxRuleInvocationDepth;
		public float avgkPerDecisionEvent;
		public float avgkPerBacktrackingDecisionEvent;
		public float averageDecisionPercentBacktracks;
		public int numBacktrackOccurrences; // doesn't count gated DFA edges

		public int numFixedDecisions;
		public int minDecisionMaxFixedLookaheads;
		public int maxDecisionMaxFixedLookaheads;
		public int avgDecisionMaxFixedLookaheads;
		public int stddevDecisionMaxFixedLookaheads;
		public int numCyclicDecisions;
		public int minDecisionMaxCyclicLookaheads;
		public int maxDecisionMaxCyclicLookaheads;
		public int avgDecisionMaxCyclicLookaheads;
		public int stddevDecisionMaxCyclicLookaheads;
//		int Stats.min(toArray(decisionMaxSynPredLookaheads);
//		int Stats.max(toArray(decisionMaxSynPredLookaheads);
//		int Stats.avg(toArray(decisionMaxSynPredLookaheads);
//		int Stats.stddev(toArray(decisionMaxSynPredLookaheads);
		public int numSemanticPredicates;
		public int numTokens;
		public int numHiddenTokens;
		public int numCharsMatched;
		public int numHiddenCharsMatched;
		public int numReportedErrors;
		public int numMemoizationCacheHits;
		public int numMemoizationCacheMisses;
		public int numGuessingRuleInvocations;
		public int numMemoizationCacheEntries;
	}

	public static class DecisionDescriptor {
		public int decision;
		public String fileName;
		public String ruleName;
		public int line;
		public int pos;
		public boolean couldBacktrack;

		public int n;
		public float avgk; // avg across all decision events
		public int maxk;
		public int numBacktrackOccurrences;
		public int numSemPredEvals;
	}

	// all about a specific exec of a single decision
	public static class DecisionEvent {
		public DecisionDescriptor decision;
		public int startIndex;
		public int k;
		public boolean backtracks; // doesn't count gated DFA edges
		public boolean evalSemPred;
		public long startTime;
		public long stopTime;
		public int numMemoizationCacheHits;
		public int numMemoizationCacheMisses;
	}

	/** Because I may change the stats, I need to track that for later
	 *  computations to be consistent.
	 */
	public static final String Version = "3";
	public static final String RUNTIME_STATS_FILENAME = "runtime.stats";

	/** Ack, should not store parser; can't do remote stuff.  Well, we pass
	 *  input stream around too so I guess it's ok.
	 */
	public DebugParser parser = null;

	// working variables

	protected int ruleLevel = 0;
	//protected int decisionLevel = 0;
	protected Token lastRealTokenTouchedInDecision;
	protected Set<String> uniqueRules = new HashSet<String>();
	protected Stack<String> currentGrammarFileName = new Stack();
	protected Stack<String> currentRuleName = new Stack();
	protected Stack<Integer> currentLine = new Stack();
	protected Stack<Integer> currentPos = new Stack();

	// Vector<DecisionStats>
	//protected Vector decisions = new Vector(200); // need setSize
	protected DoubleKeyMap<String,Integer, DecisionDescriptor> decisions =
		new DoubleKeyMap<String,Integer, DecisionDescriptor>();

	// Record a DecisionData for each decision we hit while parsing
	protected List<DecisionEvent> decisionEvents = new ArrayList<DecisionEvent>();
	protected Stack<DecisionEvent> decisionStack = new Stack<DecisionEvent>();

	protected int backtrackDepth;
	
	ProfileStats stats = new ProfileStats();

	public Profiler() {
	}

	public Profiler(DebugParser parser) {
		this.parser = parser;
	}

	public void enterRule(String grammarFileName, String ruleName) {
//		System.out.println("enterRule "+grammarFileName+":"+ruleName);
		ruleLevel++;
		stats.numRuleInvocations++;
		uniqueRules.add(grammarFileName+":"+ruleName);
		stats.maxRuleInvocationDepth = Math.max(stats.maxRuleInvocationDepth, ruleLevel);
		currentGrammarFileName.push( grammarFileName );
		currentRuleName.push( ruleName );
	}

	public void exitRule(String grammarFileName, String ruleName) {
		ruleLevel--;
		currentGrammarFileName.pop();
		currentRuleName.pop();
	}

	/** Track memoization; this is not part of standard debug interface
	 *  but is triggered by profiling.  Code gen inserts an override
	 *  for this method in the recognizer, which triggers this method.
	 *  Called from alreadyParsedRule().
	 */
	public void examineRuleMemoization(IntStream input,
									   int ruleIndex,
									   int stopIndex, // index or MEMO_RULE_UNKNOWN...
									   String ruleName)
	{
		if (dump) System.out.println("examine memo "+ruleName+" at "+input.index()+": "+stopIndex);
		if ( stopIndex==BaseRecognizer.MEMO_RULE_UNKNOWN ) {
			//System.out.println("rule "+ruleIndex+" missed @ "+input.index());
			stats.numMemoizationCacheMisses++;
			stats.numGuessingRuleInvocations++; // we'll have to enter
			currentDecision().numMemoizationCacheMisses++;
		}
		else {
			// regardless of rule success/failure, if in cache, we have a cache hit
			//System.out.println("rule "+ruleIndex+" hit @ "+input.index());
			stats.numMemoizationCacheHits++;
			currentDecision().numMemoizationCacheHits++;
		}
	}

	/** Warning: doesn't track success/failure, just unique recording event */
	public void memoize(IntStream input,
						int ruleIndex,
						int ruleStartIndex,
						String ruleName)
	{
		// count how many entries go into table
		if (dump) System.out.println("memoize "+ruleName);
		stats.numMemoizationCacheEntries++;
	}

	@Override
	public void location(int line, int pos) {
		currentLine.push(line);
		currentPos.push(pos);
	}

	public void enterDecision(int decisionNumber, boolean couldBacktrack) {
		lastRealTokenTouchedInDecision = null;
		stats.numDecisionEvents++;
		int startingLookaheadIndex = parser.getTokenStream().index();
		TokenStream input = parser.getTokenStream();
		if ( dump ) System.out.println("enterDecision canBacktrack="+couldBacktrack+" "+ decisionNumber +
						   " backtrack depth " + backtrackDepth +
						   " @ " + input.get(input.index()) +
						   " rule " +locationDescription());
		String g = (String) currentGrammarFileName.peek();
		DecisionDescriptor descriptor = decisions.get(g, decisionNumber);
		if ( descriptor == null ) {
			descriptor = new DecisionDescriptor();
			decisions.put(g, decisionNumber, descriptor);
			descriptor.decision = decisionNumber;
			descriptor.fileName = (String)currentGrammarFileName.peek();
			descriptor.ruleName = (String)currentRuleName.peek();
			descriptor.line = (Integer)currentLine.peek();
			descriptor.pos = (Integer)currentPos.peek();
			descriptor.couldBacktrack = couldBacktrack;
		}
		descriptor.n++;

		DecisionEvent d = new DecisionEvent();
		decisionStack.push(d);
		d.decision = descriptor;
		d.startTime = System.currentTimeMillis();
		d.startIndex = startingLookaheadIndex;
	}

	public void exitDecision(int decisionNumber) {
		DecisionEvent d = decisionStack.pop();
		d.stopTime = System.currentTimeMillis();

		int lastTokenIndex = lastRealTokenTouchedInDecision.getTokenIndex();
		int numHidden = getNumberOfHiddenTokens(d.startIndex, lastTokenIndex);
		int depth = lastTokenIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
		d.k = depth;
		d.decision.maxk = Math.max(d.decision.maxk, depth);

		if (dump) System.out.println("exitDecision "+decisionNumber+" in "+d.decision.ruleName+
						   " lookahead "+d.k +" max token "+lastRealTokenTouchedInDecision);
		decisionEvents.add(d); // done with decision; track all
	}

	public void consumeToken(Token token) {
		if (dump) System.out.println("consume token "+token);
		if ( !inDecision() ) {
			stats.numTokens++;
			return;
		}
		if ( lastRealTokenTouchedInDecision==null ||
			 lastRealTokenTouchedInDecision.getTokenIndex() < token.getTokenIndex() )
		{
			lastRealTokenTouchedInDecision = token;
		}
		DecisionEvent d = currentDecision();
		// compute lookahead depth
		int thisRefIndex = token.getTokenIndex();
		int numHidden = getNumberOfHiddenTokens(d.startIndex, thisRefIndex);
		int depth = thisRefIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
		//d.maxk = Math.max(d.maxk, depth);
		if (dump) System.out.println("consume "+thisRefIndex+" "+depth+" tokens ahead in "+
						   d.decision.ruleName+"-"+d.decision.decision+" start index "+d.startIndex);		
	}

	/** The parser is in a decision if the decision depth > 0.  This
	 *  works for backtracking also, which can have nested decisions.
	 */
	public boolean inDecision() {
		return decisionStack.size()>0;
	}

	public void consumeHiddenToken(Token token) {
		//System.out.println("consume hidden token "+token);
		if ( !inDecision() ) stats.numHiddenTokens++;
	}

	/** Track refs to lookahead if in a fixed/nonfixed decision.
	 */
	public void LT(int i, Token t) {
		if ( inDecision() && i>0 ) {
			DecisionEvent d = currentDecision();
			if (dump) System.out.println("LT("+i+")="+t+" index "+t.getTokenIndex()+" relative to "+d.decision.ruleName+"-"+
							   d.decision.decision+" start index "+d.startIndex);
			if ( lastRealTokenTouchedInDecision==null ||
				 lastRealTokenTouchedInDecision.getTokenIndex() < t.getTokenIndex() )
			{
				lastRealTokenTouchedInDecision = t;
				if (dump) System.out.println("set last token "+lastRealTokenTouchedInDecision);
			}
			// get starting index off stack
//			int stackTop = lookaheadStack.size()-1;
//			Integer startingIndex = (Integer)lookaheadStack.get(stackTop);
//			// compute lookahead depth
//			int thisRefIndex = parser.getTokenStream().index();
//			int numHidden =
//				getNumberOfHiddenTokens(startingIndex.intValue(), thisRefIndex);
//			int depth = i + thisRefIndex - startingIndex.intValue() - numHidden;
//			/*
//			System.out.println("LT("+i+") @ index "+thisRefIndex+" is depth "+depth+
//				" max is "+maxLookaheadInCurrentDecision);
//			*/
//			if ( depth>maxLookaheadInCurrentDecision ) {
//				maxLookaheadInCurrentDecision = depth;
//			}
//			d.maxk = currentDecision()/
		}
	}

	/** Track backtracking decisions.  You'll see a fixed or cyclic decision
	 *  and then a backtrack.
	 *
	 * 		enter rule
	 * 		...
	 * 		enter decision
	 * 		LA and possibly consumes (for cyclic DFAs)
	 * 		begin backtrack level
	 * 		mark m
	 * 		rewind m
	 * 		end backtrack level, success
	 * 		exit decision
	 * 		...
	 * 		exit rule
	 */
	public void beginBacktrack(int level) {
		if (dump) System.out.println("enter backtrack "+level);
		backtrackDepth++;
		DecisionEvent e = currentDecision();
		if ( e.decision.couldBacktrack ) {
			stats.numBacktrackOccurrences++;
			e.decision.numBacktrackOccurrences++;
			e.backtracks = true;
		}
	}

	/** Successful or not, track how much lookahead synpreds use */
	public void endBacktrack(int level, boolean successful) {
		if (dump) System.out.println("exit backtrack "+level+": "+successful);
		backtrackDepth--;		
	}

	@Override
	public void mark(int i) {
		if (dump) System.out.println("mark "+i);
	}

	@Override
	public void rewind(int i) {
		if (dump) System.out.println("rewind "+i);
	}

	@Override
	public void rewind() {
		if (dump) System.out.println("rewind");
	}



	protected DecisionEvent currentDecision() {
		return decisionStack.peek();
	}

	public void recognitionException(RecognitionException e) {
		stats.numReportedErrors++;
	}

	public void semanticPredicate(boolean result, String predicate) {
		stats.numSemanticPredicates++;
		if ( inDecision() ) {
			DecisionEvent d = currentDecision();
			d.evalSemPred = true;
			d.decision.numSemPredEvals++;
			if (dump) System.out.println("eval "+predicate+" in "+d.decision.ruleName+"-"+
							   d.decision.decision);
		}
	}

	public void terminate() {
		for (DecisionEvent e : decisionEvents) {
			//System.out.println("decision "+e.decision.decision+": k="+e.k);
			e.decision.avgk += e.k;
			stats.avgkPerDecisionEvent += e.k;
			if ( e.backtracks ) { // doesn't count gated syn preds on DFA edges
				stats.avgkPerBacktrackingDecisionEvent += e.k;
			}
		}
		stats.averageDecisionPercentBacktracks = 0.0f;
		for (DecisionDescriptor d : decisions.values()) {
			stats.numDecisionsCovered++;
			d.avgk /= (double)d.n;
			if ( d.couldBacktrack ) {
				stats.numDecisionsThatPotentiallyBacktrack++;
				float percentBacktracks = d.numBacktrackOccurrences / (float)d.n;
				//System.out.println("dec "+d.decision+" backtracks "+percentBacktracks*100+"%");
				stats.averageDecisionPercentBacktracks += percentBacktracks;
			}
			// ignore rules that backtrack along gated DFA edges
			if ( d.numBacktrackOccurrences > 0 ) {
				stats.numDecisionsThatDoBacktrack++;
			}
		}
		stats.averageDecisionPercentBacktracks /= stats.numDecisionsThatPotentiallyBacktrack;
		stats.averageDecisionPercentBacktracks *= 100; // it's a percentage
		stats.avgkPerDecisionEvent /= stats.numDecisionEvents;
		stats.avgkPerBacktrackingDecisionEvent /= (double)stats.numBacktrackOccurrences;

		System.err.println(toString());
		System.err.println(getDecisionStatsDump());

//		String stats = toNotifyString();
//		try {
//			Stats.writeReport(RUNTIME_STATS_FILENAME,stats);
//		}
//		catch (IOException ioe) {
//			System.err.println(ioe);
//			ioe.printStackTrace(System.err);
//		}
	}

	public void setParser(DebugParser parser) {
		this.parser = parser;
	}

	// R E P O R T I N G

	public String toNotifyString() {
		StringBuffer buf = new StringBuffer();
		buf.append(Version);
		buf.append('\t');
		buf.append(parser.getClass().getName());
//		buf.append('\t');
//		buf.append(numRuleInvocations);
//		buf.append('\t');
//		buf.append(maxRuleInvocationDepth);
//		buf.append('\t');
//		buf.append(numFixedDecisions);
//		buf.append('\t');
//		buf.append(Stats.min(decisionMaxFixedLookaheads));
//		buf.append('\t');
//		buf.append(Stats.max(decisionMaxFixedLookaheads));
//		buf.append('\t');
//		buf.append(Stats.avg(decisionMaxFixedLookaheads));
//		buf.append('\t');
//		buf.append(Stats.stddev(decisionMaxFixedLookaheads));
//		buf.append('\t');
//		buf.append(numCyclicDecisions);
//		buf.append('\t');
//		buf.append(Stats.min(decisionMaxCyclicLookaheads));
//		buf.append('\t');
//		buf.append(Stats.max(decisionMaxCyclicLookaheads));
//		buf.append('\t');
//		buf.append(Stats.avg(decisionMaxCyclicLookaheads));
//		buf.append('\t');
//		buf.append(Stats.stddev(decisionMaxCyclicLookaheads));
//		buf.append('\t');
//		buf.append(numBacktrackDecisions);
//		buf.append('\t');
//		buf.append(Stats.min(toArray(decisionMaxSynPredLookaheads)));
//		buf.append('\t');
//		buf.append(Stats.max(toArray(decisionMaxSynPredLookaheads)));
//		buf.append('\t');
//		buf.append(Stats.avg(toArray(decisionMaxSynPredLookaheads)));
//		buf.append('\t');
//		buf.append(Stats.stddev(toArray(decisionMaxSynPredLookaheads)));
//		buf.append('\t');
//		buf.append(numSemanticPredicates);
//		buf.append('\t');
//		buf.append(parser.getTokenStream().size());
//		buf.append('\t');
//		buf.append(numHiddenTokens);
//		buf.append('\t');
//		buf.append(numCharsMatched);
//		buf.append('\t');
//		buf.append(numHiddenCharsMatched);
//		buf.append('\t');
//		buf.append(numberReportedErrors);
//		buf.append('\t');
//		buf.append(numMemoizationCacheHits);
//		buf.append('\t');
//		buf.append(numMemoizationCacheMisses);
//		buf.append('\t');
//		buf.append(numGuessingRuleInvocations);
//		buf.append('\t');
//		buf.append(numMemoizationCacheEntries);
		return buf.toString();
	}

	public String toString() {
		return toString(getReport());
	}

	public ProfileStats getReport() {
//		TokenStream input = parser.getTokenStream();
//		for (int i=0; i<input.size()&& lastRealTokenTouchedInDecision !=null&&i<= lastRealTokenTouchedInDecision.getTokenIndex(); i++) {
//			Token t = input.get(i);
//			if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
//				stats.numHiddenTokens++;
//				stats.numHiddenCharsMatched += t.getText().length();
//			}
//		}
		stats.Version = Version;
		stats.name = parser.getClass().getName();
		stats.numUniqueRulesInvoked = uniqueRules.size();
		//stats.numCharsMatched = lastTokenConsumed.getStopIndex() + 1;
		return stats;
	}

	public DoubleKeyMap getDecisionStats() {
		return decisions;
	}

	public List getDecisionEvents() {
		return decisionEvents;
	}

	public static String toString(ProfileStats stats) {
		StringBuffer buf = new StringBuffer();
		buf.append("ANTLR Runtime Report; Profile Version ");
		buf.append(stats.Version);
		buf.append(newline);
		buf.append("parser name ");
		buf.append(stats.name);
		buf.append(newline);
		buf.append("Number of rule invocations ");
		buf.append(stats.numRuleInvocations);
		buf.append(newline);
		buf.append("Number of unique rules visited ");
		buf.append(stats.numUniqueRulesInvoked);
		buf.append(newline);
		buf.append("Number of decision events ");
		buf.append(stats.numDecisionEvents);
		buf.append(newline);
		buf.append("Overall average k per decision event ");
		buf.append(stats.avgkPerDecisionEvent);
		buf.append(newline);
		buf.append("Number of backtracking occurrences (can be multiple per decision) ");
		buf.append(stats.numBacktrackOccurrences);
		buf.append(newline);
		buf.append("Overall average k per decision event that backtracks ");
		buf.append(stats.avgkPerBacktrackingDecisionEvent);
		buf.append(newline);
		buf.append("Number of rule invocations while backtracking ");
		buf.append(stats.numGuessingRuleInvocations);
		buf.append(newline);
		buf.append("num decisions that potentially backtrack ");
		buf.append(stats.numDecisionsThatPotentiallyBacktrack);
		buf.append(newline);
		buf.append("num decisions that do backtrack ");
		buf.append(stats.numDecisionsThatDoBacktrack);
		buf.append(newline);
		buf.append("num decisions that potentially backtrack but don't ");
		buf.append(stats.numDecisionsThatPotentiallyBacktrack - stats.numDecisionsThatDoBacktrack);
		buf.append(newline);
		buf.append("average % of time a potentially backtracking decision backtracks ");
		buf.append(stats.averageDecisionPercentBacktracks);
		buf.append(newline);
		buf.append("num unique decisions covered ");
		buf.append(stats.numDecisionsCovered);
		buf.append(newline);
		buf.append("max rule invocation nesting depth ");
		buf.append(stats.maxRuleInvocationDepth);
		buf.append(newline);

//		buf.append("number of fixed lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("min lookahead used in a fixed lookahead decision ");
//		buf.append();
//		buf.append('\n');
//		buf.append("max lookahead used in a fixed lookahead decision ");
//		buf.append();
//		buf.append('\n');
//		buf.append("average lookahead depth used in fixed lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("standard deviation of depth used in fixed lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("number of arbitrary lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("min lookahead used in an arbitrary lookahead decision ");
//		buf.append();
//		buf.append('\n');
//		buf.append("max lookahead used in an arbitrary lookahead decision ");
//		buf.append();
//		buf.append('\n');
//		buf.append("average lookahead depth used in arbitrary lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("standard deviation of depth used in arbitrary lookahead decisions ");
//		buf.append();
//		buf.append('\n');
//		buf.append("number of evaluated syntactic predicates ");
//		buf.append();
//		buf.append('\n');
//		buf.append("min lookahead used in a syntactic predicate ");
//		buf.append();
//		buf.append('\n');
//		buf.append("max lookahead used in a syntactic predicate ");
//		buf.append();
//		buf.append('\n');
//		buf.append("average lookahead depth used in syntactic predicates ");
//		buf.append();
//		buf.append('\n');
//		buf.append("standard deviation of depth used in syntactic predicates ");
//		buf.append();
//		buf.append('\n');
		buf.append("rule memoization cache size ");
		buf.append(stats.numMemoizationCacheEntries);
		buf.append(newline);
		buf.append("number of rule memoization cache hits ");
		buf.append(stats.numMemoizationCacheHits);
		buf.append(newline);
		buf.append("number of rule memoization cache misses ");
		buf.append(stats.numMemoizationCacheMisses);
		buf.append(newline);
//		buf.append("number of evaluated semantic predicates ");
//		buf.append();
//		buf.append(newline);
		buf.append("number of tokens ");
		buf.append(stats.numTokens);
		buf.append(newline);
		buf.append("number of hidden tokens ");
		buf.append(stats.numHiddenTokens);
		buf.append(newline);
		buf.append("number of char ");
		buf.append(stats.numCharsMatched);
		buf.append(newline);
		buf.append("number of hidden char ");
		buf.append(stats.numHiddenCharsMatched);
		buf.append(newline);
		buf.append("number of syntax errors ");
		buf.append(stats.numReportedErrors);
		buf.append(newline);
		return buf.toString();
	}

	public String getDecisionStatsDump() {
		StringBuffer buf = new StringBuffer();
		buf.append("location");
		buf.append(DATA_SEP);
		buf.append("n");
		buf.append(DATA_SEP);
		buf.append("avgk");
		buf.append(DATA_SEP);
		buf.append("maxk");
		buf.append(DATA_SEP);
		buf.append("synpred");
		buf.append(DATA_SEP);
		buf.append("sempred");
		buf.append(DATA_SEP);
		buf.append("canbacktrack");
		buf.append("\n");
		for (String fileName : decisions.keySet()) {
			for (int d : decisions.keySet(fileName)) {
				DecisionDescriptor s = decisions.get(fileName, d);
				buf.append(s.decision);
				buf.append("@");
				buf.append(locationDescription(s.fileName,s.ruleName,s.line,s.pos)); // decision number
				buf.append(DATA_SEP);
				buf.append(s.n);
				buf.append(DATA_SEP);
				buf.append(String.format("%.2f",s.avgk));
				buf.append(DATA_SEP);
				buf.append(s.maxk);
				buf.append(DATA_SEP);
				buf.append(s.numBacktrackOccurrences);
				buf.append(DATA_SEP);
				buf.append(s.numSemPredEvals);
				buf.append(DATA_SEP);
				buf.append(s.couldBacktrack ?"1":"0");
				buf.append(newline);
			}
		}
		return buf.toString();
	}

	protected int[] trim(int[] X, int n) {
		if ( n<X.length ) {
			int[] trimmed = new int[n];
			System.arraycopy(X,0,trimmed,0,n);
			X = trimmed;
		}
		return X;
	}

	protected int[] toArray(List a) {
		int[] x = new int[a.size()];
		for (int i = 0; i < a.size(); i++) {
			Integer I = (Integer) a.get(i);
			x[i] = I.intValue();
		}
		return x;
	}

	/** Get num hidden tokens between i..j inclusive */
	public int getNumberOfHiddenTokens(int i, int j) {
		int n = 0;
		TokenStream input = parser.getTokenStream();
		for (int ti = i; ti<input.size() && ti <= j; ti++) {
			Token t = input.get(ti);
			if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
				n++;
			}
		}
		return n;
	}

	protected String locationDescription() {
		return locationDescription(
			currentGrammarFileName.peek(),
			currentRuleName.peek(),
			currentLine.peek(),
			currentPos.peek());
	}

	protected String locationDescription(String file, String rule, int line, int pos) {
		return file+":"+line+":"+pos+"(" + rule + ")";
	}
}
