Coverage Report

Created: 2025-11-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/external/antlr4-cpp-runtime~/runtime/src/Parser.h
Line
Count
Source
1
/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2
 * Use of this file is governed by the BSD 3-clause license that
3
 * can be found in the LICENSE.txt file in the project root.
4
 */
5
6
#pragma once
7
8
#include "Recognizer.h"
9
#include "tree/ParseTreeListener.h"
10
#include "tree/ParseTree.h"
11
#include "TokenStream.h"
12
#include "TokenSource.h"
13
#include "misc/Interval.h"
14
15
namespace antlr4 {
16
17
  /// This is all the parsing support code essentially; most of it is error recovery stuff.
18
  class ANTLR4CPP_PUBLIC Parser : public Recognizer {
19
  public:
20
21
    class TraceListener : public tree::ParseTreeListener {
22
    public:
23
      TraceListener(Parser *outerInstance);
24
      virtual ~TraceListener();
25
26
      virtual void enterEveryRule(ParserRuleContext *ctx) override;
27
      virtual void visitTerminal(tree::TerminalNode *node) override;
28
      virtual void visitErrorNode(tree::ErrorNode *node) override;
29
      virtual void exitEveryRule(ParserRuleContext *ctx) override;
30
31
    private:
32
      Parser *const outerInstance;
33
    };
34
35
    class TrimToSizeListener : public tree::ParseTreeListener {
36
    public:
37
      static TrimToSizeListener INSTANCE;
38
39
      virtual ~TrimToSizeListener();
40
41
      virtual void enterEveryRule(ParserRuleContext *ctx) override;
42
      virtual void visitTerminal(tree::TerminalNode *node) override;
43
      virtual void visitErrorNode(tree::ErrorNode *node) override;
44
      virtual void exitEveryRule(ParserRuleContext *ctx) override;
45
    };
46
47
    Parser(TokenStream *input);
48
    virtual ~Parser();
49
50
    /// reset the parser's state
51
    virtual void reset();
52
53
    /// <summary>
54
    /// Match current input symbol against {@code ttype}. If the symbol type
55
    /// matches, <seealso cref="ANTLRErrorStrategy#reportMatch"/> and <seealso cref="#consume"/> are
56
    /// called to complete the match process.
57
    ///
58
    /// If the symbol type does not match,
59
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
60
    /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
61
    /// {@code true} and the token index of the symbol returned by
62
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
63
    /// the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
64
    /// {@link ParserRuleContext#addErrorNode(ErrorNode)}.
65
    /// </summary>
66
    /// <param name="ttype"> the token type to match </param>
67
    /// <returns> the matched symbol </returns>
68
    /// <exception cref="RecognitionException"> if the current input symbol did not match
69
    /// {@code ttype} and the error strategy could not recover from the
70
    /// mismatched symbol </exception>
71
    virtual Token* match(size_t ttype);
72
73
    /// <summary>
74
    /// Match current input symbol as a wildcard. If the symbol type matches
75
    /// (i.e. has a value greater than 0), <seealso cref="ANTLRErrorStrategy#reportMatch"/>
76
    /// and <seealso cref="#consume"/> are called to complete the match process.
77
    /// <p/>
78
    /// If the symbol type does not match,
79
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
80
    /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
81
    /// {@code true} and the token index of the symbol returned by
82
    /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
83
    /// the parse tree by calling <seealso cref="ParserRuleContext#addErrorNode"/>.
84
    /// </summary>
85
    /// <returns> the matched symbol </returns>
86
    /// <exception cref="RecognitionException"> if the current input symbol did not match
87
    /// a wildcard and the error strategy could not recover from the mismatched
88
    /// symbol </exception>
89
    virtual Token* matchWildcard();
90
91
    /// <summary>
92
    /// Track the <seealso cref="ParserRuleContext"/> objects during the parse and hook
93
    /// them up using the <seealso cref="ParserRuleContext#children"/> list so that it
94
    /// forms a parse tree. The <seealso cref="ParserRuleContext"/> returned from the start
95
    /// rule represents the root of the parse tree.
96
    /// <p/>
97
    /// Note that if we are not building parse trees, rule contexts only point
98
    /// upwards. When a rule exits, it returns the context but that gets garbage
99
    /// collected if nobody holds a reference. It points upwards but nobody
100
    /// points at it.
101
    /// <p/>
102
    /// When we build parse trees, we are adding all of these contexts to
103
    /// <seealso cref="ParserRuleContext#children"/> list. Contexts are then not candidates
104
    /// for garbage collection.
105
    /// </summary>
106
    virtual void setBuildParseTree(bool buildParseTrees);
107
108
    /// <summary>
109
    /// Gets whether or not a complete parse tree will be constructed while
110
    /// parsing. This property is {@code true} for a newly constructed parser.
111
    /// </summary>
112
    /// <returns> {@code true} if a complete parse tree will be constructed while
113
    /// parsing, otherwise {@code false} </returns>
114
    virtual bool getBuildParseTree();
115
116
    /// <summary>
117
    /// Trim the internal lists of the parse tree during parsing to conserve memory.
118
    /// This property is set to {@code false} by default for a newly constructed parser.
119
    /// </summary>
120
    /// <param name="trimParseTrees"> {@code true} to trim the capacity of the <seealso cref="ParserRuleContext#children"/>
121
    /// list to its size after a rule is parsed. </param>
122
    virtual void setTrimParseTree(bool trimParseTrees);
123
124
    /// <returns> {@code true} if the <seealso cref="ParserRuleContext#children"/> list is trimmed
125
    /// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns>
126
    virtual bool getTrimParseTree();
127
128
    virtual std::vector<tree::ParseTreeListener *> getParseListeners();
129
130
    /// <summary>
131
    /// Registers {@code listener} to receive events during the parsing process.
132
    /// <p/>
133
    /// To support output-preserving grammar transformations (including but not
134
    /// limited to left-recursion removal, automated left-factoring, and
135
    /// optimized code generation), calls to listener methods during the parse
136
    /// may differ substantially from calls made by
137
    /// <seealso cref="ParseTreeWalker#DEFAULT"/> used after the parse is complete. In
138
    /// particular, rule entry and exit events may occur in a different order
139
    /// during the parse than after the parser. In addition, calls to certain
140
    /// rule entry methods may be omitted.
141
    /// <p/>
142
    /// With the following specific exceptions, calls to listener events are
143
    /// <em>deterministic</em>, i.e. for identical input the calls to listener
144
    /// methods will be the same.
145
    ///
146
    /// <ul>
147
    /// <li>Alterations to the grammar used to generate code may change the
148
    /// behavior of the listener calls.</li>
149
    /// <li>Alterations to the command line options passed to ANTLR 4 when
150
    /// generating the parser may change the behavior of the listener calls.</li>
151
    /// <li>Changing the version of the ANTLR Tool used to generate the parser
152
    /// may change the behavior of the listener calls.</li>
153
    /// </ul>
154
    /// </summary>
155
    /// <param name="listener"> the listener to add
156
    /// </param>
157
    /// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception>
158
    virtual void addParseListener(tree::ParseTreeListener *listener);
159
160
    /// <summary>
161
    /// Remove {@code listener} from the list of parse listeners.
162
    /// <p/>
163
    /// If {@code listener} is {@code null} or has not been added as a parse
164
    /// listener, this method does nothing.
165
    /// </summary>
166
    /// <seealso cref= #addParseListener
167
    /// </seealso>
168
    /// <param name="listener"> the listener to remove </param>
169
    virtual void removeParseListener(tree::ParseTreeListener *listener);
170
171
    /// <summary>
172
    /// Remove all parse listeners.
173
    /// </summary>
174
    /// <seealso cref= #addParseListener </seealso>
175
    virtual void removeParseListeners();
176
177
    /// <summary>
178
    /// Notify any parse listeners of an enter rule event.
179
    /// </summary>
180
    /// <seealso cref= #addParseListener </seealso>
181
    virtual void triggerEnterRuleEvent();
182
183
    /// <summary>
184
    /// Notify any parse listeners of an exit rule event.
185
    /// </summary>
186
    /// <seealso cref= #addParseListener </seealso>
187
    virtual void triggerExitRuleEvent();
188
189
    /// <summary>
190
    /// Gets the number of syntax errors reported during parsing. This value is
191
    /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
192
    /// </summary>
193
    /// <seealso cref= #notifyErrorListeners </seealso>
194
    virtual size_t getNumberOfSyntaxErrors();
195
196
    virtual TokenFactory<CommonToken>* getTokenFactory() override;
197
198
    /// <summary>
199
    /// Tell our token source and error strategy about a new way to create tokens. </summary>
200
    template<typename T1>
201
    void setTokenFactory(TokenFactory<T1> *factory)  {
202
      _input->getTokenSource()->setTokenFactory(factory);
203
    }
204
205
    /// The ATN with bypass alternatives is expensive to create so we create it
206
    /// lazily. The ATN is owned by us.
207
    virtual const atn::ATN& getATNWithBypassAlts();
208
209
    /// <summary>
210
    /// The preferred method of getting a tree pattern. For example, here's a
211
    /// sample use:
212
    ///
213
    /// <pre>
214
    /// ParseTree t = parser.expr();
215
    /// ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
216
    /// ParseTreeMatch m = p.match(t);
217
    /// String id = m.get("ID");
218
    /// </pre>
219
    /// </summary>
220
    virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex);
221
222
    /// <summary>
223
    /// The same as <seealso cref="#compileParseTreePattern(String, int)"/> but specify a
224
    /// <seealso cref="Lexer"/> rather than trying to deduce it from this parser.
225
    /// </summary>
226
    virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex,
227
                                                                    Lexer *lexer);
228
229
    virtual Ref<ANTLRErrorStrategy> getErrorHandler();
230
    virtual void setErrorHandler(Ref<ANTLRErrorStrategy> const& handler);
231
232
    virtual IntStream* getInputStream() override;
233
    void setInputStream(IntStream *input) override;
234
235
    virtual TokenStream* getTokenStream();
236
237
    /// Set the token stream and reset the parser.
238
    virtual void setTokenStream(TokenStream *input);
239
240
    /// <summary>
241
    /// Match needs to return the current input symbol, which gets put
242
    ///  into the label for the associated token ref; e.g., x=ID.
243
    /// </summary>
244
    virtual Token* getCurrentToken();
245
246
    void notifyErrorListeners(const std::string &msg);
247
248
    virtual void notifyErrorListeners(Token *offendingToken, const std::string &msg, std::exception_ptr e);
249
250
    /// Consume and return the <seealso cref="#getCurrentToken current symbol"/>.
251
    /// <p/>
252
    /// E.g., given the following input with {@code A} being the current
253
    /// lookahead symbol, this function moves the cursor to {@code B} and returns
254
    /// {@code A}.
255
    ///
256
    /// <pre>
257
    ///  A B
258
    ///  ^
259
    /// </pre>
260
    ///
261
    /// If the parser is not in error recovery mode, the consumed symbol is added
262
    /// to the parse tree using <seealso cref="ParserRuleContext#addChild(TerminalNode)"/>, and
263
    /// <seealso cref="ParseTreeListener#visitTerminal"/> is called on any parse listeners.
264
    /// If the parser <em>is</em> in error recovery mode, the consumed symbol is
265
    /// added to the parse tree using {@link #createErrorNode(ParserRuleContext, Token)} then
266
    /// {@link ParserRuleContext#addErrorNode(ErrorNode)} and
267
    /// <seealso cref="ParseTreeListener#visitErrorNode"/> is called on any parse
268
    /// listeners.
269
    virtual Token* consume();
270
271
    /// Always called by generated parsers upon entry to a rule. Access field
272
    /// <seealso cref="#_ctx"/> get the current context.
273
    virtual void enterRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex);
274
275
    void exitRule();
276
277
    virtual void enterOuterAlt(ParserRuleContext *localctx, size_t altNum);
278
279
    /**
280
     * Get the precedence level for the top-most precedence rule.
281
     *
282
     * @return The precedence level for the top-most precedence rule, or -1 if
283
     * the parser context is not nested within a precedence rule.
284
     */
285
    int getPrecedence() const;
286
287
    /// @deprecated Use
288
    /// <seealso cref="#enterRecursionRule(ParserRuleContext, int, int, int)"/> instead.
289
    virtual void enterRecursionRule(ParserRuleContext *localctx, size_t ruleIndex);
290
    virtual void enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex, int precedence);
291
292
    /** Like {@link #enterRule} but for recursive rules.
293
     *  Make the current context the child of the incoming localctx.
294
     */
295
    virtual void pushNewRecursionContext(ParserRuleContext *localctx, size_t state, size_t ruleIndex);
296
    virtual void unrollRecursionContexts(ParserRuleContext *parentctx);
297
    virtual ParserRuleContext* getInvokingContext(size_t ruleIndex);
298
    virtual ParserRuleContext* getContext();
299
    virtual void setContext(ParserRuleContext *ctx);
300
    virtual bool precpred(RuleContext *localctx, int precedence) override;
301
    virtual bool inContext(const std::string &context);
302
303
    /// <summary>
304
    /// Checks whether or not {@code symbol} can follow the current state in the
305
    /// ATN. The behavior of this method is equivalent to the following, but is
306
    /// implemented such that the complete context-sensitive follow set does not
307
    /// need to be explicitly constructed.
308
    ///
309
    /// <pre>
310
    /// return getExpectedTokens().contains(symbol);
311
    /// </pre>
312
    /// </summary>
313
    /// <param name="symbol"> the symbol type to check </param>
314
    /// <returns> {@code true} if {@code symbol} can follow the current state in
315
    /// the ATN, otherwise {@code false}. </returns>
316
    virtual bool isExpectedToken(size_t symbol);
317
318
    bool isMatchedEOF() const;
319
320
    /// <summary>
321
    /// Computes the set of input symbols which could follow the current parser
322
    /// state and context, as given by <seealso cref="#getState"/> and <seealso cref="#getContext"/>,
323
    /// respectively.
324
    /// </summary>
325
    /// <seealso cref= ATN#getExpectedTokens(int, RuleContext) </seealso>
326
    virtual misc::IntervalSet getExpectedTokens();
327
328
    virtual misc::IntervalSet getExpectedTokensWithinCurrentRule();
329
330
    /// Get a rule's index (i.e., {@code RULE_ruleName} field) or INVALID_INDEX if not found.
331
    virtual size_t getRuleIndex(const std::string &ruleName);
332
333
    virtual ParserRuleContext* getRuleContext();
334
335
    /// <summary>
336
    /// Return List&lt;String&gt; of the rule names in your parser instance
337
    ///  leading up to a call to the current rule.  You could override if
338
    ///  you want more details such as the file/line info of where
339
    ///  in the ATN a rule is invoked.
340
    ///
341
    ///  This is very useful for error messages.
342
    /// </summary>
343
    virtual std::vector<std::string> getRuleInvocationStack();
344
345
    virtual std::vector<std::string> getRuleInvocationStack(RuleContext *p);
346
347
    /// <summary>
348
    /// For debugging and other purposes. </summary>
349
    virtual std::vector<std::string> getDFAStrings();
350
351
    /// <summary>
352
    /// For debugging and other purposes. </summary>
353
    virtual void dumpDFA();
354
355
    virtual std::string getSourceName();
356
357
    atn::ParseInfo getParseInfo() const;
358
359
    /**
360
     * @since 4.3
361
     */
362
    void setProfile(bool profile);
363
364
    /// <summary>
365
    /// During a parse is sometimes useful to listen in on the rule entry and exit
366
    ///  events as well as token matches. This is for quick and dirty debugging.
367
    /// </summary>
368
    virtual void setTrace(bool trace);
369
370
    /**
371
     * Gets whether a {@link TraceListener} is registered as a parse listener
372
     * for the parser.
373
     *
374
     * @see #setTrace(boolean)
375
     */
376
    bool isTrace() const;
377
378
0
    tree::ParseTreeTracker& getTreeTracker() { return _tracker; }
379
380
    /** How to create a token leaf node associated with a parent.
381
     *  Typically, the terminal node to create is not a function of the parent
382
     *  but this method must still set the parent pointer of the terminal node
383
     *  returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
384
     *  set the parent pointer, but the parent pointer is implementation dependent
385
     *  and currently there is no setParent() in {@link TerminalNode} (and can't
386
     *  add method in Java 1.7 without breaking backward compatibility).
387
     *
388
     * @since 4.7
389
     */
390
    tree::TerminalNode *createTerminalNode(Token *t);
391
392
    /** How to create an error node, given a token, associated with a parent.
393
       *  Typically, the error node to create is not a function of the parent
394
       *  but this method must still set the parent pointer of the terminal node
395
       *  returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
396
       *  set the parent pointer, but the parent pointer is implementation dependent
397
       *  and currently there is no setParent() in {@link ErrorNode} (and can't
398
       *  add method in Java 1.7 without breaking backward compatibility).
399
       *
400
       * @since 4.7
401
       */
402
    tree::ErrorNode *createErrorNode(Token *t);
403
404
  protected:
405
    /// The ParserRuleContext object for the currently executing rule.
406
    /// This is always non-null during the parsing process.
407
    // ml: this is one of the contexts tracked in _allocatedContexts.
408
    ParserRuleContext *_ctx;
409
410
    /// The error handling strategy for the parser. The default is DefaultErrorStrategy.
411
    /// See also getErrorHandler.
412
    Ref<ANTLRErrorStrategy> _errHandler;
413
414
    /// <summary>
415
    /// The input stream.
416
    /// </summary>
417
    /// <seealso cref= #getInputStream </seealso>
418
    /// <seealso cref= #setInputStream </seealso>
419
    TokenStream *_input;
420
421
    std::vector<int> _precedenceStack;
422
423
    /// <summary>
424
    /// Specifies whether or not the parser should construct a parse tree during
425
    /// the parsing process. The default value is {@code true}.
426
    /// </summary>
427
    /// <seealso cref= #getBuildParseTree </seealso>
428
    /// <seealso cref= #setBuildParseTree </seealso>
429
    bool _buildParseTrees;
430
431
    /// The list of <seealso cref="ParseTreeListener"/> listeners registered to receive
432
    /// events during the parse.
433
    /// <seealso cref= #addParseListener </seealso>
434
    std::vector<tree::ParseTreeListener *> _parseListeners;
435
436
    /// <summary>
437
    /// The number of syntax errors reported during parsing. This value is
438
    /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
439
    /// </summary>
440
    size_t _syntaxErrors;
441
442
    /** Indicates parser has match()ed EOF token. See {@link #exitRule()}. */
443
    bool _matchedEOF;
444
445
    virtual void addContextToParseTree();
446
447
    // All rule contexts created during a parse run. This is cleared when calling reset().
448
    tree::ParseTreeTracker _tracker;
449
450
  private:
451
    /// When setTrace(true) is called, a reference to the
452
    /// TraceListener is stored here so it can be easily removed in a
453
    /// later call to setTrace(false). The listener itself is
454
    /// implemented as a parser listener so this field is not directly used by
455
    /// other parser methods.
456
    TraceListener *_tracer;
457
458
    void InitializeInstanceFields();
459
  };
460
461
} // namespace antlr4