1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/*
2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Note to JL: Replaced Hashset with Dictionary.
3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * [The "BSD licence"]
5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2005-2008 Terence Parr
6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Conversion to C#:
9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2008-2009 Sam Harwell, Pixel Mine, Inc.
10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * All rights reserved.
11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Redistribution and use in source and binary forms, with or without
13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * modification, are permitted provided that the following conditions
14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * are met:
15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 1. Redistributions of source code must retain the above copyright
16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer.
17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 2. Redistributions in binary form must reproduce the above copyright
18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    notice, this list of conditions and the following disclaimer in the
19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    documentation and/or other materials provided with the distribution.
20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 3. The name of the author may not be used to endorse or promote products
21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *    derived from this software without specific prior written permission.
22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver *
23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */
34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
35324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruvernamespace Antlr.Runtime.Debug {
36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using System.Collections.Generic;
37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using System.Collections.ObjectModel;
38324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Antlr.Runtime.Debug.Misc;
39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Array = System.Array;
41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using CLSCompliantAttribute = System.CLSCompliantAttribute;
42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Console = System.Console;
43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using DateTime = System.DateTime;
44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Environment = System.Environment;
45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using Math = System.Math;
46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    using StringBuilder = System.Text.StringBuilder;
47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    /** <summary>Using the debug event interface, track what is happening in the parser
49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     *  and record statistics about the runtime.
50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver     */
51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    public class Profiler : BlankDebugEventListener {
52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static readonly string DataSeparator = "\t";
53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static readonly string NewLine = Environment.NewLine;
54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        internal static bool dump = false;
56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Because I may change the stats, I need to track that for later
58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  computations to be consistent.
59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static readonly string Version = "3";
61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static readonly string RuntimeStatsFilename = "runtime.stats";
62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Ack, should not store parser; can't do remote stuff.  Well, we pass
64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  input stream around too so I guess it's ok.
65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public DebugParser parser = null;
67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // working variables
69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        [CLSCompliant(false)]
71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected int ruleLevel = 0;
72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        //protected int decisionLevel = 0;
73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected IToken lastRealTokenTouchedInDecision;
74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Dictionary<string, string> uniqueRules = new Dictionary<string, string>();
75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Stack<string> currentGrammarFileName = new Stack<string>();
76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Stack<string> currentRuleName = new Stack<string>();
77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Stack<int> currentLine = new Stack<int>();
78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Stack<int> currentPos = new Stack<int>();
79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Vector<DecisionStats>
81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        //protected Vector decisions = new Vector(200); // need setSize
82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected DoubleKeyMap<string, int, DecisionDescriptor> decisions = new DoubleKeyMap<string, int, DecisionDescriptor>();
83324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
84324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // Record a DecisionData for each decision we hit while parsing
85324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        private List<DecisionEvent> decisionEvents = new List<DecisionEvent>();
86324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected Stack<DecisionEvent> decisionStack = new Stack<DecisionEvent>();
87324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
88324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected int backtrackDepth;
89324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
90324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        ProfileStats stats = new ProfileStats();
91324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
92324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public Profiler() {
93324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
94324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
95324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public Profiler(DebugParser parser) {
96324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this.parser = parser;
97324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
98324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
99324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void EnterRule(string grammarFileName, string ruleName) {
100324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //System.out.println("enterRule "+grammarFileName+":"+ruleName);
101324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ruleLevel++;
102324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numRuleInvocations++;
103324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            uniqueRules[ruleName] = (grammarFileName + ":" + ruleName);
104324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.maxRuleInvocationDepth = Math.Max(stats.maxRuleInvocationDepth, ruleLevel);
105324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentGrammarFileName.Push(grammarFileName);
106324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentRuleName.Push(ruleName);
107324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
108324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
109324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void ExitRule(string grammarFileName, string ruleName) {
110324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ruleLevel--;
111324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentGrammarFileName.Pop();
112324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentRuleName.Pop();
113324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
114324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
115324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Track memoization; this is not part of standard debug interface
116324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  but is triggered by profiling.  Code gen inserts an override
117324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  for this method in the recognizer, which triggers this method.
118324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  Called from alreadyParsedRule().
119324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
120324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void ExamineRuleMemoization(IIntStream input,
121324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           int ruleIndex,
122324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           int stopIndex, // index or MEMO_RULE_UNKNOWN...
123324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                           string ruleName) {
124324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
125324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("examine memo " + ruleName + " at " + input.Index + ": " + stopIndex);
126324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (stopIndex == BaseRecognizer.MemoRuleUnknown) {
127324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //System.out.println("rule "+ruleIndex+" missed @ "+input.index());
128324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numMemoizationCacheMisses++;
129324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numGuessingRuleInvocations++; // we'll have to enter
130324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                CurrentDecision().numMemoizationCacheMisses++;
131324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            } else {
132324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // regardless of rule success/failure, if in cache, we have a cache hit
133324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //System.out.println("rule "+ruleIndex+" hit @ "+input.index());
134324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numMemoizationCacheHits++;
135324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                CurrentDecision().numMemoizationCacheHits++;
136324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
137324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
138324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
139324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Warning: doesn't track success/failure, just unique recording event */
140324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void Memoize(IIntStream input,
141324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            int ruleIndex,
142324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            int ruleStartIndex,
143324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                            string ruleName) {
144324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // count how many entries go into table
145324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
146324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("memoize " + ruleName);
147324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numMemoizationCacheEntries++;
148324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
149324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
150324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void Location(int line, int pos) {
151324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentLine.Push(line);
152324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            currentPos.Push(pos);
153324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
154324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
155324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void EnterDecision(int decisionNumber, bool couldBacktrack) {
156324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            lastRealTokenTouchedInDecision = null;
157324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numDecisionEvents++;
158324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int startingLookaheadIndex = parser.TokenStream.Index;
159324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ITokenStream input = parser.TokenStream;
160324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump) {
161324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("enterDecision canBacktrack=" + couldBacktrack + " " + decisionNumber +
162324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      " backtrack depth " + backtrackDepth +
163324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      " @ " + input.Get(input.Index) +
164324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                      " rule " + LocationDescription());
165324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
166324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            string g = currentGrammarFileName.Peek();
167324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            DecisionDescriptor descriptor = decisions.Get(g, decisionNumber);
168324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (descriptor == null) {
169324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor = new DecisionDescriptor();
170324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                decisions.Put(g, decisionNumber, descriptor);
171324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.decision = decisionNumber;
172324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.fileName = currentGrammarFileName.Peek();
173324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.ruleName = currentRuleName.Peek();
174324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.line = currentLine.Peek();
175324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.pos = currentPos.Peek();
176324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                descriptor.couldBacktrack = couldBacktrack;
177324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
178324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            descriptor.n++;
179324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
180324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            DecisionEvent d = new DecisionEvent();
181324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            decisionStack.Push(d);
182324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.decision = descriptor;
183324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.startTime = DateTime.Now;
184324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.startIndex = startingLookaheadIndex;
185324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
186324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
187324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void ExitDecision(int decisionNumber) {
188324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            DecisionEvent d = decisionStack.Pop();
189324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.stopTime = DateTime.Now;
190324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
191324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int lastTokenIndex = lastRealTokenTouchedInDecision.TokenIndex;
192324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int numHidden = GetNumberOfHiddenTokens(d.startIndex, lastTokenIndex);
193324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int depth = lastTokenIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
194324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.k = depth;
195324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            d.decision.maxk = Math.Max(d.decision.maxk, depth);
196324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
197324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump) {
198324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("exitDecision " + decisionNumber + " in " + d.decision.ruleName +
199324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   " lookahead " + d.k + " max token " + lastRealTokenTouchedInDecision);
200324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
201324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
202324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            decisionEvents.Add(d); // done with decision; track all
203324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
204324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
205324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void ConsumeToken(IToken token) {
206324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
207324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("consume token " + token);
208324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
209324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (!InDecision) {
210324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numTokens++;
211324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return;
212324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
213324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
214324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (lastRealTokenTouchedInDecision == null ||
215324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                 lastRealTokenTouchedInDecision.TokenIndex < token.TokenIndex) {
216324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                lastRealTokenTouchedInDecision = token;
217324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
218324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            DecisionEvent d = CurrentDecision();
219324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            // compute lookahead depth
220324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int thisRefIndex = token.TokenIndex;
221324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int numHidden = GetNumberOfHiddenTokens(d.startIndex, thisRefIndex);
222324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int depth = thisRefIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
223324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //d.maxk = Math.max(d.maxk, depth);
224324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump) {
225324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("consume " + thisRefIndex + " " + depth + " tokens ahead in " +
226324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                   d.decision.ruleName + "-" + d.decision.decision + " start index " + d.startIndex);
227324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
228324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
229324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
230324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** The parser is in a decision if the decision depth > 0.  This
231324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  works for backtracking also, which can have nested decisions.
232324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
233324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual bool InDecision {
234324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get {
235324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return decisionStack.Count > 0;
236324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
237324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
238324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
239324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void ConsumeHiddenToken(IToken token) {
240324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //System.out.println("consume hidden token "+token);
241324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (!InDecision)
242324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numHiddenTokens++;
243324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
244324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
245324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Track refs to lookahead if in a fixed/nonfixed decision.
246324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
247324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void LT(int i, IToken t) {
248324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (InDecision && i > 0) {
249324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                DecisionEvent d = CurrentDecision();
250324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (dump) {
251324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    Console.WriteLine("LT(" + i + ")=" + t + " index " + t.TokenIndex + " relative to " + d.decision.ruleName + "-" +
252324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                             d.decision.decision + " start index " + d.startIndex);
253324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
254324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
255324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (lastRealTokenTouchedInDecision == null ||
256324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                     lastRealTokenTouchedInDecision.TokenIndex < t.TokenIndex) {
257324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    lastRealTokenTouchedInDecision = t;
258324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    if (dump)
259324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                        Console.WriteLine("set last token " + lastRealTokenTouchedInDecision);
260324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
261324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // get starting index off stack
262324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			int stackTop = lookaheadStack.size()-1;
263324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			Integer startingIndex = (Integer)lookaheadStack.get(stackTop);
264324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			// compute lookahead depth
265324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			int thisRefIndex = parser.getTokenStream().index();
266324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			int numHidden =
267324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //				getNumberOfHiddenTokens(startingIndex.intValue(), thisRefIndex);
268324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			int depth = i + thisRefIndex - startingIndex.intValue() - numHidden;
269324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			/*
270324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			System.out.println("LT("+i+") @ index "+thisRefIndex+" is depth "+depth+
271324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //				" max is "+maxLookaheadInCurrentDecision);
272324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			*/
273324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			if ( depth>maxLookaheadInCurrentDecision ) {
274324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //				maxLookaheadInCurrentDecision = depth;
275324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			}
276324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //			d.maxk = currentDecision()/
277324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
278324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
279324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
280324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Track backtracking decisions.  You'll see a fixed or cyclic decision
281324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *  and then a backtrack.
282324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         *
283324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		enter rule
284324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		...
285324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		enter decision
286324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		LA and possibly consumes (for cyclic DFAs)
287324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		begin backtrack level
288324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		mark m
289324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		rewind m
290324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		end backtrack level, success
291324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		exit decision
292324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		...
293324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         * 		exit rule
294324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver         */
295324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void BeginBacktrack(int level) {
296324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
297324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("enter backtrack " + level);
298324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            backtrackDepth++;
299324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            DecisionEvent e = CurrentDecision();
300324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (e.decision.couldBacktrack) {
301324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numBacktrackOccurrences++;
302324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                e.decision.numBacktrackOccurrences++;
303324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                e.backtracks = true;
304324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
305324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
306324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
307324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Successful or not, track how much lookahead synpreds use */
308324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void EndBacktrack(int level, bool successful) {
309324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
310324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("exit backtrack " + level + ": " + successful);
311324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            backtrackDepth--;
312324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
313324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
314324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void Mark(int i) {
315324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
316324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("mark " + i);
317324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
318324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
319324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void Rewind(int i) {
320324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
321324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("rewind " + i);
322324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
323324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
324324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void Rewind() {
325324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (dump)
326324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Console.WriteLine("rewind");
327324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
328324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
329324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual DecisionEvent CurrentDecision() {
330324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return decisionStack.Peek();
331324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
332324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
333324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void RecognitionException(RecognitionException e) {
334324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numReportedErrors++;
335324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
336324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
337324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void SemanticPredicate(bool result, string predicate) {
338324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numSemanticPredicates++;
339324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (InDecision) {
340324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                DecisionEvent d = CurrentDecision();
341324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                d.evalSemPred = true;
342324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                d.decision.numSemPredEvals++;
343324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (dump) {
344324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    Console.WriteLine("eval " + predicate + " in " + d.decision.ruleName + "-" +
345324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                                       d.decision.decision);
346324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
347324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
348324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
349324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
350324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override void Terminate() {
351324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (DecisionEvent e in decisionEvents) {
352324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                //System.out.println("decision "+e.decision.decision+": k="+e.k);
353324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                e.decision.avgk += e.k;
354324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.avgkPerDecisionEvent += e.k;
355324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (e.backtracks) { // doesn't count gated syn preds on DFA edges
356324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    stats.avgkPerBacktrackingDecisionEvent += e.k;
357324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
358324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
359324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.averageDecisionPercentBacktracks = 0.0f;
360324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (DecisionDescriptor d in decisions.Values()) {
361324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                stats.numDecisionsCovered++;
362324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                d.avgk /= (float)d.n;
363324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (d.couldBacktrack) {
364324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    stats.numDecisionsThatPotentiallyBacktrack++;
365324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    float percentBacktracks = d.numBacktrackOccurrences / (float)d.n;
366324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    //System.out.println("dec "+d.decision+" backtracks "+percentBacktracks*100+"%");
367324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    stats.averageDecisionPercentBacktracks += percentBacktracks;
368324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
369324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                // ignore rules that backtrack along gated DFA edges
370324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (d.numBacktrackOccurrences > 0) {
371324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    stats.numDecisionsThatDoBacktrack++;
372324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
373324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
374324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.averageDecisionPercentBacktracks /= stats.numDecisionsThatPotentiallyBacktrack;
375324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.averageDecisionPercentBacktracks *= 100; // it's a percentage
376324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.avgkPerDecisionEvent /= stats.numDecisionEvents;
377324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.avgkPerBacktrackingDecisionEvent /= (float)stats.numBacktrackOccurrences;
378324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
379324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Console.Error.WriteLine(ToString());
380324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            Console.Error.WriteLine(GetDecisionStatsDump());
381324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
382324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		String stats = toNotifyString();
383324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		try {
384324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //			Stats.writeReport(RUNTIME_STATS_FILENAME,stats);
385324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		}
386324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		catch (IOException ioe) {
387324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //			System.err.println(ioe);
388324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //			ioe.printStackTrace(System.err);
389324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		}
390324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
391324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
392324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual void SetParser(DebugParser parser) {
393324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            this.parser = parser;
394324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
395324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
396324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // R E P O R T I N G
397324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
398324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual string ToNotifyString() {
399324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
400324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(Version);
401324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append('\t');
402324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(parser.GetType().Name);
403324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
404324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numRuleInvocations);
405324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
406324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(maxRuleInvocationDepth);
407324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
408324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numFixedDecisions);
409324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
410324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.min(decisionMaxFixedLookaheads));
411324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
412324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.max(decisionMaxFixedLookaheads));
413324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
414324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.avg(decisionMaxFixedLookaheads));
415324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
416324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.stddev(decisionMaxFixedLookaheads));
417324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
418324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numCyclicDecisions);
419324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
420324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.min(decisionMaxCyclicLookaheads));
421324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
422324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.max(decisionMaxCyclicLookaheads));
423324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
424324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.avg(decisionMaxCyclicLookaheads));
425324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
426324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.stddev(decisionMaxCyclicLookaheads));
427324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
428324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numBacktrackDecisions);
429324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
430324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.min(toArray(decisionMaxSynPredLookaheads)));
431324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
432324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.max(toArray(decisionMaxSynPredLookaheads)));
433324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
434324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.avg(toArray(decisionMaxSynPredLookaheads)));
435324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
436324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(Stats.stddev(toArray(decisionMaxSynPredLookaheads)));
437324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
438324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numSemanticPredicates);
439324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
440324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(parser.getTokenStream().size());
441324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
442324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numHiddenTokens);
443324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
444324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numCharsMatched);
445324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
446324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numHiddenCharsMatched);
447324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
448324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numberReportedErrors);
449324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
450324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numMemoizationCacheHits);
451324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
452324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numMemoizationCacheMisses);
453324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
454324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numGuessingRuleInvocations);
455324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append('\t');
456324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(numMemoizationCacheEntries);
457324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
458324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
459324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
460324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public override string ToString() {
461324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return ToString(GetReport());
462324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
463324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
464324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual ProfileStats GetReport() {
465324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //ITokenStream input = parser.TokenStream;
466324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //for (int i = 0; i < input.Count && lastRealTokenTouchedInDecision != null && i <= lastRealTokenTouchedInDecision.TokenIndex; i++)
467324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //{
468324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //    IToken t = input.Get(i);
469324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //    if (t.Channel != TokenChannels.Default)
470324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //    {
471324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //        stats.numHiddenTokens++;
472324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //        stats.numHiddenCharsMatched += t.Text.Length;
473324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //    }
474324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //}
475324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.Version = Version;
476324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.name = parser.GetType().Name;
477324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            stats.numUniqueRulesInvoked = uniqueRules.Count;
478324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //stats.numCharsMatched = lastTokenConsumed.getStopIndex() + 1;
479324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return stats;
480324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
481324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
482324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual DoubleKeyMap<string, int, DecisionDescriptor> GetDecisionStats() {
483324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return decisions;
484324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
485324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
486324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual ReadOnlyCollection<DecisionEvent> DecisionEvents {
487324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            get {
488324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                return decisionEvents.AsReadOnly();
489324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
490324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
491324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
492324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public static string ToString(ProfileStats stats) {
493324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
494324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("ANTLR Runtime Report; Profile Version ");
495324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.Version);
496324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
497324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("parser name ");
498324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.name);
499324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
500324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("Number of rule invocations ");
501324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numRuleInvocations);
502324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
503324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("Number of unique rules visited ");
504324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numUniqueRulesInvoked);
505324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
506324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("Number of decision events ");
507324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numDecisionEvents);
508324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
509324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("Number of rule invocations while backtracking ");
510324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numGuessingRuleInvocations);
511324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
512324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("max rule invocation nesting depth ");
513324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.maxRuleInvocationDepth);
514324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
515324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("number of fixed lookahead decisions ");
516324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
517324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
518324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("min lookahead used in a fixed lookahead decision ");
519324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
520324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
521324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("max lookahead used in a fixed lookahead decision ");
522324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
523324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
524324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("average lookahead depth used in fixed lookahead decisions ");
525324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
526324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
527324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("standard deviation of depth used in fixed lookahead decisions ");
528324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
529324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
530324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("number of arbitrary lookahead decisions ");
531324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
532324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
533324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("min lookahead used in an arbitrary lookahead decision ");
534324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
535324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
536324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("max lookahead used in an arbitrary lookahead decision ");
537324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
538324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
539324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("average lookahead depth used in arbitrary lookahead decisions ");
540324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
541324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
542324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("standard deviation of depth used in arbitrary lookahead decisions ");
543324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
544324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
545324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("number of evaluated syntactic predicates ");
546324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
547324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
548324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("min lookahead used in a syntactic predicate ");
549324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
550324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
551324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("max lookahead used in a syntactic predicate ");
552324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
553324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
554324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("average lookahead depth used in syntactic predicates ");
555324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
556324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
557324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("standard deviation of depth used in syntactic predicates ");
558324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
559324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
560324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("rule memoization cache size ");
561324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numMemoizationCacheEntries);
562324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
563324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of rule memoization cache hits ");
564324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numMemoizationCacheHits);
565324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
566324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of rule memoization cache misses ");
567324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numMemoizationCacheMisses);
568324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
569324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append("number of evaluated semantic predicates ");
570324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append();
571324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		buf.Append(newline);
572324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of tokens ");
573324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numTokens);
574324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
575324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of hidden tokens ");
576324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numHiddenTokens);
577324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
578324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of char ");
579324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numCharsMatched);
580324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
581324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of hidden char ");
582324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numHiddenCharsMatched);
583324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
584324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("number of syntax errors ");
585324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(stats.numReportedErrors);
586324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(NewLine);
587324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
588324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
589324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
590324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual string GetDecisionStatsDump() {
591324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            StringBuilder buf = new StringBuilder();
592324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("location");
593324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
594324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("n");
595324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
596324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("avgk");
597324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
598324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("maxk");
599324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
600324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("synpred");
601324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
602324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("sempred");
603324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append(DataSeparator);
604324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("canbacktrack");
605324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            buf.Append("\n");
606324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            foreach (string fileName in decisions.KeySet()) {
607324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                foreach (int d in decisions.KeySet(fileName)) {
608324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    DecisionDescriptor s = decisions.Get(fileName, d);
609324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.decision);
610324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append("@");
611324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(LocationDescription(s.fileName, s.ruleName, s.line, s.pos)); // decision number
612324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
613324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.n);
614324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
615324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(string.Format("{0}", s.avgk));
616324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
617324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.maxk);
618324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
619324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.numBacktrackOccurrences);
620324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
621324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.numSemPredEvals);
622324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(DataSeparator);
623324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(s.couldBacktrack ? "1" : "0");
624324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    buf.Append(NewLine);
625324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
626324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
627324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return buf.ToString();
628324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
629324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
630324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual int[] Trim(int[] X, int n) {
631324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            if (n < X.Length) {
632324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                int[] trimmed = new int[n];
633324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                Array.Copy(X, 0, trimmed, 0, n);
634324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                X = trimmed;
635324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
636324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return X;
637324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
638324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
639324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        /** Get num hidden tokens between i..j inclusive */
640324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public virtual int GetNumberOfHiddenTokens(int i, int j) {
641324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            int n = 0;
642324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            ITokenStream input = parser.TokenStream;
643324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            for (int ti = i; ti < input.Count && ti <= j; ti++) {
644324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                IToken t = input.Get(ti);
645324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                if (t.Channel != TokenChannels.Default) {
646324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                    n++;
647324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                }
648324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            }
649324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return n;
650324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
651324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
652324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual string LocationDescription() {
653324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return LocationDescription(
654324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                currentGrammarFileName.Peek(),
655324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                currentRuleName.Peek(),
656324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                currentLine.Peek(),
657324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver                currentPos.Peek());
658324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
659324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
660324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        protected virtual string LocationDescription(string file, string rule, int line, int pos) {
661324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            return file + ":" + line + ":" + pos + "(" + rule + ")";
662324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
663324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
664324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public class ProfileStats {
665324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public string Version;
666324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public string name;
667324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numRuleInvocations;
668324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numUniqueRulesInvoked;
669324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numDecisionEvents;
670324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numDecisionsCovered;
671324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numDecisionsThatPotentiallyBacktrack;
672324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numDecisionsThatDoBacktrack;
673324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int maxRuleInvocationDepth;
674324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public float avgkPerDecisionEvent;
675324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public float avgkPerBacktrackingDecisionEvent;
676324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public float averageDecisionPercentBacktracks;
677324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numBacktrackOccurrences; // doesn't count gated DFA edges
678324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
679324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numFixedDecisions;
680324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int minDecisionMaxFixedLookaheads;
681324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int maxDecisionMaxFixedLookaheads;
682324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int avgDecisionMaxFixedLookaheads;
683324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int stddevDecisionMaxFixedLookaheads;
684324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numCyclicDecisions;
685324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int minDecisionMaxCyclicLookaheads;
686324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int maxDecisionMaxCyclicLookaheads;
687324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int avgDecisionMaxCyclicLookaheads;
688324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int stddevDecisionMaxCyclicLookaheads;
689324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		int Stats.min(toArray(decisionMaxSynPredLookaheads);
690324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		int Stats.max(toArray(decisionMaxSynPredLookaheads);
691324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		int Stats.avg(toArray(decisionMaxSynPredLookaheads);
692324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            //		int Stats.stddev(toArray(decisionMaxSynPredLookaheads);
693324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numSemanticPredicates;
694324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numTokens;
695324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numHiddenTokens;
696324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numCharsMatched;
697324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numHiddenCharsMatched;
698324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numReportedErrors;
699324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numMemoizationCacheHits;
700324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numMemoizationCacheMisses;
701324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numGuessingRuleInvocations;
702324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numMemoizationCacheEntries;
703324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
704324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
705324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public class DecisionDescriptor {
706324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int decision;
707324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public string fileName;
708324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public string ruleName;
709324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int line;
710324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int pos;
711324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public bool couldBacktrack;
712324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
713324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int n;
714324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public float avgk; // avg across all decision events
715324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int maxk;
716324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numBacktrackOccurrences;
717324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numSemPredEvals;
718324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
719324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver
720324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        // all about a specific exec of a single decision
721324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        public class DecisionEvent {
722324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public DecisionDescriptor decision;
723324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int startIndex;
724324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int k;
725324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public bool backtracks; // doesn't count gated DFA edges
726324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public bool evalSemPred;
727324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public DateTime startTime;
728324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public DateTime stopTime;
729324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numMemoizationCacheHits;
730324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver            public int numMemoizationCacheMisses;
731324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver        }
732324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver    }
733324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver}
734