calabash-android 0.4.0.pre1 → 0.4.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/calabash-android-build.rb +6 -0
- data/bin/calabash-android-setup.rb +2 -3
- data/lib/calabash-android/canned_steps.md +1 -1
- data/lib/calabash-android/helpers.rb +35 -2
- data/lib/calabash-android/lib/TestServer.apk +0 -0
- data/lib/calabash-android/operations.rb +13 -6
- data/lib/calabash-android/version.rb +1 -1
- data/test-server/instrumentation-backend/.classpath +2 -1
- data/test-server/instrumentation-backend/antlr.sh +2 -0
- data/test-server/instrumentation-backend/antlr/UIQuery.g +70 -0
- data/test-server/instrumentation-backend/antlr/UIQuery.tokens +12 -0
- data/test-server/instrumentation-backend/build-libs/antlr-3.4-complete.jar +0 -0
- data/test-server/instrumentation-backend/build-libs/junit.jar +0 -0
- data/test-server/instrumentation-backend/build.xml +56 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRFileStream.java +78 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRInputStream.java +70 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRReaderStream.java +95 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ANTLRStringStream.java +230 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BaseRecognizer.java +894 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BitSet.java +325 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/BufferedTokenStream.java +272 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStream.java +57 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CharStreamState.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ClassicToken.java +141 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonToken.java +191 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/CommonTokenStream.java +153 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/DFA.java +250 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/EarlyExitException.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/FailedPredicateException.java +54 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/IntStream.java +122 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/LegacyCommonTokenStream.java +394 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Lexer.java +340 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedNotSetException.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedRangeException.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedSetException.java +44 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTokenException.java +45 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MismatchedTreeNodeException.java +49 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/MissingTokenException.java +56 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/NoViableAltException.java +57 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Parser.java +98 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/ParserRuleReturnScope.java +52 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognitionException.java +180 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RecognizerSharedState.java +144 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/RuleReturnScope.java +42 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/SerializedGrammar.java +204 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/Token.java +92 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenRewriteStream.java +569 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenSource.java +54 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/TokenStream.java +75 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/UnbufferedTokenStream.java +82 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/UnwantedTokenException.java +53 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/BlankDebugEventListener.java +77 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventHub.java +292 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventListener.java +323 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventRepeater.java +88 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugEventSocketProxy.java +358 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugParser.java +101 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTokenStream.java +156 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeAdaptor.java +250 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeNodeStream.java +155 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/DebugTreeParser.java +112 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/ParseTreeBuilder.java +109 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Profiler.java +772 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/RemoteDebugEventSocketListener.java +541 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/TraceDebugEventListener.java +108 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/debug/Tracer.java +69 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/DoubleKeyMap.java +62 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/FastQueue.java +100 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/IntArray.java +87 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/LookaheadStream.java +161 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/misc/Stats.java +189 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTree.java +349 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BaseTreeAdaptor.java +279 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/BufferedTreeNodeStream.java +489 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonErrorNode.java +108 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTree.java +185 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeAdaptor.java +168 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/CommonTreeNodeStream.java +171 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/ParseTree.java +119 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteCardinalityException.java +47 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEarlyExitException.java +39 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteEmptyStreamException.java +35 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleElementStream.java +210 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleNodeStream.java +70 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleSubtreeStream.java +86 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/RewriteRuleTokenStream.java +76 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/Tree.java +127 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeAdaptor.java +263 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeFilter.java +135 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeIterator.java +132 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeNodeStream.java +106 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeParser.java +169 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternLexer.java +135 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreePatternParser.java +154 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRewriter.java +124 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeRuleReturnScope.java +41 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitor.java +69 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeVisitorAction.java +47 -0
- data/test-server/instrumentation-backend/src/org/antlr/runtime/tree/TreeWizard.java +531 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/ClearAppData.java +22 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/InstrumentationBackend.java +4 -4
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/Result.java +0 -1
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/HttpServer.java +161 -129
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetActivityOrientation.java +5 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/view/GetViewProperty.java +1 -7
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/Query.java +70 -61
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/UIQuery.tokens +12 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ViewMapper.java +63 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQuery.tokens +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryLexer.java +945 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/antlr/UIQueryParser.java +463 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/InvalidUIQueryException.java +10 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryAST.java +8 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTClassName.java +115 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryASTWith.java +157 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryDirection.java +5 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryEvaluator.java +205 -0
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/query/ast/UIQueryUtils.java +135 -0
- data/test-server/instrumentation-backend/tests/sh/calaba/instrumentationbackend/query/tests/UIQueryTest.java +134 -0
- metadata +106 -3
- data/test-server/instrumentation-backend/src/sh/calaba/instrumentationbackend/actions/activity/SetOrientation.java +0 -39
@@ -0,0 +1,155 @@
|
|
1
|
+
/*
|
2
|
+
[The "BSD license"]
|
3
|
+
Copyright (c) 2005-2009 Terence Parr
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions
|
8
|
+
are met:
|
9
|
+
1. Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the distribution.
|
14
|
+
3. The name of the author may not be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*/
|
28
|
+
package org.antlr.runtime.debug;
|
29
|
+
|
30
|
+
import org.antlr.runtime.tree.TreeAdaptor;
|
31
|
+
import org.antlr.runtime.tree.TreeNodeStream;
|
32
|
+
import org.antlr.runtime.TokenStream;
|
33
|
+
|
34
|
+
/** Debug any tree node stream. The constructor accepts the stream
|
35
|
+
* and a debug listener. As node stream calls come in, debug events
|
36
|
+
* are triggered.
|
37
|
+
*/
|
38
|
+
public class DebugTreeNodeStream implements TreeNodeStream {
|
39
|
+
protected DebugEventListener dbg;
|
40
|
+
protected TreeAdaptor adaptor;
|
41
|
+
protected TreeNodeStream input;
|
42
|
+
protected boolean initialStreamState = true;
|
43
|
+
|
44
|
+
/** Track the last mark() call result value for use in rewind(). */
|
45
|
+
protected int lastMarker;
|
46
|
+
|
47
|
+
public DebugTreeNodeStream(TreeNodeStream input,
|
48
|
+
DebugEventListener dbg)
|
49
|
+
{
|
50
|
+
this.input = input;
|
51
|
+
this.adaptor = input.getTreeAdaptor();
|
52
|
+
this.input.setUniqueNavigationNodes(true);
|
53
|
+
setDebugListener(dbg);
|
54
|
+
}
|
55
|
+
|
56
|
+
public void setDebugListener(DebugEventListener dbg) {
|
57
|
+
this.dbg = dbg;
|
58
|
+
}
|
59
|
+
|
60
|
+
public TreeAdaptor getTreeAdaptor() {
|
61
|
+
return adaptor;
|
62
|
+
}
|
63
|
+
|
64
|
+
public void consume() {
|
65
|
+
Object node = input.LT(1);
|
66
|
+
input.consume();
|
67
|
+
dbg.consumeNode(node);
|
68
|
+
}
|
69
|
+
|
70
|
+
public Object get(int i) {
|
71
|
+
return input.get(i);
|
72
|
+
}
|
73
|
+
|
74
|
+
public Object LT(int i) {
|
75
|
+
Object node = input.LT(i);
|
76
|
+
int ID = adaptor.getUniqueID(node);
|
77
|
+
String text = adaptor.getText(node);
|
78
|
+
int type = adaptor.getType(node);
|
79
|
+
dbg.LT(i, node);
|
80
|
+
return node;
|
81
|
+
}
|
82
|
+
|
83
|
+
public int LA(int i) {
|
84
|
+
Object node = input.LT(i);
|
85
|
+
int ID = adaptor.getUniqueID(node);
|
86
|
+
String text = adaptor.getText(node);
|
87
|
+
int type = adaptor.getType(node);
|
88
|
+
dbg.LT(i, node);
|
89
|
+
return type;
|
90
|
+
}
|
91
|
+
|
92
|
+
public int mark() {
|
93
|
+
lastMarker = input.mark();
|
94
|
+
dbg.mark(lastMarker);
|
95
|
+
return lastMarker;
|
96
|
+
}
|
97
|
+
|
98
|
+
public int index() {
|
99
|
+
return input.index();
|
100
|
+
}
|
101
|
+
|
102
|
+
public void rewind(int marker) {
|
103
|
+
dbg.rewind(marker);
|
104
|
+
input.rewind(marker);
|
105
|
+
}
|
106
|
+
|
107
|
+
public void rewind() {
|
108
|
+
dbg.rewind();
|
109
|
+
input.rewind(lastMarker);
|
110
|
+
}
|
111
|
+
|
112
|
+
public void release(int marker) {
|
113
|
+
}
|
114
|
+
|
115
|
+
public void seek(int index) {
|
116
|
+
// TODO: implement seek in dbg interface
|
117
|
+
// db.seek(index);
|
118
|
+
input.seek(index);
|
119
|
+
}
|
120
|
+
|
121
|
+
public int size() {
|
122
|
+
return input.size();
|
123
|
+
}
|
124
|
+
|
125
|
+
public void reset() { ; }
|
126
|
+
|
127
|
+
public Object getTreeSource() {
|
128
|
+
return input;
|
129
|
+
}
|
130
|
+
|
131
|
+
public String getSourceName() {
|
132
|
+
return getTokenStream().getSourceName();
|
133
|
+
}
|
134
|
+
|
135
|
+
public TokenStream getTokenStream() {
|
136
|
+
return input.getTokenStream();
|
137
|
+
}
|
138
|
+
|
139
|
+
/** It is normally this object that instructs the node stream to
|
140
|
+
* create unique nav nodes, but to satisfy interface, we have to
|
141
|
+
* define it. It might be better to ignore the parameter but
|
142
|
+
* there might be a use for it later, so I'll leave.
|
143
|
+
*/
|
144
|
+
public void setUniqueNavigationNodes(boolean uniqueNavigationNodes) {
|
145
|
+
input.setUniqueNavigationNodes(uniqueNavigationNodes);
|
146
|
+
}
|
147
|
+
|
148
|
+
public void replaceChildren(Object parent, int startChildIndex, int stopChildIndex, Object t) {
|
149
|
+
input.replaceChildren(parent, startChildIndex, stopChildIndex, t);
|
150
|
+
}
|
151
|
+
|
152
|
+
public String toString(Object start, Object stop) {
|
153
|
+
return input.toString(start,stop);
|
154
|
+
}
|
155
|
+
}
|
@@ -0,0 +1,112 @@
|
|
1
|
+
/*
|
2
|
+
[The "BSD license"]
|
3
|
+
Copyright (c) 2005-2009 Terence Parr
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions
|
8
|
+
are met:
|
9
|
+
1. Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the distribution.
|
14
|
+
3. The name of the author may not be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*/
|
28
|
+
package org.antlr.runtime.debug;
|
29
|
+
|
30
|
+
import org.antlr.runtime.*;
|
31
|
+
import org.antlr.runtime.tree.TreeNodeStream;
|
32
|
+
import org.antlr.runtime.tree.TreeParser;
|
33
|
+
|
34
|
+
import java.io.IOException;
|
35
|
+
|
36
|
+
public class DebugTreeParser extends TreeParser {
|
37
|
+
/** Who to notify when events in the parser occur. */
|
38
|
+
protected DebugEventListener dbg = null;
|
39
|
+
|
40
|
+
private static final String TAG = "ANTLR:DEBUG:DebugTreeParser";
|
41
|
+
|
42
|
+
/** Used to differentiate between fixed lookahead and cyclic DFA decisions
|
43
|
+
* while profiling.
|
44
|
+
*/
|
45
|
+
public boolean isCyclicDecision = false;
|
46
|
+
|
47
|
+
/** Create a normal parser except wrap the token stream in a debug
|
48
|
+
* proxy that fires consume events.
|
49
|
+
*/
|
50
|
+
public DebugTreeParser(TreeNodeStream input, DebugEventListener dbg, RecognizerSharedState state) {
|
51
|
+
super(input instanceof DebugTreeNodeStream?input:new DebugTreeNodeStream(input,dbg), state);
|
52
|
+
setDebugListener(dbg);
|
53
|
+
}
|
54
|
+
|
55
|
+
public DebugTreeParser(TreeNodeStream input, RecognizerSharedState state) {
|
56
|
+
super(input instanceof DebugTreeNodeStream?input:new DebugTreeNodeStream(input,null), state);
|
57
|
+
}
|
58
|
+
|
59
|
+
public DebugTreeParser(TreeNodeStream input, DebugEventListener dbg) {
|
60
|
+
this(input instanceof DebugTreeNodeStream?input:new DebugTreeNodeStream(input,dbg), dbg, null);
|
61
|
+
}
|
62
|
+
|
63
|
+
/** Provide a new debug event listener for this parser. Notify the
|
64
|
+
* input stream too that it should send events to this listener.
|
65
|
+
*/
|
66
|
+
public void setDebugListener(DebugEventListener dbg) {
|
67
|
+
if ( input instanceof DebugTreeNodeStream ) {
|
68
|
+
((DebugTreeNodeStream)input).setDebugListener(dbg);
|
69
|
+
}
|
70
|
+
this.dbg = dbg;
|
71
|
+
}
|
72
|
+
|
73
|
+
public DebugEventListener getDebugListener() {
|
74
|
+
return dbg;
|
75
|
+
}
|
76
|
+
|
77
|
+
public void reportError(IOException e) {
|
78
|
+
//System.err.println(e);
|
79
|
+
//e.printStackTrace(System.err);
|
80
|
+
android.util.Log.e(TAG, android.util.Log.getStackTraceString(e));
|
81
|
+
}
|
82
|
+
|
83
|
+
public void reportError(RecognitionException e) {
|
84
|
+
dbg.recognitionException(e);
|
85
|
+
}
|
86
|
+
|
87
|
+
protected Object getMissingSymbol(IntStream input,
|
88
|
+
RecognitionException e,
|
89
|
+
int expectedTokenType,
|
90
|
+
BitSet follow)
|
91
|
+
{
|
92
|
+
Object o = super.getMissingSymbol(input, e, expectedTokenType, follow);
|
93
|
+
dbg.consumeNode(o);
|
94
|
+
return o;
|
95
|
+
}
|
96
|
+
|
97
|
+
public void beginResync() {
|
98
|
+
dbg.beginResync();
|
99
|
+
}
|
100
|
+
|
101
|
+
public void endResync() {
|
102
|
+
dbg.endResync();
|
103
|
+
}
|
104
|
+
|
105
|
+
public void beginBacktrack(int level) {
|
106
|
+
dbg.beginBacktrack(level);
|
107
|
+
}
|
108
|
+
|
109
|
+
public void endBacktrack(int level, boolean successful) {
|
110
|
+
dbg.endBacktrack(level,successful);
|
111
|
+
}
|
112
|
+
}
|
@@ -0,0 +1,109 @@
|
|
1
|
+
/*
|
2
|
+
[The "BSD license"]
|
3
|
+
Copyright (c) 2005-2009 Terence Parr
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions
|
8
|
+
are met:
|
9
|
+
1. Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the distribution.
|
14
|
+
3. The name of the author may not be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*/
|
28
|
+
package org.antlr.runtime.debug;
|
29
|
+
|
30
|
+
import org.antlr.runtime.RecognitionException;
|
31
|
+
import org.antlr.runtime.Token;
|
32
|
+
import org.antlr.runtime.tree.ParseTree;
|
33
|
+
|
34
|
+
import java.util.Stack;
|
35
|
+
import java.util.ArrayList;
|
36
|
+
import java.util.List;
|
37
|
+
|
38
|
+
/** This parser listener tracks rule entry/exit and token matches
|
39
|
+
* to build a simple parse tree using ParseTree nodes.
|
40
|
+
*/
|
41
|
+
public class ParseTreeBuilder extends BlankDebugEventListener {
|
42
|
+
public static final String EPSILON_PAYLOAD = "<epsilon>";
|
43
|
+
|
44
|
+
Stack callStack = new Stack();
|
45
|
+
List hiddenTokens = new ArrayList();
|
46
|
+
int backtracking = 0;
|
47
|
+
|
48
|
+
public ParseTreeBuilder(String grammarName) {
|
49
|
+
ParseTree root = create("<grammar "+grammarName+">");
|
50
|
+
callStack.push(root);
|
51
|
+
}
|
52
|
+
|
53
|
+
public ParseTree getTree() {
|
54
|
+
return (ParseTree)callStack.elementAt(0);
|
55
|
+
}
|
56
|
+
|
57
|
+
/** What kind of node to create. You might want to override
|
58
|
+
* so I factored out creation here.
|
59
|
+
*/
|
60
|
+
public ParseTree create(Object payload) {
|
61
|
+
return new ParseTree(payload);
|
62
|
+
}
|
63
|
+
|
64
|
+
public ParseTree epsilonNode() {
|
65
|
+
return create(EPSILON_PAYLOAD);
|
66
|
+
}
|
67
|
+
|
68
|
+
/** Backtracking or cyclic DFA, don't want to add nodes to tree */
|
69
|
+
public void enterDecision(int d, boolean couldBacktrack) { backtracking++; }
|
70
|
+
public void exitDecision(int i) { backtracking--; }
|
71
|
+
|
72
|
+
public void enterRule(String filename, String ruleName) {
|
73
|
+
if ( backtracking>0 ) return;
|
74
|
+
ParseTree parentRuleNode = (ParseTree)callStack.peek();
|
75
|
+
ParseTree ruleNode = create(ruleName);
|
76
|
+
parentRuleNode.addChild(ruleNode);
|
77
|
+
callStack.push(ruleNode);
|
78
|
+
}
|
79
|
+
|
80
|
+
public void exitRule(String filename, String ruleName) {
|
81
|
+
if ( backtracking>0 ) return;
|
82
|
+
ParseTree ruleNode = (ParseTree)callStack.peek();
|
83
|
+
if ( ruleNode.getChildCount()==0 ) {
|
84
|
+
ruleNode.addChild(epsilonNode());
|
85
|
+
}
|
86
|
+
callStack.pop();
|
87
|
+
}
|
88
|
+
|
89
|
+
public void consumeToken(Token token) {
|
90
|
+
if ( backtracking>0 ) return;
|
91
|
+
ParseTree ruleNode = (ParseTree)callStack.peek();
|
92
|
+
ParseTree elementNode = create(token);
|
93
|
+
elementNode.hiddenTokens = this.hiddenTokens;
|
94
|
+
this.hiddenTokens = new ArrayList();
|
95
|
+
ruleNode.addChild(elementNode);
|
96
|
+
}
|
97
|
+
|
98
|
+
public void consumeHiddenToken(Token token) {
|
99
|
+
if ( backtracking>0 ) return;
|
100
|
+
hiddenTokens.add(token);
|
101
|
+
}
|
102
|
+
|
103
|
+
public void recognitionException(RecognitionException e) {
|
104
|
+
if ( backtracking>0 ) return;
|
105
|
+
ParseTree ruleNode = (ParseTree)callStack.peek();
|
106
|
+
ParseTree errorNode = create(e);
|
107
|
+
ruleNode.addChild(errorNode);
|
108
|
+
}
|
109
|
+
}
|
@@ -0,0 +1,772 @@
|
|
1
|
+
/*
|
2
|
+
[The "BSD license"]
|
3
|
+
Copyright (c) 2005-2009 Terence Parr
|
4
|
+
All rights reserved.
|
5
|
+
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
7
|
+
modification, are permitted provided that the following conditions
|
8
|
+
are met:
|
9
|
+
1. Redistributions of source code must retain the above copyright
|
10
|
+
notice, this list of conditions and the following disclaimer.
|
11
|
+
2. Redistributions in binary form must reproduce the above copyright
|
12
|
+
notice, this list of conditions and the following disclaimer in the
|
13
|
+
documentation and/or other materials provided with the distribution.
|
14
|
+
3. The name of the author may not be used to endorse or promote products
|
15
|
+
derived from this software without specific prior written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
18
|
+
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
19
|
+
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
21
|
+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
22
|
+
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
24
|
+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
26
|
+
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27
|
+
*/
|
28
|
+
package org.antlr.runtime.debug;
|
29
|
+
|
30
|
+
import org.antlr.runtime.*;
|
31
|
+
import org.antlr.runtime.misc.DoubleKeyMap;
|
32
|
+
|
33
|
+
import java.util.*;
|
34
|
+
|
35
|
+
/** Using the debug event interface, track what is happening in the parser
|
36
|
+
* and record statistics about the runtime.
|
37
|
+
*/
|
38
|
+
public class Profiler extends BlankDebugEventListener {
|
39
|
+
public static final String DATA_SEP = "\t";
|
40
|
+
public static final String newline = System.getProperty("line.separator");
|
41
|
+
|
42
|
+
static boolean dump = false;
|
43
|
+
|
44
|
+
private static final String TAG = "ANTLR:DEBUG:Profiler";
|
45
|
+
|
46
|
+
public static class ProfileStats {
|
47
|
+
public String Version;
|
48
|
+
public String name;
|
49
|
+
public int numRuleInvocations;
|
50
|
+
public int numUniqueRulesInvoked;
|
51
|
+
public int numDecisionEvents;
|
52
|
+
public int numDecisionsCovered;
|
53
|
+
public int numDecisionsThatPotentiallyBacktrack;
|
54
|
+
public int numDecisionsThatDoBacktrack;
|
55
|
+
public int maxRuleInvocationDepth;
|
56
|
+
public float avgkPerDecisionEvent;
|
57
|
+
public float avgkPerBacktrackingDecisionEvent;
|
58
|
+
public float averageDecisionPercentBacktracks;
|
59
|
+
public int numBacktrackOccurrences; // doesn't count gated DFA edges
|
60
|
+
|
61
|
+
public int numFixedDecisions;
|
62
|
+
public int minDecisionMaxFixedLookaheads;
|
63
|
+
public int maxDecisionMaxFixedLookaheads;
|
64
|
+
public int avgDecisionMaxFixedLookaheads;
|
65
|
+
public int stddevDecisionMaxFixedLookaheads;
|
66
|
+
public int numCyclicDecisions;
|
67
|
+
public int minDecisionMaxCyclicLookaheads;
|
68
|
+
public int maxDecisionMaxCyclicLookaheads;
|
69
|
+
public int avgDecisionMaxCyclicLookaheads;
|
70
|
+
public int stddevDecisionMaxCyclicLookaheads;
|
71
|
+
// int Stats.min(toArray(decisionMaxSynPredLookaheads);
|
72
|
+
// int Stats.max(toArray(decisionMaxSynPredLookaheads);
|
73
|
+
// int Stats.avg(toArray(decisionMaxSynPredLookaheads);
|
74
|
+
// int Stats.stddev(toArray(decisionMaxSynPredLookaheads);
|
75
|
+
public int numSemanticPredicates;
|
76
|
+
public int numTokens;
|
77
|
+
public int numHiddenTokens;
|
78
|
+
public int numCharsMatched;
|
79
|
+
public int numHiddenCharsMatched;
|
80
|
+
public int numReportedErrors;
|
81
|
+
public int numMemoizationCacheHits;
|
82
|
+
public int numMemoizationCacheMisses;
|
83
|
+
public int numGuessingRuleInvocations;
|
84
|
+
public int numMemoizationCacheEntries;
|
85
|
+
}
|
86
|
+
|
87
|
+
public static class DecisionDescriptor {
|
88
|
+
public int decision;
|
89
|
+
public String fileName;
|
90
|
+
public String ruleName;
|
91
|
+
public int line;
|
92
|
+
public int pos;
|
93
|
+
public boolean couldBacktrack;
|
94
|
+
|
95
|
+
public int n;
|
96
|
+
public float avgk; // avg across all decision events
|
97
|
+
public int maxk;
|
98
|
+
public int numBacktrackOccurrences;
|
99
|
+
public int numSemPredEvals;
|
100
|
+
}
|
101
|
+
|
102
|
+
// all about a specific exec of a single decision
|
103
|
+
public static class DecisionEvent {
|
104
|
+
public DecisionDescriptor decision;
|
105
|
+
public int startIndex;
|
106
|
+
public int k;
|
107
|
+
public boolean backtracks; // doesn't count gated DFA edges
|
108
|
+
public boolean evalSemPred;
|
109
|
+
public long startTime;
|
110
|
+
public long stopTime;
|
111
|
+
public int numMemoizationCacheHits;
|
112
|
+
public int numMemoizationCacheMisses;
|
113
|
+
}
|
114
|
+
|
115
|
+
/** Because I may change the stats, I need to track that for later
|
116
|
+
* computations to be consistent.
|
117
|
+
*/
|
118
|
+
public static final String Version = "3";
|
119
|
+
public static final String RUNTIME_STATS_FILENAME = "runtime.stats";
|
120
|
+
|
121
|
+
/** Ack, should not store parser; can't do remote stuff. Well, we pass
|
122
|
+
* input stream around too so I guess it's ok.
|
123
|
+
*/
|
124
|
+
public DebugParser parser = null;
|
125
|
+
|
126
|
+
// working variables
|
127
|
+
|
128
|
+
protected int ruleLevel = 0;
|
129
|
+
//protected int decisionLevel = 0;
|
130
|
+
protected Token lastRealTokenTouchedInDecision;
|
131
|
+
protected Set<String> uniqueRules = new HashSet<String>();
|
132
|
+
protected Stack<String> currentGrammarFileName = new Stack();
|
133
|
+
protected Stack<String> currentRuleName = new Stack();
|
134
|
+
protected Stack<Integer> currentLine = new Stack();
|
135
|
+
protected Stack<Integer> currentPos = new Stack();
|
136
|
+
|
137
|
+
// Vector<DecisionStats>
|
138
|
+
//protected Vector decisions = new Vector(200); // need setSize
|
139
|
+
protected DoubleKeyMap<String,Integer, DecisionDescriptor> decisions =
|
140
|
+
new DoubleKeyMap<String,Integer, DecisionDescriptor>();
|
141
|
+
|
142
|
+
// Record a DecisionData for each decision we hit while parsing
|
143
|
+
protected List<DecisionEvent> decisionEvents = new ArrayList<DecisionEvent>();
|
144
|
+
protected Stack<DecisionEvent> decisionStack = new Stack<DecisionEvent>();
|
145
|
+
|
146
|
+
protected int backtrackDepth;
|
147
|
+
|
148
|
+
ProfileStats stats = new ProfileStats();
|
149
|
+
|
150
|
+
public Profiler() {
|
151
|
+
}
|
152
|
+
|
153
|
+
public Profiler(DebugParser parser) {
|
154
|
+
this.parser = parser;
|
155
|
+
}
|
156
|
+
|
157
|
+
public void enterRule(String grammarFileName, String ruleName) {
|
158
|
+
// System.out.println("enterRule "+grammarFileName+":"+ruleName);
|
159
|
+
ruleLevel++;
|
160
|
+
stats.numRuleInvocations++;
|
161
|
+
uniqueRules.add(grammarFileName+":"+ruleName);
|
162
|
+
stats.maxRuleInvocationDepth = Math.max(stats.maxRuleInvocationDepth, ruleLevel);
|
163
|
+
currentGrammarFileName.push( grammarFileName );
|
164
|
+
currentRuleName.push( ruleName );
|
165
|
+
}
|
166
|
+
|
167
|
+
public void exitRule(String grammarFileName, String ruleName) {
|
168
|
+
ruleLevel--;
|
169
|
+
currentGrammarFileName.pop();
|
170
|
+
currentRuleName.pop();
|
171
|
+
}
|
172
|
+
|
173
|
+
/** Track memoization; this is not part of standard debug interface
|
174
|
+
* but is triggered by profiling. Code gen inserts an override
|
175
|
+
* for this method in the recognizer, which triggers this method.
|
176
|
+
* Called from alreadyParsedRule().
|
177
|
+
*/
|
178
|
+
public void examineRuleMemoization(IntStream input,
|
179
|
+
int ruleIndex,
|
180
|
+
int stopIndex, // index or MEMO_RULE_UNKNOWN...
|
181
|
+
String ruleName)
|
182
|
+
{
|
183
|
+
if (dump) System.out.println("examine memo "+ruleName+" at "+input.index()+": "+stopIndex);
|
184
|
+
if ( stopIndex==BaseRecognizer.MEMO_RULE_UNKNOWN ) {
|
185
|
+
//System.out.println("rule "+ruleIndex+" missed @ "+input.index());
|
186
|
+
stats.numMemoizationCacheMisses++;
|
187
|
+
stats.numGuessingRuleInvocations++; // we'll have to enter
|
188
|
+
currentDecision().numMemoizationCacheMisses++;
|
189
|
+
}
|
190
|
+
else {
|
191
|
+
// regardless of rule success/failure, if in cache, we have a cache hit
|
192
|
+
//System.out.println("rule "+ruleIndex+" hit @ "+input.index());
|
193
|
+
stats.numMemoizationCacheHits++;
|
194
|
+
currentDecision().numMemoizationCacheHits++;
|
195
|
+
}
|
196
|
+
}
|
197
|
+
|
198
|
+
/** Warning: doesn't track success/failure, just unique recording event */
|
199
|
+
public void memoize(IntStream input,
|
200
|
+
int ruleIndex,
|
201
|
+
int ruleStartIndex,
|
202
|
+
String ruleName)
|
203
|
+
{
|
204
|
+
// count how many entries go into table
|
205
|
+
if (dump) { //System.out.println("memoize "+ruleName);
|
206
|
+
android.util.Log.i(TAG, "memoize "+ruleName);
|
207
|
+
}
|
208
|
+
stats.numMemoizationCacheEntries++;
|
209
|
+
}
|
210
|
+
|
211
|
+
@Override
|
212
|
+
public void location(int line, int pos) {
|
213
|
+
currentLine.push(line);
|
214
|
+
currentPos.push(pos);
|
215
|
+
}
|
216
|
+
|
217
|
+
public void enterDecision(int decisionNumber, boolean couldBacktrack) {
|
218
|
+
lastRealTokenTouchedInDecision = null;
|
219
|
+
stats.numDecisionEvents++;
|
220
|
+
int startingLookaheadIndex = parser.getTokenStream().index();
|
221
|
+
TokenStream input = parser.getTokenStream();
|
222
|
+
if ( dump ) { //System.out.println("enterDecision canBacktrack="+couldBacktrack+" "+ decisionNumber +
|
223
|
+
//" backtrack depth " + backtrackDepth +
|
224
|
+
//" @ " + input.get(input.index()) +
|
225
|
+
//" rule " +locationDescription());
|
226
|
+
|
227
|
+
android.util.Log.i(TAG, "enterDecision canBacktrack="+couldBacktrack+" "+ decisionNumber +
|
228
|
+
" backtrack depth " + backtrackDepth +
|
229
|
+
" @ " + input.get(input.index()) +
|
230
|
+
" rule " +locationDescription());
|
231
|
+
}
|
232
|
+
String g = (String) currentGrammarFileName.peek();
|
233
|
+
DecisionDescriptor descriptor = decisions.get(g, decisionNumber);
|
234
|
+
if ( descriptor == null ) {
|
235
|
+
descriptor = new DecisionDescriptor();
|
236
|
+
decisions.put(g, decisionNumber, descriptor);
|
237
|
+
descriptor.decision = decisionNumber;
|
238
|
+
descriptor.fileName = (String)currentGrammarFileName.peek();
|
239
|
+
descriptor.ruleName = (String)currentRuleName.peek();
|
240
|
+
descriptor.line = (Integer)currentLine.peek();
|
241
|
+
descriptor.pos = (Integer)currentPos.peek();
|
242
|
+
descriptor.couldBacktrack = couldBacktrack;
|
243
|
+
}
|
244
|
+
descriptor.n++;
|
245
|
+
|
246
|
+
DecisionEvent d = new DecisionEvent();
|
247
|
+
decisionStack.push(d);
|
248
|
+
d.decision = descriptor;
|
249
|
+
d.startTime = System.currentTimeMillis();
|
250
|
+
d.startIndex = startingLookaheadIndex;
|
251
|
+
}
|
252
|
+
|
253
|
+
public void exitDecision(int decisionNumber) {
|
254
|
+
DecisionEvent d = decisionStack.pop();
|
255
|
+
d.stopTime = System.currentTimeMillis();
|
256
|
+
|
257
|
+
int lastTokenIndex = lastRealTokenTouchedInDecision.getTokenIndex();
|
258
|
+
int numHidden = getNumberOfHiddenTokens(d.startIndex, lastTokenIndex);
|
259
|
+
int depth = lastTokenIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
|
260
|
+
d.k = depth;
|
261
|
+
d.decision.maxk = Math.max(d.decision.maxk, depth);
|
262
|
+
|
263
|
+
if (dump) { //System.out.println("exitDecision "+decisionNumber+" in "+d.decision.ruleName+
|
264
|
+
//" lookahead "+d.k +" max token "+lastRealTokenTouchedInDecision);
|
265
|
+
android.util.Log.i(TAG, "exitDecision "+decisionNumber+" in "+d.decision.ruleName+
|
266
|
+
" lookahead "+d.k +" max token "+lastRealTokenTouchedInDecision);
|
267
|
+
}
|
268
|
+
decisionEvents.add(d); // done with decision; track all
|
269
|
+
}
|
270
|
+
|
271
|
+
public void consumeToken(Token token) {
|
272
|
+
if (dump) { //System.out.println("consume token "+token);
|
273
|
+
android.util.Log.i(TAG, "consume token "+token);
|
274
|
+
}
|
275
|
+
if ( !inDecision() ) {
|
276
|
+
stats.numTokens++;
|
277
|
+
return;
|
278
|
+
}
|
279
|
+
if ( lastRealTokenTouchedInDecision==null ||
|
280
|
+
lastRealTokenTouchedInDecision.getTokenIndex() < token.getTokenIndex() )
|
281
|
+
{
|
282
|
+
lastRealTokenTouchedInDecision = token;
|
283
|
+
}
|
284
|
+
DecisionEvent d = currentDecision();
|
285
|
+
// compute lookahead depth
|
286
|
+
int thisRefIndex = token.getTokenIndex();
|
287
|
+
int numHidden = getNumberOfHiddenTokens(d.startIndex, thisRefIndex);
|
288
|
+
int depth = thisRefIndex - d.startIndex - numHidden + 1; // +1 counts consuming start token as 1
|
289
|
+
//d.maxk = Math.max(d.maxk, depth);
|
290
|
+
if (dump) { //System.out.println("consume "+thisRefIndex+" "+depth+" tokens ahead in "+
|
291
|
+
//d.decision.ruleName+"-"+d.decision.decision+" start index "+d.startIndex);
|
292
|
+
android.util.Log.i(TAG, "consume "+thisRefIndex+" "+depth+" tokens ahead in "+
|
293
|
+
d.decision.ruleName+"-"+d.decision.decision+" start index "+d.startIndex);
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
/** The parser is in a decision if the decision depth > 0. This
|
298
|
+
* works for backtracking also, which can have nested decisions.
|
299
|
+
*/
|
300
|
+
public boolean inDecision() {
|
301
|
+
return decisionStack.size()>0;
|
302
|
+
}
|
303
|
+
|
304
|
+
public void consumeHiddenToken(Token token) {
|
305
|
+
//System.out.println("consume hidden token "+token);
|
306
|
+
if ( !inDecision() ) stats.numHiddenTokens++;
|
307
|
+
}
|
308
|
+
|
309
|
+
/** Track refs to lookahead if in a fixed/nonfixed decision.
|
310
|
+
*/
|
311
|
+
public void LT(int i, Token t) {
|
312
|
+
if ( inDecision() && i>0 ) {
|
313
|
+
DecisionEvent d = currentDecision();
|
314
|
+
if (dump) { //System.out.println("LT("+i+")="+t+" index "+t.getTokenIndex()+" relative to "+d.decision.ruleName+"-"+
|
315
|
+
//d.decision.decision+" start index "+d.startIndex);
|
316
|
+
android.util.Log.i(TAG, "LT("+i+")="+t+" index "+t.getTokenIndex()+" relative to "+d.decision.ruleName+"-"+
|
317
|
+
d.decision.decision+" start index "+d.startIndex);
|
318
|
+
}
|
319
|
+
if ( lastRealTokenTouchedInDecision==null ||
|
320
|
+
lastRealTokenTouchedInDecision.getTokenIndex() < t.getTokenIndex() )
|
321
|
+
{
|
322
|
+
lastRealTokenTouchedInDecision = t;
|
323
|
+
if (dump) { //System.out.println("set last token "+lastRealTokenTouchedInDecision);
|
324
|
+
android.util.Log.i(TAG, "set last token "+lastRealTokenTouchedInDecision);
|
325
|
+
}
|
326
|
+
}
|
327
|
+
// get starting index off stack
|
328
|
+
// int stackTop = lookaheadStack.size()-1;
|
329
|
+
// Integer startingIndex = (Integer)lookaheadStack.get(stackTop);
|
330
|
+
// // compute lookahead depth
|
331
|
+
// int thisRefIndex = parser.getTokenStream().index();
|
332
|
+
// int numHidden =
|
333
|
+
// getNumberOfHiddenTokens(startingIndex.intValue(), thisRefIndex);
|
334
|
+
// int depth = i + thisRefIndex - startingIndex.intValue() - numHidden;
|
335
|
+
// /*
|
336
|
+
// System.out.println("LT("+i+") @ index "+thisRefIndex+" is depth "+depth+
|
337
|
+
// " max is "+maxLookaheadInCurrentDecision);
|
338
|
+
// */
|
339
|
+
// if ( depth>maxLookaheadInCurrentDecision ) {
|
340
|
+
// maxLookaheadInCurrentDecision = depth;
|
341
|
+
// }
|
342
|
+
// d.maxk = currentDecision()/
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
/** Track backtracking decisions. You'll see a fixed or cyclic decision
|
347
|
+
* and then a backtrack.
|
348
|
+
*
|
349
|
+
* enter rule
|
350
|
+
* ...
|
351
|
+
* enter decision
|
352
|
+
* LA and possibly consumes (for cyclic DFAs)
|
353
|
+
* begin backtrack level
|
354
|
+
* mark m
|
355
|
+
* rewind m
|
356
|
+
* end backtrack level, success
|
357
|
+
* exit decision
|
358
|
+
* ...
|
359
|
+
* exit rule
|
360
|
+
*/
|
361
|
+
public void beginBacktrack(int level) {
|
362
|
+
if (dump) { //System.out.println("enter backtrack "+level);
|
363
|
+
android.util.Log.i(TAG, "enter backtrack "+level);
|
364
|
+
}
|
365
|
+
backtrackDepth++;
|
366
|
+
DecisionEvent e = currentDecision();
|
367
|
+
if ( e.decision.couldBacktrack ) {
|
368
|
+
stats.numBacktrackOccurrences++;
|
369
|
+
e.decision.numBacktrackOccurrences++;
|
370
|
+
e.backtracks = true;
|
371
|
+
}
|
372
|
+
}
|
373
|
+
|
374
|
+
/** Successful or not, track how much lookahead synpreds use */
|
375
|
+
public void endBacktrack(int level, boolean successful) {
|
376
|
+
if (dump) { //System.out.println("exit backtrack "+level+": "+successful);
|
377
|
+
android.util.Log.i(TAG, "exit backtrack "+level+": "+successful);
|
378
|
+
}
|
379
|
+
backtrackDepth--;
|
380
|
+
}
|
381
|
+
|
382
|
+
@Override
|
383
|
+
public void mark(int i) {
|
384
|
+
if (dump) { //System.out.println("mark "+i);
|
385
|
+
android.util.Log.i(TAG, "mark "+i);
|
386
|
+
}
|
387
|
+
}
|
388
|
+
|
389
|
+
@Override
|
390
|
+
public void rewind(int i) {
|
391
|
+
if (dump) { //System.out.println("rewind "+i);
|
392
|
+
android.util.Log.i(TAG, "rewind "+i);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
@Override
|
397
|
+
public void rewind() {
|
398
|
+
if (dump) { //System.out.println("rewind");
|
399
|
+
android.util.Log.i(TAG, "rewind");
|
400
|
+
}
|
401
|
+
}
|
402
|
+
|
403
|
+
|
404
|
+
|
405
|
+
protected DecisionEvent currentDecision() {
|
406
|
+
return decisionStack.peek();
|
407
|
+
}
|
408
|
+
|
409
|
+
public void recognitionException(RecognitionException e) {
|
410
|
+
stats.numReportedErrors++;
|
411
|
+
}
|
412
|
+
|
413
|
+
public void semanticPredicate(boolean result, String predicate) {
|
414
|
+
stats.numSemanticPredicates++;
|
415
|
+
if ( inDecision() ) {
|
416
|
+
DecisionEvent d = currentDecision();
|
417
|
+
d.evalSemPred = true;
|
418
|
+
d.decision.numSemPredEvals++;
|
419
|
+
if (dump) { //System.out.println("eval "+predicate+" in "+d.decision.ruleName+"-"+
|
420
|
+
//d.decision.decision);
|
421
|
+
android.util.Log.i(TAG, "eval "+predicate+" in "+d.decision.ruleName+"-"+
|
422
|
+
d.decision.decision);
|
423
|
+
}
|
424
|
+
}
|
425
|
+
}
|
426
|
+
|
427
|
+
public void terminate() {
|
428
|
+
for (DecisionEvent e : decisionEvents) {
|
429
|
+
//System.out.println("decision "+e.decision.decision+": k="+e.k);
|
430
|
+
e.decision.avgk += e.k;
|
431
|
+
stats.avgkPerDecisionEvent += e.k;
|
432
|
+
if ( e.backtracks ) { // doesn't count gated syn preds on DFA edges
|
433
|
+
stats.avgkPerBacktrackingDecisionEvent += e.k;
|
434
|
+
}
|
435
|
+
}
|
436
|
+
stats.averageDecisionPercentBacktracks = 0.0f;
|
437
|
+
for (DecisionDescriptor d : decisions.values()) {
|
438
|
+
stats.numDecisionsCovered++;
|
439
|
+
d.avgk /= (double)d.n;
|
440
|
+
if ( d.couldBacktrack ) {
|
441
|
+
stats.numDecisionsThatPotentiallyBacktrack++;
|
442
|
+
float percentBacktracks = d.numBacktrackOccurrences / (float)d.n;
|
443
|
+
//System.out.println("dec "+d.decision+" backtracks "+percentBacktracks*100+"%");
|
444
|
+
stats.averageDecisionPercentBacktracks += percentBacktracks;
|
445
|
+
}
|
446
|
+
// ignore rules that backtrack along gated DFA edges
|
447
|
+
if ( d.numBacktrackOccurrences > 0 ) {
|
448
|
+
stats.numDecisionsThatDoBacktrack++;
|
449
|
+
}
|
450
|
+
}
|
451
|
+
stats.averageDecisionPercentBacktracks /= stats.numDecisionsThatPotentiallyBacktrack;
|
452
|
+
stats.averageDecisionPercentBacktracks *= 100; // it's a percentage
|
453
|
+
stats.avgkPerDecisionEvent /= stats.numDecisionEvents;
|
454
|
+
stats.avgkPerBacktrackingDecisionEvent /= (double)stats.numBacktrackOccurrences;
|
455
|
+
|
456
|
+
//System.err.println(toString());
|
457
|
+
android.util.Log.e(TAG, toString());
|
458
|
+
//System.err.println(getDecisionStatsDump());
|
459
|
+
android.util.Log.e(TAG, getDecisionStatsDump());
|
460
|
+
|
461
|
+
// String stats = toNotifyString();
|
462
|
+
// try {
|
463
|
+
// Stats.writeReport(RUNTIME_STATS_FILENAME,stats);
|
464
|
+
// }
|
465
|
+
// catch (IOException ioe) {
|
466
|
+
// System.err.println(ioe);
|
467
|
+
// ioe.printStackTrace(System.err);
|
468
|
+
// }
|
469
|
+
}
|
470
|
+
|
471
|
+
public void setParser(DebugParser parser) {
|
472
|
+
this.parser = parser;
|
473
|
+
}
|
474
|
+
|
475
|
+
// R E P O R T I N G
|
476
|
+
|
477
|
+
public String toNotifyString() {
|
478
|
+
StringBuffer buf = new StringBuffer();
|
479
|
+
buf.append(Version);
|
480
|
+
buf.append('\t');
|
481
|
+
buf.append(parser.getClass().getName());
|
482
|
+
// buf.append('\t');
|
483
|
+
// buf.append(numRuleInvocations);
|
484
|
+
// buf.append('\t');
|
485
|
+
// buf.append(maxRuleInvocationDepth);
|
486
|
+
// buf.append('\t');
|
487
|
+
// buf.append(numFixedDecisions);
|
488
|
+
// buf.append('\t');
|
489
|
+
// buf.append(Stats.min(decisionMaxFixedLookaheads));
|
490
|
+
// buf.append('\t');
|
491
|
+
// buf.append(Stats.max(decisionMaxFixedLookaheads));
|
492
|
+
// buf.append('\t');
|
493
|
+
// buf.append(Stats.avg(decisionMaxFixedLookaheads));
|
494
|
+
// buf.append('\t');
|
495
|
+
// buf.append(Stats.stddev(decisionMaxFixedLookaheads));
|
496
|
+
// buf.append('\t');
|
497
|
+
// buf.append(numCyclicDecisions);
|
498
|
+
// buf.append('\t');
|
499
|
+
// buf.append(Stats.min(decisionMaxCyclicLookaheads));
|
500
|
+
// buf.append('\t');
|
501
|
+
// buf.append(Stats.max(decisionMaxCyclicLookaheads));
|
502
|
+
// buf.append('\t');
|
503
|
+
// buf.append(Stats.avg(decisionMaxCyclicLookaheads));
|
504
|
+
// buf.append('\t');
|
505
|
+
// buf.append(Stats.stddev(decisionMaxCyclicLookaheads));
|
506
|
+
// buf.append('\t');
|
507
|
+
// buf.append(numBacktrackDecisions);
|
508
|
+
// buf.append('\t');
|
509
|
+
// buf.append(Stats.min(toArray(decisionMaxSynPredLookaheads)));
|
510
|
+
// buf.append('\t');
|
511
|
+
// buf.append(Stats.max(toArray(decisionMaxSynPredLookaheads)));
|
512
|
+
// buf.append('\t');
|
513
|
+
// buf.append(Stats.avg(toArray(decisionMaxSynPredLookaheads)));
|
514
|
+
// buf.append('\t');
|
515
|
+
// buf.append(Stats.stddev(toArray(decisionMaxSynPredLookaheads)));
|
516
|
+
// buf.append('\t');
|
517
|
+
// buf.append(numSemanticPredicates);
|
518
|
+
// buf.append('\t');
|
519
|
+
// buf.append(parser.getTokenStream().size());
|
520
|
+
// buf.append('\t');
|
521
|
+
// buf.append(numHiddenTokens);
|
522
|
+
// buf.append('\t');
|
523
|
+
// buf.append(numCharsMatched);
|
524
|
+
// buf.append('\t');
|
525
|
+
// buf.append(numHiddenCharsMatched);
|
526
|
+
// buf.append('\t');
|
527
|
+
// buf.append(numberReportedErrors);
|
528
|
+
// buf.append('\t');
|
529
|
+
// buf.append(numMemoizationCacheHits);
|
530
|
+
// buf.append('\t');
|
531
|
+
// buf.append(numMemoizationCacheMisses);
|
532
|
+
// buf.append('\t');
|
533
|
+
// buf.append(numGuessingRuleInvocations);
|
534
|
+
// buf.append('\t');
|
535
|
+
// buf.append(numMemoizationCacheEntries);
|
536
|
+
return buf.toString();
|
537
|
+
}
|
538
|
+
|
539
|
+
public String toString() {
|
540
|
+
return toString(getReport());
|
541
|
+
}
|
542
|
+
|
543
|
+
public ProfileStats getReport() {
|
544
|
+
// TokenStream input = parser.getTokenStream();
|
545
|
+
// for (int i=0; i<input.size()&& lastRealTokenTouchedInDecision !=null&&i<= lastRealTokenTouchedInDecision.getTokenIndex(); i++) {
|
546
|
+
// Token t = input.get(i);
|
547
|
+
// if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
|
548
|
+
// stats.numHiddenTokens++;
|
549
|
+
// stats.numHiddenCharsMatched += t.getText().length();
|
550
|
+
// }
|
551
|
+
// }
|
552
|
+
stats.Version = Version;
|
553
|
+
stats.name = parser.getClass().getName();
|
554
|
+
stats.numUniqueRulesInvoked = uniqueRules.size();
|
555
|
+
//stats.numCharsMatched = lastTokenConsumed.getStopIndex() + 1;
|
556
|
+
return stats;
|
557
|
+
}
|
558
|
+
|
559
|
+
public DoubleKeyMap getDecisionStats() {
|
560
|
+
return decisions;
|
561
|
+
}
|
562
|
+
|
563
|
+
public List getDecisionEvents() {
|
564
|
+
return decisionEvents;
|
565
|
+
}
|
566
|
+
|
567
|
+
public static String toString(ProfileStats stats) {
|
568
|
+
StringBuffer buf = new StringBuffer();
|
569
|
+
buf.append("ANTLR Runtime Report; Profile Version ");
|
570
|
+
buf.append(stats.Version);
|
571
|
+
buf.append(newline);
|
572
|
+
buf.append("parser name ");
|
573
|
+
buf.append(stats.name);
|
574
|
+
buf.append(newline);
|
575
|
+
buf.append("Number of rule invocations ");
|
576
|
+
buf.append(stats.numRuleInvocations);
|
577
|
+
buf.append(newline);
|
578
|
+
buf.append("Number of unique rules visited ");
|
579
|
+
buf.append(stats.numUniqueRulesInvoked);
|
580
|
+
buf.append(newline);
|
581
|
+
buf.append("Number of decision events ");
|
582
|
+
buf.append(stats.numDecisionEvents);
|
583
|
+
buf.append(newline);
|
584
|
+
buf.append("Overall average k per decision event ");
|
585
|
+
buf.append(stats.avgkPerDecisionEvent);
|
586
|
+
buf.append(newline);
|
587
|
+
buf.append("Number of backtracking occurrences (can be multiple per decision) ");
|
588
|
+
buf.append(stats.numBacktrackOccurrences);
|
589
|
+
buf.append(newline);
|
590
|
+
buf.append("Overall average k per decision event that backtracks ");
|
591
|
+
buf.append(stats.avgkPerBacktrackingDecisionEvent);
|
592
|
+
buf.append(newline);
|
593
|
+
buf.append("Number of rule invocations while backtracking ");
|
594
|
+
buf.append(stats.numGuessingRuleInvocations);
|
595
|
+
buf.append(newline);
|
596
|
+
buf.append("num decisions that potentially backtrack ");
|
597
|
+
buf.append(stats.numDecisionsThatPotentiallyBacktrack);
|
598
|
+
buf.append(newline);
|
599
|
+
buf.append("num decisions that do backtrack ");
|
600
|
+
buf.append(stats.numDecisionsThatDoBacktrack);
|
601
|
+
buf.append(newline);
|
602
|
+
buf.append("num decisions that potentially backtrack but don't ");
|
603
|
+
buf.append(stats.numDecisionsThatPotentiallyBacktrack - stats.numDecisionsThatDoBacktrack);
|
604
|
+
buf.append(newline);
|
605
|
+
buf.append("average % of time a potentially backtracking decision backtracks ");
|
606
|
+
buf.append(stats.averageDecisionPercentBacktracks);
|
607
|
+
buf.append(newline);
|
608
|
+
buf.append("num unique decisions covered ");
|
609
|
+
buf.append(stats.numDecisionsCovered);
|
610
|
+
buf.append(newline);
|
611
|
+
buf.append("max rule invocation nesting depth ");
|
612
|
+
buf.append(stats.maxRuleInvocationDepth);
|
613
|
+
buf.append(newline);
|
614
|
+
|
615
|
+
// buf.append("number of fixed lookahead decisions ");
|
616
|
+
// buf.append();
|
617
|
+
// buf.append('\n');
|
618
|
+
// buf.append("min lookahead used in a fixed lookahead decision ");
|
619
|
+
// buf.append();
|
620
|
+
// buf.append('\n');
|
621
|
+
// buf.append("max lookahead used in a fixed lookahead decision ");
|
622
|
+
// buf.append();
|
623
|
+
// buf.append('\n');
|
624
|
+
// buf.append("average lookahead depth used in fixed lookahead decisions ");
|
625
|
+
// buf.append();
|
626
|
+
// buf.append('\n');
|
627
|
+
// buf.append("standard deviation of depth used in fixed lookahead decisions ");
|
628
|
+
// buf.append();
|
629
|
+
// buf.append('\n');
|
630
|
+
// buf.append("number of arbitrary lookahead decisions ");
|
631
|
+
// buf.append();
|
632
|
+
// buf.append('\n');
|
633
|
+
// buf.append("min lookahead used in an arbitrary lookahead decision ");
|
634
|
+
// buf.append();
|
635
|
+
// buf.append('\n');
|
636
|
+
// buf.append("max lookahead used in an arbitrary lookahead decision ");
|
637
|
+
// buf.append();
|
638
|
+
// buf.append('\n');
|
639
|
+
// buf.append("average lookahead depth used in arbitrary lookahead decisions ");
|
640
|
+
// buf.append();
|
641
|
+
// buf.append('\n');
|
642
|
+
// buf.append("standard deviation of depth used in arbitrary lookahead decisions ");
|
643
|
+
// buf.append();
|
644
|
+
// buf.append('\n');
|
645
|
+
// buf.append("number of evaluated syntactic predicates ");
|
646
|
+
// buf.append();
|
647
|
+
// buf.append('\n');
|
648
|
+
// buf.append("min lookahead used in a syntactic predicate ");
|
649
|
+
// buf.append();
|
650
|
+
// buf.append('\n');
|
651
|
+
// buf.append("max lookahead used in a syntactic predicate ");
|
652
|
+
// buf.append();
|
653
|
+
// buf.append('\n');
|
654
|
+
// buf.append("average lookahead depth used in syntactic predicates ");
|
655
|
+
// buf.append();
|
656
|
+
// buf.append('\n');
|
657
|
+
// buf.append("standard deviation of depth used in syntactic predicates ");
|
658
|
+
// buf.append();
|
659
|
+
// buf.append('\n');
|
660
|
+
buf.append("rule memoization cache size ");
|
661
|
+
buf.append(stats.numMemoizationCacheEntries);
|
662
|
+
buf.append(newline);
|
663
|
+
buf.append("number of rule memoization cache hits ");
|
664
|
+
buf.append(stats.numMemoizationCacheHits);
|
665
|
+
buf.append(newline);
|
666
|
+
buf.append("number of rule memoization cache misses ");
|
667
|
+
buf.append(stats.numMemoizationCacheMisses);
|
668
|
+
buf.append(newline);
|
669
|
+
// buf.append("number of evaluated semantic predicates ");
|
670
|
+
// buf.append();
|
671
|
+
// buf.append(newline);
|
672
|
+
buf.append("number of tokens ");
|
673
|
+
buf.append(stats.numTokens);
|
674
|
+
buf.append(newline);
|
675
|
+
buf.append("number of hidden tokens ");
|
676
|
+
buf.append(stats.numHiddenTokens);
|
677
|
+
buf.append(newline);
|
678
|
+
buf.append("number of char ");
|
679
|
+
buf.append(stats.numCharsMatched);
|
680
|
+
buf.append(newline);
|
681
|
+
buf.append("number of hidden char ");
|
682
|
+
buf.append(stats.numHiddenCharsMatched);
|
683
|
+
buf.append(newline);
|
684
|
+
buf.append("number of syntax errors ");
|
685
|
+
buf.append(stats.numReportedErrors);
|
686
|
+
buf.append(newline);
|
687
|
+
return buf.toString();
|
688
|
+
}
|
689
|
+
|
690
|
+
public String getDecisionStatsDump() {
|
691
|
+
StringBuffer buf = new StringBuffer();
|
692
|
+
buf.append("location");
|
693
|
+
buf.append(DATA_SEP);
|
694
|
+
buf.append("n");
|
695
|
+
buf.append(DATA_SEP);
|
696
|
+
buf.append("avgk");
|
697
|
+
buf.append(DATA_SEP);
|
698
|
+
buf.append("maxk");
|
699
|
+
buf.append(DATA_SEP);
|
700
|
+
buf.append("synpred");
|
701
|
+
buf.append(DATA_SEP);
|
702
|
+
buf.append("sempred");
|
703
|
+
buf.append(DATA_SEP);
|
704
|
+
buf.append("canbacktrack");
|
705
|
+
buf.append("\n");
|
706
|
+
for (String fileName : decisions.keySet()) {
|
707
|
+
for (int d : decisions.keySet(fileName)) {
|
708
|
+
DecisionDescriptor s = decisions.get(fileName, d);
|
709
|
+
buf.append(s.decision);
|
710
|
+
buf.append("@");
|
711
|
+
buf.append(locationDescription(s.fileName,s.ruleName,s.line,s.pos)); // decision number
|
712
|
+
buf.append(DATA_SEP);
|
713
|
+
buf.append(s.n);
|
714
|
+
buf.append(DATA_SEP);
|
715
|
+
buf.append(String.format("%.2f",s.avgk));
|
716
|
+
buf.append(DATA_SEP);
|
717
|
+
buf.append(s.maxk);
|
718
|
+
buf.append(DATA_SEP);
|
719
|
+
buf.append(s.numBacktrackOccurrences);
|
720
|
+
buf.append(DATA_SEP);
|
721
|
+
buf.append(s.numSemPredEvals);
|
722
|
+
buf.append(DATA_SEP);
|
723
|
+
buf.append(s.couldBacktrack ?"1":"0");
|
724
|
+
buf.append(newline);
|
725
|
+
}
|
726
|
+
}
|
727
|
+
return buf.toString();
|
728
|
+
}
|
729
|
+
|
730
|
+
protected int[] trim(int[] X, int n) {
|
731
|
+
if ( n<X.length ) {
|
732
|
+
int[] trimmed = new int[n];
|
733
|
+
System.arraycopy(X,0,trimmed,0,n);
|
734
|
+
X = trimmed;
|
735
|
+
}
|
736
|
+
return X;
|
737
|
+
}
|
738
|
+
|
739
|
+
protected int[] toArray(List a) {
|
740
|
+
int[] x = new int[a.size()];
|
741
|
+
for (int i = 0; i < a.size(); i++) {
|
742
|
+
Integer I = (Integer) a.get(i);
|
743
|
+
x[i] = I.intValue();
|
744
|
+
}
|
745
|
+
return x;
|
746
|
+
}
|
747
|
+
|
748
|
+
/** Get num hidden tokens between i..j inclusive */
|
749
|
+
public int getNumberOfHiddenTokens(int i, int j) {
|
750
|
+
int n = 0;
|
751
|
+
TokenStream input = parser.getTokenStream();
|
752
|
+
for (int ti = i; ti<input.size() && ti <= j; ti++) {
|
753
|
+
Token t = input.get(ti);
|
754
|
+
if ( t.getChannel()!=Token.DEFAULT_CHANNEL ) {
|
755
|
+
n++;
|
756
|
+
}
|
757
|
+
}
|
758
|
+
return n;
|
759
|
+
}
|
760
|
+
|
761
|
+
protected String locationDescription() {
|
762
|
+
return locationDescription(
|
763
|
+
currentGrammarFileName.peek(),
|
764
|
+
currentRuleName.peek(),
|
765
|
+
currentLine.peek(),
|
766
|
+
currentPos.peek());
|
767
|
+
}
|
768
|
+
|
769
|
+
protected String locationDescription(String file, String rule, int line, int pos) {
|
770
|
+
return file+":"+line+":"+pos+"(" + rule + ")";
|
771
|
+
}
|
772
|
+
}
|