@cparra/apex-reflection 0.1.0-alpha.0 → 0.1.1-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/__tests__/end-to-end.test.ts +256 -0
- package/coverage/clover.xml +12857 -0
- package/coverage/coverage-final.json +3 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +79 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +126 -0
- package/coverage/lcov-report/index.js.html +104 -0
- package/coverage/lcov-report/out.js.html +41126 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +170 -0
- package/coverage/lcov.info +24801 -0
- package/index.d.ts +118 -0
- package/index.js +8 -0
- package/index.ts +141 -0
- package/jest.config.js +11 -0
- package/out.js +13708 -0
- package/package.json +22 -17
- package/tsconfig.json +5 -3
- package/.idea/apexdocs-dart.iml +0 -18
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/libraries/Dart_Packages.xml +0 -556
- package/.idea/libraries/Dart_SDK.xml +0 -28
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/runConfigurations/_template__of_Dart_Test.xml +0 -6
- package/.idea/vcs.xml +0 -6
- package/CHANGELOG.md +0 -3
- package/README.md +0 -26
- package/TODO.md +0 -5
- package/analysis_options.yaml +0 -30
- package/antlr4-4.9.2/CHANGELOG.md +0 -4
- package/antlr4-4.9.2/LICENSE +0 -52
- package/antlr4-4.9.2/README.md +0 -11
- package/antlr4-4.9.2/analysis_options.yaml +0 -1
- package/antlr4-4.9.2/lib/antlr4.dart +0 -21
- package/antlr4-4.9.2/lib/src/atn/atn.dart +0 -18
- package/antlr4-4.9.2/lib/src/atn/src/atn.dart +0 -170
- package/antlr4-4.9.2/lib/src/atn/src/atn_config.dart +0 -242
- package/antlr4-4.9.2/lib/src/atn/src/atn_config_set.dart +0 -283
- package/antlr4-4.9.2/lib/src/atn/src/atn_deserializer.dart +0 -809
- package/antlr4-4.9.2/lib/src/atn/src/atn_simulator.dart +0 -95
- package/antlr4-4.9.2/lib/src/atn/src/atn_state.dart +0 -296
- package/antlr4-4.9.2/lib/src/atn/src/atn_type.dart +0 -14
- package/antlr4-4.9.2/lib/src/atn/src/info.dart +0 -553
- package/antlr4-4.9.2/lib/src/atn/src/lexer_action.dart +0 -601
- package/antlr4-4.9.2/lib/src/atn/src/lexer_action_executor.dart +0 -167
- package/antlr4-4.9.2/lib/src/atn/src/lexer_atn_simulator.dart +0 -731
- package/antlr4-4.9.2/lib/src/atn/src/parser_atn_simulator.dart +0 -2630
- package/antlr4-4.9.2/lib/src/atn/src/profiling_atn_simulator.dart +0 -229
- package/antlr4-4.9.2/lib/src/atn/src/semantic_context.dart +0 -404
- package/antlr4-4.9.2/lib/src/atn/src/transition.dart +0 -305
- package/antlr4-4.9.2/lib/src/dfa/dfa.dart +0 -8
- package/antlr4-4.9.2/lib/src/dfa/src/dfa.dart +0 -138
- package/antlr4-4.9.2/lib/src/dfa/src/dfa_serializer.dart +0 -76
- package/antlr4-4.9.2/lib/src/dfa/src/dfa_state.dart +0 -151
- package/antlr4-4.9.2/lib/src/error/error.dart +0 -10
- package/antlr4-4.9.2/lib/src/error/src/diagnostic_error_listener.dart +0 -116
- package/antlr4-4.9.2/lib/src/error/src/error_listener.dart +0 -241
- package/antlr4-4.9.2/lib/src/error/src/error_strategy.dart +0 -902
- package/antlr4-4.9.2/lib/src/error/src/errors.dart +0 -204
- package/antlr4-4.9.2/lib/src/input_stream.dart +0 -335
- package/antlr4-4.9.2/lib/src/interval_set.dart +0 -735
- package/antlr4-4.9.2/lib/src/lexer.dart +0 -343
- package/antlr4-4.9.2/lib/src/ll1_analyzer.dart +0 -204
- package/antlr4-4.9.2/lib/src/misc/multi_map.dart +0 -32
- package/antlr4-4.9.2/lib/src/misc/pair.dart +0 -34
- package/antlr4-4.9.2/lib/src/parser.dart +0 -777
- package/antlr4-4.9.2/lib/src/parser_interpreter.dart +0 -393
- package/antlr4-4.9.2/lib/src/parser_rule_context.dart +0 -275
- package/antlr4-4.9.2/lib/src/prediction_context.dart +0 -877
- package/antlr4-4.9.2/lib/src/recognizer.dart +0 -182
- package/antlr4-4.9.2/lib/src/rule_context.dart +0 -192
- package/antlr4-4.9.2/lib/src/runtime_meta_data.dart +0 -188
- package/antlr4-4.9.2/lib/src/token.dart +0 -431
- package/antlr4-4.9.2/lib/src/token_factory.dart +0 -88
- package/antlr4-4.9.2/lib/src/token_source.dart +0 -241
- package/antlr4-4.9.2/lib/src/token_stream.dart +0 -627
- package/antlr4-4.9.2/lib/src/tree/src/pattern/chunk.dart +0 -90
- package/antlr4-4.9.2/lib/src/tree/src/pattern/parse_tree_match.dart +0 -635
- package/antlr4-4.9.2/lib/src/tree/src/tree.dart +0 -370
- package/antlr4-4.9.2/lib/src/tree/src/trees.dart +0 -226
- package/antlr4-4.9.2/lib/src/tree/tree.dart +0 -10
- package/antlr4-4.9.2/lib/src/util/bit_set.dart +0 -308
- package/antlr4-4.9.2/lib/src/util/murmur_hash.dart +0 -77
- package/antlr4-4.9.2/lib/src/util/utils.dart +0 -31
- package/antlr4-4.9.2/lib/src/vocabulary.dart +0 -254
- package/antlr4-4.9.2/pubspec.yaml +0 -13
- package/example/node_example/index.js +0 -8
- package/example/node_example/package.json +0 -12
- package/example/node_example_ts/package-lock.json +0 -70
- package/example/node_example_ts/package.json +0 -19
- package/example/node_example_ts/src/index.js +0 -5
- package/example/node_example_ts/src/index.ts +0 -9
- package/example/node_example_ts/tsconfig.json +0 -79
- package/js/dart2jsout.js +0 -25898
- package/js/dart2jsout.js.map +0 -16
- package/js/index.d.ts +0 -1
- package/js/index.js +0 -4
- package/js/out.js +0 -26023
- package/js/out.js.map +0 -16
- package/js/package-lock.json +0 -57
- package/js/preamble.js +0 -125
- package/lib/apexdocs_dart.dart +0 -28
- package/lib/src/antlr/grammars/Apexdoc/ApexdocLexer.g4 +0 -120
- package/lib/src/antlr/grammars/Apexdoc/ApexdocParser.g4 +0 -158
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.interp +0 -95
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.java +0 -238
- package/lib/src/antlr/grammars/Apexdoc/gen/ApexdocLexer.tokens +0 -23
- package/lib/src/antlr/grammars/apex/ApexLexer.g4 +0 -255
- package/lib/src/antlr/grammars/apex/ApexParser.g4 +0 -567
- package/lib/src/antlr/grammars/apex/examples/ApexClass.cls +0 -6
- package/lib/src/antlr/lib/apex/ApexLexer.dart +0 -1223
- package/lib/src/antlr/lib/apex/ApexLexer.interp +0 -393
- package/lib/src/antlr/lib/apex/ApexLexer.tokens +0 -212
- package/lib/src/antlr/lib/apex/ApexParser.dart +0 -9349
- package/lib/src/antlr/lib/apex/ApexParser.interp +0 -326
- package/lib/src/antlr/lib/apex/ApexParser.tokens +0 -212
- package/lib/src/antlr/lib/apex/ApexParserBaseListener.dart +0 -1036
- package/lib/src/antlr/lib/apex/ApexParserListener.dart +0 -975
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.dart +0 -373
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.interp +0 -95
- package/lib/src/antlr/lib/apexdoc/ApexdocLexer.tokens +0 -23
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.dart +0 -2471
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.interp +0 -69
- package/lib/src/antlr/lib/apexdoc/ApexdocParser.tokens +0 -23
- package/lib/src/antlr/lib/apexdoc/ApexdocParserBaseListener.dart +0 -252
- package/lib/src/antlr/lib/apexdoc/ApexdocParserListener.dart +0 -215
- package/lib/src/builders/builders.dart +0 -32
- package/lib/src/model/apex_file_manifest.dart +0 -37
- package/lib/src/model/apex_file_manifest.g.dart +0 -18
- package/lib/src/model/declaration.dart +0 -50
- package/lib/src/model/doc_comment.dart +0 -117
- package/lib/src/model/doc_comment.g.dart +0 -118
- package/lib/src/model/members.dart +0 -143
- package/lib/src/model/members.g.dart +0 -105
- package/lib/src/model/types.dart +0 -159
- package/lib/src/model/types.g.dart +0 -111
- package/lib/src/service/apex_listener.dart +0 -226
- package/lib/src/service/apexdoc_listener.dart +0 -82
- package/lib/src/service/parsers.dart +0 -33
- package/lib/src/service/utils/parsing/access_modifiers_parser.dart +0 -33
- package/lib/src/service/utils/parsing/parameters_parser.dart +0 -18
- package/lib/src/service/utils/parsing/parsing_utils.dart +0 -2
- package/lib/src/service/walker.dart +0 -82
- package/pubspec.yaml +0 -19
- package/test/apex_file_manifest_test.dart +0 -16
- package/test/apex_listener_test.dart +0 -703
- package/test/apexdoc_parser_test.dart +0 -179
- package/test/doc_comment_test.dart +0 -89
- package/test/members_serialization_test.dart +0 -158
- package/test/members_test.dart +0 -178
- package/test/types_serialization_test.dart +0 -191
- package/test/types_test.dart +0 -311
- package/test/walker_test.dart +0 -58
- package/tool/grind.dart +0 -20
|
@@ -1,902 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
|
|
3
|
-
* Use of this file is governed by the BSD 3-clause license that
|
|
4
|
-
* can be found in the LICENSE.txt file in the project root.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import 'dart:developer';
|
|
8
|
-
|
|
9
|
-
import 'package:logging/logging.dart';
|
|
10
|
-
|
|
11
|
-
import '../../atn/atn.dart';
|
|
12
|
-
import '../../interval_set.dart';
|
|
13
|
-
import '../../misc/pair.dart';
|
|
14
|
-
import '../../parser.dart';
|
|
15
|
-
import '../../parser_rule_context.dart';
|
|
16
|
-
import '../../rule_context.dart';
|
|
17
|
-
import '../../token.dart';
|
|
18
|
-
import '../../tree/tree.dart';
|
|
19
|
-
import 'errors.dart';
|
|
20
|
-
|
|
21
|
-
/// The interface for defining strategies to deal with syntax errors encountered
|
|
22
|
-
/// during a parse by ANTLR-generated parsers. We distinguish between three
|
|
23
|
-
/// different kinds of errors:
|
|
24
|
-
///
|
|
25
|
-
/// <ul>
|
|
26
|
-
/// <li>The parser could not figure out which path to take in the ATN (none of
|
|
27
|
-
/// the available alternatives could possibly match)</li>
|
|
28
|
-
/// <li>The current input does not match what we were looking for</li>
|
|
29
|
-
/// <li>A predicate evaluated to false</li>
|
|
30
|
-
/// </ul>
|
|
31
|
-
///
|
|
32
|
-
/// Implementations of this interface report syntax errors by calling
|
|
33
|
-
/// {@link Parser#notifyErrorListeners}.
|
|
34
|
-
///
|
|
35
|
-
/// <p>TODO: what to do about lexers</p>
|
|
36
|
-
abstract class ErrorStrategy {
|
|
37
|
-
/// Reset the error handler state for the specified [recognizer].
|
|
38
|
-
/// @param recognizer the parser instance
|
|
39
|
-
void reset(Parser recognizer);
|
|
40
|
-
|
|
41
|
-
/// This method is called when an unexpected symbol is encountered during an
|
|
42
|
-
/// inline match operation, such as {@link Parser#match}. If the error
|
|
43
|
-
/// strategy successfully recovers from the match failure, this method
|
|
44
|
-
/// returns the [Token] instance which should be treated as the
|
|
45
|
-
/// successful result of the match.
|
|
46
|
-
///
|
|
47
|
-
/// <p>This method handles the consumption of any tokens - the caller should
|
|
48
|
-
/// <b>not</b> call {@link Parser#consume} after a successful recovery.</p>
|
|
49
|
-
///
|
|
50
|
-
/// <p>Note that the calling code will not report an error if this method
|
|
51
|
-
/// returns successfully. The error strategy implementation is responsible
|
|
52
|
-
/// for calling {@link Parser#notifyErrorListeners} as appropriate.</p>
|
|
53
|
-
///
|
|
54
|
-
/// @param recognizer the parser instance
|
|
55
|
-
/// @ if the error strategy was not able to
|
|
56
|
-
/// recover from the unexpected input symbol
|
|
57
|
-
Token recoverInline(Parser recognizer);
|
|
58
|
-
|
|
59
|
-
/// This method is called to recover from exception [e]. This method is
|
|
60
|
-
/// called after {@link #reportError} by the default exception handler
|
|
61
|
-
/// generated for a rule method.
|
|
62
|
-
///
|
|
63
|
-
/// @see #reportError
|
|
64
|
-
///
|
|
65
|
-
/// @param recognizer the parser instance
|
|
66
|
-
/// @param e the recognition exception to recover from
|
|
67
|
-
/// @ if the error strategy could not recover from
|
|
68
|
-
/// the recognition exception
|
|
69
|
-
void recover(Parser recognizer, RecognitionException e);
|
|
70
|
-
|
|
71
|
-
/// This method provides the error handler with an opportunity to handle
|
|
72
|
-
/// syntactic or semantic errors in the input stream before they result in a
|
|
73
|
-
/// [RecognitionException].
|
|
74
|
-
///
|
|
75
|
-
/// <p>The generated code currently contains calls to {@link #sync} after
|
|
76
|
-
/// entering the decision state of a closure block ({@code (...)*} or
|
|
77
|
-
/// {@code (...)+}).</p>
|
|
78
|
-
///
|
|
79
|
-
/// <p>For an implementation based on Jim Idle's "magic sync" mechanism, see
|
|
80
|
-
/// {@link DefaultErrorStrategy#sync}.</p>
|
|
81
|
-
///
|
|
82
|
-
/// @see DefaultErrorStrategy#sync
|
|
83
|
-
///
|
|
84
|
-
/// @param recognizer the parser instance
|
|
85
|
-
/// @ if an error is detected by the error
|
|
86
|
-
/// strategy but cannot be automatically recovered at the current state in
|
|
87
|
-
/// the parsing process
|
|
88
|
-
void sync(Parser recognizer);
|
|
89
|
-
|
|
90
|
-
/// Tests whether or not [recognizer] is in the process of recovering
|
|
91
|
-
/// from an error. In error recovery mode, {@link Parser#consume} adds
|
|
92
|
-
/// symbols to the parse tree by calling
|
|
93
|
-
/// {@link Parser#createErrorNode(ParserRuleContext, Token)} then
|
|
94
|
-
/// {@link ParserRuleContext#addErrorNode(ErrorNode)} instead of
|
|
95
|
-
/// {@link Parser#createTerminalNode(ParserRuleContext, Token)}.
|
|
96
|
-
///
|
|
97
|
-
/// @param recognizer the parser instance
|
|
98
|
-
/// @return [true] if the parser is currently recovering from a parse
|
|
99
|
-
/// error, otherwise [false]
|
|
100
|
-
bool inErrorRecoveryMode(Parser recognizer);
|
|
101
|
-
|
|
102
|
-
/// This method is called by when the parser successfully matches an input
|
|
103
|
-
/// symbol.
|
|
104
|
-
///
|
|
105
|
-
/// @param recognizer the parser instance
|
|
106
|
-
void reportMatch(Parser recognizer);
|
|
107
|
-
|
|
108
|
-
/// Report any kind of [RecognitionException]. This method is called by
|
|
109
|
-
/// the default exception handler generated for a rule method.
|
|
110
|
-
///
|
|
111
|
-
/// @param recognizer the parser instance
|
|
112
|
-
/// @param e the recognition exception to report
|
|
113
|
-
void reportError(Parser recognizer, RecognitionException e);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/// This is the default implementation of [ANTLRErrorStrategy] used for
|
|
117
|
-
/// error reporting and recovery in ANTLR parsers.
|
|
118
|
-
class DefaultErrorStrategy implements ErrorStrategy {
|
|
119
|
-
/// Indicates whether the error strategy is currently "recovering from an
|
|
120
|
-
/// error". This is used to suppress reporting multiple error messages while
|
|
121
|
-
/// attempting to recover from a detected syntax error.
|
|
122
|
-
///
|
|
123
|
-
/// @see #inErrorRecoveryMode
|
|
124
|
-
bool errorRecoveryMode = false;
|
|
125
|
-
|
|
126
|
-
/// The index into the input stream where the last error occurred.
|
|
127
|
-
/// This is used to prevent infinite loops where an error is found
|
|
128
|
-
/// but no token is consumed during recovery...another error is found,
|
|
129
|
-
/// ad nauseum. This is a failsafe mechanism to guarantee that at least
|
|
130
|
-
/// one token/tree node is consumed for two errors.
|
|
131
|
-
int lastErrorIndex = -1;
|
|
132
|
-
|
|
133
|
-
IntervalSet lastErrorStates;
|
|
134
|
-
|
|
135
|
-
/// This field is used to propagate information about the lookahead following
|
|
136
|
-
/// the previous match. Since prediction prefers completing the current rule
|
|
137
|
-
/// to error recovery efforts, error reporting may occur later than the
|
|
138
|
-
/// original point where it was discoverable. The original context is used to
|
|
139
|
-
/// compute the true expected sets as though the reporting occurred as early
|
|
140
|
-
/// as possible.
|
|
141
|
-
ParserRuleContext nextTokensContext;
|
|
142
|
-
|
|
143
|
-
/// @see #nextTokensContext
|
|
144
|
-
int nextTokensState;
|
|
145
|
-
|
|
146
|
-
/// {@inheritDoc}
|
|
147
|
-
///
|
|
148
|
-
/// <p>The default implementation simply calls {@link #endErrorCondition} to
|
|
149
|
-
/// ensure that the handler is not in error recovery mode.</p>
|
|
150
|
-
|
|
151
|
-
@override
|
|
152
|
-
void reset(Parser recognizer) {
|
|
153
|
-
endErrorCondition(recognizer);
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
/// This method is called to enter error recovery mode when a recognition
|
|
157
|
-
/// exception is reported.
|
|
158
|
-
///
|
|
159
|
-
/// @param recognizer the parser instance
|
|
160
|
-
void beginErrorCondition(Parser recognizer) {
|
|
161
|
-
errorRecoveryMode = true;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/// {@inheritDoc}
|
|
165
|
-
|
|
166
|
-
@override
|
|
167
|
-
bool inErrorRecoveryMode(Parser recognizer) {
|
|
168
|
-
return errorRecoveryMode;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/// This method is called to leave error recovery mode after recovering from
|
|
172
|
-
/// a recognition exception.
|
|
173
|
-
///
|
|
174
|
-
/// @param recognizer
|
|
175
|
-
void endErrorCondition(Parser recognizer) {
|
|
176
|
-
errorRecoveryMode = false;
|
|
177
|
-
lastErrorStates = null;
|
|
178
|
-
lastErrorIndex = -1;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/// {@inheritDoc}
|
|
182
|
-
///
|
|
183
|
-
/// <p>The default implementation simply calls {@link #endErrorCondition}.</p>
|
|
184
|
-
|
|
185
|
-
@override
|
|
186
|
-
void reportMatch(Parser recognizer) {
|
|
187
|
-
endErrorCondition(recognizer);
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/// {@inheritDoc}
|
|
191
|
-
///
|
|
192
|
-
/// <p>The default implementation returns immediately if the handler is already
|
|
193
|
-
/// in error recovery mode. Otherwise, it calls {@link #beginErrorCondition}
|
|
194
|
-
/// and dispatches the reporting task based on the runtime type of [e]
|
|
195
|
-
/// according to the following table.</p>
|
|
196
|
-
///
|
|
197
|
-
/// <ul>
|
|
198
|
-
/// <li>[NoViableAltException]: Dispatches the call to
|
|
199
|
-
/// {@link #reportNoViableAlternative}</li>
|
|
200
|
-
/// <li>[InputMismatchException]: Dispatches the call to
|
|
201
|
-
/// {@link #reportInputMismatch}</li>
|
|
202
|
-
/// <li>[FailedPredicateException]: Dispatches the call to
|
|
203
|
-
/// {@link #reportFailedPredicate}</li>
|
|
204
|
-
/// <li>All other types: calls {@link Parser#notifyErrorListeners} to report
|
|
205
|
-
/// the exception</li>
|
|
206
|
-
/// </ul>
|
|
207
|
-
|
|
208
|
-
@override
|
|
209
|
-
void reportError(Parser recognizer, RecognitionException e) {
|
|
210
|
-
// if we've already reported an error and have not matched a token
|
|
211
|
-
// yet successfully, don't report any errors.
|
|
212
|
-
if (inErrorRecoveryMode(recognizer)) {
|
|
213
|
-
// System.err.print("[SPURIOUS] ");
|
|
214
|
-
return; // don't report spurious errors
|
|
215
|
-
}
|
|
216
|
-
beginErrorCondition(recognizer);
|
|
217
|
-
if (e is NoViableAltException) {
|
|
218
|
-
reportNoViableAlternative(recognizer, e);
|
|
219
|
-
} else if (e is InputMismatchException) {
|
|
220
|
-
reportInputMismatch(recognizer, e);
|
|
221
|
-
} else if (e is FailedPredicateException) {
|
|
222
|
-
reportFailedPredicate(recognizer, e);
|
|
223
|
-
} else {
|
|
224
|
-
log('unknown recognition error type: ${e.runtimeType}',
|
|
225
|
-
level: Level.SEVERE.value);
|
|
226
|
-
recognizer.notifyErrorListeners(e.message, e.offendingToken, e);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/// {@inheritDoc}
|
|
231
|
-
///
|
|
232
|
-
/// <p>The default implementation resynchronizes the parser by consuming tokens
|
|
233
|
-
/// until we find one in the resynchronization set--loosely the set of tokens
|
|
234
|
-
/// that can follow the current rule.</p>
|
|
235
|
-
|
|
236
|
-
@override
|
|
237
|
-
void recover(Parser recognizer, RecognitionException e) {
|
|
238
|
-
// System.out.println("recover in "+recognizer.getRuleInvocationStack()+
|
|
239
|
-
// " index="+recognizer.inputStream.index()+
|
|
240
|
-
// ", lastErrorIndex="+
|
|
241
|
-
// lastErrorIndex+
|
|
242
|
-
// ", states="+lastErrorStates);
|
|
243
|
-
if (lastErrorIndex == recognizer.inputStream.index &&
|
|
244
|
-
lastErrorStates != null &&
|
|
245
|
-
lastErrorStates.contains(recognizer.state)) {
|
|
246
|
-
// uh oh, another error at same token index and previously-visited
|
|
247
|
-
// state in ATN; must be a case where LT(1) is in the recovery
|
|
248
|
-
// token set so nothing got consumed. Consume a single token
|
|
249
|
-
// at least to prevent an infinite loop; this is a failsafe.
|
|
250
|
-
// log("seen error condition before index=, level: Level.SEVERE.value"+
|
|
251
|
-
// lastErrorIndex+", states="+lastErrorStates);
|
|
252
|
-
// log("FAILSAFE consumes "+recognizer.getTokenNames()[recognizer.inputStream.LA(1)], level: Level.SEVERE.value);
|
|
253
|
-
recognizer.consume();
|
|
254
|
-
}
|
|
255
|
-
lastErrorIndex = recognizer.inputStream.index;
|
|
256
|
-
lastErrorStates ??= IntervalSet(); lastErrorStates.addOne(recognizer.state);
|
|
257
|
-
final followSet = getErrorRecoverySet(recognizer);
|
|
258
|
-
consumeUntil(recognizer, followSet);
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
/// The default implementation of {@link ANTLRErrorStrategy#sync} makes sure
|
|
262
|
-
/// that the current lookahead symbol is consistent with what were expecting
|
|
263
|
-
/// at this point in the ATN. You can call this anytime but ANTLR only
|
|
264
|
-
/// generates code to check before subrules/loops and each iteration.
|
|
265
|
-
///
|
|
266
|
-
/// <p>Implements Jim Idle's magic sync mechanism in closures and optional
|
|
267
|
-
/// subrules. E.g.,</p>
|
|
268
|
-
///
|
|
269
|
-
/// <pre>
|
|
270
|
-
/// a : sync ( stuff sync )* ;
|
|
271
|
-
/// sync : {consume to what can follow sync} ;
|
|
272
|
-
/// </pre>
|
|
273
|
-
///
|
|
274
|
-
/// At the start of a sub rule upon error, {@link #sync} performs single
|
|
275
|
-
/// token deletion, if possible. If it can't do that, it bails on the current
|
|
276
|
-
/// rule and uses the default error recovery, which consumes until the
|
|
277
|
-
/// resynchronization set of the current rule.
|
|
278
|
-
///
|
|
279
|
-
/// <p>If the sub rule is optional ({@code (...)?}, {@code (...)*}, or block
|
|
280
|
-
/// with an empty alternative), then the expected set includes what follows
|
|
281
|
-
/// the subrule.</p>
|
|
282
|
-
///
|
|
283
|
-
/// <p>During loop iteration, it consumes until it sees a token that can start a
|
|
284
|
-
/// sub rule or what follows loop. Yes, that is pretty aggressive. We opt to
|
|
285
|
-
/// stay in the loop as long as possible.</p>
|
|
286
|
-
///
|
|
287
|
-
/// <p><strong>ORIGINS</strong></p>
|
|
288
|
-
///
|
|
289
|
-
/// <p>Previous versions of ANTLR did a poor job of their recovery within loops.
|
|
290
|
-
/// A single mismatch token or missing token would force the parser to bail
|
|
291
|
-
/// out of the entire rules surrounding the loop. So, for rule</p>
|
|
292
|
-
///
|
|
293
|
-
/// <pre>
|
|
294
|
-
/// classDef : 'class' ID '{' member* '}'
|
|
295
|
-
/// </pre>
|
|
296
|
-
///
|
|
297
|
-
/// input with an extra token between members would force the parser to
|
|
298
|
-
/// consume until it found the next class definition rather than the next
|
|
299
|
-
/// member definition of the current class.
|
|
300
|
-
///
|
|
301
|
-
/// <p>This functionality cost a little bit of effort because the parser has to
|
|
302
|
-
/// compare token set at the start of the loop and at each iteration. If for
|
|
303
|
-
/// some reason speed is suffering for you, you can turn off this
|
|
304
|
-
/// functionality by simply overriding this method as a blank { }.</p>
|
|
305
|
-
|
|
306
|
-
@override
|
|
307
|
-
void sync(Parser recognizer) {
|
|
308
|
-
final s = recognizer.interpreter.atn.states[recognizer.state];
|
|
309
|
-
// log("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName(), level: Level.SEVERE.value);
|
|
310
|
-
// If already recovering, don't try to sync
|
|
311
|
-
if (inErrorRecoveryMode(recognizer)) {
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
final tokens = recognizer.inputStream;
|
|
316
|
-
final la = tokens.LA(1);
|
|
317
|
-
|
|
318
|
-
// try cheaper subset first; might get lucky. seems to shave a wee bit off
|
|
319
|
-
final nextTokens = recognizer.getATN().nextTokens(s);
|
|
320
|
-
if (nextTokens.contains(la)) {
|
|
321
|
-
// We are sure the token matches
|
|
322
|
-
nextTokensContext = null;
|
|
323
|
-
nextTokensState = ATNState.INVALID_STATE_NUMBER;
|
|
324
|
-
return;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
if (nextTokens.contains(Token.EPSILON)) {
|
|
328
|
-
if (nextTokensContext == null) {
|
|
329
|
-
// It's possible the next token won't match; information tracked
|
|
330
|
-
// by sync is restricted for performance.
|
|
331
|
-
nextTokensContext = recognizer.context;
|
|
332
|
-
nextTokensState = recognizer.state;
|
|
333
|
-
}
|
|
334
|
-
return;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
switch (s.stateType) {
|
|
338
|
-
case StateType.BLOCK_START:
|
|
339
|
-
case StateType.STAR_BLOCK_START:
|
|
340
|
-
case StateType.PLUS_BLOCK_START:
|
|
341
|
-
case StateType.STAR_LOOP_ENTRY:
|
|
342
|
-
// report error and recover if possible
|
|
343
|
-
if (singleTokenDeletion(recognizer) != null) {
|
|
344
|
-
return;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
throw InputMismatchException(recognizer);
|
|
348
|
-
|
|
349
|
-
case StateType.PLUS_LOOP_BACK:
|
|
350
|
-
case StateType.STAR_LOOP_BACK:
|
|
351
|
-
// log("at loop back: "+s.getClass().getSimpleName(), level: Level.SEVERE.value);
|
|
352
|
-
reportUnwantedToken(recognizer);
|
|
353
|
-
final expecting = recognizer.expectedTokens;
|
|
354
|
-
final whatFollowsLoopIterationOrRule =
|
|
355
|
-
expecting | getErrorRecoverySet(recognizer);
|
|
356
|
-
consumeUntil(recognizer, whatFollowsLoopIterationOrRule);
|
|
357
|
-
break;
|
|
358
|
-
|
|
359
|
-
default:
|
|
360
|
-
// do nothing if we can't identify the exact kind of ATN state
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/// This is called by {@link #reportError} when the exception is a
|
|
366
|
-
/// [NoViableAltException].
|
|
367
|
-
///
|
|
368
|
-
/// @see #reportError
|
|
369
|
-
///
|
|
370
|
-
/// @param recognizer the parser instance
|
|
371
|
-
/// @param e the recognition exception
|
|
372
|
-
void reportNoViableAlternative(Parser recognizer, NoViableAltException e) {
|
|
373
|
-
final tokens = recognizer.inputStream;
|
|
374
|
-
String input;
|
|
375
|
-
if (tokens != null) {
|
|
376
|
-
if (e.startToken.type == Token.EOF) {
|
|
377
|
-
input = '<EOF>';
|
|
378
|
-
} else {
|
|
379
|
-
input = tokens.getTextRange(e.startToken, e.offendingToken);
|
|
380
|
-
}
|
|
381
|
-
} else {
|
|
382
|
-
input = '<unknown input>';
|
|
383
|
-
}
|
|
384
|
-
final msg = 'no viable alternative at input ' + escapeWSAndQuote(input);
|
|
385
|
-
recognizer.notifyErrorListeners(msg, e.offendingToken, e);
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
/// This is called by {@link #reportError} when the exception is an
|
|
389
|
-
/// [InputMismatchException].
|
|
390
|
-
///
|
|
391
|
-
/// @see #reportError
|
|
392
|
-
///
|
|
393
|
-
/// @param recognizer the parser instance
|
|
394
|
-
/// @param e the recognition exception
|
|
395
|
-
void reportInputMismatch(Parser recognizer, InputMismatchException e) {
|
|
396
|
-
final msg = 'mismatched input ' +
|
|
397
|
-
getTokenErrorDisplay(e.offendingToken) +
|
|
398
|
-
' expecting ' +
|
|
399
|
-
e.expectedTokens.toString(vocabulary: recognizer.vocabulary);
|
|
400
|
-
recognizer.notifyErrorListeners(msg, e.offendingToken, e);
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
/// This is called by {@link #reportError} when the exception is a
|
|
404
|
-
/// [FailedPredicateException].
|
|
405
|
-
///
|
|
406
|
-
/// @see #reportError
|
|
407
|
-
///
|
|
408
|
-
/// @param recognizer the parser instance
|
|
409
|
-
/// @param e the recognition exception
|
|
410
|
-
void reportFailedPredicate(Parser recognizer, FailedPredicateException e) {
|
|
411
|
-
final ruleName =
|
|
412
|
-
recognizer.ruleNames[recognizer.context.ruleIndex];
|
|
413
|
-
final msg = 'rule ' + ruleName + ' ' + e.message;
|
|
414
|
-
recognizer.notifyErrorListeners(msg, e.offendingToken, e);
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
/// This method is called to report a syntax error which requires the removal
|
|
418
|
-
/// of a token from the input stream. At the time this method is called, the
|
|
419
|
-
/// erroneous symbol is current {@code LT(1)} symbol and has not yet been
|
|
420
|
-
/// removed from the input stream. When this method returns,
|
|
421
|
-
/// [recognizer] is in error recovery mode.
|
|
422
|
-
///
|
|
423
|
-
/// <p>This method is called when {@link #singleTokenDeletion} identifies
|
|
424
|
-
/// single-token deletion as a viable recovery strategy for a mismatched
|
|
425
|
-
/// input error.</p>
|
|
426
|
-
///
|
|
427
|
-
/// <p>The default implementation simply returns if the handler is already in
|
|
428
|
-
/// error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
|
|
429
|
-
/// enter error recovery mode, followed by calling
|
|
430
|
-
/// {@link Parser#notifyErrorListeners}.</p>
|
|
431
|
-
///
|
|
432
|
-
/// @param recognizer the parser instance
|
|
433
|
-
void reportUnwantedToken(Parser recognizer) {
|
|
434
|
-
if (inErrorRecoveryMode(recognizer)) {
|
|
435
|
-
return;
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
beginErrorCondition(recognizer);
|
|
439
|
-
|
|
440
|
-
final t = recognizer.currentToken;
|
|
441
|
-
final tokenName = getTokenErrorDisplay(t);
|
|
442
|
-
final expecting = getExpectedTokens(recognizer);
|
|
443
|
-
final msg = 'extraneous input ' +
|
|
444
|
-
tokenName +
|
|
445
|
-
' expecting ' +
|
|
446
|
-
expecting.toString(vocabulary: recognizer.vocabulary);
|
|
447
|
-
recognizer.notifyErrorListeners(msg, t, null);
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
/// This method is called to report a syntax error which requires the
|
|
451
|
-
/// insertion of a missing token into the input stream. At the time this
|
|
452
|
-
/// method is called, the missing token has not yet been inserted. When this
|
|
453
|
-
/// method returns, [recognizer] is in error recovery mode.
|
|
454
|
-
///
|
|
455
|
-
/// <p>This method is called when {@link #singleTokenInsertion} identifies
|
|
456
|
-
/// single-token insertion as a viable recovery strategy for a mismatched
|
|
457
|
-
/// input error.</p>
|
|
458
|
-
///
|
|
459
|
-
/// <p>The default implementation simply returns if the handler is already in
|
|
460
|
-
/// error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
|
|
461
|
-
/// enter error recovery mode, followed by calling
|
|
462
|
-
/// {@link Parser#notifyErrorListeners}.</p>
|
|
463
|
-
///
|
|
464
|
-
/// @param recognizer the parser instance
|
|
465
|
-
void reportMissingToken(Parser recognizer) {
|
|
466
|
-
if (inErrorRecoveryMode(recognizer)) {
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
beginErrorCondition(recognizer);
|
|
471
|
-
|
|
472
|
-
final t = recognizer.currentToken;
|
|
473
|
-
final expecting = getExpectedTokens(recognizer);
|
|
474
|
-
final msg = 'missing ' +
|
|
475
|
-
expecting.toString(vocabulary: recognizer.vocabulary) +
|
|
476
|
-
' at ' +
|
|
477
|
-
getTokenErrorDisplay(t);
|
|
478
|
-
|
|
479
|
-
recognizer.notifyErrorListeners(msg, t, null);
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/// {@inheritDoc}
|
|
483
|
-
///
|
|
484
|
-
/// <p>The default implementation attempts to recover from the mismatched input
|
|
485
|
-
/// by using single token insertion and deletion as described below. If the
|
|
486
|
-
/// recovery attempt fails, this method throws an
|
|
487
|
-
/// [InputMismatchException].</p>
|
|
488
|
-
///
|
|
489
|
-
/// <p><strong>EXTRA TOKEN</strong> (single token deletion)</p>
|
|
490
|
-
///
|
|
491
|
-
/// <p>{@code LA(1)} is not what we are looking for. If {@code LA(2)} has the
|
|
492
|
-
/// right token, however, then assume {@code LA(1)} is some extra spurious
|
|
493
|
-
/// token and delete it. Then consume and return the next token (which was
|
|
494
|
-
/// the {@code LA(2)} token) as the successful result of the match operation.</p>
|
|
495
|
-
///
|
|
496
|
-
/// <p>This recovery strategy is implemented by {@link #singleTokenDeletion}.</p>
|
|
497
|
-
///
|
|
498
|
-
/// <p><strong>MISSING TOKEN</strong> (single token insertion)</p>
|
|
499
|
-
///
|
|
500
|
-
/// <p>If current token (at {@code LA(1)}) is consistent with what could come
|
|
501
|
-
/// after the expected {@code LA(1)} token, then assume the token is missing
|
|
502
|
-
/// and use the parser's [TokenFactory] to create it on the fly. The
|
|
503
|
-
/// "insertion" is performed by returning the created token as the successful
|
|
504
|
-
/// result of the match operation.</p>
|
|
505
|
-
///
|
|
506
|
-
/// <p>This recovery strategy is implemented by {@link #singleTokenInsertion}.</p>
|
|
507
|
-
///
|
|
508
|
-
/// <p><strong>EXAMPLE</strong></p>
|
|
509
|
-
///
|
|
510
|
-
/// <p>For example, Input {@code i=(3;} is clearly missing the {@code ')'}. When
|
|
511
|
-
/// the parser returns from the nested call to [expr], it will have
|
|
512
|
-
/// call chain:</p>
|
|
513
|
-
///
|
|
514
|
-
/// <pre>
|
|
515
|
-
/// stat → expr → atom
|
|
516
|
-
/// </pre>
|
|
517
|
-
///
|
|
518
|
-
/// and it will be trying to match the {@code ')'} at this point in the
|
|
519
|
-
/// derivation:
|
|
520
|
-
///
|
|
521
|
-
/// <pre>
|
|
522
|
-
/// => ID '=' '(' INT ')' ('+' atom)* ';'
|
|
523
|
-
/// ^
|
|
524
|
-
/// </pre>
|
|
525
|
-
///
|
|
526
|
-
/// The attempt to match {@code ')'} will fail when it sees {@code ';'} and
|
|
527
|
-
/// call {@link #recoverInline}. To recover, it sees that {@code LA(1)==';'}
|
|
528
|
-
/// is in the set of tokens that can follow the {@code ')'} token reference
|
|
529
|
-
/// in rule [atom]. It can assume that you forgot the {@code ')'}.
|
|
530
|
-
|
|
531
|
-
@override
|
|
532
|
-
Token recoverInline(Parser recognizer) {
|
|
533
|
-
// SINGLE TOKEN DELETION
|
|
534
|
-
final matchedSymbol = singleTokenDeletion(recognizer);
|
|
535
|
-
if (matchedSymbol != null) {
|
|
536
|
-
// we have deleted the extra token.
|
|
537
|
-
// now, move past ttype token as if all were ok
|
|
538
|
-
recognizer.consume();
|
|
539
|
-
return matchedSymbol;
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
// SINGLE TOKEN INSERTION
|
|
543
|
-
if (singleTokenInsertion(recognizer)) {
|
|
544
|
-
return getMissingSymbol(recognizer);
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// even that didn't work; must throw the exception
|
|
548
|
-
InputMismatchException e;
|
|
549
|
-
if (nextTokensContext == null) {
|
|
550
|
-
e = InputMismatchException(recognizer);
|
|
551
|
-
} else {
|
|
552
|
-
e = InputMismatchException(
|
|
553
|
-
recognizer, nextTokensState, nextTokensContext);
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
throw e;
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
/// This method implements the single-token insertion inline error recovery
|
|
560
|
-
/// strategy. It is called by {@link #recoverInline} if the single-token
|
|
561
|
-
/// deletion strategy fails to recover from the mismatched input. If this
|
|
562
|
-
/// method returns [true], [recognizer] will be in error recovery
|
|
563
|
-
/// mode.
|
|
564
|
-
///
|
|
565
|
-
/// <p>This method determines whether or not single-token insertion is viable by
|
|
566
|
-
/// checking if the {@code LA(1)} input symbol could be successfully matched
|
|
567
|
-
/// if it were instead the {@code LA(2)} symbol. If this method returns
|
|
568
|
-
/// [true], the caller is responsible for creating and inserting a
|
|
569
|
-
/// token with the correct type to produce this behavior.</p>
|
|
570
|
-
///
|
|
571
|
-
/// @param recognizer the parser instance
|
|
572
|
-
/// @return [true] if single-token insertion is a viable recovery
|
|
573
|
-
/// strategy for the current mismatched input, otherwise [false]
|
|
574
|
-
bool singleTokenInsertion(Parser recognizer) {
|
|
575
|
-
final currentSymbolType = recognizer.inputStream.LA(1);
|
|
576
|
-
// if current token is consistent with what could come after current
|
|
577
|
-
// ATN state, then we know we're missing a token; error recovery
|
|
578
|
-
// is free to conjure up and insert the missing token
|
|
579
|
-
final currentState =
|
|
580
|
-
recognizer.interpreter.atn.states[recognizer.state];
|
|
581
|
-
final next = currentState.transition(0).target;
|
|
582
|
-
final atn = recognizer.interpreter.atn;
|
|
583
|
-
final expectingAtLL2 = atn.nextTokens(next, recognizer.context);
|
|
584
|
-
// System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
|
|
585
|
-
if (expectingAtLL2.contains(currentSymbolType)) {
|
|
586
|
-
reportMissingToken(recognizer);
|
|
587
|
-
return true;
|
|
588
|
-
}
|
|
589
|
-
return false;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
/// This method implements the single-token deletion inline error recovery
|
|
593
|
-
/// strategy. It is called by {@link #recoverInline} to attempt to recover
|
|
594
|
-
/// from mismatched input. If this method returns null, the parser and error
|
|
595
|
-
/// handler state will not have changed. If this method returns non-null,
|
|
596
|
-
/// [recognizer] will <em>not</em> be in error recovery mode since the
|
|
597
|
-
/// returned token was a successful match.
|
|
598
|
-
///
|
|
599
|
-
/// <p>If the single-token deletion is successful, this method calls
|
|
600
|
-
/// {@link #reportUnwantedToken} to report the error, followed by
|
|
601
|
-
/// {@link Parser#consume} to actually "delete" the extraneous token. Then,
|
|
602
|
-
/// before returning {@link #reportMatch} is called to signal a successful
|
|
603
|
-
/// match.</p>
|
|
604
|
-
///
|
|
605
|
-
/// @param recognizer the parser instance
|
|
606
|
-
/// @return the successfully matched [Token] instance if single-token
|
|
607
|
-
/// deletion successfully recovers from the mismatched input, otherwise
|
|
608
|
-
/// null
|
|
609
|
-
Token singleTokenDeletion(Parser recognizer) {
|
|
610
|
-
final nextTokenType = recognizer.inputStream.LA(2);
|
|
611
|
-
final expecting = getExpectedTokens(recognizer);
|
|
612
|
-
if (expecting.contains(nextTokenType)) {
|
|
613
|
-
reportUnwantedToken(recognizer);
|
|
614
|
-
/*
|
|
615
|
-
log("recoverFromMismatchedToken deleting , level: Level.SEVERE.value"+
|
|
616
|
-
((TokenStream)recognizer.inputStream).LT(1)+
|
|
617
|
-
" since "+((TokenStream)recognizer.inputStream).LT(2)+
|
|
618
|
-
" is what we want");
|
|
619
|
-
*/
|
|
620
|
-
recognizer.consume(); // simply delete extra token
|
|
621
|
-
// we want to return the token we're actually matching
|
|
622
|
-
final matchedSymbol = recognizer.currentToken;
|
|
623
|
-
reportMatch(recognizer); // we know current token is correct
|
|
624
|
-
return matchedSymbol;
|
|
625
|
-
}
|
|
626
|
-
return null;
|
|
627
|
-
}
|
|
628
|
-
|
|
629
|
-
/// Conjure up a missing token during error recovery.
|
|
630
|
-
///
|
|
631
|
-
/// The recognizer attempts to recover from single missing
|
|
632
|
-
/// symbols. But, actions might refer to that missing symbol.
|
|
633
|
-
/// For example, x=ID {f($x);}. The action clearly assumes
|
|
634
|
-
/// that there has been an identifier matched previously and that
|
|
635
|
-
/// $x points at that token. If that token is missing, but
|
|
636
|
-
/// the next token in the stream is what we want we assume that
|
|
637
|
-
/// this token is missing and we keep going. Because we
|
|
638
|
-
/// have to return some token to replace the missing token,
|
|
639
|
-
/// we have to conjure one up. This method gives the user control
|
|
640
|
-
/// over the tokens returned for missing tokens. Mostly,
|
|
641
|
-
/// you will want to create something special for identifier
|
|
642
|
-
/// tokens. For literals such as '{' and ',', the default
|
|
643
|
-
/// action in the parser or tree parser works. It simply creates
|
|
644
|
-
/// a CommonToken of the appropriate type. The text will be the token.
|
|
645
|
-
/// If you change what tokens must be created by the lexer,
|
|
646
|
-
/// override this method to create the appropriate tokens.
|
|
647
|
-
Token getMissingSymbol(Parser recognizer) {
|
|
648
|
-
final currentSymbol = recognizer.currentToken;
|
|
649
|
-
final expecting = getExpectedTokens(recognizer);
|
|
650
|
-
var expectedTokenType = Token.INVALID_TYPE;
|
|
651
|
-
if (!expecting.isNil) {
|
|
652
|
-
expectedTokenType = expecting.minElement; // get any element
|
|
653
|
-
}
|
|
654
|
-
String tokenText;
|
|
655
|
-
if (expectedTokenType == Token.EOF) {
|
|
656
|
-
tokenText = '<missing EOF>';
|
|
657
|
-
} else {
|
|
658
|
-
tokenText = '<missing ' +
|
|
659
|
-
recognizer.vocabulary.getDisplayName(expectedTokenType) +
|
|
660
|
-
'>';
|
|
661
|
-
}
|
|
662
|
-
var current = currentSymbol;
|
|
663
|
-
final lookback = recognizer.inputStream.LT(-1);
|
|
664
|
-
if (current.type == Token.EOF && lookback != null) {
|
|
665
|
-
current = lookback;
|
|
666
|
-
}
|
|
667
|
-
return recognizer.tokenFactory.create(
|
|
668
|
-
expectedTokenType,
|
|
669
|
-
tokenText,
|
|
670
|
-
Pair(current.tokenSource, current.tokenSource.inputStream),
|
|
671
|
-
Token.DEFAULT_CHANNEL,
|
|
672
|
-
-1,
|
|
673
|
-
-1,
|
|
674
|
-
current.line,
|
|
675
|
-
current.charPositionInLine);
|
|
676
|
-
}
|
|
677
|
-
|
|
678
|
-
IntervalSet getExpectedTokens(Parser recognizer) {
|
|
679
|
-
return recognizer.expectedTokens;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
/// How should a token be displayed in an error message? The default
|
|
683
|
-
/// is to display just the text, but during development you might
|
|
684
|
-
/// want to have a lot of information spit out. Override in that case
|
|
685
|
-
/// to use t.toString() (which, for CommonToken, dumps everything about
|
|
686
|
-
/// the token). This is better than forcing you to override a method in
|
|
687
|
-
/// your token objects because you don't have to go modify your lexer
|
|
688
|
-
/// so that it creates a new Java type.
|
|
689
|
-
String getTokenErrorDisplay(Token t) {
|
|
690
|
-
if (t == null) return '<no token>';
|
|
691
|
-
var s = getSymbolText(t);
|
|
692
|
-
if (s == null) {
|
|
693
|
-
if (getSymbolType(t) == Token.EOF) {
|
|
694
|
-
s = '<EOF>';
|
|
695
|
-
} else {
|
|
696
|
-
s = '<${getSymbolType(t)}>';
|
|
697
|
-
}
|
|
698
|
-
}
|
|
699
|
-
return escapeWSAndQuote(s);
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
String getSymbolText(Token symbol) {
|
|
703
|
-
return symbol.text;
|
|
704
|
-
}
|
|
705
|
-
|
|
706
|
-
int getSymbolType(Token symbol) {
|
|
707
|
-
return symbol.type;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
String escapeWSAndQuote(String s) {
|
|
711
|
-
// if ( s==null ) return s;
|
|
712
|
-
s = s.replaceAll('\n', r'\n');
|
|
713
|
-
s = s.replaceAll('\r', r'\r');
|
|
714
|
-
s = s.replaceAll('\t', r'\t');
|
|
715
|
-
return "'" + s + "'";
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
/* Compute the error recovery set for the current rule. During
|
|
719
|
-
* rule invocation, the parser pushes the set of tokens that can
|
|
720
|
-
* follow that rule reference on the stack; this amounts to
|
|
721
|
-
* computing FIRST of what follows the rule reference in the
|
|
722
|
-
* enclosing rule. See LinearApproximator.FIRST().
|
|
723
|
-
* This local follow set only includes tokens
|
|
724
|
-
* from within the rule; i.e., the FIRST computation done by
|
|
725
|
-
* ANTLR stops at the end of a rule.
|
|
726
|
-
*
|
|
727
|
-
* EXAMPLE
|
|
728
|
-
*
|
|
729
|
-
* When you find a "no viable alt exception", the input is not
|
|
730
|
-
* consistent with any of the alternatives for rule r. The best
|
|
731
|
-
* thing to do is to consume tokens until you see something that
|
|
732
|
-
* can legally follow a call to r *or* any rule that called r.
|
|
733
|
-
* You don't want the exact set of viable next tokens because the
|
|
734
|
-
* input might just be missing a token--you might consume the
|
|
735
|
-
* rest of the input looking for one of the missing tokens.
|
|
736
|
-
*
|
|
737
|
-
* Consider grammar:
|
|
738
|
-
*
|
|
739
|
-
* a : '[' b ']'
|
|
740
|
-
* | '(' b ')'
|
|
741
|
-
* ;
|
|
742
|
-
* b : c '^' INT ;
|
|
743
|
-
* c : ID
|
|
744
|
-
* | INT
|
|
745
|
-
* ;
|
|
746
|
-
*
|
|
747
|
-
* At each rule invocation, the set of tokens that could follow
|
|
748
|
-
* that rule is pushed on a stack. Here are the various
|
|
749
|
-
* context-sensitive follow sets:
|
|
750
|
-
*
|
|
751
|
-
* FOLLOW(b1_in_a) = FIRST(']') = ']'
|
|
752
|
-
* FOLLOW(b2_in_a) = FIRST(')') = ')'
|
|
753
|
-
* FOLLOW(c_in_b) = FIRST('^') = '^'
|
|
754
|
-
*
|
|
755
|
-
* Upon erroneous input "[]", the call chain is
|
|
756
|
-
*
|
|
757
|
-
* a -> b -> c
|
|
758
|
-
*
|
|
759
|
-
* and, hence, the follow context stack is:
|
|
760
|
-
*
|
|
761
|
-
* depth follow set start of rule execution
|
|
762
|
-
* 0 <EOF> a (from main())
|
|
763
|
-
* 1 ']' b
|
|
764
|
-
* 2 '^' c
|
|
765
|
-
*
|
|
766
|
-
* Notice that ')' is not included, because b would have to have
|
|
767
|
-
* been called from a different context in rule a for ')' to be
|
|
768
|
-
* included.
|
|
769
|
-
*
|
|
770
|
-
* For error recovery, we cannot consider FOLLOW(c)
|
|
771
|
-
* (context-sensitive or otherwise). We need the combined set of
|
|
772
|
-
* all context-sensitive FOLLOW sets--the set of all tokens that
|
|
773
|
-
* could follow any reference in the call chain. We need to
|
|
774
|
-
* resync to one of those tokens. Note that FOLLOW(c)='^' and if
|
|
775
|
-
* we resync'd to that token, we'd consume until EOF. We need to
|
|
776
|
-
* sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
|
|
777
|
-
* In this case, for input "[]", LA(1) is ']' and in the set, so we would
|
|
778
|
-
* not consume anything. After printing an error, rule c would
|
|
779
|
-
* return normally. Rule b would not find the required '^' though.
|
|
780
|
-
* At this point, it gets a mismatched token error and throws an
|
|
781
|
-
* exception (since LA(1) is not in the viable following token
|
|
782
|
-
* set). The rule exception handler tries to recover, but finds
|
|
783
|
-
* the same recovery set and doesn't consume anything. Rule b
|
|
784
|
-
* exits normally returning to rule a. Now it finds the ']' (and
|
|
785
|
-
* with the successful match exits errorRecovery mode).
|
|
786
|
-
*
|
|
787
|
-
* So, you can see that the parser walks up the call chain looking
|
|
788
|
-
* for the token that was a member of the recovery set.
|
|
789
|
-
*
|
|
790
|
-
* Errors are not generated in errorRecovery mode.
|
|
791
|
-
*
|
|
792
|
-
* ANTLR's error recovery mechanism is based upon original ideas:
|
|
793
|
-
*
|
|
794
|
-
* "Algorithms + Data Structures = Programs" by Niklaus Wirth
|
|
795
|
-
*
|
|
796
|
-
* and
|
|
797
|
-
*
|
|
798
|
-
* "A note on error recovery in recursive descent parsers":
|
|
799
|
-
* http://portal.acm.org/citation.cfm?id=947902.947905
|
|
800
|
-
*
|
|
801
|
-
* Later, Josef Grosch had some good ideas:
|
|
802
|
-
*
|
|
803
|
-
* "Efficient and Comfortable Error Recovery in Recursive Descent
|
|
804
|
-
* Parsers":
|
|
805
|
-
* ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
|
|
806
|
-
*
|
|
807
|
-
* Like Grosch I implement context-sensitive FOLLOW sets that are combined
|
|
808
|
-
* at run-time upon error to avoid overhead during parsing.
|
|
809
|
-
*/
|
|
810
|
-
IntervalSet getErrorRecoverySet(Parser recognizer) {
|
|
811
|
-
final atn = recognizer.interpreter.atn;
|
|
812
|
-
RuleContext ctx = recognizer.context;
|
|
813
|
-
final recoverSet = IntervalSet();
|
|
814
|
-
while (ctx != null && ctx.invokingState >= 0) {
|
|
815
|
-
// compute what follows who invoked us
|
|
816
|
-
final invokingState = atn.states[ctx.invokingState];
|
|
817
|
-
RuleTransition rt = invokingState.transition(0);
|
|
818
|
-
final follow = atn.nextTokens(rt.followState);
|
|
819
|
-
recoverSet.addAll(follow);
|
|
820
|
-
ctx = ctx.parent;
|
|
821
|
-
}
|
|
822
|
-
recoverSet.remove(Token.EPSILON);
|
|
823
|
-
// System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
|
|
824
|
-
return recoverSet;
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
/// Consume tokens until one matches the given token set. */
|
|
828
|
-
void consumeUntil(Parser recognizer, IntervalSet set) {
|
|
829
|
-
// log("consumeUntil("+set.toString(recognizer.getTokenNames())+")", level: Level.SEVERE.value);
|
|
830
|
-
var ttype = recognizer.inputStream.LA(1);
|
|
831
|
-
while (ttype != Token.EOF && !set.contains(ttype)) {
|
|
832
|
-
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
|
|
833
|
-
// recognizer.inputStream.consume();
|
|
834
|
-
recognizer.consume();
|
|
835
|
-
ttype = recognizer.inputStream.LA(1);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
|
|
840
|
-
/// This implementation of [ANTLRErrorStrategy] responds to syntax errors
|
|
841
|
-
/// by immediately canceling the parse operation with a
|
|
842
|
-
/// [ParseCancellationException]. The implementation ensures that the
|
|
843
|
-
/// {@link ParserRuleContext#exception} field is set for all parse tree nodes
|
|
844
|
-
/// that were not completed prior to encountering the error.
|
|
845
|
-
///
|
|
846
|
-
/// <p>
|
|
847
|
-
/// This error strategy is useful in the following scenarios.</p>
|
|
848
|
-
///
|
|
849
|
-
/// <ul>
|
|
850
|
-
/// <li><strong>Two-stage parsing:</strong> This error strategy allows the first
|
|
851
|
-
/// stage of two-stage parsing to immediately terminate if an error is
|
|
852
|
-
/// encountered, and immediately fall back to the second stage. In addition to
|
|
853
|
-
/// avoiding wasted work by attempting to recover from errors here, the empty
|
|
854
|
-
/// implementation of {@link BailErrorStrategy#sync} improves the performance of
|
|
855
|
-
/// the first stage.</li>
|
|
856
|
-
/// <li><strong>Silent validation:</strong> When syntax errors are not being
|
|
857
|
-
/// reported or logged, and the parse result is simply ignored if errors occur,
|
|
858
|
-
/// the [BailErrorStrategy] avoids wasting work on recovering from errors
|
|
859
|
-
/// when the result will be ignored either way.</li>
|
|
860
|
-
/// </ul>
|
|
861
|
-
///
|
|
862
|
-
/// <p>
|
|
863
|
-
/// {@code myparser.setErrorHandler(new BailErrorStrategy());}</p>
|
|
864
|
-
///
|
|
865
|
-
/// @see Parser#setErrorHandler(ANTLRErrorStrategy)
|
|
866
|
-
class BailErrorStrategy extends DefaultErrorStrategy {
|
|
867
|
-
/// Instead of recovering from exception [e], re-throw it wrapped
|
|
868
|
-
/// in a [ParseCancellationException] so it is not caught by the
|
|
869
|
-
/// rule function catches. Use {@link Exception#getCause()} to get the
|
|
870
|
-
/// original [RecognitionException].
|
|
871
|
-
|
|
872
|
-
@override
|
|
873
|
-
void recover(Parser recognizer, RecognitionException e) {
|
|
874
|
-
for (var context = recognizer.context;
|
|
875
|
-
context != null;
|
|
876
|
-
context = context.parent) {
|
|
877
|
-
context.exception = e;
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
throw ParseCancellationException(e.message);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
/// Make sure we don't attempt to recover inline; if the parser
|
|
884
|
-
/// successfully recovers, it won't throw an exception.
|
|
885
|
-
|
|
886
|
-
@override
|
|
887
|
-
Token recoverInline(Parser recognizer) {
|
|
888
|
-
final e = InputMismatchException(recognizer);
|
|
889
|
-
for (var context = recognizer.context;
|
|
890
|
-
context != null;
|
|
891
|
-
context = context.parent) {
|
|
892
|
-
context.exception = e;
|
|
893
|
-
}
|
|
894
|
-
|
|
895
|
-
throw ParseCancellationException(e.message);
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
/// Make sure we don't attempt to recover from problems in subrules. */
|
|
899
|
-
|
|
900
|
-
@override
|
|
901
|
-
void sync(Parser recognizer) {}
|
|
902
|
-
}
|