--- /dev/null
+grammar Toc;\r
+\r
+prog: (decl)+ EOF;\r
+\r
+decl: varDecl\r
+ | funcDecl\r
+ | structDecl\r
+ ;\r
+\r
+varDecl: 'var' var;\r
+var: varName (':' type) ('=' expr)?;\r
+\r
+type: typeName;\r
+\r
+\r
+funcDecl: 'func' func;\r
+func: funcName '(' parameter ')' (':' type) body;\r
+parameter: (firstParameter (additionalParameter)*)?;\r
+firstParameter: var;\r
+additionalParameter: ',' var;\r
+\r
+body: '{' stmt* '}';\r
+\r
+\r
+structDecl: 'struct' structName '{' structMember* '}';\r
+structMember: structVar | structMethod;\r
+structVar: var;\r
+structMethod: func;\r
+\r
+\r
+stmt: (varDecl\r
+ | conditional\r
+ | loop\r
+ | assignment\r
+ | returnStmt\r
+ | expr) ;\r
+\r
+conditional: ifCond;\r
+ifCond: 'if' expr body;\r
+\r
+loop: whileLoop;\r
+whileLoop: 'while' expr body;\r
+\r
+assignment: identifier '=' expr;\r
+\r
+returnStmt: 'return' expr;\r
+\r
+expr: funcCall\r
+ | literal\r
+ | identifier\r
+ | subscript\r
+ | memberAccess\r
+ | parenExpr\r
+ | operatorExpr;\r
+\r
+nonOpExpr: funcCall\r
+ | literal\r
+ | identifier\r
+ | subscript\r
+ | memberAccess\r
+ | parenExpr;\r
+\r
+nonSubscriptExpr: funcCall\r
+ | identifier\r
+ | memberAccess\r
+ | parenExpr;\r
+\r
+funcCall: funcName '(' (expr (',' expr)*)? ')';\r
+\r
+operatorExpr: binaryOperator;\r
+binaryOperator: nonOpExpr BINARY_OPERATOR nonOpExpr (BINARY_OPERATOR nonOpExpr)*;\r
+\r
+identifier: varName;\r
+\r
+literal: INTLIT;\r
+\r
+subscript: nonSubscriptExpr '[' expr ']';\r
+\r
+memberAccess: identifier '.' identifier;\r
+\r
+parenExpr: '(' expr ')';\r
+\r
+funcName: NAME;\r
+varName: NAME;\r
+typeName: NAME;\r
+structName: NAME;\r
+\r
+\r
+BINARY_OPERATOR:\r
+ '+' | '-' | '*' | '/'\r
+ | '==' | '!='\r
+ | '<' | '>';\r
+INTLIT: ('+' | '-')? [0-9]+;\r
+NAME: ([a-z] | [A-Z] | [0-9])+;\r
+WS: [ \t\r\n]+ -> skip;\r
+NEWLINE: [\r\n]+;\r
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RecognitionException.h"
+
+namespace antlrcpp {
+ class BitSet;
+}
+
+namespace antlr4 {
+
+ /// How to emit recognition errors (an interface in Java).
+ class ANTLR4CPP_PUBLIC ANTLRErrorListener {
+ public:
+ virtual ~ANTLRErrorListener();
+
+ /// <summary>
+ /// Upon syntax error, notify any interested parties. This is not how to
+ /// recover from errors or compute error messages. <seealso cref="ANTLRErrorStrategy"/>
+ /// specifies how to recover from syntax errors and how to compute error
+ /// messages. This listener's job is simply to emit a computed message,
+ /// though it has enough information to create its own message in many cases.
+ /// <p/>
+ /// The <seealso cref="RecognitionException"/> is non-null for all syntax errors except
+ /// when we discover mismatched token errors that we can recover from
+ /// in-line, without returning from the surrounding rule (via the single
+ /// token insertion and deletion mechanism).
+ /// </summary>
+ /// <param name="recognizer">
+ /// What parser got the error. From this
+ /// object, you can access the context as well
+ /// as the input stream. </param>
+ /// <param name="offendingSymbol">
+ /// The offending token in the input token
+ /// stream, unless recognizer is a lexer (then it's null). If
+ /// no viable alternative error, {@code e} has token at which we
+ /// started production for the decision. </param>
+ /// <param name="line">
+ /// The line number in the input where the error occurred. </param>
+ /// <param name="charPositionInLine">
+ /// The character position within that line where the error occurred. </param>
+ /// <param name="msg">
+ /// The message to emit. </param>
+ /// <param name="e">
+ /// The exception generated by the parser that led to
+ /// the reporting of an error. It is null in the case where
+ /// the parser was able to recover in line without exiting the
+ /// surrounding rule. </param>
+ virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
+ size_t charPositionInLine, const std::string &msg, std::exception_ptr e) = 0;
+
+ /**
+ * This method is called by the parser when a full-context prediction
+ * results in an ambiguity.
+ *
+ * <p>Each full-context prediction which does not result in a syntax error
+ * will call either {@link #reportContextSensitivity} or
+ * {@link #reportAmbiguity}.</p>
+ *
+ * <p>When {@code ambigAlts} is not null, it contains the set of potentially
+ * viable alternatives identified by the prediction algorithm. When
+ * {@code ambigAlts} is null, use {@link ATNConfigSet#getAlts} to obtain the
+ * represented alternatives from the {@code configs} argument.</p>
+ *
+ * <p>When {@code exact} is {@code true}, <em>all</em> of the potentially
+ * viable alternatives are truly viable, i.e. this is reporting an exact
+ * ambiguity. When {@code exact} is {@code false}, <em>at least two</em> of
+ * the potentially viable alternatives are viable for the current input, but
+ * the prediction algorithm terminated as soon as it determined that at
+ * least the <em>minimum</em> potentially viable alternative is truly
+ * viable.</p>
+ *
+ * <p>When the {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} prediction
+ * mode is used, the parser is required to identify exact ambiguities so
+ * {@code exact} will always be {@code true}.</p>
+ *
+ * <p>This method is not used by lexers.</p>
+ *
+ * @param recognizer the parser instance
+ * @param dfa the DFA for the current decision
+ * @param startIndex the input index where the decision started
+ * @param stopIndex the input input where the ambiguity was identified
+ * @param exact {@code true} if the ambiguity is exactly known, otherwise
+ * {@code false}. This is always {@code true} when
+ * {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
+ * @param ambigAlts the potentially ambiguous alternatives, or {@code null}
+ * to indicate that the potentially ambiguous alternatives are the complete
+ * set of represented alternatives in {@code configs}
+ * @param configs the ATN configuration set where the ambiguity was
+ * identified
+ */
+ virtual void reportAmbiguity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
+ const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) = 0;
+
+ /**
+ * This method is called when an SLL conflict occurs and the parser is about
+ * to use the full context information to make an LL decision.
+ *
+ * <p>If one or more configurations in {@code configs} contains a semantic
+ * predicate, the predicates are evaluated before this method is called. The
+ * subset of alternatives which are still viable after predicates are
+ * evaluated is reported in {@code conflictingAlts}.</p>
+ *
+ * <p>This method is not used by lexers.</p>
+ *
+ * @param recognizer the parser instance
+ * @param dfa the DFA for the current decision
+ * @param startIndex the input index where the decision started
+ * @param stopIndex the input index where the SLL conflict occurred
+ * @param conflictingAlts The specific conflicting alternatives. If this is
+ * {@code null}, the conflicting alternatives are all alternatives
+ * represented in {@code configs}. At the moment, conflictingAlts is non-null
+ * (for the reference implementation, but Sam's optimized version can see this
+ * as null).
+ * @param configs the ATN configuration set where the SLL conflict was
+ * detected
+ */
+ virtual void reportAttemptingFullContext(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) = 0;
+
+ /**
+ * This method is called by the parser when a full-context prediction has a
+ * unique result.
+ *
+ * <p>Each full-context prediction which does not result in a syntax error
+ * will call either {@link #reportContextSensitivity} or
+ * {@link #reportAmbiguity}.</p>
+ *
+ * <p>For prediction implementations that only evaluate full-context
+ * predictions when an SLL conflict is found (including the default
+ * {@link ParserATNSimulator} implementation), this method reports cases
+ * where SLL conflicts were resolved to unique full-context predictions,
+ * i.e. the decision was context-sensitive. This report does not necessarily
+ * indicate a problem, and it may appear even in completely unambiguous
+ * grammars.</p>
+ *
+ * <p>{@code configs} may have more than one represented alternative if the
+ * full-context prediction algorithm does not evaluate predicates before
+ * beginning the full-context prediction. In all cases, the final prediction
+ * is passed as the {@code prediction} argument.</p>
+ *
+ * <p>Note that the definition of "context sensitivity" in this method
+ * differs from the concept in {@link DecisionInfo#contextSensitivities}.
+ * This method reports all instances where an SLL conflict occurred but LL
+ * parsing produced a unique result, whether or not that unique result
+ * matches the minimum alternative in the SLL conflicting set.</p>
+ *
+ * <p>This method is not used by lexers.</p>
+ *
+ * @param recognizer the parser instance
+ * @param dfa the DFA for the current decision
+ * @param startIndex the input index where the decision started
+ * @param stopIndex the input index where the context sensitivity was
+ * finally determined
+ * @param prediction the unambiguous result of the full-context prediction
+ * @param configs the ATN configuration set where the unambiguous prediction
+ * was determined
+ */
+ virtual void reportContextSensitivity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ size_t prediction, atn::ATNConfigSet *configs) = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Token.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// The interface for defining strategies to deal with syntax errors encountered
+ /// during a parse by ANTLR-generated parsers. We distinguish between three
+ /// different kinds of errors:
+ ///
+ /// <ul>
+ /// <li>The parser could not figure out which path to take in the ATN (none of
+ /// the available alternatives could possibly match)</li>
+ /// <li>The current input does not match what we were looking for</li>
+ /// <li>A predicate evaluated to false</li>
+ /// </ul>
+ ///
+ /// Implementations of this interface report syntax errors by calling
+ /// <seealso cref="Parser#notifyErrorListeners"/>.
+ /// <p/>
+ /// TODO: what to do about lexers
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ANTLRErrorStrategy {
+ public:
+
+ /// <summary>
+ /// Reset the error handler state for the specified {@code recognizer}. </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ virtual ~ANTLRErrorStrategy();
+
+ virtual void reset(Parser *recognizer) = 0;
+
+ /**
+ * This method is called when an unexpected symbol is encountered during an
+ * inline match operation, such as {@link Parser#match}. If the error
+ * strategy successfully recovers from the match failure, this method
+ * returns the {@link Token} instance which should be treated as the
+ * successful result of the match.
+ *
+ * <p>This method handles the consumption of any tokens - the caller should
+ * <b>not</b> call {@link Parser#consume} after a successful recovery.</p>
+ *
+ * <p>Note that the calling code will not report an error if this method
+ * returns successfully. The error strategy implementation is responsible
+ * for calling {@link Parser#notifyErrorListeners} as appropriate.</p>
+ *
+ * @param recognizer the parser instance
+ * @throws RecognitionException if the error strategy was not able to
+ * recover from the unexpected input symbol
+ */
+ virtual Token* recoverInline(Parser *recognizer) = 0;
+
+ /// <summary>
+ /// This method is called to recover from exception {@code e}. This method is
+ /// called after <seealso cref="#reportError"/> by the default exception handler
+ /// generated for a rule method.
+ /// </summary>
+ /// <seealso cref= #reportError
+ /// </seealso>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <param name="e"> the recognition exception to recover from </param>
+ /// <exception cref="RecognitionException"> if the error strategy could not recover from
+ /// the recognition exception </exception>
+ virtual void recover(Parser *recognizer, std::exception_ptr e) = 0;
+
+ /// <summary>
+ /// This method provides the error handler with an opportunity to handle
+ /// syntactic or semantic errors in the input stream before they result in a
+ /// <seealso cref="RecognitionException"/>.
+ /// <p/>
+ /// The generated code currently contains calls to <seealso cref="#sync"/> after
+ /// entering the decision state of a closure block ({@code (...)*} or
+ /// {@code (...)+}).
+ /// <p/>
+ /// For an implementation based on Jim Idle's "magic sync" mechanism, see
+ /// <seealso cref="DefaultErrorStrategy#sync"/>.
+ /// </summary>
+ /// <seealso cref= DefaultErrorStrategy#sync
+ /// </seealso>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <exception cref="RecognitionException"> if an error is detected by the error
+ /// strategy but cannot be automatically recovered at the current state in
+ /// the parsing process </exception>
+ virtual void sync(Parser *recognizer) = 0;
+
+ /// <summary>
+ /// Tests whether or not {@code recognizer} is in the process of recovering
+ /// from an error. In error recovery mode, <seealso cref="Parser#consume"/> adds
+ /// symbols to the parse tree by calling
+ /// {@link Parser#createErrorNode(ParserRuleContext, Token)} then
+ /// {@link ParserRuleContext#addErrorNode(ErrorNode)} instead of
+ /// {@link Parser#createTerminalNode(ParserRuleContext, Token)}.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <returns> {@code true} if the parser is currently recovering from a parse
+ /// error, otherwise {@code false} </returns>
+ virtual bool inErrorRecoveryMode(Parser *recognizer) = 0;
+
+ /// <summary>
+ /// This method is called by when the parser successfully matches an input
+ /// symbol.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ virtual void reportMatch(Parser *recognizer) = 0;
+
+ /// <summary>
+ /// Report any kind of <seealso cref="RecognitionException"/>. This method is called by
+ /// the default exception handler generated for a rule method.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <param name="e"> the recognition exception to report </param>
+ virtual void reportError(Parser *recognizer, const RecognitionException &e) = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ANTLRInputStream.h"
+
+namespace antlr4 {
+
+ /// This is an ANTLRInputStream that is loaded from a file all at once
+ /// when you construct the object (or call load()).
+ // TODO: this class needs testing.
+ class ANTLR4CPP_PUBLIC ANTLRFileStream : public ANTLRInputStream {
+ public:
+ ANTLRFileStream() = default;
+ ANTLRFileStream(const std::string &) = delete;
+ ANTLRFileStream(const char *data, size_t length) = delete;
+ ANTLRFileStream(std::istream &stream) = delete;
+
+ // Assumes a file name encoded in UTF-8 and file content in the same encoding (with or w/o BOM).
+ virtual void loadFromFile(const std::string &fileName);
+ virtual std::string getSourceName() const override;
+
+ private:
+ std::string _fileName; // UTF-8 encoded file name.
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "CharStream.h"
+
+namespace antlr4 {
+
+ // Vacuum all input from a stream and then treat it
+ // like a string. Can also pass in a string or char[] to use.
+ // Input is expected to be encoded in UTF-8 and converted to UTF-32 internally.
+ class ANTLR4CPP_PUBLIC ANTLRInputStream : public CharStream {
+ protected:
+ /// The data being scanned.
+ // UTF-32
+ UTF32String _data;
+
+ /// 0..n-1 index into string of next char </summary>
+ size_t p;
+
+ public:
+ /// What is name or source of this char stream?
+ std::string name;
+
+ ANTLRInputStream();
+
+#if __cplusplus >= 201703L
+ ANTLRInputStream(const std::string_view &input);
+#endif
+
+ ANTLRInputStream(const std::string &input);
+ ANTLRInputStream(const char *data, size_t length);
+ ANTLRInputStream(std::istream &stream);
+
+ virtual void load(const std::string &input);
+ virtual void load(const char *data, size_t length);
+ virtual void load(std::istream &stream);
+
+ /// Reset the stream so that it's in the same state it was
+ /// when the object was created *except* the data array is not
+ /// touched.
+ virtual void reset();
+ virtual void consume() override;
+ virtual size_t LA(ssize_t i) override;
+ virtual size_t LT(ssize_t i);
+
+ /// <summary>
+ /// Return the current input symbol index 0..n where n indicates the
+ /// last symbol has been read. The index is the index of char to
+ /// be returned from LA(1).
+ /// </summary>
+ virtual size_t index() override;
+ virtual size_t size() override;
+
+ /// <summary>
+ /// mark/release do nothing; we have entire buffer </summary>
+ virtual ssize_t mark() override;
+ virtual void release(ssize_t marker) override;
+
+ /// <summary>
+ /// consume() ahead until p==index; can't just set p=index as we must
+ /// update line and charPositionInLine. If we seek backwards, just set p
+ /// </summary>
+ virtual void seek(size_t index) override;
+ virtual std::string getText(const misc::Interval &interval) override;
+ virtual std::string getSourceName() const override;
+ virtual std::string toString() const override;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "DefaultErrorStrategy.h"
+
+namespace antlr4 {
+
+ /**
+ * This implementation of {@link ANTLRErrorStrategy} responds to syntax errors
+ * by immediately canceling the parse operation with a
+ * {@link ParseCancellationException}. The implementation ensures that the
+ * {@link ParserRuleContext#exception} field is set for all parse tree nodes
+ * that were not completed prior to encountering the error.
+ *
+ * <p>
+ * This error strategy is useful in the following scenarios.</p>
+ *
+ * <ul>
+ * <li><strong>Two-stage parsing:</strong> This error strategy allows the first
+ * stage of two-stage parsing to immediately terminate if an error is
+ * encountered, and immediately fall back to the second stage. In addition to
+ * avoiding wasted work by attempting to recover from errors here, the empty
+ * implementation of {@link BailErrorStrategy#sync} improves the performance of
+ * the first stage.</li>
+ * <li><strong>Silent validation:</strong> When syntax errors are not being
+ * reported or logged, and the parse result is simply ignored if errors occur,
+ * the {@link BailErrorStrategy} avoids wasting work on recovering from errors
+ * when the result will be ignored either way.</li>
+ * </ul>
+ *
+ * <p>
+ * {@code myparser.setErrorHandler(new BailErrorStrategy());}</p>
+ *
+ * @see Parser#setErrorHandler(ANTLRErrorStrategy)
+ */
+ class ANTLR4CPP_PUBLIC BailErrorStrategy : public DefaultErrorStrategy {
+ /// <summary>
+ /// Instead of recovering from exception {@code e}, re-throw it wrapped
+ /// in a <seealso cref="ParseCancellationException"/> so it is not caught by the
+ /// rule function catches. Use <seealso cref="Exception#getCause()"/> to get the
+ /// original <seealso cref="RecognitionException"/>.
+ /// </summary>
+ public:
+ virtual void recover(Parser *recognizer, std::exception_ptr e) override;
+
+ /// Make sure we don't attempt to recover inline; if the parser
+ /// successfully recovers, it won't throw an exception.
+ virtual Token* recoverInline(Parser *recognizer) override;
+
+ /// <summary>
+ /// Make sure we don't attempt to recover from problems in subrules. </summary>
+ virtual void sync(Parser *recognizer) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ANTLRErrorListener.h"
+
+namespace antlrcpp {
+ class BitSet;
+}
+
+namespace antlr4 {
+
+ /**
+ * Provides an empty default implementation of {@link ANTLRErrorListener}. The
+ * default implementation of each method does nothing, but can be overridden as
+ * necessary.
+ */
+ class ANTLR4CPP_PUBLIC BaseErrorListener : public ANTLRErrorListener {
+
+ virtual void syntaxError(Recognizer *recognizer, Token * offendingSymbol, size_t line, size_t charPositionInLine,
+ const std::string &msg, std::exception_ptr e) override;
+
+ virtual void reportAmbiguity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
+ const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportAttemptingFullContext(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportContextSensitivity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ size_t prediction, atn::ATNConfigSet *configs) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "TokenStream.h"
+
+namespace antlr4 {
+
+ /**
+ * This implementation of {@link TokenStream} loads tokens from a
+ * {@link TokenSource} on-demand, and places the tokens in a buffer to provide
+ * access to any previous token by index.
+ *
+ * <p>
+ * This token stream ignores the value of {@link Token#getChannel}. If your
+ * parser requires the token stream filter tokens to only those on a particular
+ * channel, such as {@link Token#DEFAULT_CHANNEL} or
+ * {@link Token#HIDDEN_CHANNEL}, use a filtering token stream such a
+ * {@link CommonTokenStream}.</p>
+ */
+ class ANTLR4CPP_PUBLIC BufferedTokenStream : public TokenStream {
+ public:
+ BufferedTokenStream(TokenSource *tokenSource);
+ BufferedTokenStream(const BufferedTokenStream& other) = delete;
+
+ BufferedTokenStream& operator = (const BufferedTokenStream& other) = delete;
+
+ virtual TokenSource* getTokenSource() const override;
+ virtual size_t index() override;
+ virtual ssize_t mark() override;
+
+ virtual void release(ssize_t marker) override;
+ virtual void reset();
+ virtual void seek(size_t index) override;
+
+ virtual size_t size() override;
+ virtual void consume() override;
+
+ virtual Token* get(size_t i) const override;
+
+ /// Get all tokens from start..stop inclusively.
+ virtual std::vector<Token *> get(size_t start, size_t stop);
+
+ virtual size_t LA(ssize_t i) override;
+ virtual Token* LT(ssize_t k) override;
+
+ /// Reset this token stream by setting its token source.
+ virtual void setTokenSource(TokenSource *tokenSource);
+ virtual std::vector<Token *> getTokens();
+ virtual std::vector<Token *> getTokens(size_t start, size_t stop);
+
+ /// <summary>
+ /// Given a start and stop index, return a List of all tokens in
+ /// the token type BitSet. Return null if no tokens were found. This
+ /// method looks at both on and off channel tokens.
+ /// </summary>
+ virtual std::vector<Token *> getTokens(size_t start, size_t stop, const std::vector<size_t> &types);
+ virtual std::vector<Token *> getTokens(size_t start, size_t stop, size_t ttype);
+
+ /// Collect all tokens on specified channel to the right of
+ /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL or
+ /// EOF. If channel is -1, find any non default channel token.
+ virtual std::vector<Token *> getHiddenTokensToRight(size_t tokenIndex, ssize_t channel);
+
+ /// <summary>
+ /// Collect all hidden tokens (any off-default channel) to the right of
+ /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL
+ /// or EOF.
+ /// </summary>
+ virtual std::vector<Token *> getHiddenTokensToRight(size_t tokenIndex);
+
+ /// <summary>
+ /// Collect all tokens on specified channel to the left of
+ /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
+ /// If channel is -1, find any non default channel token.
+ /// </summary>
+ virtual std::vector<Token *> getHiddenTokensToLeft(size_t tokenIndex, ssize_t channel);
+
+ /// <summary>
+ /// Collect all hidden tokens (any off-default channel) to the left of
+ /// the current token up until we see a token on DEFAULT_TOKEN_CHANNEL.
+ /// </summary>
+ virtual std::vector<Token *> getHiddenTokensToLeft(size_t tokenIndex);
+
+ virtual std::string getSourceName() const override;
+ virtual std::string getText() override;
+ virtual std::string getText(const misc::Interval &interval) override;
+ virtual std::string getText(RuleContext *ctx) override;
+ virtual std::string getText(Token *start, Token *stop) override;
+
+ /// Get all tokens from lexer until EOF.
+ virtual void fill();
+
+ protected:
+ /**
+ * The {@link TokenSource} from which tokens for this stream are fetched.
+ */
+ TokenSource *_tokenSource;
+
+ /**
+ * A collection of all tokens fetched from the token source. The list is
+ * considered a complete view of the input once {@link #fetchedEOF} is set
+ * to {@code true}.
+ */
+ std::vector<std::unique_ptr<Token>> _tokens;
+
+ /**
+ * The index into {@link #tokens} of the current token (next token to
+ * {@link #consume}). {@link #tokens}{@code [}{@link #p}{@code ]} should be
+ * {@link #LT LT(1)}.
+ *
+ * <p>This field is set to -1 when the stream is first constructed or when
+ * {@link #setTokenSource} is called, indicating that the first token has
+ * not yet been fetched from the token source. For additional information,
+ * see the documentation of {@link IntStream} for a description of
+ * Initializing Methods.</p>
+ */
+ // ml: since -1 requires to make this member signed for just this single aspect we use a member _needSetup instead.
+ // Use bool isInitialized() to find out if this stream has started reading.
+ size_t _p;
+
+ /**
+ * Indicates whether the {@link Token#EOF} token has been fetched from
+ * {@link #tokenSource} and added to {@link #tokens}. This field improves
+ * performance for the following cases:
+ *
+ * <ul>
+ * <li>{@link #consume}: The lookahead check in {@link #consume} to prevent
+ * consuming the EOF symbol is optimized by checking the values of
+ * {@link #fetchedEOF} and {@link #p} instead of calling {@link #LA}.</li>
+ * <li>{@link #fetch}: The check to prevent adding multiple EOF symbols into
+ * {@link #tokens} is trivial with this field.</li>
+ * <ul>
+ */
+ bool _fetchedEOF;
+
+ /// <summary>
+ /// Make sure index {@code i} in tokens has a token.
+ /// </summary>
+ /// <returns> {@code true} if a token is located at index {@code i}, otherwise
+ /// {@code false}. </returns>
+ /// <seealso cref= #get(int i) </seealso>
+ virtual bool sync(size_t i);
+
+ /// <summary>
+ /// Add {@code n} elements to buffer.
+ /// </summary>
+ /// <returns> The actual number of elements added to the buffer. </returns>
+ virtual size_t fetch(size_t n);
+
+ virtual Token* LB(size_t k);
+
+ /// Allowed derived classes to modify the behavior of operations which change
+ /// the current stream position by adjusting the target token index of a seek
+ /// operation. The default implementation simply returns {@code i}. If an
+ /// exception is thrown in this method, the current stream index should not be
+ /// changed.
+ /// <p/>
+ /// For example, <seealso cref="CommonTokenStream"/> overrides this method to ensure that
+ /// the seek target is always an on-channel token.
+ ///
+ /// <param name="i"> The target token index. </param>
+ /// <returns> The adjusted target token index. </returns>
+ virtual ssize_t adjustSeekIndex(size_t i);
+ void lazyInit();
+ virtual void setup();
+
+ /**
+ * Given a starting index, return the index of the next token on channel.
+ * Return {@code i} if {@code tokens[i]} is on channel. Return the index of
+ * the EOF token if there are no tokens on channel between {@code i} and
+ * EOF.
+ */
+ virtual ssize_t nextTokenOnChannel(size_t i, size_t channel);
+
+ /**
+ * Given a starting index, return the index of the previous token on
+ * channel. Return {@code i} if {@code tokens[i]} is on channel. Return -1
+ * if there are no tokens on channel between {@code i} and 0.
+ *
+ * <p>
+ * If {@code i} specifies an index at or after the EOF token, the EOF token
+ * index is returned. This is due to the fact that the EOF token is treated
+ * as though it were on every channel.</p>
+ */
+ virtual ssize_t previousTokenOnChannel(size_t i, size_t channel);
+
+ virtual std::vector<Token *> filterForChannel(size_t from, size_t to, ssize_t channel);
+
+ bool isInitialized() const;
+
+ private:
+ bool _needSetup;
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "IntStream.h"
+#include "misc/Interval.h"
+
+namespace antlr4 {
+
+ /// A source of characters for an ANTLR lexer.
+ class ANTLR4CPP_PUBLIC CharStream : public IntStream {
+ public:
+ virtual ~CharStream();
+
+ /// This method returns the text for a range of characters within this input
+ /// stream. This method is guaranteed to not throw an exception if the
+ /// specified interval lies entirely within a marked range. For more
+ /// information about marked ranges, see IntStream::mark.
+ ///
+ /// <param name="interval"> an interval within the stream </param>
+ /// <returns> the text of the specified interval
+ /// </returns>
+ /// <exception cref="NullPointerException"> if {@code interval} is {@code null} </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code interval.a < 0}, or if
+ /// {@code interval.b < interval.a - 1}, or if {@code interval.b} lies at or
+ /// past the end of the stream </exception>
+ /// <exception cref="UnsupportedOperationException"> if the stream does not support
+ /// getting the text of the specified interval </exception>
+ virtual std::string getText(const misc::Interval &interval) = 0;
+
+ virtual std::string toString() const = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "WritableToken.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC CommonToken : public WritableToken {
+ protected:
+ /**
+ * An empty {@link Pair} which is used as the default value of
+ * {@link #source} for tokens that do not have a source.
+ */
+ static const std::pair<TokenSource *, CharStream *> EMPTY_SOURCE;
+
+ /**
+ * This is the backing field for {@link #getType} and {@link #setType}.
+ */
+ size_t _type;
+
+ /**
+ * This is the backing field for {@link #getLine} and {@link #setLine}.
+ */
+ size_t _line;
+
+ /**
+ * This is the backing field for {@link #getCharPositionInLine} and
+ * {@link #setCharPositionInLine}.
+ */
+ size_t _charPositionInLine; // set to invalid position
+
+ /**
+ * This is the backing field for {@link #getChannel} and
+ * {@link #setChannel}.
+ */
+ size_t _channel;
+
+ /**
+ * This is the backing field for {@link #getTokenSource} and
+ * {@link #getInputStream}.
+ *
+ * <p>
+ * These properties share a field to reduce the memory footprint of
+ * {@link CommonToken}. Tokens created by a {@link CommonTokenFactory} from
+ * the same source and input stream share a reference to the same
+ * {@link Pair} containing these values.</p>
+ */
+
+ std::pair<TokenSource *, CharStream *> _source; // ml: pure references, usually from statically allocated classes.
+
+ /**
+ * This is the backing field for {@link #getText} when the token text is
+ * explicitly set in the constructor or via {@link #setText}.
+ *
+ * @see #getText()
+ */
+ std::string _text;
+
+ /**
+ * This is the backing field for {@link #getTokenIndex} and
+ * {@link #setTokenIndex}.
+ */
+ size_t _index;
+
+ /**
+ * This is the backing field for {@link #getStartIndex} and
+ * {@link #setStartIndex}.
+ */
+ size_t _start;
+
+ /**
+ * This is the backing field for {@link #getStopIndex} and
+ * {@link #setStopIndex}.
+ */
+ size_t _stop;
+
+ public:
+ /**
+ * Constructs a new {@link CommonToken} with the specified token type.
+ *
+ * @param type The token type.
+ */
+ CommonToken(size_t type);
+ CommonToken(std::pair<TokenSource*, CharStream*> source, size_t type, size_t channel, size_t start, size_t stop);
+
+ /**
+ * Constructs a new {@link CommonToken} with the specified token type and
+ * text.
+ *
+ * @param type The token type.
+ * @param text The text of the token.
+ */
+ CommonToken(size_t type, const std::string &text);
+
+ /**
+ * Constructs a new {@link CommonToken} as a copy of another {@link Token}.
+ *
+ * <p>
+ * If {@code oldToken} is also a {@link CommonToken} instance, the newly
+ * constructed token will share a reference to the {@link #text} field and
+ * the {@link Pair} stored in {@link #source}. Otherwise, {@link #text} will
+ * be assigned the result of calling {@link #getText}, and {@link #source}
+ * will be constructed from the result of {@link Token#getTokenSource} and
+ * {@link Token#getInputStream}.</p>
+ *
+ * @param oldToken The token to copy.
+ */
+ CommonToken(Token *oldToken);
+
+ virtual size_t getType() const override;
+
+ /**
+ * Explicitly set the text for this token. If {code text} is not
+ * {@code null}, then {@link #getText} will return this value rather than
+ * extracting the text from the input.
+ *
+ * @param text The explicit text of the token, or {@code null} if the text
+ * should be obtained from the input along with the start and stop indexes
+ * of the token.
+ */
+ virtual void setText(const std::string &text) override;
+ virtual std::string getText() const override;
+
+ virtual void setLine(size_t line) override;
+ virtual size_t getLine() const override;
+
+ virtual size_t getCharPositionInLine() const override;
+ virtual void setCharPositionInLine(size_t charPositionInLine) override;
+
+ virtual size_t getChannel() const override;
+ virtual void setChannel(size_t channel) override;
+
+ virtual void setType(size_t type) override;
+
+ virtual size_t getStartIndex() const override;
+ virtual void setStartIndex(size_t start);
+
+ virtual size_t getStopIndex() const override;
+ virtual void setStopIndex(size_t stop);
+
+ virtual size_t getTokenIndex() const override;
+ virtual void setTokenIndex(size_t index) override;
+
+ virtual TokenSource *getTokenSource() const override;
+ virtual CharStream *getInputStream() const override;
+
+ virtual std::string toString() const override;
+
+ virtual std::string toString(Recognizer *r) const;
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "TokenFactory.h"
+
+namespace antlr4 {
+
+ /**
+ * This default implementation of {@link TokenFactory} creates
+ * {@link CommonToken} objects.
+ */
+ class ANTLR4CPP_PUBLIC CommonTokenFactory : public TokenFactory<CommonToken> {
+ public:
+ /**
+ * The default {@link CommonTokenFactory} instance.
+ *
+ * <p>
+ * This token factory does not explicitly copy token text when constructing
+ * tokens.</p>
+ */
+ static const std::unique_ptr<TokenFactory<CommonToken>> DEFAULT;
+
+ protected:
+ /**
+ * Indicates whether {@link CommonToken#setText} should be called after
+ * constructing tokens to explicitly set the text. This is useful for cases
+ * where the input stream might not be able to provide arbitrary substrings
+ * of text from the input after the lexer creates a token (e.g. the
+ * implementation of {@link CharStream#getText} in
+ * {@link UnbufferedCharStream} throws an
+ * {@link UnsupportedOperationException}). Explicitly setting the token text
+ * allows {@link Token#getText} to be called at any time regardless of the
+ * input stream implementation.
+ *
+ * <p>
+ * The default value is {@code false} to avoid the performance and memory
+ * overhead of copying text for every token unless explicitly requested.</p>
+ */
+ const bool copyText;
+
+ public:
+ /**
+ * Constructs a {@link CommonTokenFactory} with the specified value for
+ * {@link #copyText}.
+ *
+ * <p>
+ * When {@code copyText} is {@code false}, the {@link #DEFAULT} instance
+ * should be used instead of constructing a new instance.</p>
+ *
+ * @param copyText The value for {@link #copyText}.
+ */
+ CommonTokenFactory(bool copyText);
+
+ /**
+ * Constructs a {@link CommonTokenFactory} with {@link #copyText} set to
+ * {@code false}.
+ *
+ * <p>
+ * The {@link #DEFAULT} instance should be used instead of calling this
+ * directly.</p>
+ */
+ CommonTokenFactory();
+
+ virtual std::unique_ptr<CommonToken> create(std::pair<TokenSource*, CharStream*> source, size_t type,
+ const std::string &text, size_t channel, size_t start, size_t stop, size_t line, size_t charPositionInLine) override;
+
+ virtual std::unique_ptr<CommonToken> create(size_t type, const std::string &text) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "BufferedTokenStream.h"
+
+namespace antlr4 {
+
+ /**
+ * This class extends {@link BufferedTokenStream} with functionality to filter
+ * token streams to tokens on a particular channel (tokens where
+ * {@link Token#getChannel} returns a particular value).
+ *
+ * <p>
+ * This token stream provides access to all tokens by index or when calling
+ * methods like {@link #getText}. The channel filtering is only used for code
+ * accessing tokens via the lookahead methods {@link #LA}, {@link #LT}, and
+ * {@link #LB}.</p>
+ *
+ * <p>
+ * By default, tokens are placed on the default channel
+ * ({@link Token#DEFAULT_CHANNEL}), but may be reassigned by using the
+ * {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to
+ * call {@link Lexer#setChannel}.
+ * </p>
+ *
+ * <p>
+ * Note: lexer rules which use the {@code ->skip} lexer command or call
+ * {@link Lexer#skip} do not produce tokens at all, so input text matched by
+ * such a rule will not be available as part of the token stream, regardless of
+ * channel.</p>
+ */
+ class ANTLR4CPP_PUBLIC CommonTokenStream : public BufferedTokenStream {
+ public:
+ /**
+ * Constructs a new {@link CommonTokenStream} using the specified token
+ * source and the default token channel ({@link Token#DEFAULT_CHANNEL}).
+ *
+ * @param tokenSource The token source.
+ */
+ CommonTokenStream(TokenSource *tokenSource);
+
+ /**
+ * Constructs a new {@link CommonTokenStream} using the specified token
+ * source and filtering tokens to the specified channel. Only tokens whose
+ * {@link Token#getChannel} matches {@code channel} or have the
+ * {@link Token#getType} equal to {@link Token#EOF} will be returned by the
+ * token stream lookahead methods.
+ *
+ * @param tokenSource The token source.
+ * @param channel The channel to use for filtering tokens.
+ */
+ CommonTokenStream(TokenSource *tokenSource, size_t channel);
+
+ virtual Token* LT(ssize_t k) override;
+
+ /// Count EOF just once.
+ virtual int getNumberOfOnChannelTokens();
+
+ protected:
+ /**
+ * Specifies the channel to use for filtering tokens.
+ *
+ * <p>
+ * The default value is {@link Token#DEFAULT_CHANNEL}, which matches the
+ * default channel assigned to tokens created by the lexer.</p>
+ */
+ size_t channel;
+
+ virtual ssize_t adjustSeekIndex(size_t i) override;
+
+ virtual Token* LB(size_t k) override;
+
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "BaseErrorListener.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC ConsoleErrorListener : public BaseErrorListener {
+ public:
+ /**
+ * Provides a default instance of {@link ConsoleErrorListener}.
+ */
+ static ConsoleErrorListener INSTANCE;
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p>
+ * This implementation prints messages to {@link System#err} containing the
+ * values of {@code line}, {@code charPositionInLine}, and {@code msg} using
+ * the following format.</p>
+ *
+ * <pre>
+ * line <em>line</em>:<em>charPositionInLine</em> <em>msg</em>
+ * </pre>
+ */
+ virtual void syntaxError(Recognizer *recognizer, Token * offendingSymbol, size_t line, size_t charPositionInLine,
+ const std::string &msg, std::exception_ptr e) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ANTLRErrorStrategy.h"
+#include "misc/IntervalSet.h"
+
+namespace antlr4 {
+
+ /**
+ * This is the default implementation of {@link ANTLRErrorStrategy} used for
+ * error reporting and recovery in ANTLR parsers.
+ */
+ class ANTLR4CPP_PUBLIC DefaultErrorStrategy : public ANTLRErrorStrategy {
+ public:
+ DefaultErrorStrategy();
+ DefaultErrorStrategy(DefaultErrorStrategy const& other) = delete;
+ virtual ~DefaultErrorStrategy();
+
+ DefaultErrorStrategy& operator = (DefaultErrorStrategy const& other) = delete;
+
+ protected:
+ /**
+ * Indicates whether the error strategy is currently "recovering from an
+ * error". This is used to suppress reporting multiple error messages while
+ * attempting to recover from a detected syntax error.
+ *
+ * @see #inErrorRecoveryMode
+ */
+ bool errorRecoveryMode;
+
+ /** The index into the input stream where the last error occurred.
+ * This is used to prevent infinite loops where an error is found
+ * but no token is consumed during recovery...another error is found,
+ * ad nauseum. This is a failsafe mechanism to guarantee that at least
+ * one token/tree node is consumed for two errors.
+ */
+ int lastErrorIndex;
+
+ misc::IntervalSet lastErrorStates;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The default implementation simply calls <seealso cref="#endErrorCondition"/> to
+ /// ensure that the handler is not in error recovery mode.
+ /// </summary>
+ public:
+ virtual void reset(Parser *recognizer) override;
+
+ /// <summary>
+ /// This method is called to enter error recovery mode when a recognition
+ /// exception is reported.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ protected:
+ virtual void beginErrorCondition(Parser *recognizer);
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// </summary>
+ public:
+ virtual bool inErrorRecoveryMode(Parser *recognizer) override;
+
+ /// <summary>
+ /// This method is called to leave error recovery mode after recovering from
+ /// a recognition exception.
+ /// </summary>
+ /// <param name="recognizer"> </param>
+ protected:
+ virtual void endErrorCondition(Parser *recognizer);
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The default implementation simply calls <seealso cref="#endErrorCondition"/>.
+ /// </summary>
+ public:
+ virtual void reportMatch(Parser *recognizer) override;
+
+ /// {@inheritDoc}
+ /// <p/>
+ /// The default implementation returns immediately if the handler is already
+ /// in error recovery mode. Otherwise, it calls <seealso cref="#beginErrorCondition"/>
+ /// and dispatches the reporting task based on the runtime type of {@code e}
+ /// according to the following table.
+ ///
+ /// <ul>
+ /// <li><seealso cref="NoViableAltException"/>: Dispatches the call to
+ /// <seealso cref="#reportNoViableAlternative"/></li>
+ /// <li><seealso cref="InputMismatchException"/>: Dispatches the call to
+ /// <seealso cref="#reportInputMismatch"/></li>
+ /// <li><seealso cref="FailedPredicateException"/>: Dispatches the call to
+ /// <seealso cref="#reportFailedPredicate"/></li>
+ /// <li>All other types: calls <seealso cref="Parser#notifyErrorListeners"/> to report
+ /// the exception</li>
+ /// </ul>
+ virtual void reportError(Parser *recognizer, const RecognitionException &e) override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The default implementation resynchronizes the parser by consuming tokens
+ /// until we find one in the resynchronization set--loosely the set of tokens
+ /// that can follow the current rule.
+ /// </summary>
+ virtual void recover(Parser *recognizer, std::exception_ptr e) override;
+
+ /**
+ * The default implementation of {@link ANTLRErrorStrategy#sync} makes sure
+ * that the current lookahead symbol is consistent with what were expecting
+ * at this point in the ATN. You can call this anytime but ANTLR only
+ * generates code to check before subrules/loops and each iteration.
+ *
+ * <p>Implements Jim Idle's magic sync mechanism in closures and optional
+ * subrules. E.g.,</p>
+ *
+ * <pre>
+ * a : sync ( stuff sync )* ;
+ * sync : {consume to what can follow sync} ;
+ * </pre>
+ *
+ * At the start of a sub rule upon error, {@link #sync} performs single
+ * token deletion, if possible. If it can't do that, it bails on the current
+ * rule and uses the default error recovery, which consumes until the
+ * resynchronization set of the current rule.
+ *
+ * <p>If the sub rule is optional ({@code (...)?}, {@code (...)*}, or block
+ * with an empty alternative), then the expected set includes what follows
+ * the subrule.</p>
+ *
+ * <p>During loop iteration, it consumes until it sees a token that can start a
+ * sub rule or what follows loop. Yes, that is pretty aggressive. We opt to
+ * stay in the loop as long as possible.</p>
+ *
+ * <p><strong>ORIGINS</strong></p>
+ *
+ * <p>Previous versions of ANTLR did a poor job of their recovery within loops.
+ * A single mismatch token or missing token would force the parser to bail
+ * out of the entire rules surrounding the loop. So, for rule</p>
+ *
+ * <pre>
+ * classDef : 'class' ID '{' member* '}'
+ * </pre>
+ *
+ * input with an extra token between members would force the parser to
+ * consume until it found the next class definition rather than the next
+ * member definition of the current class.
+ *
+ * <p>This functionality cost a little bit of effort because the parser has to
+ * compare token set at the start of the loop and at each iteration. If for
+ * some reason speed is suffering for you, you can turn off this
+ * functionality by simply overriding this method as a blank { }.</p>
+ */
+ virtual void sync(Parser *recognizer) override;
+
+ /// <summary>
+ /// This is called by <seealso cref="#reportError"/> when the exception is a
+ /// <seealso cref="NoViableAltException"/>.
+ /// </summary>
+ /// <seealso cref= #reportError
+ /// </seealso>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <param name="e"> the recognition exception </param>
+ protected:
+ virtual void reportNoViableAlternative(Parser *recognizer, const NoViableAltException &e);
+
+ /// <summary>
+ /// This is called by <seealso cref="#reportError"/> when the exception is an
+ /// <seealso cref="InputMismatchException"/>.
+ /// </summary>
+ /// <seealso cref= #reportError
+ /// </seealso>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <param name="e"> the recognition exception </param>
+ virtual void reportInputMismatch(Parser *recognizer, const InputMismatchException &e);
+
+ /// <summary>
+ /// This is called by <seealso cref="#reportError"/> when the exception is a
+ /// <seealso cref="FailedPredicateException"/>.
+ /// </summary>
+ /// <seealso cref= #reportError
+ /// </seealso>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <param name="e"> the recognition exception </param>
+ virtual void reportFailedPredicate(Parser *recognizer, const FailedPredicateException &e);
+
+ /**
+ * This method is called to report a syntax error which requires the removal
+ * of a token from the input stream. At the time this method is called, the
+ * erroneous symbol is current {@code LT(1)} symbol and has not yet been
+ * removed from the input stream. When this method returns,
+ * {@code recognizer} is in error recovery mode.
+ *
+ * <p>This method is called when {@link #singleTokenDeletion} identifies
+ * single-token deletion as a viable recovery strategy for a mismatched
+ * input error.</p>
+ *
+ * <p>The default implementation simply returns if the handler is already in
+ * error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
+ * enter error recovery mode, followed by calling
+ * {@link Parser#notifyErrorListeners}.</p>
+ *
+ * @param recognizer the parser instance
+ */
+ virtual void reportUnwantedToken(Parser *recognizer);
+
+ /**
+ * This method is called to report a syntax error which requires the
+ * insertion of a missing token into the input stream. At the time this
+ * method is called, the missing token has not yet been inserted. When this
+ * method returns, {@code recognizer} is in error recovery mode.
+ *
+ * <p>This method is called when {@link #singleTokenInsertion} identifies
+ * single-token insertion as a viable recovery strategy for a mismatched
+ * input error.</p>
+ *
+ * <p>The default implementation simply returns if the handler is already in
+ * error recovery mode. Otherwise, it calls {@link #beginErrorCondition} to
+ * enter error recovery mode, followed by calling
+ * {@link Parser#notifyErrorListeners}.</p>
+ *
+ * @param recognizer the parser instance
+ */
+ virtual void reportMissingToken(Parser *recognizer);
+
+ public:
+ /**
+ * {@inheritDoc}
+ *
+ * <p>The default implementation attempts to recover from the mismatched input
+ * by using single token insertion and deletion as described below. If the
+ * recovery attempt fails, this method throws an
+ * {@link InputMismatchException}.</p>
+ *
+ * <p><strong>EXTRA TOKEN</strong> (single token deletion)</p>
+ *
+ * <p>{@code LA(1)} is not what we are looking for. If {@code LA(2)} has the
+ * right token, however, then assume {@code LA(1)} is some extra spurious
+ * token and delete it. Then consume and return the next token (which was
+ * the {@code LA(2)} token) as the successful result of the match operation.</p>
+ *
+ * <p>This recovery strategy is implemented by {@link #singleTokenDeletion}.</p>
+ *
+ * <p><strong>MISSING TOKEN</strong> (single token insertion)</p>
+ *
+ * <p>If current token (at {@code LA(1)}) is consistent with what could come
+ * after the expected {@code LA(1)} token, then assume the token is missing
+ * and use the parser's {@link TokenFactory} to create it on the fly. The
+ * "insertion" is performed by returning the created token as the successful
+ * result of the match operation.</p>
+ *
+ * <p>This recovery strategy is implemented by {@link #singleTokenInsertion}.</p>
+ *
+ * <p><strong>EXAMPLE</strong></p>
+ *
+ * <p>For example, Input {@code i=(3;} is clearly missing the {@code ')'}. When
+ * the parser returns from the nested call to {@code expr}, it will have
+ * call chain:</p>
+ *
+ * <pre>
+ * stat → expr → atom
+ * </pre>
+ *
+ * and it will be trying to match the {@code ')'} at this point in the
+ * derivation:
+ *
+ * <pre>
+ * => ID '=' '(' INT ')' ('+' atom)* ';'
+ * ^
+ * </pre>
+ *
+ * The attempt to match {@code ')'} will fail when it sees {@code ';'} and
+ * call {@link #recoverInline}. To recover, it sees that {@code LA(1)==';'}
+ * is in the set of tokens that can follow the {@code ')'} token reference
+ * in rule {@code atom}. It can assume that you forgot the {@code ')'}.
+ */
+ virtual Token* recoverInline(Parser *recognizer) override;
+
+ /// <summary>
+ /// This method implements the single-token insertion inline error recovery
+ /// strategy. It is called by <seealso cref="#recoverInline"/> if the single-token
+ /// deletion strategy fails to recover from the mismatched input. If this
+ /// method returns {@code true}, {@code recognizer} will be in error recovery
+ /// mode.
+ /// <p/>
+ /// This method determines whether or not single-token insertion is viable by
+ /// checking if the {@code LA(1)} input symbol could be successfully matched
+ /// if it were instead the {@code LA(2)} symbol. If this method returns
+ /// {@code true}, the caller is responsible for creating and inserting a
+ /// token with the correct type to produce this behavior.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <returns> {@code true} if single-token insertion is a viable recovery
+ /// strategy for the current mismatched input, otherwise {@code false} </returns>
+ protected:
+ virtual bool singleTokenInsertion(Parser *recognizer);
+
+ /// <summary>
+ /// This method implements the single-token deletion inline error recovery
+ /// strategy. It is called by <seealso cref="#recoverInline"/> to attempt to recover
+ /// from mismatched input. If this method returns null, the parser and error
+ /// handler state will not have changed. If this method returns non-null,
+ /// {@code recognizer} will <em>not</em> be in error recovery mode since the
+ /// returned token was a successful match.
+ /// <p/>
+ /// If the single-token deletion is successful, this method calls
+ /// <seealso cref="#reportUnwantedToken"/> to report the error, followed by
+ /// <seealso cref="Parser#consume"/> to actually "delete" the extraneous token. Then,
+ /// before returning <seealso cref="#reportMatch"/> is called to signal a successful
+ /// match.
+ /// </summary>
+ /// <param name="recognizer"> the parser instance </param>
+ /// <returns> the successfully matched <seealso cref="Token"/> instance if single-token
+ /// deletion successfully recovers from the mismatched input, otherwise
+ /// {@code null} </returns>
+ virtual Token* singleTokenDeletion(Parser *recognizer);
+
+ /// <summary>
+ /// Conjure up a missing token during error recovery.
+ ///
+ /// The recognizer attempts to recover from single missing
+ /// symbols. But, actions might refer to that missing symbol.
+ /// For example, x=ID {f($x);}. The action clearly assumes
+ /// that there has been an identifier matched previously and that
+ /// $x points at that token. If that token is missing, but
+ /// the next token in the stream is what we want we assume that
+ /// this token is missing and we keep going. Because we
+ /// have to return some token to replace the missing token,
+ /// we have to conjure one up. This method gives the user control
+ /// over the tokens returned for missing tokens. Mostly,
+ /// you will want to create something special for identifier
+ /// tokens. For literals such as '{' and ',', the default
+ /// action in the parser or tree parser works. It simply creates
+ /// a CommonToken of the appropriate type. The text will be the token.
+ /// If you change what tokens must be created by the lexer,
+ /// override this method to create the appropriate tokens.
+ /// </summary>
+ virtual Token* getMissingSymbol(Parser *recognizer);
+
+ virtual misc::IntervalSet getExpectedTokens(Parser *recognizer);
+
+ /// <summary>
+ /// How should a token be displayed in an error message? The default
+ /// is to display just the text, but during development you might
+ /// want to have a lot of information spit out. Override in that case
+ /// to use t.toString() (which, for CommonToken, dumps everything about
+ /// the token). This is better than forcing you to override a method in
+ /// your token objects because you don't have to go modify your lexer
+ /// so that it creates a new class.
+ /// </summary>
+ virtual std::string getTokenErrorDisplay(Token *t);
+
+ virtual std::string getSymbolText(Token *symbol);
+
+ virtual size_t getSymbolType(Token *symbol);
+
+ virtual std::string escapeWSAndQuote(const std::string &s) const;
+
+ /* Compute the error recovery set for the current rule. During
+ * rule invocation, the parser pushes the set of tokens that can
+ * follow that rule reference on the stack; this amounts to
+ * computing FIRST of what follows the rule reference in the
+ * enclosing rule. See LinearApproximator.FIRST().
+ * This local follow set only includes tokens
+ * from within the rule; i.e., the FIRST computation done by
+ * ANTLR stops at the end of a rule.
+ *
+ * EXAMPLE
+ *
+ * When you find a "no viable alt exception", the input is not
+ * consistent with any of the alternatives for rule r. The best
+ * thing to do is to consume tokens until you see something that
+ * can legally follow a call to r *or* any rule that called r.
+ * You don't want the exact set of viable next tokens because the
+ * input might just be missing a token--you might consume the
+ * rest of the input looking for one of the missing tokens.
+ *
+ * Consider grammar:
+ *
+ * a : '[' b ']'
+ * | '(' b ')'
+ * ;
+ * b : c '^' INT ;
+ * c : ID
+ * | INT
+ * ;
+ *
+ * At each rule invocation, the set of tokens that could follow
+ * that rule is pushed on a stack. Here are the various
+ * context-sensitive follow sets:
+ *
+ * FOLLOW(b1_in_a) = FIRST(']') = ']'
+ * FOLLOW(b2_in_a) = FIRST(')') = ')'
+ * FOLLOW(c_in_b) = FIRST('^') = '^'
+ *
+ * Upon erroneous input "[]", the call chain is
+ *
+ * a -> b -> c
+ *
+ * and, hence, the follow context stack is:
+ *
+ * depth follow set start of rule execution
+ * 0 <EOF> a (from main())
+ * 1 ']' b
+ * 2 '^' c
+ *
+ * Notice that ')' is not included, because b would have to have
+ * been called from a different context in rule a for ')' to be
+ * included.
+ *
+ * For error recovery, we cannot consider FOLLOW(c)
+ * (context-sensitive or otherwise). We need the combined set of
+ * all context-sensitive FOLLOW sets--the set of all tokens that
+ * could follow any reference in the call chain. We need to
+ * resync to one of those tokens. Note that FOLLOW(c)='^' and if
+ * we resync'd to that token, we'd consume until EOF. We need to
+ * sync to context-sensitive FOLLOWs for a, b, and c: {']','^'}.
+ * In this case, for input "[]", LA(1) is ']' and in the set, so we would
+ * not consume anything. After printing an error, rule c would
+ * return normally. Rule b would not find the required '^' though.
+ * At this point, it gets a mismatched token error and throws an
+ * exception (since LA(1) is not in the viable following token
+ * set). The rule exception handler tries to recover, but finds
+ * the same recovery set and doesn't consume anything. Rule b
+ * exits normally returning to rule a. Now it finds the ']' (and
+ * with the successful match exits errorRecovery mode).
+ *
+ * So, you can see that the parser walks up the call chain looking
+ * for the token that was a member of the recovery set.
+ *
+ * Errors are not generated in errorRecovery mode.
+ *
+ * ANTLR's error recovery mechanism is based upon original ideas:
+ *
+ * "Algorithms + Data Structures = Programs" by Niklaus Wirth
+ *
+ * and
+ *
+ * "A note on error recovery in recursive descent parsers":
+ * http://portal.acm.org/citation.cfm?id=947902.947905
+ *
+ * Later, Josef Grosch had some good ideas:
+ *
+ * "Efficient and Comfortable Error Recovery in Recursive Descent
+ * Parsers":
+ * ftp://www.cocolab.com/products/cocktail/doca4.ps/ell.ps.zip
+ *
+ * Like Grosch I implement context-sensitive FOLLOW sets that are combined
+ * at run-time upon error to avoid overhead during parsing.
+ */
+ virtual misc::IntervalSet getErrorRecoverySet(Parser *recognizer);
+
+ /// <summary>
+ /// Consume tokens until one matches the given token set. </summary>
+ virtual void consumeUntil(Parser *recognizer, const misc::IntervalSet &set);
+
+ private:
+ std::vector<std::unique_ptr<Token>> _errorSymbols; // Temporarily created token.
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "BaseErrorListener.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// This implementation of <seealso cref="ANTLRErrorListener"/> can be used to identify
+ /// certain potential correctness and performance problems in grammars. "Reports"
+ /// are made by calling <seealso cref="Parser#notifyErrorListeners"/> with the appropriate
+ /// message.
+ ///
+ /// <ul>
+ /// <li><b>Ambiguities</b>: These are cases where more than one path through the
+ /// grammar can match the input.</li>
+ /// <li><b>Weak context sensitivity</b>: These are cases where full-context
+ /// prediction resolved an SLL conflict to a unique alternative which equaled the
+ /// minimum alternative of the SLL conflict.</li>
+ /// <li><b>Strong (forced) context sensitivity</b>: These are cases where the
+ /// full-context prediction resolved an SLL conflict to a unique alternative,
+ /// <em>and</em> the minimum alternative of the SLL conflict was found to not be
+ /// a truly viable alternative. Two-stage parsing cannot be used for inputs where
+ /// this situation occurs.</li>
+ /// </ul>
+ ///
+ /// @author Sam Harwell
+ /// </summary>
+ class ANTLR4CPP_PUBLIC DiagnosticErrorListener : public BaseErrorListener {
+ /// <summary>
+ /// When {@code true}, only exactly known ambiguities are reported.
+ /// </summary>
+ protected:
+ const bool exactOnly;
+
+ /// <summary>
+ /// Initializes a new instance of <seealso cref="DiagnosticErrorListener"/> which only
+ /// reports exact ambiguities.
+ /// </summary>
+ public:
+ DiagnosticErrorListener();
+
+ /// <summary>
+ /// Initializes a new instance of <seealso cref="DiagnosticErrorListener"/>, specifying
+ /// whether all ambiguities or only exact ambiguities are reported.
+ /// </summary>
+ /// <param name="exactOnly"> {@code true} to report only exact ambiguities, otherwise
+ /// {@code false} to report all ambiguities. </param>
+ DiagnosticErrorListener(bool exactOnly);
+
+ virtual void reportAmbiguity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
+ const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportAttemptingFullContext(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportContextSensitivity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ size_t prediction, atn::ATNConfigSet *configs) override;
+
+ protected:
+ virtual std::string getDecisionDescription(Parser *recognizer, const dfa::DFA &dfa);
+
+ /// <summary>
+ /// Computes the set of conflicting or ambiguous alternatives from a
+ /// configuration set, if that information was not already provided by the
+ /// parser.
+ /// </summary>
+ /// <param name="reportedAlts"> The set of conflicting or ambiguous alternatives, as
+ /// reported by the parser. </param>
+ /// <param name="configs"> The conflicting or ambiguous configuration set. </param>
+ /// <returns> Returns {@code reportedAlts} if it is not {@code null}, otherwise
+ /// returns the set of alternatives represented in {@code configs}. </returns>
+ virtual antlrcpp::BitSet getConflictingAlts(const antlrcpp::BitSet &reportedAlts, atn::ATNConfigSet *configs);
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+
+ // An exception hierarchy modelled loosely after java.lang.* exceptions.
+ class ANTLR4CPP_PUBLIC RuntimeException : public std::exception {
+ private:
+ std::string _message;
+ public:
+ RuntimeException(const std::string &msg = "");
+
+ virtual const char* what() const NOEXCEPT override;
+ };
+
+ class ANTLR4CPP_PUBLIC IllegalStateException : public RuntimeException {
+ public:
+ IllegalStateException(const std::string &msg = "") : RuntimeException(msg) {}
+ IllegalStateException(IllegalStateException const&) = default;
+ ~IllegalStateException();
+ IllegalStateException& operator=(IllegalStateException const&) = default;
+ };
+
+ class ANTLR4CPP_PUBLIC IllegalArgumentException : public RuntimeException {
+ public:
+ IllegalArgumentException(IllegalArgumentException const&) = default;
+ IllegalArgumentException(const std::string &msg = "") : RuntimeException(msg) {}
+ ~IllegalArgumentException();
+ IllegalArgumentException& operator=(IllegalArgumentException const&) = default;
+ };
+
+ class ANTLR4CPP_PUBLIC NullPointerException : public RuntimeException {
+ public:
+ NullPointerException(const std::string &msg = "") : RuntimeException(msg) {}
+ NullPointerException(NullPointerException const&) = default;
+ ~NullPointerException();
+ NullPointerException& operator=(NullPointerException const&) = default;
+ };
+
+ class ANTLR4CPP_PUBLIC IndexOutOfBoundsException : public RuntimeException {
+ public:
+ IndexOutOfBoundsException(const std::string &msg = "") : RuntimeException(msg) {}
+ IndexOutOfBoundsException(IndexOutOfBoundsException const&) = default;
+ ~IndexOutOfBoundsException();
+ IndexOutOfBoundsException& operator=(IndexOutOfBoundsException const&) = default;
+ };
+
+ class ANTLR4CPP_PUBLIC UnsupportedOperationException : public RuntimeException {
+ public:
+ UnsupportedOperationException(const std::string &msg = "") : RuntimeException(msg) {}
+ UnsupportedOperationException(UnsupportedOperationException const&) = default;
+ ~UnsupportedOperationException();
+ UnsupportedOperationException& operator=(UnsupportedOperationException const&) = default;
+
+ };
+
+ class ANTLR4CPP_PUBLIC EmptyStackException : public RuntimeException {
+ public:
+ EmptyStackException(const std::string &msg = "") : RuntimeException(msg) {}
+ EmptyStackException(EmptyStackException const&) = default;
+ ~EmptyStackException();
+ EmptyStackException& operator=(EmptyStackException const&) = default;
+ };
+
+ // IOException is not a runtime exception (in the java hierarchy).
+ // Hence we have to duplicate the RuntimeException implementation.
+ class ANTLR4CPP_PUBLIC IOException : public std::exception {
+ private:
+ std::string _message;
+
+ public:
+ IOException(const std::string &msg = "");
+
+ virtual const char* what() const NOEXCEPT override;
+ };
+
+ class ANTLR4CPP_PUBLIC CancellationException : public IllegalStateException {
+ public:
+ CancellationException(const std::string &msg = "") : IllegalStateException(msg) {}
+ CancellationException(CancellationException const&) = default;
+ ~CancellationException();
+ CancellationException& operator=(CancellationException const&) = default;
+ };
+
+ class ANTLR4CPP_PUBLIC ParseCancellationException : public CancellationException {
+ public:
+ ParseCancellationException(const std::string &msg = "") : CancellationException(msg) {}
+ ParseCancellationException(ParseCancellationException const&) = default;
+ ~ParseCancellationException();
+ ParseCancellationException& operator=(ParseCancellationException const&) = default;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RecognitionException.h"
+
+namespace antlr4 {
+
+ /// A semantic predicate failed during validation. Validation of predicates
+ /// occurs when normally parsing the alternative just like matching a token.
+ /// Disambiguating predicate evaluation occurs when we test a predicate during
+ /// prediction.
+ class ANTLR4CPP_PUBLIC FailedPredicateException : public RecognitionException {
+ public:
+ FailedPredicateException(Parser *recognizer);
+ FailedPredicateException(Parser *recognizer, const std::string &predicate);
+ FailedPredicateException(Parser *recognizer, const std::string &predicate, const std::string &message);
+
+ virtual size_t getRuleIndex();
+ virtual size_t getPredIndex();
+ virtual std::string getPredicate();
+
+ private:
+ size_t _ruleIndex;
+ size_t _predicateIndex;
+ std::string _predicate;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RecognitionException.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// This signifies any kind of mismatched input exceptions such as
+ /// when the current input does not match the expected token.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC InputMismatchException : public RecognitionException {
+ public:
+ InputMismatchException(Parser *recognizer);
+ InputMismatchException(InputMismatchException const&) = default;
+ ~InputMismatchException();
+ InputMismatchException& operator=(InputMismatchException const&) = default;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// A simple stream of symbols whose values are represented as integers. This
+ /// interface provides <em>marked ranges</em> with support for a minimum level
+ /// of buffering necessary to implement arbitrary lookahead during prediction.
+ /// For more information on marked ranges, see <seealso cref="#mark"/>.
+ /// <p/>
+ /// <strong>Initializing Methods:</strong> Some methods in this interface have
+ /// unspecified behavior if no call to an initializing method has occurred after
+ /// the stream was constructed. The following is a list of initializing methods:
+ ///
+ /// <ul>
+ /// <li><seealso cref="#LA"/></li>
+ /// <li><seealso cref="#consume"/></li>
+ /// <li><seealso cref="#size"/></li>
+ /// </ul>
+ /// </summary>
+ class ANTLR4CPP_PUBLIC IntStream {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t EOF = std::numeric_limits<size_t>::max();
+#else
+ enum : size_t {
+ EOF = static_cast<size_t>(-1), // std::numeric_limits<size_t>::max(); doesn't work in VS 2013
+ };
+#endif
+
+ /// The value returned by <seealso cref="#LA LA()"/> when the end of the stream is
+ /// reached.
+ /// No explicit EOF definition. We got EOF on all platforms.
+ //static const size_t _EOF = std::ios::eofbit;
+
+ /// <summary>
+ /// The value returned by <seealso cref="#getSourceName"/> when the actual name of the
+ /// underlying source is not known.
+ /// </summary>
+ static const std::string UNKNOWN_SOURCE_NAME;
+
+ virtual ~IntStream();
+
+ /// <summary>
+ /// Consumes the current symbol in the stream. This method has the following
+ /// effects:
+ ///
+ /// <ul>
+ /// <li><strong>Forward movement:</strong> The value of <seealso cref="#index index()"/>
+ /// before calling this method is less than the value of {@code index()}
+ /// after calling this method.</li>
+ /// <li><strong>Ordered lookahead:</strong> The value of {@code LA(1)} before
+ /// calling this method becomes the value of {@code LA(-1)} after calling
+ /// this method.</li>
+ /// </ul>
+ ///
+ /// Note that calling this method does not guarantee that {@code index()} is
+ /// incremented by exactly 1, as that would preclude the ability to implement
+ /// filtering streams (e.g. <seealso cref="CommonTokenStream"/> which distinguishes
+ /// between "on-channel" and "off-channel" tokens).
+ /// </summary>
+ /// <exception cref="IllegalStateException"> if an attempt is made to consume the the
+ /// end of the stream (i.e. if {@code LA(1)==}<seealso cref="#EOF EOF"/> before calling
+ /// {@code consume}). </exception>
+ virtual void consume() = 0;
+
+ /// <summary>
+ /// Gets the value of the symbol at offset {@code i} from the current
+ /// position. When {@code i==1}, this method returns the value of the current
+ /// symbol in the stream (which is the next symbol to be consumed). When
+ /// {@code i==-1}, this method returns the value of the previously read
+ /// symbol in the stream. It is not valid to call this method with
+ /// {@code i==0}, but the specific behavior is unspecified because this
+ /// method is frequently called from performance-critical code.
+ /// <p/>
+ /// This method is guaranteed to succeed if any of the following are true:
+ ///
+ /// <ul>
+ /// <li>{@code i>0}</li>
+ /// <li>{@code i==-1} and <seealso cref="#index index()"/> returns a value greater
+ /// than the value of {@code index()} after the stream was constructed
+ /// and {@code LA(1)} was called in that order. Specifying the current
+ /// {@code index()} relative to the index after the stream was created
+ /// allows for filtering implementations that do not return every symbol
+ /// from the underlying source. Specifying the call to {@code LA(1)}
+ /// allows for lazily initialized streams.</li>
+ /// <li>{@code LA(i)} refers to a symbol consumed within a marked region
+ /// that has not yet been released.</li>
+ /// </ul>
+ ///
+ /// If {@code i} represents a position at or beyond the end of the stream,
+ /// this method returns <seealso cref="#EOF"/>.
+ /// <p/>
+ /// The return value is unspecified if {@code i<0} and fewer than {@code -i}
+ /// calls to <seealso cref="#consume consume()"/> have occurred from the beginning of
+ /// the stream before calling this method.
+ /// </summary>
+ /// <exception cref="UnsupportedOperationException"> if the stream does not support
+ /// retrieving the value of the specified symbol </exception>
+ virtual size_t LA(ssize_t i) = 0;
+
+ /// <summary>
+ /// A mark provides a guarantee that <seealso cref="#seek seek()"/> operations will be
+ /// valid over a "marked range" extending from the index where {@code mark()}
+ /// was called to the current <seealso cref="#index index()"/>. This allows the use of
+ /// streaming input sources by specifying the minimum buffering requirements
+ /// to support arbitrary lookahead during prediction.
+ /// <p/>
+ /// The returned mark is an opaque handle (type {@code int}) which is passed
+ /// to <seealso cref="#release release()"/> when the guarantees provided by the marked
+ /// range are no longer necessary. When calls to
+ /// {@code mark()}/{@code release()} are nested, the marks must be released
+ /// in reverse order of which they were obtained. Since marked regions are
+ /// used during performance-critical sections of prediction, the specific
+ /// behavior of invalid usage is unspecified (i.e. a mark is not released, or
+ /// a mark is released twice, or marks are not released in reverse order from
+ /// which they were created).
+ /// <p/>
+ /// The behavior of this method is unspecified if no call to an
+ /// <seealso cref="IntStream initializing method"/> has occurred after this stream was
+ /// constructed.
+ /// <p/>
+ /// This method does not change the current position in the input stream.
+ /// <p/>
+ /// The following example shows the use of <seealso cref="#mark mark()"/>,
+ /// <seealso cref="#release release(mark)"/>, <seealso cref="#index index()"/>, and
+ /// <seealso cref="#seek seek(index)"/> as part of an operation to safely work within a
+ /// marked region, then restore the stream position to its original value and
+ /// release the mark.
+ /// <pre>
+ /// IntStream stream = ...;
+ /// int index = -1;
+ /// int mark = stream.mark();
+ /// try {
+ /// index = stream.index();
+ /// // perform work here...
+ /// } finally {
+ /// if (index != -1) {
+ /// stream.seek(index);
+ /// }
+ /// stream.release(mark);
+ /// }
+ /// </pre>
+ /// </summary>
+ /// <returns> An opaque marker which should be passed to
+ /// <seealso cref="#release release()"/> when the marked range is no longer required. </returns>
+ virtual ssize_t mark() = 0;
+
+ /// <summary>
+ /// This method releases a marked range created by a call to
+ /// <seealso cref="#mark mark()"/>. Calls to {@code release()} must appear in the
+ /// reverse order of the corresponding calls to {@code mark()}. If a mark is
+ /// released twice, or if marks are not released in reverse order of the
+ /// corresponding calls to {@code mark()}, the behavior is unspecified.
+ /// <p/>
+ /// For more information and an example, see <seealso cref="#mark"/>.
+ /// </summary>
+ /// <param name="marker"> A marker returned by a call to {@code mark()}. </param>
+ /// <seealso cref= #mark </seealso>
+ virtual void release(ssize_t marker) = 0;
+
+ /// <summary>
+ /// Return the index into the stream of the input symbol referred to by
+ /// {@code LA(1)}.
+ /// <p/>
+ /// The behavior of this method is unspecified if no call to an
+ /// <seealso cref="IntStream initializing method"/> has occurred after this stream was
+ /// constructed.
+ /// </summary>
+ virtual size_t index() = 0;
+
+ /// <summary>
+ /// Set the input cursor to the position indicated by {@code index}. If the
+ /// specified index lies past the end of the stream, the operation behaves as
+ /// though {@code index} was the index of the EOF symbol. After this method
+ /// returns without throwing an exception, the at least one of the following
+ /// will be true.
+ ///
+ /// <ul>
+ /// <li><seealso cref="#index index()"/> will return the index of the first symbol
+ /// appearing at or after the specified {@code index}. Specifically,
+ /// implementations which filter their sources should automatically
+ /// adjust {@code index} forward the minimum amount required for the
+ /// operation to target a non-ignored symbol.</li>
+ /// <li>{@code LA(1)} returns <seealso cref="#EOF"/></li>
+ /// </ul>
+ ///
+ /// This operation is guaranteed to not throw an exception if {@code index}
+ /// lies within a marked region. For more information on marked regions, see
+ /// <seealso cref="#mark"/>. The behavior of this method is unspecified if no call to
+ /// an <seealso cref="IntStream initializing method"/> has occurred after this stream
+ /// was constructed.
+ /// </summary>
+ /// <param name="index"> The absolute index to seek to.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code index} is less than 0 </exception>
+ /// <exception cref="UnsupportedOperationException"> if the stream does not support
+ /// seeking to the specified index </exception>
+ virtual void seek(size_t index) = 0;
+
+ /// <summary>
+ /// Returns the total number of symbols in the stream, including a single EOF
+ /// symbol.
+ /// </summary>
+ /// <exception cref="UnsupportedOperationException"> if the size of the stream is
+ /// unknown. </exception>
+ virtual size_t size() = 0;
+
+ /// <summary>
+ /// Gets the name of the underlying symbol source. This method returns a
+ /// non-null, non-empty string. If such a name is not known, this method
+ /// returns <seealso cref="#UNKNOWN_SOURCE_NAME"/>.
+ /// </summary>
+ virtual std::string getSourceName() const = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ParserRuleContext.h"
+
+namespace antlr4 {
+
+ /**
+ * This class extends {@link ParserRuleContext} by allowing the value of
+ * {@link #getRuleIndex} to be explicitly set for the context.
+ *
+ * <p>
+ * {@link ParserRuleContext} does not include field storage for the rule index
+ * since the context classes created by the code generator override the
+ * {@link #getRuleIndex} method to return the correct value for that context.
+ * Since the parser interpreter does not use the context classes generated for a
+ * parser, this class (with slightly more memory overhead per node) is used to
+ * provide equivalent functionality.</p>
+ */
+ class ANTLR4CPP_PUBLIC InterpreterRuleContext : public ParserRuleContext {
+ public:
+ InterpreterRuleContext();
+
+ /**
+ * Constructs a new {@link InterpreterRuleContext} with the specified
+ * parent, invoking state, and rule index.
+ *
+ * @param parent The parent context.
+ * @param invokingStateNumber The invoking state number.
+ * @param ruleIndex The rule index for the current context.
+ */
+ InterpreterRuleContext(ParserRuleContext *parent, size_t invokingStateNumber, size_t ruleIndex);
+
+ virtual size_t getRuleIndex() const override;
+
+ protected:
+ /** This is the backing field for {@link #getRuleIndex}. */
+ const size_t _ruleIndex = INVALID_INDEX;
+};
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Recognizer.h"
+#include "TokenSource.h"
+#include "CharStream.h"
+#include "Token.h"
+
+namespace antlr4 {
+
+ /// A lexer is recognizer that draws input symbols from a character stream.
+ /// lexer grammars result in a subclass of this object. A Lexer object
+ /// uses simplified match() and error recovery mechanisms in the interest
+ /// of speed.
+ class ANTLR4CPP_PUBLIC Lexer : public Recognizer, public TokenSource {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t DEFAULT_MODE = 0;
+ static constexpr size_t MORE = std::numeric_limits<size_t>::max() - 1;
+ static constexpr size_t SKIP = std::numeric_limits<size_t>::max() - 2;
+
+ static constexpr size_t DEFAULT_TOKEN_CHANNEL = Token::DEFAULT_CHANNEL;
+ static constexpr size_t HIDDEN = Token::HIDDEN_CHANNEL;
+ static constexpr size_t MIN_CHAR_VALUE = 0;
+ static constexpr size_t MAX_CHAR_VALUE = 0x10FFFF;
+#else
+ enum : size_t {
+ DEFAULT_MODE = 0,
+ MORE = static_cast<size_t>(-2), // std::numeric_limits<size_t>::max() - 1; doesn't work in VS 2013
+ SKIP = static_cast<size_t>(-3), // std::numeric_limits<size_t>::max() - 2; doesn't work in VS 2013
+
+ DEFAULT_TOKEN_CHANNEL = Token::DEFAULT_CHANNEL,
+ HIDDEN = Token::HIDDEN_CHANNEL,
+ MIN_CHAR_VALUE = 0,
+ MAX_CHAR_VALUE = 0x10FFFF,
+ };
+#endif
+
+ CharStream *_input; // Pure reference, usually from statically allocated instance.
+
+ protected:
+ /// How to create token objects.
+ TokenFactory<CommonToken> *_factory;
+
+ public:
+ /// The goal of all lexer rules/methods is to create a token object.
+ /// This is an instance variable as multiple rules may collaborate to
+ /// create a single token. nextToken will return this object after
+ /// matching lexer rule(s). If you subclass to allow multiple token
+ /// emissions, then set this to the last token to be matched or
+ /// something nonnull so that the auto token emit mechanism will not
+ /// emit another token.
+
+ // Life cycle of a token is this:
+ // Created by emit() (via the token factory) or by action code, holding ownership of it.
+ // Ownership is handed over to the token stream when calling nextToken().
+ std::unique_ptr<Token> token;
+
+ /// <summary>
+ /// What character index in the stream did the current token start at?
+ /// Needed, for example, to get the text for current token. Set at
+ /// the start of nextToken.
+ /// </summary>
+ size_t tokenStartCharIndex;
+
+ /// <summary>
+ /// The line on which the first character of the token resides </summary>
+ size_t tokenStartLine;
+
+ /// The character position of first character within the line.
+ size_t tokenStartCharPositionInLine;
+
+ /// Once we see EOF on char stream, next token will be EOF.
+ /// If you have DONE : EOF ; then you see DONE EOF.
+ bool hitEOF;
+
+ /// The channel number for the current token.
+ size_t channel;
+
+ /// The token type for the current token.
+ size_t type;
+
+ // Use the vector as a stack.
+ std::vector<size_t> modeStack;
+ size_t mode;
+
+ Lexer();
+ Lexer(CharStream *input);
+ virtual ~Lexer() {}
+
+ virtual void reset();
+
+ /// Return a token from this source; i.e., match a token on the char stream.
+ virtual std::unique_ptr<Token> nextToken() override;
+
+ /// Instruct the lexer to skip creating a token for current lexer rule
+ /// and look for another token. nextToken() knows to keep looking when
+ /// a lexer rule finishes with token set to SKIP_TOKEN. Recall that
+ /// if token == null at end of any token rule, it creates one for you
+ /// and emits it.
+ virtual void skip();
+ virtual void more();
+ virtual void setMode(size_t m);
+ virtual void pushMode(size_t m);
+ virtual size_t popMode();
+
+ template<typename T1>
+ void setTokenFactory(TokenFactory<T1> *factory) {
+ this->_factory = factory;
+ }
+
+ virtual TokenFactory<CommonToken>* getTokenFactory() override;
+
+ /// Set the char stream and reset the lexer
+ virtual void setInputStream(IntStream *input) override;
+
+ virtual std::string getSourceName() override;
+
+ virtual CharStream* getInputStream() override;
+
+ /// By default does not support multiple emits per nextToken invocation
+ /// for efficiency reasons. Subclasses can override this method, nextToken,
+ /// and getToken (to push tokens into a list and pull from that list
+ /// rather than a single variable as this implementation does).
+ virtual void emit(std::unique_ptr<Token> newToken);
+
+ /// The standard method called to automatically emit a token at the
+ /// outermost lexical rule. The token object should point into the
+ /// char buffer start..stop. If there is a text override in 'text',
+ /// use that to set the token's text. Override this method to emit
+ /// custom Token objects or provide a new factory.
+ virtual Token* emit();
+
+ virtual Token* emitEOF();
+
+ virtual size_t getLine() const override;
+
+ virtual size_t getCharPositionInLine() override;
+
+ virtual void setLine(size_t line);
+
+ virtual void setCharPositionInLine(size_t charPositionInLine);
+
+ /// What is the index of the current character of lookahead?
+ virtual size_t getCharIndex();
+
+ /// Return the text matched so far for the current token or any
+ /// text override.
+ virtual std::string getText();
+
+ /// Set the complete text of this token; it wipes any previous
+ /// changes to the text.
+ virtual void setText(const std::string &text);
+
+ /// Override if emitting multiple tokens.
+ virtual std::unique_ptr<Token> getToken();
+
+ virtual void setToken(std::unique_ptr<Token> newToken);
+
+ virtual void setType(size_t ttype);
+
+ virtual size_t getType();
+
+ virtual void setChannel(size_t newChannel);
+
+ virtual size_t getChannel();
+
+ virtual const std::vector<std::string>& getChannelNames() const = 0;
+
+ virtual const std::vector<std::string>& getModeNames() const = 0;
+
+ /// Return a list of all Token objects in input char stream.
+ /// Forces load of all tokens. Does not include EOF token.
+ virtual std::vector<std::unique_ptr<Token>> getAllTokens();
+
+ virtual void recover(const LexerNoViableAltException &e);
+
+ virtual void notifyListeners(const LexerNoViableAltException &e);
+
+ virtual std::string getErrorDisplay(const std::string &s);
+
+ /// Lexers can normally match any char in it's vocabulary after matching
+ /// a token, so do the easy thing and just kill a character and hope
+ /// it all works out. You can instead use the rule invocation stack
+ /// to do sophisticated error recovery if you are in a fragment rule.
+ virtual void recover(RecognitionException *re);
+
+ /// <summary>
+ /// Gets the number of syntax errors reported during parsing. This value is
+ /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
+ /// </summary>
+ /// <seealso cref= #notifyListeners </seealso>
+ virtual size_t getNumberOfSyntaxErrors();
+
+ protected:
+ /// You can set the text for the current token to override what is in
+ /// the input char buffer (via setText()).
+ std::string _text;
+
+ private:
+ size_t _syntaxErrors;
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Lexer.h"
+#include "atn/PredictionContext.h"
+#include "Vocabulary.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC LexerInterpreter : public Lexer {
+ public:
+ // @deprecated
+ LexerInterpreter(const std::string &grammarFileName, const std::vector<std::string> &tokenNames,
+ const std::vector<std::string> &ruleNames, const std::vector<std::string> &channelNames,
+ const std::vector<std::string> &modeNames, const atn::ATN &atn, CharStream *input);
+ LexerInterpreter(const std::string &grammarFileName, const dfa::Vocabulary &vocabulary,
+ const std::vector<std::string> &ruleNames, const std::vector<std::string> &channelNames,
+ const std::vector<std::string> &modeNames, const atn::ATN &atn, CharStream *input);
+
+ ~LexerInterpreter();
+
+ virtual const atn::ATN& getATN() const override;
+ virtual std::string getGrammarFileName() const override;
+ virtual const std::vector<std::string>& getTokenNames() const override;
+ virtual const std::vector<std::string>& getRuleNames() const override;
+ virtual const std::vector<std::string>& getChannelNames() const override;
+ virtual const std::vector<std::string>& getModeNames() const override;
+
+ virtual const dfa::Vocabulary& getVocabulary() const override;
+
+ protected:
+ const std::string _grammarFileName;
+ const atn::ATN &_atn;
+
+ // @deprecated
+ std::vector<std::string> _tokenNames;
+ const std::vector<std::string> &_ruleNames;
+ const std::vector<std::string> &_channelNames;
+ const std::vector<std::string> &_modeNames;
+ std::vector<dfa::DFA> _decisionToDFA;
+
+ atn::PredictionContextCache _sharedContextCache;
+
+ private:
+ dfa::Vocabulary _vocabulary;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RecognitionException.h"
+#include "atn/ATNConfigSet.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC LexerNoViableAltException : public RecognitionException {
+ public:
+ LexerNoViableAltException(Lexer *lexer, CharStream *input, size_t startIndex,
+ atn::ATNConfigSet *deadEndConfigs);
+
+ virtual size_t getStartIndex();
+ virtual atn::ATNConfigSet* getDeadEndConfigs();
+ virtual std::string toString();
+
+ private:
+ /// Matching attempted at what input index?
+ const size_t _startIndex;
+
+ /// Which configurations did we try at input.index() that couldn't match input.LA(1)?
+ atn::ATNConfigSet *_deadEndConfigs;
+
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "TokenSource.h"
+#include "CommonTokenFactory.h"
+
+namespace antlr4 {
+
+ /// Provides an implementation of <seealso cref="TokenSource"/> as a wrapper around a list
+ /// of <seealso cref="Token"/> objects.
+ ///
+ /// If the final token in the list is an <seealso cref="Token#EOF"/> token, it will be used
+ /// as the EOF token for every call to <seealso cref="#nextToken"/> after the end of the
+ /// list is reached. Otherwise, an EOF token will be created.
+ class ANTLR4CPP_PUBLIC ListTokenSource : public TokenSource {
+ protected:
+ // This list will be emptied token by token as we call nextToken().
+ // Token streams can be used to buffer tokens for a while.
+ std::vector<std::unique_ptr<Token>> tokens;
+
+ private:
+ /// <summary>
+ /// The name of the input source. If this value is {@code null}, a call to
+ /// <seealso cref="#getSourceName"/> should return the source name used to create the
+ /// the next token in <seealso cref="#tokens"/> (or the previous token if the end of
+ /// the input has been reached).
+ /// </summary>
+ const std::string sourceName;
+
+ protected:
+ /// The index into <seealso cref="#tokens"/> of token to return by the next call to
+ /// <seealso cref="#nextToken"/>. The end of the input is indicated by this value
+ /// being greater than or equal to the number of items in <seealso cref="#tokens"/>.
+ size_t i;
+
+ private:
+ /// This is the backing field for <seealso cref="#getTokenFactory"/> and
+ /// <seealso cref="setTokenFactory"/>.
+ TokenFactory<CommonToken> *_factory = CommonTokenFactory::DEFAULT.get();
+
+ public:
+ /// Constructs a new <seealso cref="ListTokenSource"/> instance from the specified
+ /// collection of <seealso cref="Token"/> objects.
+ ///
+ /// <param name="tokens"> The collection of <seealso cref="Token"/> objects to provide as a
+ /// <seealso cref="TokenSource"/>. </param>
+ /// <exception cref="NullPointerException"> if {@code tokens} is {@code null} </exception>
+ ListTokenSource(std::vector<std::unique_ptr<Token>> tokens);
+ ListTokenSource(const ListTokenSource& other) = delete;
+
+ ListTokenSource& operator = (const ListTokenSource& other) = delete;
+
+ /// <summary>
+ /// Constructs a new <seealso cref="ListTokenSource"/> instance from the specified
+ /// collection of <seealso cref="Token"/> objects and source name.
+ /// </summary>
+ /// <param name="tokens"> The collection of <seealso cref="Token"/> objects to provide as a
+ /// <seealso cref="TokenSource"/>. </param>
+ /// <param name="sourceName"> The name of the <seealso cref="TokenSource"/>. If this value is
+ /// {@code null}, <seealso cref="#getSourceName"/> will attempt to infer the name from
+ /// the next <seealso cref="Token"/> (or the previous token if the end of the input has
+ /// been reached).
+ /// </param>
+ /// <exception cref="NullPointerException"> if {@code tokens} is {@code null} </exception>
+ ListTokenSource(std::vector<std::unique_ptr<Token>> tokens_, const std::string &sourceName_);
+
+ virtual size_t getCharPositionInLine() override;
+ virtual std::unique_ptr<Token> nextToken() override;
+ virtual size_t getLine() const override;
+ virtual CharStream* getInputStream() override;
+ virtual std::string getSourceName() override;
+
+ template<typename T1>
+ void setTokenFactory(TokenFactory<T1> *factory) {
+ this->_factory = factory;
+ }
+
+ virtual TokenFactory<CommonToken>* getTokenFactory() override;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RecognitionException.h"
+#include "Token.h"
+#include "atn/ATNConfigSet.h"
+
+namespace antlr4 {
+
+ /// Indicates that the parser could not decide which of two or more paths
+ /// to take based upon the remaining input. It tracks the starting token
+ /// of the offending input and also knows where the parser was
+ /// in the various paths when the error. Reported by reportNoViableAlternative()
+ class ANTLR4CPP_PUBLIC NoViableAltException : public RecognitionException {
+ public:
+ NoViableAltException(Parser *recognizer); // LL(1) error
+ NoViableAltException(Parser *recognizer, TokenStream *input,Token *startToken,
+ Token *offendingToken, atn::ATNConfigSet *deadEndConfigs, ParserRuleContext *ctx, bool deleteConfigs);
+ ~NoViableAltException();
+
+ virtual Token* getStartToken() const;
+ virtual atn::ATNConfigSet* getDeadEndConfigs() const;
+
+ private:
+ /// Which configurations did we try at input.index() that couldn't match input.LT(1)?
+ /// Shared pointer that conditionally deletes the configurations (based on flag
+ /// passed during construction)
+ Ref<atn::ATNConfigSet> _deadEndConfigs;
+
+ /// The token object at the start index; the input stream might
+ /// not be buffering tokens so get a reference to it. (At the
+ /// time the error occurred, of course the stream needs to keep a
+ /// buffer all of the tokens but later we might not have access to those.)
+ Token *_startToken;
+
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Recognizer.h"
+#include "tree/ParseTreeListener.h"
+#include "tree/ParseTree.h"
+#include "TokenStream.h"
+#include "TokenSource.h"
+#include "misc/Interval.h"
+
+namespace antlr4 {
+
+ /// This is all the parsing support code essentially; most of it is error recovery stuff.
+ class ANTLR4CPP_PUBLIC Parser : public Recognizer {
+ public:
+
+ class TraceListener : public tree::ParseTreeListener {
+ public:
+ TraceListener(Parser *outerInstance);
+ virtual ~TraceListener();
+
+ virtual void enterEveryRule(ParserRuleContext *ctx) override;
+ virtual void visitTerminal(tree::TerminalNode *node) override;
+ virtual void visitErrorNode(tree::ErrorNode *node) override;
+ virtual void exitEveryRule(ParserRuleContext *ctx) override;
+
+ private:
+ Parser *const outerInstance;
+ };
+
+ class TrimToSizeListener : public tree::ParseTreeListener {
+ public:
+ static TrimToSizeListener INSTANCE;
+
+ virtual ~TrimToSizeListener();
+
+ virtual void enterEveryRule(ParserRuleContext *ctx) override;
+ virtual void visitTerminal(tree::TerminalNode *node) override;
+ virtual void visitErrorNode(tree::ErrorNode *node) override;
+ virtual void exitEveryRule(ParserRuleContext *ctx) override;
+ };
+
+ Parser(TokenStream *input);
+ virtual ~Parser();
+
+ /// reset the parser's state
+ virtual void reset();
+
+ /// <summary>
+ /// Match current input symbol against {@code ttype}. If the symbol type
+ /// matches, <seealso cref="ANTLRErrorStrategy#reportMatch"/> and <seealso cref="#consume"/> are
+ /// called to complete the match process.
+ ///
+ /// If the symbol type does not match,
+ /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
+ /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
+ /// {@code true} and the token index of the symbol returned by
+ /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
+ /// the parse tree by calling {@link #createErrorNode(ParserRuleContext, Token)} then
+ /// {@link ParserRuleContext#addErrorNode(ErrorNode)}.
+ /// </summary>
+ /// <param name="ttype"> the token type to match </param>
+ /// <returns> the matched symbol </returns>
+ /// <exception cref="RecognitionException"> if the current input symbol did not match
+ /// {@code ttype} and the error strategy could not recover from the
+ /// mismatched symbol </exception>
+ virtual Token* match(size_t ttype);
+
+ /// <summary>
+ /// Match current input symbol as a wildcard. If the symbol type matches
+ /// (i.e. has a value greater than 0), <seealso cref="ANTLRErrorStrategy#reportMatch"/>
+ /// and <seealso cref="#consume"/> are called to complete the match process.
+ /// <p/>
+ /// If the symbol type does not match,
+ /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is called on the current error
+ /// strategy to attempt recovery. If <seealso cref="#getBuildParseTree"/> is
+ /// {@code true} and the token index of the symbol returned by
+ /// <seealso cref="ANTLRErrorStrategy#recoverInline"/> is -1, the symbol is added to
+ /// the parse tree by calling <seealso cref="ParserRuleContext#addErrorNode"/>.
+ /// </summary>
+ /// <returns> the matched symbol </returns>
+ /// <exception cref="RecognitionException"> if the current input symbol did not match
+ /// a wildcard and the error strategy could not recover from the mismatched
+ /// symbol </exception>
+ virtual Token* matchWildcard();
+
+ /// <summary>
+ /// Track the <seealso cref="ParserRuleContext"/> objects during the parse and hook
+ /// them up using the <seealso cref="ParserRuleContext#children"/> list so that it
+ /// forms a parse tree. The <seealso cref="ParserRuleContext"/> returned from the start
+ /// rule represents the root of the parse tree.
+ /// <p/>
+ /// Note that if we are not building parse trees, rule contexts only point
+ /// upwards. When a rule exits, it returns the context but that gets garbage
+ /// collected if nobody holds a reference. It points upwards but nobody
+ /// points at it.
+ /// <p/>
+ /// When we build parse trees, we are adding all of these contexts to
+ /// <seealso cref="ParserRuleContext#children"/> list. Contexts are then not candidates
+ /// for garbage collection.
+ /// </summary>
+ virtual void setBuildParseTree(bool buildParseTrees);
+
+ /// <summary>
+ /// Gets whether or not a complete parse tree will be constructed while
+ /// parsing. This property is {@code true} for a newly constructed parser.
+ /// </summary>
+ /// <returns> {@code true} if a complete parse tree will be constructed while
+ /// parsing, otherwise {@code false} </returns>
+ virtual bool getBuildParseTree();
+
+ /// <summary>
+ /// Trim the internal lists of the parse tree during parsing to conserve memory.
+ /// This property is set to {@code false} by default for a newly constructed parser.
+ /// </summary>
+ /// <param name="trimParseTrees"> {@code true} to trim the capacity of the <seealso cref="ParserRuleContext#children"/>
+ /// list to its size after a rule is parsed. </param>
+ virtual void setTrimParseTree(bool trimParseTrees);
+
+ /// <returns> {@code true} if the <seealso cref="ParserRuleContext#children"/> list is trimmed
+ /// using the default <seealso cref="Parser.TrimToSizeListener"/> during the parse process. </returns>
+ virtual bool getTrimParseTree();
+
+ virtual std::vector<tree::ParseTreeListener *> getParseListeners();
+
+ /// <summary>
+ /// Registers {@code listener} to receive events during the parsing process.
+ /// <p/>
+ /// To support output-preserving grammar transformations (including but not
+ /// limited to left-recursion removal, automated left-factoring, and
+ /// optimized code generation), calls to listener methods during the parse
+ /// may differ substantially from calls made by
+ /// <seealso cref="ParseTreeWalker#DEFAULT"/> used after the parse is complete. In
+ /// particular, rule entry and exit events may occur in a different order
+ /// during the parse than after the parser. In addition, calls to certain
+ /// rule entry methods may be omitted.
+ /// <p/>
+ /// With the following specific exceptions, calls to listener events are
+ /// <em>deterministic</em>, i.e. for identical input the calls to listener
+ /// methods will be the same.
+ ///
+ /// <ul>
+ /// <li>Alterations to the grammar used to generate code may change the
+ /// behavior of the listener calls.</li>
+ /// <li>Alterations to the command line options passed to ANTLR 4 when
+ /// generating the parser may change the behavior of the listener calls.</li>
+ /// <li>Changing the version of the ANTLR Tool used to generate the parser
+ /// may change the behavior of the listener calls.</li>
+ /// </ul>
+ /// </summary>
+ /// <param name="listener"> the listener to add
+ /// </param>
+ /// <exception cref="NullPointerException"> if {@code} listener is {@code null} </exception>
+ virtual void addParseListener(tree::ParseTreeListener *listener);
+
+ /// <summary>
+ /// Remove {@code listener} from the list of parse listeners.
+ /// <p/>
+ /// If {@code listener} is {@code null} or has not been added as a parse
+ /// listener, this method does nothing.
+ /// </summary>
+ /// <seealso cref= #addParseListener
+ /// </seealso>
+ /// <param name="listener"> the listener to remove </param>
+ virtual void removeParseListener(tree::ParseTreeListener *listener);
+
+ /// <summary>
+ /// Remove all parse listeners.
+ /// </summary>
+ /// <seealso cref= #addParseListener </seealso>
+ virtual void removeParseListeners();
+
+ /// <summary>
+ /// Notify any parse listeners of an enter rule event.
+ /// </summary>
+ /// <seealso cref= #addParseListener </seealso>
+ virtual void triggerEnterRuleEvent();
+
+ /// <summary>
+ /// Notify any parse listeners of an exit rule event.
+ /// </summary>
+ /// <seealso cref= #addParseListener </seealso>
+ virtual void triggerExitRuleEvent();
+
+ /// <summary>
+ /// Gets the number of syntax errors reported during parsing. This value is
+ /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
+ /// </summary>
+ /// <seealso cref= #notifyErrorListeners </seealso>
+ virtual size_t getNumberOfSyntaxErrors();
+
+ virtual TokenFactory<CommonToken>* getTokenFactory() override;
+
+ /// <summary>
+ /// Tell our token source and error strategy about a new way to create tokens. </summary>
+ template<typename T1>
+ void setTokenFactory(TokenFactory<T1> *factory) {
+ _input->getTokenSource()->setTokenFactory(factory);
+ }
+
+ /// The ATN with bypass alternatives is expensive to create so we create it
+ /// lazily. The ATN is owned by us.
+ virtual const atn::ATN& getATNWithBypassAlts();
+
+ /// <summary>
+ /// The preferred method of getting a tree pattern. For example, here's a
+ /// sample use:
+ ///
+ /// <pre>
+ /// ParseTree t = parser.expr();
+ /// ParseTreePattern p = parser.compileParseTreePattern("<ID>+0", MyParser.RULE_expr);
+ /// ParseTreeMatch m = p.match(t);
+ /// String id = m.get("ID");
+ /// </pre>
+ /// </summary>
+ virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// The same as <seealso cref="#compileParseTreePattern(String, int)"/> but specify a
+ /// <seealso cref="Lexer"/> rather than trying to deduce it from this parser.
+ /// </summary>
+ virtual tree::pattern::ParseTreePattern compileParseTreePattern(const std::string &pattern, int patternRuleIndex,
+ Lexer *lexer);
+
+ virtual Ref<ANTLRErrorStrategy> getErrorHandler();
+ virtual void setErrorHandler(Ref<ANTLRErrorStrategy> const& handler);
+
+ virtual IntStream* getInputStream() override;
+ void setInputStream(IntStream *input) override;
+
+ virtual TokenStream* getTokenStream();
+
+ /// Set the token stream and reset the parser.
+ virtual void setTokenStream(TokenStream *input);
+
+ /// <summary>
+ /// Match needs to return the current input symbol, which gets put
+ /// into the label for the associated token ref; e.g., x=ID.
+ /// </summary>
+ virtual Token* getCurrentToken();
+
+ void notifyErrorListeners(const std::string &msg);
+
+ virtual void notifyErrorListeners(Token *offendingToken, const std::string &msg, std::exception_ptr e);
+
+ /// Consume and return the <seealso cref="#getCurrentToken current symbol"/>.
+ /// <p/>
+ /// E.g., given the following input with {@code A} being the current
+ /// lookahead symbol, this function moves the cursor to {@code B} and returns
+ /// {@code A}.
+ ///
+ /// <pre>
+ /// A B
+ /// ^
+ /// </pre>
+ ///
+ /// If the parser is not in error recovery mode, the consumed symbol is added
+ /// to the parse tree using <seealso cref="ParserRuleContext#addChild(TerminalNode)"/>, and
+ /// <seealso cref="ParseTreeListener#visitTerminal"/> is called on any parse listeners.
+ /// If the parser <em>is</em> in error recovery mode, the consumed symbol is
+ /// added to the parse tree using {@link #createErrorNode(ParserRuleContext, Token)} then
+ /// {@link ParserRuleContext#addErrorNode(ErrorNode)} and
+ /// <seealso cref="ParseTreeListener#visitErrorNode"/> is called on any parse
+ /// listeners.
+ virtual Token* consume();
+
+ /// Always called by generated parsers upon entry to a rule. Access field
+ /// <seealso cref="#_ctx"/> get the current context.
+ virtual void enterRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex);
+
+ void exitRule();
+
+ virtual void enterOuterAlt(ParserRuleContext *localctx, size_t altNum);
+
+ /**
+ * Get the precedence level for the top-most precedence rule.
+ *
+ * @return The precedence level for the top-most precedence rule, or -1 if
+ * the parser context is not nested within a precedence rule.
+ */
+ int getPrecedence() const;
+
+ /// @deprecated Use
+ /// <seealso cref="#enterRecursionRule(ParserRuleContext, int, int, int)"/> instead.
+ virtual void enterRecursionRule(ParserRuleContext *localctx, size_t ruleIndex);
+ virtual void enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex, int precedence);
+
+ /** Like {@link #enterRule} but for recursive rules.
+ * Make the current context the child of the incoming localctx.
+ */
+ virtual void pushNewRecursionContext(ParserRuleContext *localctx, size_t state, size_t ruleIndex);
+ virtual void unrollRecursionContexts(ParserRuleContext *parentctx);
+ virtual ParserRuleContext* getInvokingContext(size_t ruleIndex);
+ virtual ParserRuleContext* getContext();
+ virtual void setContext(ParserRuleContext *ctx);
+ virtual bool precpred(RuleContext *localctx, int precedence) override;
+ virtual bool inContext(const std::string &context);
+
+ /// <summary>
+ /// Checks whether or not {@code symbol} can follow the current state in the
+ /// ATN. The behavior of this method is equivalent to the following, but is
+ /// implemented such that the complete context-sensitive follow set does not
+ /// need to be explicitly constructed.
+ ///
+ /// <pre>
+ /// return getExpectedTokens().contains(symbol);
+ /// </pre>
+ /// </summary>
+ /// <param name="symbol"> the symbol type to check </param>
+ /// <returns> {@code true} if {@code symbol} can follow the current state in
+ /// the ATN, otherwise {@code false}. </returns>
+ virtual bool isExpectedToken(size_t symbol);
+
+ bool isMatchedEOF() const;
+
+ /// <summary>
+ /// Computes the set of input symbols which could follow the current parser
+ /// state and context, as given by <seealso cref="#getState"/> and <seealso cref="#getContext"/>,
+ /// respectively.
+ /// </summary>
+ /// <seealso cref= ATN#getExpectedTokens(int, RuleContext) </seealso>
+ virtual misc::IntervalSet getExpectedTokens();
+
+ virtual misc::IntervalSet getExpectedTokensWithinCurrentRule();
+
+ /// Get a rule's index (i.e., {@code RULE_ruleName} field) or INVALID_INDEX if not found.
+ virtual size_t getRuleIndex(const std::string &ruleName);
+
+ virtual ParserRuleContext* getRuleContext();
+
+ /// <summary>
+ /// Return List<String> of the rule names in your parser instance
+ /// leading up to a call to the current rule. You could override if
+ /// you want more details such as the file/line info of where
+ /// in the ATN a rule is invoked.
+ ///
+ /// This is very useful for error messages.
+ /// </summary>
+ virtual std::vector<std::string> getRuleInvocationStack();
+
+ virtual std::vector<std::string> getRuleInvocationStack(RuleContext *p);
+
+ /// <summary>
+ /// For debugging and other purposes. </summary>
+ virtual std::vector<std::string> getDFAStrings();
+
+ /// <summary>
+ /// For debugging and other purposes. </summary>
+ virtual void dumpDFA();
+
+ virtual std::string getSourceName();
+
+ atn::ParseInfo getParseInfo() const;
+
+ /**
+ * @since 4.3
+ */
+ void setProfile(bool profile);
+
+ /// <summary>
+ /// During a parse is sometimes useful to listen in on the rule entry and exit
+ /// events as well as token matches. This is for quick and dirty debugging.
+ /// </summary>
+ virtual void setTrace(bool trace);
+
+ /**
+ * Gets whether a {@link TraceListener} is registered as a parse listener
+ * for the parser.
+ *
+ * @see #setTrace(boolean)
+ */
+ bool isTrace() const;
+
+ tree::ParseTreeTracker& getTreeTracker() { return _tracker; }
+
+ /** How to create a token leaf node associated with a parent.
+ * Typically, the terminal node to create is not a function of the parent
+ * but this method must still set the parent pointer of the terminal node
+ * returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
+ * set the parent pointer, but the parent pointer is implementation dependent
+ * and currently there is no setParent() in {@link TerminalNode} (and can't
+ * add method in Java 1.7 without breaking backward compatibility).
+ *
+ * @since 4.7
+ */
+ tree::TerminalNode *createTerminalNode(Token *t);
+
+ /** How to create an error node, given a token, associated with a parent.
+ * Typically, the error node to create is not a function of the parent
+ * but this method must still set the parent pointer of the terminal node
+ * returned. I would prefer having {@link ParserRuleContext#addAnyChild(ParseTree)}
+ * set the parent pointer, but the parent pointer is implementation dependent
+ * and currently there is no setParent() in {@link ErrorNode} (and can't
+ * add method in Java 1.7 without breaking backward compatibility).
+ *
+ * @since 4.7
+ */
+ tree::ErrorNode *createErrorNode(Token *t);
+
+ protected:
+ /// The ParserRuleContext object for the currently executing rule.
+ /// This is always non-null during the parsing process.
+ // ml: this is one of the contexts tracked in _allocatedContexts.
+ ParserRuleContext *_ctx;
+
+ /// The error handling strategy for the parser. The default is DefaultErrorStrategy.
+ /// See also getErrorHandler.
+ Ref<ANTLRErrorStrategy> _errHandler;
+
+ /// <summary>
+ /// The input stream.
+ /// </summary>
+ /// <seealso cref= #getInputStream </seealso>
+ /// <seealso cref= #setInputStream </seealso>
+ TokenStream *_input;
+
+ std::vector<int> _precedenceStack;
+
+ /// <summary>
+ /// Specifies whether or not the parser should construct a parse tree during
+ /// the parsing process. The default value is {@code true}.
+ /// </summary>
+ /// <seealso cref= #getBuildParseTree </seealso>
+ /// <seealso cref= #setBuildParseTree </seealso>
+ bool _buildParseTrees;
+
+ /// The list of <seealso cref="ParseTreeListener"/> listeners registered to receive
+ /// events during the parse.
+ /// <seealso cref= #addParseListener </seealso>
+ std::vector<tree::ParseTreeListener *> _parseListeners;
+
+ /// <summary>
+ /// The number of syntax errors reported during parsing. This value is
+ /// incremented each time <seealso cref="#notifyErrorListeners"/> is called.
+ /// </summary>
+ size_t _syntaxErrors;
+
+ /** Indicates parser has match()ed EOF token. See {@link #exitRule()}. */
+ bool _matchedEOF;
+
+ virtual void addContextToParseTree();
+
+ // All rule contexts created during a parse run. This is cleared when calling reset().
+ tree::ParseTreeTracker _tracker;
+
+ private:
+ /// This field maps from the serialized ATN string to the deserialized <seealso cref="ATN"/> with
+ /// bypass alternatives.
+ ///
+ /// <seealso cref= ATNDeserializationOptions#isGenerateRuleBypassTransitions() </seealso>
+ static std::map<std::vector<uint16_t>, atn::ATN> bypassAltsAtnCache;
+
+ /// When setTrace(true) is called, a reference to the
+ /// TraceListener is stored here so it can be easily removed in a
+ /// later call to setTrace(false). The listener itself is
+ /// implemented as a parser listener so this field is not directly used by
+ /// other parser methods.
+ TraceListener *_tracer;
+
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Parser.h"
+#include "atn/ATN.h"
+#include "support/BitSet.h"
+#include "atn/PredictionContext.h"
+#include "Vocabulary.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// A parser simulator that mimics what ANTLR's generated
+ /// parser code does. A ParserATNSimulator is used to make
+ /// predictions via adaptivePredict but this class moves a pointer through the
+ /// ATN to simulate parsing. ParserATNSimulator just
+ /// makes us efficient rather than having to backtrack, for example.
+ ///
+ /// This properly creates parse trees even for left recursive rules.
+ ///
+ /// We rely on the left recursive rule invocation and special predicate
+ /// transitions to make left recursive rules work.
+ ///
+ /// See TestParserInterpreter for examples.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParserInterpreter : public Parser {
+ public:
+ // @deprecated
+ ParserInterpreter(const std::string &grammarFileName, const std::vector<std::string>& tokenNames,
+ const std::vector<std::string>& ruleNames, const atn::ATN &atn, TokenStream *input);
+ ParserInterpreter(const std::string &grammarFileName, const dfa::Vocabulary &vocabulary,
+ const std::vector<std::string> &ruleNames, const atn::ATN &atn, TokenStream *input);
+ ~ParserInterpreter();
+
+ virtual void reset() override;
+
+ virtual const atn::ATN& getATN() const override;
+
+ // @deprecated
+ virtual const std::vector<std::string>& getTokenNames() const override;
+
+ virtual const dfa::Vocabulary& getVocabulary() const override;
+
+ virtual const std::vector<std::string>& getRuleNames() const override;
+ virtual std::string getGrammarFileName() const override;
+
+ /// Begin parsing at startRuleIndex
+ virtual ParserRuleContext* parse(size_t startRuleIndex);
+
+ virtual void enterRecursionRule(ParserRuleContext *localctx, size_t state, size_t ruleIndex, int precedence) override;
+
+
+ /** Override this parser interpreters normal decision-making process
+ * at a particular decision and input token index. Instead of
+ * allowing the adaptive prediction mechanism to choose the
+ * first alternative within a block that leads to a successful parse,
+ * force it to take the alternative, 1..n for n alternatives.
+ *
+ * As an implementation limitation right now, you can only specify one
+ * override. This is sufficient to allow construction of different
+ * parse trees for ambiguous input. It means re-parsing the entire input
+ * in general because you're never sure where an ambiguous sequence would
+ * live in the various parse trees. For example, in one interpretation,
+ * an ambiguous input sequence would be matched completely in expression
+ * but in another it could match all the way back to the root.
+ *
+ * s : e '!'? ;
+ * e : ID
+ * | ID '!'
+ * ;
+ *
+ * Here, x! can be matched as (s (e ID) !) or (s (e ID !)). In the first
+ * case, the ambiguous sequence is fully contained only by the root.
+ * In the second case, the ambiguous sequences fully contained within just
+ * e, as in: (e ID !).
+ *
+ * Rather than trying to optimize this and make
+ * some intelligent decisions for optimization purposes, I settled on
+ * just re-parsing the whole input and then using
+ * {link Trees#getRootOfSubtreeEnclosingRegion} to find the minimal
+ * subtree that contains the ambiguous sequence. I originally tried to
+ * record the call stack at the point the parser detected and ambiguity but
+ * left recursive rules create a parse tree stack that does not reflect
+ * the actual call stack. That impedance mismatch was enough to make
+ * it it challenging to restart the parser at a deeply nested rule
+ * invocation.
+ *
+ * Only parser interpreters can override decisions so as to avoid inserting
+ * override checking code in the critical ALL(*) prediction execution path.
+ *
+ * @since 4.5.1
+ */
+ void addDecisionOverride(int decision, int tokenIndex, int forcedAlt);
+
+ Ref<InterpreterRuleContext> getOverrideDecisionRoot() const;
+
+ /** Return the root of the parse, which can be useful if the parser
+ * bails out. You still can access the top node. Note that,
+ * because of the way left recursive rules add children, it's possible
+ * that the root will not have any children if the start rule immediately
+ * called and left recursive rule that fails.
+ *
+ * @since 4.5.1
+ */
+ InterpreterRuleContext* getRootContext();
+
+ protected:
+ const std::string _grammarFileName;
+ std::vector<std::string> _tokenNames;
+ const atn::ATN &_atn;
+
+ std::vector<std::string> _ruleNames;
+
+ std::vector<dfa::DFA> _decisionToDFA; // not shared like it is for generated parsers
+ atn::PredictionContextCache _sharedContextCache;
+
+ /** This stack corresponds to the _parentctx, _parentState pair of locals
+ * that would exist on call stack frames with a recursive descent parser;
+ * in the generated function for a left-recursive rule you'd see:
+ *
+ * private EContext e(int _p) throws RecognitionException {
+ * ParserRuleContext _parentctx = _ctx; // Pair.a
+ * int _parentState = getState(); // Pair.b
+ * ...
+ * }
+ *
+ * Those values are used to create new recursive rule invocation contexts
+ * associated with left operand of an alt like "expr '*' expr".
+ */
+ std::stack<std::pair<ParserRuleContext *, size_t>> _parentContextStack;
+
+ /** We need a map from (decision,inputIndex)->forced alt for computing ambiguous
+ * parse trees. For now, we allow exactly one override.
+ */
+ int _overrideDecision = -1;
+ size_t _overrideDecisionInputIndex = INVALID_INDEX;
+ size_t _overrideDecisionAlt = INVALID_INDEX;
+ bool _overrideDecisionReached = false; // latch and only override once; error might trigger infinite loop
+
+ /** What is the current context when we override a decision? This tells
+ * us what the root of the parse tree is when using override
+ * for an ambiguity/lookahead check.
+ */
+ Ref<InterpreterRuleContext> _overrideDecisionRoot;
+ InterpreterRuleContext* _rootContext;
+
+ virtual atn::ATNState *getATNState();
+ virtual void visitState(atn::ATNState *p);
+
+ /** Method visitDecisionState() is called when the interpreter reaches
+ * a decision state (instance of DecisionState). It gives an opportunity
+ * for subclasses to track interesting things.
+ */
+ size_t visitDecisionState(atn::DecisionState *p);
+
+ /** Provide simple "factory" for InterpreterRuleContext's.
+ * @since 4.5.1
+ */
+ InterpreterRuleContext* createInterpreterRuleContext(ParserRuleContext *parent, size_t invokingStateNumber, size_t ruleIndex);
+
+ virtual void visitRuleStopState(atn::ATNState *p);
+
+ /** Rely on the error handler for this parser but, if no tokens are consumed
+ * to recover, add an error node. Otherwise, nothing is seen in the parse
+ * tree.
+ */
+ void recover(RecognitionException &e);
+ Token* recoverInline();
+
+ private:
+ const dfa::Vocabulary &_vocabulary;
+ std::unique_ptr<Token> _errorToken;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RuleContext.h"
+#include "support/CPPUtils.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// A rule invocation record for parsing.
+ ///
+ /// Contains all of the information about the current rule not stored in the
+ /// RuleContext. It handles parse tree children list, Any ATN state
+ /// tracing, and the default values available for rule invocatons:
+ /// start, stop, rule index, current alt number.
+ ///
+ /// Subclasses made for each rule and grammar track the parameters,
+ /// return values, locals, and labels specific to that rule. These
+ /// are the objects that are returned from rules.
+ ///
+ /// Note text is not an actual field of a rule return value; it is computed
+ /// from start and stop using the input stream's toString() method. I
+ /// could add a ctor to this so that we can pass in and store the input
+ /// stream, but I'm not sure we want to do that. It would seem to be undefined
+ /// to get the .text property anyway if the rule matches tokens from multiple
+ /// input streams.
+ ///
+ /// I do not use getters for fields of objects that are used simply to
+ /// group values such as this aggregate. The getters/setters are there to
+ /// satisfy the superclass interface.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParserRuleContext : public RuleContext {
+ public:
+ static ParserRuleContext EMPTY;
+
+ /// <summary>
+ /// For debugging/tracing purposes, we want to track all of the nodes in
+ /// the ATN traversed by the parser for a particular rule.
+ /// This list indicates the sequence of ATN nodes used to match
+ /// the elements of the children list. This list does not include
+ /// ATN nodes and other rules used to match rule invocations. It
+ /// traces the rule invocation node itself but nothing inside that
+ /// other rule's ATN submachine.
+ ///
+ /// There is NOT a one-to-one correspondence between the children and
+ /// states list. There are typically many nodes in the ATN traversed
+ /// for each element in the children list. For example, for a rule
+ /// invocation there is the invoking state and the following state.
+ ///
+ /// The parser setState() method updates field s and adds it to this list
+ /// if we are debugging/tracing.
+ ///
+ /// This does not trace states visited during prediction.
+ /// </summary>
+ // public List<Integer> states;
+
+ Token *start;
+ Token *stop;
+
+ /// The exception that forced this rule to return. If the rule successfully
+ /// completed, this is "null exception pointer".
+ std::exception_ptr exception;
+
+ ParserRuleContext();
+ ParserRuleContext(ParserRuleContext *parent, size_t invokingStateNumber);
+ virtual ~ParserRuleContext() {}
+
+ /** COPY a ctx (I'm deliberately not using copy constructor) to avoid
+ * confusion with creating node with parent. Does not copy children
+ * (except error leaves).
+ */
+ virtual void copyFrom(ParserRuleContext *ctx);
+
+
+ // Double dispatch methods for listeners
+
+ virtual void enterRule(tree::ParseTreeListener *listener);
+ virtual void exitRule(tree::ParseTreeListener *listener);
+
+ /** Add a token leaf node child and force its parent to be this node. */
+ tree::TerminalNode* addChild(tree::TerminalNode *t);
+ RuleContext* addChild(RuleContext *ruleInvocation);
+
+ /// Used by enterOuterAlt to toss out a RuleContext previously added as
+ /// we entered a rule. If we have # label, we will need to remove
+ /// generic ruleContext object.
+ virtual void removeLastChild();
+
+ virtual tree::TerminalNode* getToken(size_t ttype, std::size_t i);
+
+ virtual std::vector<tree::TerminalNode *> getTokens(size_t ttype);
+
+ template<typename T>
+ T* getRuleContext(size_t i) {
+ if (children.empty()) {
+ return nullptr;
+ }
+
+ size_t j = 0; // what element have we found with ctxType?
+ for (auto &child : children) {
+ if (antlrcpp::is<T *>(child)) {
+ if (j++ == i) {
+ return dynamic_cast<T *>(child);
+ }
+ }
+ }
+ return nullptr;
+ }
+
+ template<typename T>
+ std::vector<T *> getRuleContexts() {
+ std::vector<T *> contexts;
+ for (auto *child : children) {
+ if (antlrcpp::is<T *>(child)) {
+ contexts.push_back(dynamic_cast<T *>(child));
+ }
+ }
+
+ return contexts;
+ }
+
+ virtual misc::Interval getSourceInterval() override;
+
+ /**
+ * Get the initial token in this context.
+ * Note that the range from start to stop is inclusive, so for rules that do not consume anything
+ * (for example, zero length or error productions) this token may exceed stop.
+ */
+ virtual Token *getStart();
+
+ /**
+ * Get the final token in this context.
+ * Note that the range from start to stop is inclusive, so for rules that do not consume anything
+ * (for example, zero length or error productions) this token may precede start.
+ */
+ virtual Token *getStop();
+
+ /// <summary>
+ /// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary>
+ virtual std::string toInfoString(Parser *recognizer);
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ANTLRErrorListener.h"
+#include "Exceptions.h"
+
+namespace antlr4 {
+
+ /// This implementation of ANTLRErrorListener dispatches all calls to a
+ /// collection of delegate listeners. This reduces the effort required to support multiple
+ /// listeners.
+ class ANTLR4CPP_PUBLIC ProxyErrorListener : public ANTLRErrorListener {
+ private:
+ std::set<ANTLRErrorListener *> _delegates; // Not owned.
+
+ public:
+ void addErrorListener(ANTLRErrorListener *listener);
+ void removeErrorListener(ANTLRErrorListener *listener);
+ void removeErrorListeners();
+
+ void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line, size_t charPositionInLine,
+ const std::string &msg, std::exception_ptr e) override;
+
+ virtual void reportAmbiguity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex, bool exact,
+ const antlrcpp::BitSet &ambigAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportAttemptingFullContext(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ const antlrcpp::BitSet &conflictingAlts, atn::ATNConfigSet *configs) override;
+
+ virtual void reportContextSensitivity(Parser *recognizer, const dfa::DFA &dfa, size_t startIndex, size_t stopIndex,
+ size_t prediction, atn::ATNConfigSet *configs) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Exceptions.h"
+
+namespace antlr4 {
+
+ /// The root of the ANTLR exception hierarchy. In general, ANTLR tracks just
+ /// 3 kinds of errors: prediction errors, failed predicate errors, and
+ /// mismatched input errors. In each case, the parser knows where it is
+ /// in the input, where it is in the ATN, the rule invocation stack,
+ /// and what kind of problem occurred.
+ class ANTLR4CPP_PUBLIC RecognitionException : public RuntimeException {
+ private:
+ /// The Recognizer where this exception originated.
+ Recognizer *_recognizer;
+ IntStream *_input;
+ ParserRuleContext *_ctx;
+
+ /// The current Token when an error occurred. Since not all streams
+ /// support accessing symbols by index, we have to track the Token
+ /// instance itself.
+ Token *_offendingToken;
+
+ size_t _offendingState;
+
+ public:
+ RecognitionException(Recognizer *recognizer, IntStream *input, ParserRuleContext *ctx,
+ Token *offendingToken = nullptr);
+ RecognitionException(const std::string &message, Recognizer *recognizer, IntStream *input,
+ ParserRuleContext *ctx, Token *offendingToken = nullptr);
+ RecognitionException(RecognitionException const&) = default;
+ ~RecognitionException();
+ RecognitionException& operator=(RecognitionException const&) = default;
+
+ /// Get the ATN state number the parser was in at the time the error
+ /// occurred. For NoViableAltException and
+ /// LexerNoViableAltException exceptions, this is the
+ /// DecisionState number. For others, it is the state whose outgoing
+ /// edge we couldn't match.
+ ///
+ /// If the state number is not known, this method returns -1.
+ virtual size_t getOffendingState() const;
+
+ protected:
+ void setOffendingState(size_t offendingState);
+
+ /// Gets the set of input symbols which could potentially follow the
+ /// previously matched symbol at the time this exception was thrown.
+ ///
+ /// If the set of expected tokens is not known and could not be computed,
+ /// this method returns an empty set.
+ ///
+ /// @returns The set of token types that could potentially follow the current
+ /// state in the ATN, or an empty set if the information is not available.
+ public:
+ virtual misc::IntervalSet getExpectedTokens() const;
+
+ /// <summary>
+ /// Gets the <seealso cref="RuleContext"/> at the time this exception was thrown.
+ /// <p/>
+ /// If the context is not available, this method returns {@code null}.
+ /// </summary>
+ /// <returns> The <seealso cref="RuleContext"/> at the time this exception was thrown.
+ /// If the context is not available, this method returns {@code null}. </returns>
+ virtual RuleContext* getCtx() const;
+
+ /// <summary>
+ /// Gets the input stream which is the symbol source for the recognizer where
+ /// this exception was thrown.
+ /// <p/>
+ /// If the input stream is not available, this method returns {@code null}.
+ /// </summary>
+ /// <returns> The input stream which is the symbol source for the recognizer
+ /// where this exception was thrown, or {@code null} if the stream is not
+ /// available. </returns>
+ virtual IntStream* getInputStream() const;
+
+ virtual Token* getOffendingToken() const;
+
+ /// <summary>
+ /// Gets the <seealso cref="Recognizer"/> where this exception occurred.
+ /// <p/>
+ /// If the recognizer is not available, this method returns {@code null}.
+ /// </summary>
+ /// <returns> The recognizer where this exception occurred, or {@code null} if
+ /// the recognizer is not available. </returns>
+ virtual Recognizer* getRecognizer() const;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ProxyErrorListener.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC Recognizer {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t EOF = std::numeric_limits<size_t>::max();
+#else
+ enum : size_t {
+ EOF = static_cast<size_t>(-1), // std::numeric_limits<size_t>::max(); doesn't work in VS 2013.
+ };
+#endif
+
+ Recognizer();
+ Recognizer(Recognizer const&) = delete;
+ virtual ~Recognizer();
+
+ Recognizer& operator=(Recognizer const&) = delete;
+
+ /** Used to print out token names like ID during debugging and
+ * error reporting. The generated parsers implement a method
+ * that overrides this to point to their String[] tokenNames.
+ *
+ * @deprecated Use {@link #getVocabulary()} instead.
+ */
+ virtual std::vector<std::string> const& getTokenNames() const = 0;
+ virtual std::vector<std::string> const& getRuleNames() const = 0;
+
+ /**
+ * Get the vocabulary used by the recognizer.
+ *
+ * @return A {@link Vocabulary} instance providing information about the
+ * vocabulary used by the grammar.
+ */
+ virtual dfa::Vocabulary const& getVocabulary() const;
+
+ /// <summary>
+ /// Get a map from token names to token types.
+ /// <p/>
+ /// Used for XPath and tree pattern compilation.
+ /// </summary>
+ virtual std::map<std::string, size_t> getTokenTypeMap();
+
+ /// <summary>
+ /// Get a map from rule names to rule indexes.
+ /// <p/>
+ /// Used for XPath and tree pattern compilation.
+ /// </summary>
+ virtual std::map<std::string, size_t> getRuleIndexMap();
+
+ virtual size_t getTokenType(const std::string &tokenName);
+
+ /// <summary>
+ /// If this recognizer was generated, it will have a serialized ATN
+ /// representation of the grammar.
+ /// <p/>
+ /// For interpreters, we don't know their serialized ATN despite having
+ /// created the interpreter from it.
+ /// </summary>
+ virtual const std::vector<uint16_t> getSerializedATN() const {
+ throw "there is no serialized ATN";
+ }
+
+ /// <summary>
+ /// For debugging and other purposes, might want the grammar name.
+ /// Have ANTLR generate an implementation for this method.
+ /// </summary>
+ virtual std::string getGrammarFileName() const = 0;
+
+ /// Get the ATN interpreter (in fact one of it's descendants) used by the recognizer for prediction.
+ /// @returns The ATN interpreter used by the recognizer for prediction.
+ template <class T>
+ T* getInterpreter() const {
+ return dynamic_cast<T *>(_interpreter);
+ }
+
+ /**
+ * Set the ATN interpreter used by the recognizer for prediction.
+ *
+ * @param interpreter The ATN interpreter used by the recognizer for
+ * prediction.
+ */
+ void setInterpreter(atn::ATNSimulator *interpreter);
+
+ /// What is the error header, normally line/character position information?
+ virtual std::string getErrorHeader(RecognitionException *e);
+
+ /** How should a token be displayed in an error message? The default
+ * is to display just the text, but during development you might
+ * want to have a lot of information spit out. Override in that case
+ * to use t.toString() (which, for CommonToken, dumps everything about
+ * the token). This is better than forcing you to override a method in
+ * your token objects because you don't have to go modify your lexer
+ * so that it creates a new Java type.
+ *
+ * @deprecated This method is not called by the ANTLR 4 Runtime. Specific
+ * implementations of {@link ANTLRErrorStrategy} may provide a similar
+ * feature when necessary. For example, see
+ * {@link DefaultErrorStrategy#getTokenErrorDisplay}.
+ */
+ virtual std::string getTokenErrorDisplay(Token *t);
+
+ /// <exception cref="NullPointerException"> if {@code listener} is {@code null}. </exception>
+ virtual void addErrorListener(ANTLRErrorListener *listener);
+
+ virtual void removeErrorListener(ANTLRErrorListener *listener);
+
+ virtual void removeErrorListeners();
+
+ virtual ProxyErrorListener& getErrorListenerDispatch();
+
+ // subclass needs to override these if there are sempreds or actions
+ // that the ATN interp needs to execute
+ virtual bool sempred(RuleContext *localctx, size_t ruleIndex, size_t actionIndex);
+
+ virtual bool precpred(RuleContext *localctx, int precedence);
+
+ virtual void action(RuleContext *localctx, size_t ruleIndex, size_t actionIndex);
+
+ virtual size_t getState() const ;
+
+ // Get the ATN used by the recognizer for prediction.
+ virtual const atn::ATN& getATN() const = 0;
+
+ /// <summary>
+ /// Indicate that the recognizer has changed internal state that is
+ /// consistent with the ATN state passed in. This way we always know
+ /// where we are in the ATN as the parser goes along. The rule
+ /// context objects form a stack that lets us see the stack of
+ /// invoking rules. Combine this and we have complete ATN
+ /// configuration information.
+ /// </summary>
+ void setState(size_t atnState);
+
+ virtual IntStream* getInputStream() = 0;
+
+ virtual void setInputStream(IntStream *input) = 0;
+
+ virtual TokenFactory<CommonToken>* getTokenFactory() = 0;
+
+ template<typename T1>
+ void setTokenFactory(TokenFactory<T1> *input);
+
+ protected:
+ atn::ATNSimulator *_interpreter; // Set and deleted in descendants (or the profiler).
+
+ // Mutex to manage synchronized access for multithreading.
+ std::mutex _mutex;
+
+ private:
+ static std::map<const dfa::Vocabulary*, std::map<std::string, size_t>> _tokenTypeMapCache;
+ static std::map<std::vector<std::string>, std::map<std::string, size_t>> _ruleIndexMapCache;
+
+ ProxyErrorListener _proxListener; // Manages a collection of listeners.
+
+ size_t _stateNumber;
+
+ void InitializeInstanceFields();
+
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/ParseTree.h"
+
+namespace antlr4 {
+
+ /** A rule context is a record of a single rule invocation.
+ *
+ * We form a stack of these context objects using the parent
+ * pointer. A parent pointer of null indicates that the current
+ * context is the bottom of the stack. The ParserRuleContext subclass
+ * as a children list so that we can turn this data structure into a
+ * tree.
+ *
+ * The root node always has a null pointer and invokingState of -1.
+ *
+ * Upon entry to parsing, the first invoked rule function creates a
+ * context object (asubclass specialized for that rule such as
+ * SContext) and makes it the root of a parse tree, recorded by field
+ * Parser._ctx.
+ *
+ * public final SContext s() throws RecognitionException {
+ * SContext _localctx = new SContext(_ctx, getState()); <-- create new node
+ * enterRule(_localctx, 0, RULE_s); <-- push it
+ * ...
+ * exitRule(); <-- pop back to _localctx
+ * return _localctx;
+ * }
+ *
+ * A subsequent rule invocation of r from the start rule s pushes a
+ * new context object for r whose parent points at s and use invoking
+ * state is the state with r emanating as edge label.
+ *
+ * The invokingState fields from a context object to the root
+ * together form a stack of rule indication states where the root
+ * (bottom of the stack) has a -1 sentinel value. If we invoke start
+ * symbol s then call r1, which calls r2, the would look like
+ * this:
+ *
+ * SContext[-1] <- root node (bottom of the stack)
+ * R1Context[p] <- p in rule s called r1
+ * R2Context[q] <- q in rule r1 called r2
+ *
+ * So the top of the stack, _ctx, represents a call to the current
+ * rule and it holds the return address from another rule that invoke
+ * to this rule. To invoke a rule, we must always have a current context.
+ *
+ * The parent contexts are useful for computing lookahead sets and
+ * getting error information.
+ *
+ * These objects are used during parsing and prediction.
+ * For the special case of parsers, we use the subclass
+ * ParserRuleContext.
+ *
+ * @see ParserRuleContext
+ */
+ class ANTLR4CPP_PUBLIC RuleContext : public tree::ParseTree {
+ public:
+ /// What state invoked the rule associated with this context?
+ /// The "return address" is the followState of invokingState
+ /// If parent is null, this should be -1 and this context object represents the start rule.
+ size_t invokingState;
+
+ RuleContext();
+ RuleContext(RuleContext *parent, size_t invokingState);
+
+ virtual int depth();
+
+ /// A context is empty if there is no invoking state; meaning nobody called current context.
+ virtual bool isEmpty();
+
+ // satisfy the ParseTree / SyntaxTree interface
+
+ virtual misc::Interval getSourceInterval() override;
+
+ virtual std::string getText() override;
+
+ virtual size_t getRuleIndex() const;
+
+ /** For rule associated with this parse tree internal node, return
+ * the outer alternative number used to match the input. Default
+ * implementation does not compute nor store this alt num. Create
+ * a subclass of ParserRuleContext with backing field and set
+ * option contextSuperClass.
+ * to set it.
+ *
+ * @since 4.5.3
+ */
+ virtual size_t getAltNumber() const;
+
+ /** Set the outer alternative number for this context node. Default
+ * implementation does nothing to avoid backing field overhead for
+ * trees that don't need it. Create
+ * a subclass of ParserRuleContext with backing field and set
+ * option contextSuperClass.
+ *
+ * @since 4.5.3
+ */
+ virtual void setAltNumber(size_t altNumber);
+
+ virtual antlrcpp::Any accept(tree::ParseTreeVisitor *visitor) override;
+
+ /// <summary>
+ /// Print out a whole tree, not just a node, in LISP format
+ /// (root child1 .. childN). Print just a node if this is a leaf.
+ /// We have to know the recognizer so we can get rule names.
+ /// </summary>
+ virtual std::string toStringTree(Parser *recog, bool pretty = false) override;
+
+ /// <summary>
+ /// Print out a whole tree, not just a node, in LISP format
+ /// (root child1 .. childN). Print just a node if this is a leaf.
+ /// </summary>
+ virtual std::string toStringTree(std::vector<std::string> &ruleNames, bool pretty = false);
+
+ virtual std::string toStringTree(bool pretty = false) override;
+ virtual std::string toString() override;
+ std::string toString(Recognizer *recog);
+ std::string toString(const std::vector<std::string> &ruleNames);
+
+ // recog null unless ParserRuleContext, in which case we use subclass toString(...)
+ std::string toString(Recognizer *recog, RuleContext *stop);
+
+ virtual std::string toString(const std::vector<std::string> &ruleNames, RuleContext *stop);
+
+ bool operator == (const RuleContext &other) { return this == &other; } // Simple address comparison.
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "ParserRuleContext.h"
+
+namespace antlr4 {
+
+ /// A handy class for use with
+ ///
+ /// options {contextSuperClass=org.antlr.v4.runtime.RuleContextWithAltNum;}
+ ///
+ /// that provides a backing field / impl for the outer alternative number
+ /// matched for an internal parse tree node.
+ ///
+ /// I'm only putting into Java runtime as I'm certain I'm the only one that
+ /// will really every use this.
+ class ANTLR4CPP_PUBLIC RuleContextWithAltNum : public ParserRuleContext {
+ public:
+ size_t altNum = 0;
+
+ RuleContextWithAltNum();
+ RuleContextWithAltNum(ParserRuleContext *parent, int invokingStateNumber);
+
+ virtual size_t getAltNumber() const override;
+ virtual void setAltNumber(size_t altNum) override;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// This class provides access to the current version of the ANTLR 4 runtime
+ /// library as compile-time and runtime constants, along with methods for
+ /// checking for matching version numbers and notifying listeners in the case
+ /// where a version mismatch is detected.
+ ///
+ /// <para>
+ /// The runtime version information is provided by <seealso cref="#VERSION"/> and
+ /// <seealso cref="#getRuntimeVersion()"/>. Detailed information about these values is
+ /// provided in the documentation for each member.</para>
+ ///
+ /// <para>
+ /// The runtime version check is implemented by <seealso cref="#checkVersion"/>. Detailed
+ /// information about incorporating this call into user code, as well as its use
+ /// in generated code, is provided in the documentation for the method.</para>
+ ///
+ /// <para>
+ /// Version strings x.y and x.y.z are considered "compatible" and no error
+ /// would be generated. Likewise, version strings x.y-SNAPSHOT and x.y.z are
+ /// considered "compatible" because the major and minor components x.y
+ /// are the same in each.</para>
+ ///
+ /// <para>
+ /// To trap any error messages issued by this code, use System.setErr()
+ /// in your main() startup code.
+ /// </para>
+ ///
+ /// @since 4.3
+ /// </summary>
+ class ANTLR4CPP_PUBLIC RuntimeMetaData {
+ public:
+ /// A compile-time constant containing the current version of the ANTLR 4
+ /// runtime library.
+ ///
+ /// <para>
+ /// This compile-time constant value allows generated parsers and other
+ /// libraries to include a literal reference to the version of the ANTLR 4
+ /// runtime library the code was compiled against. At each release, we
+ /// change this value.</para>
+ ///
+ /// <para>Version numbers are assumed to have the form
+ ///
+ /// <em>major</em>.<em>minor</em>.<em>patch</em>.<em>revision</em>-<em>suffix</em>,
+ ///
+ /// with the individual components defined as follows.</para>
+ ///
+ /// <ul>
+ /// <li><em>major</em> is a required non-negative integer, and is equal to
+ /// {@code 4} for ANTLR 4.</li>
+ /// <li><em>minor</em> is a required non-negative integer.</li>
+ /// <li><em>patch</em> is an optional non-negative integer. When
+ /// <em>patch</em> is omitted, the {@code .} (dot) appearing before it is
+ /// also omitted.</li>
+ /// <li><em>revision</em> is an optional non-negative integer, and may only
+ /// be included when <em>patch</em> is also included. When <em>revision</em>
+ /// is omitted, the {@code .} (dot) appearing before it is also omitted.</li>
+ /// <li><em>suffix</em> is an optional string. When <em>suffix</em> is
+ /// omitted, the {@code -} (hyphen-minus) appearing before it is also
+ /// omitted.</li>
+ /// </ul>
+ static const std::string VERSION;
+
+ /// <summary>
+ /// Gets the currently executing version of the ANTLR 4 runtime library.
+ ///
+ /// <para>
+ /// This method provides runtime access to the <seealso cref="#VERSION"/> field, as
+ /// opposed to directly referencing the field as a compile-time constant.</para>
+ /// </summary>
+ /// <returns> The currently executing version of the ANTLR 4 library </returns>
+
+ static std::string getRuntimeVersion();
+
+ /// <summary>
+ /// This method provides the ability to detect mismatches between the version
+ /// of ANTLR 4 used to generate a parser, the version of the ANTLR runtime a
+ /// parser was compiled against, and the version of the ANTLR runtime which
+ /// is currently executing.
+ ///
+ /// <para>
+ /// The version check is designed to detect the following two specific
+ /// scenarios.</para>
+ ///
+ /// <ul>
+ /// <li>The ANTLR Tool version used for code generation does not match the
+ /// currently executing runtime version.</li>
+ /// <li>The ANTLR Runtime version referenced at the time a parser was
+ /// compiled does not match the currently executing runtime version.</li>
+ /// </ul>
+ ///
+ /// <para>
+ /// Starting with ANTLR 4.3, the code generator emits a call to this method
+ /// using two constants in each generated lexer and parser: a hard-coded
+ /// constant indicating the version of the tool used to generate the parser
+ /// and a reference to the compile-time constant <seealso cref="#VERSION"/>. At
+ /// runtime, this method is called during the initialization of the generated
+ /// parser to detect mismatched versions, and notify the registered listeners
+ /// prior to creating instances of the parser.</para>
+ ///
+ /// <para>
+ /// This method does not perform any detection or filtering of semantic
+ /// changes between tool and runtime versions. It simply checks for a
+ /// version match and emits an error to stderr if a difference
+ /// is detected.</para>
+ ///
+ /// <para>
+ /// Note that some breaking changes between releases could result in other
+ /// types of runtime exceptions, such as a <seealso cref="LinkageError"/>, prior to
+ /// calling this method. In these cases, the underlying version mismatch will
+ /// not be reported here. This method is primarily intended to
+ /// notify users of potential semantic changes between releases that do not
+ /// result in binary compatibility problems which would be detected by the
+ /// class loader. As with semantic changes, changes that break binary
+ /// compatibility between releases are mentioned in the release notes
+ /// accompanying the affected release.</para>
+ ///
+ /// <para>
+ /// <strong>Additional note for target developers:</strong> The version check
+ /// implemented by this class is designed to address specific compatibility
+ /// concerns that may arise during the execution of Java applications. Other
+ /// targets should consider the implementation of this method in the context
+ /// of that target's known execution environment, which may or may not
+ /// resemble the design provided for the Java target.</para>
+ /// </summary>
+ /// <param name="generatingToolVersion"> The version of the tool used to generate a parser.
+ /// This value may be null when called from user code that was not generated
+ /// by, and does not reference, the ANTLR 4 Tool itself. </param>
+ /// <param name="compileTimeVersion"> The version of the runtime the parser was
+ /// compiled against. This should always be passed using a direct reference
+ /// to <seealso cref="#VERSION"/>. </param>
+ static void checkVersion(const std::string &generatingToolVersion, const std::string &compileTimeVersion);
+
+ /// <summary>
+ /// Gets the major and minor version numbers from a version string. For
+ /// details about the syntax of the input {@code version}.
+ /// E.g., from x.y.z return x.y.
+ /// </summary>
+ /// <param name="version"> The complete version string. </param>
+ /// <returns> A string of the form <em>major</em>.<em>minor</em> containing
+ /// only the major and minor components of the version string. </returns>
+ static std::string getMajorMinorVersion(const std::string &version);
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "IntStream.h"
+
+namespace antlr4 {
+
+ /// A token has properties: text, type, line, character position in the line
+ /// (so we can ignore tabs), token channel, index, and source from which
+ /// we obtained this token.
+ class ANTLR4CPP_PUBLIC Token {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t INVALID_TYPE = 0;
+#else
+ enum : size_t {
+ INVALID_TYPE = 0,
+ };
+#endif
+
+ /// During lookahead operations, this "token" signifies we hit rule end ATN state
+ /// and did not follow it despite needing to.
+#if __cplusplus >= 201703L
+ static constexpr size_t EPSILON = std::numeric_limits<size_t>::max() - 1;
+ static constexpr size_t MIN_USER_TOKEN_TYPE = 1;
+ static constexpr size_t EOF = IntStream::EOF;
+#else
+ enum : size_t {
+ EPSILON = static_cast<size_t>(-2), // std::numeric_limits<size_t>::max() - 1; doesn't work in VS 2013
+ MIN_USER_TOKEN_TYPE = 1,
+ EOF = IntStream::EOF,
+ };
+#endif
+
+ virtual ~Token();
+
+ /// All tokens go to the parser (unless skip() is called in that rule)
+ /// on a particular "channel". The parser tunes to a particular channel
+ /// so that whitespace etc... can go to the parser on a "hidden" channel.
+#if __cplusplus >= 201703L
+ static constexpr size_t DEFAULT_CHANNEL = 0;
+#else
+ enum : size_t {
+ DEFAULT_CHANNEL = 0,
+ };
+#endif
+
+ /// Anything on different channel than DEFAULT_CHANNEL is not parsed
+ /// by parser.
+#if __cplusplus >= 201703L
+ static constexpr size_t HIDDEN_CHANNEL = 1;
+#else
+ enum : size_t {
+ HIDDEN_CHANNEL = 1,
+ };
+#endif
+
+ /**
+ * This is the minimum constant value which can be assigned to a
+ * user-defined token channel.
+ *
+ * <p>
+ * The non-negative numbers less than {@link #MIN_USER_CHANNEL_VALUE} are
+ * assigned to the predefined channels {@link #DEFAULT_CHANNEL} and
+ * {@link #HIDDEN_CHANNEL}.</p>
+ *
+ * @see Token#getChannel()
+ */
+#if __cplusplus >= 201703L
+ static constexpr size_t MIN_USER_CHANNEL_VALUE = 2;
+#else
+ enum : size_t {
+ MIN_USER_CHANNEL_VALUE = 2,
+ };
+#endif
+
+ /// Get the text of the token.
+ virtual std::string getText() const = 0;
+
+ /// Get the token type of the token
+ virtual size_t getType() const = 0;
+
+ /// The line number on which the 1st character of this token was matched, line=1..n
+ virtual size_t getLine() const = 0;
+
+ /// The index of the first character of this token relative to the
+ /// beginning of the line at which it occurs, 0..n-1
+ virtual size_t getCharPositionInLine() const = 0;
+
+ /// Return the channel this token. Each token can arrive at the parser
+ /// on a different channel, but the parser only "tunes" to a single channel.
+ /// The parser ignores everything not on DEFAULT_CHANNEL.
+ virtual size_t getChannel() const = 0;
+
+ /// An index from 0..n-1 of the token object in the input stream.
+ /// This must be valid in order to print token streams and
+ /// use TokenRewriteStream.
+ ///
+ /// Return INVALID_INDEX to indicate that this token was conjured up since
+ /// it doesn't have a valid index.
+ virtual size_t getTokenIndex() const = 0;
+
+ /// The starting character index of the token
+ /// This method is optional; return INVALID_INDEX if not implemented.
+ virtual size_t getStartIndex() const = 0;
+
+ /// The last character index of the token.
+ /// This method is optional; return INVALID_INDEX if not implemented.
+ virtual size_t getStopIndex() const = 0;
+
+ /// Gets the <seealso cref="TokenSource"/> which created this token.
+ virtual TokenSource *getTokenSource() const = 0;
+
+ /// Gets the <seealso cref="CharStream"/> from which this token was derived.
+ virtual CharStream *getInputStream() const = 0;
+
+ virtual std::string toString() const = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+
+ /// The default mechanism for creating tokens. It's used by default in Lexer and
+ /// the error handling strategy (to create missing tokens). Notifying the parser
+ /// of a new factory means that it notifies it's token source and error strategy.
+ template<typename Symbol>
+ class ANTLR4CPP_PUBLIC TokenFactory {
+ public:
+ virtual ~TokenFactory() {}
+
+ /// This is the method used to create tokens in the lexer and in the
+ /// error handling strategy. If text!=null, than the start and stop positions
+ /// are wiped to -1 in the text override is set in the CommonToken.
+ virtual std::unique_ptr<Symbol> create(std::pair<TokenSource *, CharStream *> source, size_t type, const std::string &text,
+ size_t channel, size_t start, size_t stop, size_t line, size_t charPositionInLine) = 0;
+
+ /// Generically useful
+ virtual std::unique_ptr<Symbol> create(size_t type, const std::string &text) = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "TokenFactory.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// A source of tokens must provide a sequence of tokens via <seealso cref="#nextToken()"/>
+ /// and also must reveal it's source of characters; <seealso cref="CommonToken"/>'s text is
+ /// computed from a <seealso cref="CharStream"/>; it only store indices into the char
+ /// stream.
+ /// <p/>
+ /// Errors from the lexer are never passed to the parser. Either you want to keep
+ /// going or you do not upon token recognition error. If you do not want to
+ /// continue lexing then you do not want to continue parsing. Just throw an
+ /// exception not under <seealso cref="RecognitionException"/> and Java will naturally toss
+ /// you all the way out of the recognizers. If you want to continue lexing then
+ /// you should not throw an exception to the parser--it has already requested a
+ /// token. Keep lexing until you get a valid one. Just report errors and keep
+ /// going, looking for a valid token.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TokenSource {
+ public:
+ virtual ~TokenSource();
+
+ /// Return a <seealso cref="Token"/> object from your input stream (usually a
+ /// <seealso cref="CharStream"/>). Do not fail/return upon lexing error; keep chewing
+ /// on the characters until you get a good one; errors are not passed through
+ /// to the parser.
+ virtual std::unique_ptr<Token> nextToken() = 0;
+
+ /// <summary>
+ /// Get the line number for the current position in the input stream. The
+ /// first line in the input is line 1.
+ /// </summary>
+ /// <returns> The line number for the current position in the input stream, or
+ /// 0 if the current token source does not track line numbers. </returns>
+ virtual size_t getLine() const = 0;
+
+ /// <summary>
+ /// Get the index into the current line for the current position in the input
+ /// stream. The first character on a line has position 0.
+ /// </summary>
+ /// <returns> The line number for the current position in the input stream, or
+ /// (sze_t)-1 if the current token source does not track character positions. </returns>
+ virtual size_t getCharPositionInLine() = 0;
+
+ /// <summary>
+ /// Get the <seealso cref="CharStream"/> from which this token source is currently
+ /// providing tokens.
+ /// </summary>
+ /// <returns> The <seealso cref="CharStream"/> associated with the current position in
+ /// the input, or {@code null} if no input stream is available for the token
+ /// source. </returns>
+ virtual CharStream* getInputStream() = 0;
+
+ /// <summary>
+ /// Gets the name of the underlying input source. This method returns a
+ /// non-null, non-empty string. If such a name is not known, this method
+ /// returns <seealso cref="IntStream#UNKNOWN_SOURCE_NAME"/>.
+ /// </summary>
+ virtual std::string getSourceName() = 0;
+
+ /// <summary>
+ /// Set the <seealso cref="TokenFactory"/> this token source should use for creating
+ /// <seealso cref="Token"/> objects from the input.
+ /// </summary>
+ /// <param name="factory"> The <seealso cref="TokenFactory"/> to use for creating tokens. </param>
+ template<typename T1>
+ void setTokenFactory(TokenFactory<T1> * /*factory*/) {}
+
+ /// <summary>
+ /// Gets the <seealso cref="TokenFactory"/> this token source is currently using for
+ /// creating <seealso cref="Token"/> objects from the input.
+ /// </summary>
+ /// <returns> The <seealso cref="TokenFactory"/> currently used by this token source. </returns>
+ virtual TokenFactory<CommonToken>* getTokenFactory() = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "IntStream.h"
+
+namespace antlr4 {
+
+ /// <summary>
+ /// An <seealso cref="IntStream"/> whose symbols are <seealso cref="Token"/> instances.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TokenStream : public IntStream {
+ /// <summary>
+ /// Get the <seealso cref="Token"/> instance associated with the value returned by
+ /// <seealso cref="#LA LA(k)"/>. This method has the same pre- and post-conditions as
+ /// <seealso cref="IntStream#LA"/>. In addition, when the preconditions of this method
+ /// are met, the return value is non-null and the value of
+ /// {@code LT(k).getType()==LA(k)}.
+ /// </summary>
+ /// <seealso cref= IntStream#LA </seealso>
+ public:
+ virtual ~TokenStream();
+
+ virtual Token* LT(ssize_t k) = 0;
+
+ /// <summary>
+ /// Gets the <seealso cref="Token"/> at the specified {@code index} in the stream. When
+ /// the preconditions of this method are met, the return value is non-null.
+ /// <p/>
+ /// The preconditions for this method are the same as the preconditions of
+ /// <seealso cref="IntStream#seek"/>. If the behavior of {@code seek(index)} is
+ /// unspecified for the current state and given {@code index}, then the
+ /// behavior of this method is also unspecified.
+ /// <p/>
+ /// The symbol referred to by {@code index} differs from {@code seek()} only
+ /// in the case of filtering streams where {@code index} lies before the end
+ /// of the stream. Unlike {@code seek()}, this method does not adjust
+ /// {@code index} to point to a non-ignored symbol.
+ /// </summary>
+ /// <exception cref="IllegalArgumentException"> if {code index} is less than 0 </exception>
+ /// <exception cref="UnsupportedOperationException"> if the stream does not support
+ /// retrieving the token at the specified index </exception>
+ virtual Token* get(size_t index) const = 0;
+
+ /// Gets the underlying TokenSource which provides tokens for this stream.
+ virtual TokenSource* getTokenSource() const = 0;
+
+ /// <summary>
+ /// Return the text of all tokens within the specified {@code interval}. This
+ /// method behaves like the following code (including potential exceptions
+ /// for violating preconditions of <seealso cref="#get"/>, but may be optimized by the
+ /// specific implementation.
+ ///
+ /// <pre>
+ /// TokenStream stream = ...;
+ /// String text = "";
+ /// for (int i = interval.a; i <= interval.b; i++) {
+ /// text += stream.get(i).getText();
+ /// }
+ /// </pre>
+ /// </summary>
+ /// <param name="interval"> The interval of tokens within this stream to get text
+ /// for. </param>
+ /// <returns> The text of all tokens within the specified interval in this
+ /// stream.
+ /// </returns>
+ /// <exception cref="NullPointerException"> if {@code interval} is {@code null} </exception>
+ virtual std::string getText(const misc::Interval &interval) = 0;
+
+ /// <summary>
+ /// Return the text of all tokens in the stream. This method behaves like the
+ /// following code, including potential exceptions from the calls to
+ /// <seealso cref="IntStream#size"/> and <seealso cref="#getText(Interval)"/>, but may be
+ /// optimized by the specific implementation.
+ ///
+ /// <pre>
+ /// TokenStream stream = ...;
+ /// String text = stream.getText(new Interval(0, stream.size()));
+ /// </pre>
+ /// </summary>
+ /// <returns> The text of all tokens in the stream. </returns>
+ virtual std::string getText() = 0;
+
+ /// <summary>
+ /// Return the text of all tokens in the source interval of the specified
+ /// context. This method behaves like the following code, including potential
+ /// exceptions from the call to <seealso cref="#getText(Interval)"/>, but may be
+ /// optimized by the specific implementation.
+ /// </p>
+ /// If {@code ctx.getSourceInterval()} does not return a valid interval of
+ /// tokens provided by this stream, the behavior is unspecified.
+ ///
+ /// <pre>
+ /// TokenStream stream = ...;
+ /// String text = stream.getText(ctx.getSourceInterval());
+ /// </pre>
+ /// </summary>
+ /// <param name="ctx"> The context providing the source interval of tokens to get
+ /// text for. </param>
+ /// <returns> The text of all tokens within the source interval of {@code ctx}. </returns>
+ virtual std::string getText(RuleContext *ctx) = 0;
+
+ /// <summary>
+ /// Return the text of all tokens in this stream between {@code start} and
+ /// {@code stop} (inclusive).
+ /// <p/>
+ /// If the specified {@code start} or {@code stop} token was not provided by
+ /// this stream, or if the {@code stop} occurred before the {@code start}
+ /// token, the behavior is unspecified.
+ /// <p/>
+ /// For streams which ensure that the <seealso cref="Token#getTokenIndex"/> method is
+ /// accurate for all of its provided tokens, this method behaves like the
+ /// following code. Other streams may implement this method in other ways
+ /// provided the behavior is consistent with this at a high level.
+ ///
+ /// <pre>
+ /// TokenStream stream = ...;
+ /// String text = "";
+ /// for (int i = start.getTokenIndex(); i <= stop.getTokenIndex(); i++) {
+ /// text += stream.get(i).getText();
+ /// }
+ /// </pre>
+ /// </summary>
+ /// <param name="start"> The first token in the interval to get text for. </param>
+ /// <param name="stop"> The last token in the interval to get text for (inclusive). </param>
+ /// <returns> The text of all tokens lying between the specified {@code start}
+ /// and {@code stop} tokens.
+ /// </returns>
+ /// <exception cref="UnsupportedOperationException"> if this stream does not support
+ /// this method for the specified tokens </exception>
+ virtual std::string getText(Token *start, Token *stop) = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+namespace antlr4 {
+
+ /**
+ * Useful for rewriting out a buffered input token stream after doing some
+ * augmentation or other manipulations on it.
+ *
+ * <p>
+ * You can insert stuff, replace, and delete chunks. Note that the operations
+ * are done lazily--only if you convert the buffer to a {@link String} with
+ * {@link TokenStream#getText()}. This is very efficient because you are not
+ * moving data around all the time. As the buffer of tokens is converted to
+ * strings, the {@link #getText()} method(s) scan the input token stream and
+ * check to see if there is an operation at the current index. If so, the
+ * operation is done and then normal {@link String} rendering continues on the
+ * buffer. This is like having multiple Turing machine instruction streams
+ * (programs) operating on a single input tape. :)</p>
+ *
+ * <p>
+ * This rewriter makes no modifications to the token stream. It does not ask the
+ * stream to fill itself up nor does it advance the input cursor. The token
+ * stream {@link TokenStream#index()} will return the same value before and
+ * after any {@link #getText()} call.</p>
+ *
+ * <p>
+ * The rewriter only works on tokens that you have in the buffer and ignores the
+ * current input cursor. If you are buffering tokens on-demand, calling
+ * {@link #getText()} halfway through the input will only do rewrites for those
+ * tokens in the first half of the file.</p>
+ *
+ * <p>
+ * Since the operations are done lazily at {@link #getText}-time, operations do
+ * not screw up the token index values. That is, an insert operation at token
+ * index {@code i} does not change the index values for tokens
+ * {@code i}+1..n-1.</p>
+ *
+ * <p>
+ * Because operations never actually alter the buffer, you may always get the
+ * original token stream back without undoing anything. Since the instructions
+ * are queued up, you can easily simulate transactions and roll back any changes
+ * if there is an error just by removing instructions. For example,</p>
+ *
+ * <pre>
+ * CharStream input = new ANTLRFileStream("input");
+ * TLexer lex = new TLexer(input);
+ * CommonTokenStream tokens = new CommonTokenStream(lex);
+ * T parser = new T(tokens);
+ * TokenStreamRewriter rewriter = new TokenStreamRewriter(tokens);
+ * parser.startRule();
+ * </pre>
+ *
+ * <p>
+ * Then in the rules, you can execute (assuming rewriter is visible):</p>
+ *
+ * <pre>
+ * Token t,u;
+ * ...
+ * rewriter.insertAfter(t, "text to put after t");}
+ * rewriter.insertAfter(u, "text after u");}
+ * System.out.println(rewriter.getText());
+ * </pre>
+ *
+ * <p>
+ * You can also have multiple "instruction streams" and get multiple rewrites
+ * from a single pass over the input. Just name the instruction streams and use
+ * that name again when printing the buffer. This could be useful for generating
+ * a C file and also its header file--all from the same buffer:</p>
+ *
+ * <pre>
+ * rewriter.insertAfter("pass1", t, "text to put after t");}
+ * rewriter.insertAfter("pass2", u, "text after u");}
+ * System.out.println(rewriter.getText("pass1"));
+ * System.out.println(rewriter.getText("pass2"));
+ * </pre>
+ *
+ * <p>
+ * If you don't use named rewrite streams, a "default" stream is used as the
+ * first example shows.</p>
+ */
+ class ANTLR4CPP_PUBLIC TokenStreamRewriter {
+ public:
+ static const std::string DEFAULT_PROGRAM_NAME;
+#if __cplusplus >= 201703L
+ static constexpr size_t PROGRAM_INIT_SIZE = 100;
+ static constexpr size_t MIN_TOKEN_INDEX = 0;
+#else
+ enum : size_t {
+ PROGRAM_INIT_SIZE = 100,
+ MIN_TOKEN_INDEX = 0,
+ };
+#endif
+
+ TokenStreamRewriter(TokenStream *tokens);
+ virtual ~TokenStreamRewriter();
+
+ TokenStream *getTokenStream();
+
+ virtual void rollback(size_t instructionIndex);
+
+ /// Rollback the instruction stream for a program so that
+ /// the indicated instruction (via instructionIndex) is no
+ /// longer in the stream. UNTESTED!
+ virtual void rollback(const std::string &programName, size_t instructionIndex);
+
+ virtual void deleteProgram();
+
+ /// Reset the program so that no instructions exist.
+ virtual void deleteProgram(const std::string &programName);
+ virtual void insertAfter(Token *t, const std::string& text);
+ virtual void insertAfter(size_t index, const std::string& text);
+ virtual void insertAfter(const std::string &programName, Token *t, const std::string& text);
+ virtual void insertAfter(const std::string &programName, size_t index, const std::string& text);
+
+ virtual void insertBefore(Token *t, const std::string& text);
+ virtual void insertBefore(size_t index, const std::string& text);
+ virtual void insertBefore(const std::string &programName, Token *t, const std::string& text);
+ virtual void insertBefore(const std::string &programName, size_t index, const std::string& text);
+
+ virtual void replace(size_t index, const std::string& text);
+ virtual void replace(size_t from, size_t to, const std::string& text);
+ virtual void replace(Token *indexT, const std::string& text);
+ virtual void replace(Token *from, Token *to, const std::string& text);
+ virtual void replace(const std::string &programName, size_t from, size_t to, const std::string& text);
+ virtual void replace(const std::string &programName, Token *from, Token *to, const std::string& text);
+
+ virtual void Delete(size_t index);
+ virtual void Delete(size_t from, size_t to);
+ virtual void Delete(Token *indexT);
+ virtual void Delete(Token *from, Token *to);
+ virtual void Delete(const std::string &programName, size_t from, size_t to);
+ virtual void Delete(const std::string &programName, Token *from, Token *to);
+
+ virtual size_t getLastRewriteTokenIndex();
+
+ /// Return the text from the original tokens altered per the
+ /// instructions given to this rewriter.
+ virtual std::string getText();
+
+ /** Return the text from the original tokens altered per the
+ * instructions given to this rewriter in programName.
+ */
+ std::string getText(std::string programName);
+
+ /// Return the text associated with the tokens in the interval from the
+ /// original token stream but with the alterations given to this rewriter.
+ /// The interval refers to the indexes in the original token stream.
+ /// We do not alter the token stream in any way, so the indexes
+ /// and intervals are still consistent. Includes any operations done
+ /// to the first and last token in the interval. So, if you did an
+ /// insertBefore on the first token, you would get that insertion.
+ /// The same is true if you do an insertAfter the stop token.
+ virtual std::string getText(const misc::Interval &interval);
+
+ virtual std::string getText(const std::string &programName, const misc::Interval &interval);
+
+ protected:
+ class RewriteOperation {
+ public:
+ /// What index into rewrites List are we?
+ size_t index;
+ std::string text;
+
+ /// Token buffer index.
+ size_t instructionIndex;
+
+ RewriteOperation(TokenStreamRewriter *outerInstance, size_t index);
+ RewriteOperation(TokenStreamRewriter *outerInstance, size_t index, const std::string& text);
+ virtual ~RewriteOperation();
+
+ /// Execute the rewrite operation by possibly adding to the buffer.
+ /// Return the index of the next token to operate on.
+
+ virtual size_t execute(std::string *buf);
+ virtual std::string toString();
+
+ private:
+ TokenStreamRewriter *const outerInstance;
+ void InitializeInstanceFields();
+ };
+
+ class InsertBeforeOp : public RewriteOperation {
+ private:
+ TokenStreamRewriter *const outerInstance;
+
+ public:
+ InsertBeforeOp(TokenStreamRewriter *outerInstance, size_t index, const std::string& text);
+
+ virtual size_t execute(std::string *buf) override;
+ };
+
+ class ReplaceOp : public RewriteOperation {
+ private:
+ TokenStreamRewriter *const outerInstance;
+
+ public:
+ size_t lastIndex;
+
+ ReplaceOp(TokenStreamRewriter *outerInstance, size_t from, size_t to, const std::string& text);
+ virtual size_t execute(std::string *buf) override;
+ virtual std::string toString() override;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+ /// Our source stream
+ TokenStream *const tokens;
+
+ /// You may have multiple, named streams of rewrite operations.
+ /// I'm calling these things "programs."
+ /// Maps String (name) -> rewrite (List)
+ std::map<std::string, std::vector<RewriteOperation*>> _programs;
+
+ /// <summary>
+ /// Map String (program name) -> Integer index </summary>
+ std::map<std::string, size_t> _lastRewriteTokenIndexes;
+ virtual size_t getLastRewriteTokenIndex(const std::string &programName);
+ virtual void setLastRewriteTokenIndex(const std::string &programName, size_t i);
+ virtual std::vector<RewriteOperation*>& getProgram(const std::string &name);
+
+ /// <summary>
+ /// We need to combine operations and report invalid operations (like
+ /// overlapping replaces that are not completed nested). Inserts to
+ /// same index need to be combined etc... Here are the cases:
+ ///
+ /// I.i.u I.j.v leave alone, nonoverlapping
+ /// I.i.u I.i.v combine: Iivu
+ ///
+ /// R.i-j.u R.x-y.v | i-j in x-y delete first R
+ /// R.i-j.u R.i-j.v delete first R
+ /// R.i-j.u R.x-y.v | x-y in i-j ERROR
+ /// R.i-j.u R.x-y.v | boundaries overlap ERROR
+ ///
+ /// Delete special case of replace (text==null):
+ /// D.i-j.u D.x-y.v | boundaries overlap combine to max(min)..max(right)
+ ///
+ /// I.i.u R.x-y.v | i in (x+1)-y delete I (since insert before
+ /// we're not deleting i)
+ /// I.i.u R.x-y.v | i not in (x+1)-y leave alone, nonoverlapping
+ /// R.x-y.v I.i.u | i in x-y ERROR
+ /// R.x-y.v I.x.u R.x-y.uv (combine, delete I)
+ /// R.x-y.v I.i.u | i not in x-y leave alone, nonoverlapping
+ ///
+ /// I.i.u = insert u before op @ index i
+ /// R.x-y.u = replace x-y indexed tokens with u
+ ///
+ /// First we need to examine replaces. For any replace op:
+ ///
+ /// 1. wipe out any insertions before op within that range.
+ /// 2. Drop any replace op before that is contained completely within
+ /// that range.
+ /// 3. Throw exception upon boundary overlap with any previous replace.
+ ///
+ /// Then we can deal with inserts:
+ ///
+ /// 1. for any inserts to same index, combine even if not adjacent.
+ /// 2. for any prior replace with same left boundary, combine this
+ /// insert with replace and delete this replace.
+ /// 3. throw exception if index in same range as previous replace
+ ///
+ /// Don't actually delete; make op null in list. Easier to walk list.
+ /// Later we can throw as we add to index -> op map.
+ ///
+ /// Note that I.2 R.2-2 will wipe out I.2 even though, technically, the
+ /// inserted stuff would be before the replace range. But, if you
+ /// add tokens in front of a method body '{' and then delete the method
+ /// body, I think the stuff before the '{' you added should disappear too.
+ ///
+ /// Return a map from token index to operation.
+ /// </summary>
+ virtual std::unordered_map<size_t, RewriteOperation*> reduceToSingleOperationPerIndex(std::vector<RewriteOperation*> &rewrites);
+
+ virtual std::string catOpText(std::string *a, std::string *b);
+
+ /// Get all operations before an index of a particular kind.
+ template <typename T>
+ std::vector<T *> getKindOfOps(std::vector<RewriteOperation *> rewrites, size_t before) {
+ std::vector<T *> ops;
+ for (size_t i = 0; i < before && i < rewrites.size(); i++) {
+ T *op = dynamic_cast<T *>(rewrites[i]);
+ if (op == nullptr) { // ignore deleted or non matching entries
+ continue;
+ }
+ ops.push_back(op);
+ }
+ return ops;
+ }
+
+ private:
+ std::vector<RewriteOperation *>& initializeProgram(const std::string &name);
+
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "CharStream.h"
+
+namespace antlr4 {
+
+ /// Do not buffer up the entire char stream. It does keep a small buffer
+ /// for efficiency and also buffers while a mark exists (set by the
+ /// lookahead prediction in parser). "Unbuffered" here refers to fact
+ /// that it doesn't buffer all data, not that's it's on demand loading of char.
+ class ANTLR4CPP_PUBLIC UnbufferedCharStream : public CharStream {
+ public:
+ /// The name or source of this char stream.
+ std::string name;
+
+ UnbufferedCharStream(std::wistream &input);
+
+ virtual void consume() override;
+ virtual size_t LA(ssize_t i) override;
+
+ /// <summary>
+ /// Return a marker that we can release later.
+ /// <p/>
+ /// The specific marker value used for this class allows for some level of
+ /// protection against misuse where {@code seek()} is called on a mark or
+ /// {@code release()} is called in the wrong order.
+ /// </summary>
+ virtual ssize_t mark() override;
+
+ /// <summary>
+ /// Decrement number of markers, resetting buffer if we hit 0. </summary>
+ /// <param name="marker"> </param>
+ virtual void release(ssize_t marker) override;
+ virtual size_t index() override;
+
+ /// <summary>
+ /// Seek to absolute character index, which might not be in the current
+ /// sliding window. Move {@code p} to {@code index-bufferStartIndex}.
+ /// </summary>
+ virtual void seek(size_t index) override;
+ virtual size_t size() override;
+ virtual std::string getSourceName() const override;
+ virtual std::string getText(const misc::Interval &interval) override;
+
+ protected:
+ /// A moving window buffer of the data being scanned. While there's a marker,
+ /// we keep adding to buffer. Otherwise, <seealso cref="#consume consume()"/> resets so
+ /// we start filling at index 0 again.
+ // UTF-32 encoded.
+#if defined(_MSC_VER) && _MSC_VER == 1900
+ i32string _data; // Custom type for VS 2015.
+ typedef __int32 storage_type;
+#else
+ std::u32string _data;
+ typedef char32_t storage_type;
+#endif
+
+ /// <summary>
+ /// 0..n-1 index into <seealso cref="#data data"/> of next character.
+ /// <p/>
+ /// The {@code LA(1)} character is {@code data[p]}. If {@code p == n}, we are
+ /// out of buffered characters.
+ /// </summary>
+ size_t _p;
+
+ /// <summary>
+ /// Count up with <seealso cref="#mark mark()"/> and down with
+ /// <seealso cref="#release release()"/>. When we {@code release()} the last mark,
+ /// {@code numMarkers} reaches 0 and we reset the buffer. Copy
+ /// {@code data[p]..data[n-1]} to {@code data[0]..data[(n-1)-p]}.
+ /// </summary>
+ size_t _numMarkers;
+
+ /// This is the {@code LA(-1)} character for the current position.
+ size_t _lastChar; // UTF-32
+
+ /// <summary>
+ /// When {@code numMarkers > 0}, this is the {@code LA(-1)} character for the
+ /// first character in <seealso cref="#data data"/>. Otherwise, this is unspecified.
+ /// </summary>
+ size_t _lastCharBufferStart; // UTF-32
+
+ /// <summary>
+ /// Absolute character index. It's the index of the character about to be
+ /// read via {@code LA(1)}. Goes from 0 to the number of characters in the
+ /// entire stream, although the stream size is unknown before the end is
+ /// reached.
+ /// </summary>
+ size_t _currentCharIndex;
+
+ std::wistream &_input;
+
+ /// <summary>
+ /// Make sure we have 'want' elements from current position <seealso cref="#p p"/>.
+ /// Last valid {@code p} index is {@code data.length-1}. {@code p+need-1} is
+ /// the char index 'need' elements ahead. If we need 1 element,
+ /// {@code (p+1-1)==p} must be less than {@code data.length}.
+ /// </summary>
+ virtual void sync(size_t want);
+
+ /// <summary>
+ /// Add {@code n} characters to the buffer. Returns the number of characters
+ /// actually added to the buffer. If the return value is less than {@code n},
+ /// then EOF was reached before {@code n} characters could be added.
+ /// </summary>
+ virtual size_t fill(size_t n);
+
+ /// Override to provide different source of characters than
+ /// <seealso cref="#input input"/>.
+ virtual char32_t nextChar();
+ virtual void add(char32_t c);
+ size_t getBufferStartIndex() const;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "TokenStream.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC UnbufferedTokenStream : public TokenStream {
+ public:
+ UnbufferedTokenStream(TokenSource *tokenSource);
+ UnbufferedTokenStream(TokenSource *tokenSource, int bufferSize);
+ UnbufferedTokenStream(const UnbufferedTokenStream& other) = delete;
+ virtual ~UnbufferedTokenStream();
+
+ UnbufferedTokenStream& operator = (const UnbufferedTokenStream& other) = delete;
+
+ virtual Token* get(size_t i) const override;
+ virtual Token* LT(ssize_t i) override;
+ virtual size_t LA(ssize_t i) override;
+
+ virtual TokenSource* getTokenSource() const override;
+
+ virtual std::string getText(const misc::Interval &interval) override;
+ virtual std::string getText() override;
+ virtual std::string getText(RuleContext *ctx) override;
+ virtual std::string getText(Token *start, Token *stop) override;
+
+ virtual void consume() override;
+
+ /// <summary>
+ /// Return a marker that we can release later.
+ /// <p/>
+ /// The specific marker value used for this class allows for some level of
+ /// protection against misuse where {@code seek()} is called on a mark or
+ /// {@code release()} is called in the wrong order.
+ /// </summary>
+ virtual ssize_t mark() override;
+ virtual void release(ssize_t marker) override;
+ virtual size_t index() override;
+ virtual void seek(size_t index) override;
+ virtual size_t size() override;
+ virtual std::string getSourceName() const override;
+
+ protected:
+ /// Make sure we have 'need' elements from current position p. Last valid
+ /// p index is tokens.length - 1. p + need - 1 is the tokens index 'need' elements
+ /// ahead. If we need 1 element, (p+1-1)==p must be less than tokens.length.
+ TokenSource *_tokenSource;
+
+ /// <summary>
+ /// A moving window buffer of the data being scanned. While there's a marker,
+ /// we keep adding to buffer. Otherwise, <seealso cref="#consume consume()"/> resets so
+ /// we start filling at index 0 again.
+ /// </summary>
+
+ std::vector<std::unique_ptr<Token>> _tokens;
+
+ /// <summary>
+ /// 0..n-1 index into <seealso cref="#tokens tokens"/> of next token.
+ /// <p/>
+ /// The {@code LT(1)} token is {@code tokens[p]}. If {@code p == n}, we are
+ /// out of buffered tokens.
+ /// </summary>
+ size_t _p;
+
+ /// <summary>
+ /// Count up with <seealso cref="#mark mark()"/> and down with
+ /// <seealso cref="#release release()"/>. When we {@code release()} the last mark,
+ /// {@code numMarkers} reaches 0 and we reset the buffer. Copy
+ /// {@code tokens[p]..tokens[n-1]} to {@code tokens[0]..tokens[(n-1)-p]}.
+ /// </summary>
+ int _numMarkers;
+
+ /// <summary>
+ /// This is the {@code LT(-1)} token for the current position.
+ /// </summary>
+ Token *_lastToken;
+
+ /// <summary>
+ /// When {@code numMarkers > 0}, this is the {@code LT(-1)} token for the
+ /// first token in <seealso cref="#tokens"/>. Otherwise, this is {@code null}.
+ /// </summary>
+ Token *_lastTokenBufferStart;
+
+ /// <summary>
+ /// Absolute token index. It's the index of the token about to be read via
+ /// {@code LT(1)}. Goes from 0 to the number of tokens in the entire stream,
+ /// although the stream size is unknown before the end is reached.
+ /// <p/>
+ /// This value is used to set the token indexes if the stream provides tokens
+ /// that implement <seealso cref="WritableToken"/>.
+ /// </summary>
+ size_t _currentTokenIndex;
+
+ virtual void sync(ssize_t want);
+
+ /// <summary>
+ /// Add {@code n} elements to the buffer. Returns the number of tokens
+ /// actually added to the buffer. If the return value is less than {@code n},
+ /// then EOF was reached before {@code n} tokens could be added.
+ /// </summary>
+ virtual size_t fill(size_t n);
+ virtual void add(std::unique_ptr<Token> t);
+
+ size_t getBufferStartIndex() const;
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace dfa {
+
+ /// This class provides a default implementation of the <seealso cref="Vocabulary"/>
+ /// interface.
+ class ANTLR4CPP_PUBLIC Vocabulary {
+ public:
+ /// Gets an empty <seealso cref="Vocabulary"/> instance.
+ ///
+ /// <para>
+ /// No literal or symbol names are assigned to token types, so
+ /// <seealso cref="#getDisplayName(int)"/> returns the numeric value for all tokens
+ /// except <seealso cref="Token#EOF"/>.</para>
+ static const Vocabulary EMPTY_VOCABULARY;
+
+ Vocabulary() {}
+ Vocabulary(Vocabulary const&) = default;
+ virtual ~Vocabulary();
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="Vocabulary"/> from the specified
+ /// literal and symbolic token names.
+ /// </summary>
+ /// <param name="literalNames"> The literal names assigned to tokens, or {@code null}
+ /// if no literal names are assigned. </param>
+ /// <param name="symbolicNames"> The symbolic names assigned to tokens, or
+ /// {@code null} if no symbolic names are assigned.
+ /// </param>
+ /// <seealso cref= #getLiteralName(int) </seealso>
+ /// <seealso cref= #getSymbolicName(int) </seealso>
+ Vocabulary(const std::vector<std::string> &literalNames, const std::vector<std::string> &symbolicNames);
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="Vocabulary"/> from the specified
+ /// literal, symbolic, and display token names.
+ /// </summary>
+ /// <param name="literalNames"> The literal names assigned to tokens, or {@code null}
+ /// if no literal names are assigned. </param>
+ /// <param name="symbolicNames"> The symbolic names assigned to tokens, or
+ /// {@code null} if no symbolic names are assigned. </param>
+ /// <param name="displayNames"> The display names assigned to tokens, or {@code null}
+ /// to use the values in {@code literalNames} and {@code symbolicNames} as
+ /// the source of display names, as described in
+ /// <seealso cref="#getDisplayName(int)"/>.
+ /// </param>
+ /// <seealso cref= #getLiteralName(int) </seealso>
+ /// <seealso cref= #getSymbolicName(int) </seealso>
+ /// <seealso cref= #getDisplayName(int) </seealso>
+ Vocabulary(const std::vector<std::string> &literalNames, const std::vector<std::string> &symbolicNames,
+ const std::vector<std::string> &displayNames);
+
+ /// <summary>
+ /// Returns a <seealso cref="Vocabulary"/> instance from the specified set of token
+ /// names. This method acts as a compatibility layer for the single
+ /// {@code tokenNames} array generated by previous releases of ANTLR.
+ ///
+ /// <para>The resulting vocabulary instance returns {@code null} for
+ /// <seealso cref="#getLiteralName(int)"/> and <seealso cref="#getSymbolicName(int)"/>, and the
+ /// value from {@code tokenNames} for the display names.</para>
+ /// </summary>
+ /// <param name="tokenNames"> The token names, or {@code null} if no token names are
+ /// available. </param>
+ /// <returns> A <seealso cref="Vocabulary"/> instance which uses {@code tokenNames} for
+ /// the display names of tokens. </returns>
+ static Vocabulary fromTokenNames(const std::vector<std::string> &tokenNames);
+
+ /// <summary>
+ /// Returns the highest token type value. It can be used to iterate from
+ /// zero to that number, inclusively, thus querying all stored entries. </summary>
+ /// <returns> the highest token type value </returns>
+ virtual size_t getMaxTokenType() const;
+
+ /// <summary>
+ /// Gets the string literal associated with a token type. The string returned
+ /// by this method, when not {@code null}, can be used unaltered in a parser
+ /// grammar to represent this token type.
+ ///
+ /// <para>The following table shows examples of lexer rules and the literal
+ /// names assigned to the corresponding token types.</para>
+ ///
+ /// <table>
+ /// <tr>
+ /// <th>Rule</th>
+ /// <th>Literal Name</th>
+ /// <th>Java String Literal</th>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code THIS : 'this';}</td>
+ /// <td>{@code 'this'}</td>
+ /// <td>{@code "'this'"}</td>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code SQUOTE : '\'';}</td>
+ /// <td>{@code '\''}</td>
+ /// <td>{@code "'\\''"}</td>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code ID : [A-Z]+;}</td>
+ /// <td>n/a</td>
+ /// <td>{@code null}</td>
+ /// </tr>
+ /// </table>
+ /// </summary>
+ /// <param name="tokenType"> The token type.
+ /// </param>
+ /// <returns> The string literal associated with the specified token type, or
+ /// {@code null} if no string literal is associated with the type. </returns>
+ virtual std::string getLiteralName(size_t tokenType) const;
+
+ /// <summary>
+ /// Gets the symbolic name associated with a token type. The string returned
+ /// by this method, when not {@code null}, can be used unaltered in a parser
+ /// grammar to represent this token type.
+ ///
+ /// <para>This method supports token types defined by any of the following
+ /// methods:</para>
+ ///
+ /// <ul>
+ /// <li>Tokens created by lexer rules.</li>
+ /// <li>Tokens defined in a <code>tokens{}</code> block in a lexer or parser
+ /// grammar.</li>
+ /// <li>The implicitly defined {@code EOF} token, which has the token type
+ /// <seealso cref="Token#EOF"/>.</li>
+ /// </ul>
+ ///
+ /// <para>The following table shows examples of lexer rules and the literal
+ /// names assigned to the corresponding token types.</para>
+ ///
+ /// <table>
+ /// <tr>
+ /// <th>Rule</th>
+ /// <th>Symbolic Name</th>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code THIS : 'this';}</td>
+ /// <td>{@code THIS}</td>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code SQUOTE : '\'';}</td>
+ /// <td>{@code SQUOTE}</td>
+ /// </tr>
+ /// <tr>
+ /// <td>{@code ID : [A-Z]+;}</td>
+ /// <td>{@code ID}</td>
+ /// </tr>
+ /// </table>
+ /// </summary>
+ /// <param name="tokenType"> The token type.
+ /// </param>
+ /// <returns> The symbolic name associated with the specified token type, or
+ /// {@code null} if no symbolic name is associated with the type. </returns>
+ virtual std::string getSymbolicName(size_t tokenType) const;
+
+ /// <summary>
+ /// Gets the display name of a token type.
+ ///
+ /// <para>ANTLR provides a default implementation of this method, but
+ /// applications are free to override the behavior in any manner which makes
+ /// sense for the application. The default implementation returns the first
+ /// result from the following list which produces a non-{@code null}
+ /// result.</para>
+ ///
+ /// <ol>
+ /// <li>The result of <seealso cref="#getLiteralName"/></li>
+ /// <li>The result of <seealso cref="#getSymbolicName"/></li>
+ /// <li>The result of <seealso cref="Integer#toString"/></li>
+ /// </ol>
+ /// </summary>
+ /// <param name="tokenType"> The token type.
+ /// </param>
+ /// <returns> The display name of the token type, for use in error reporting or
+ /// other user-visible messages which reference specific token types. </returns>
+ virtual std::string getDisplayName(size_t tokenType) const;
+
+ private:
+ std::vector<std::string> const _literalNames;
+ std::vector<std::string> const _symbolicNames;
+ std::vector<std::string> const _displayNames;
+ const size_t _maxTokenType = 0;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Token.h"
+
+namespace antlr4 {
+
+ class ANTLR4CPP_PUBLIC WritableToken : public Token {
+ public:
+ virtual ~WritableToken();
+ virtual void setText(const std::string &text) = 0;
+ virtual void setType(size_t ttype) = 0;
+ virtual void setLine(size_t line) = 0;
+ virtual void setCharPositionInLine(size_t pos) = 0;
+ virtual void setChannel(size_t channel) = 0;
+ virtual void setTokenIndex(size_t index) = 0;
+ };
+
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include <algorithm>
+#include <assert.h>
+#include <atomic>
+#include <chrono>
+#include <fstream>
+#include <iostream>
+#include <iterator>
+#include <limits>
+#include <limits.h>
+#include <list>
+#include <map>
+#include <memory>
+#include <set>
+#include <stdarg.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sstream>
+#include <stack>
+#include <string>
+#include <typeinfo>
+#include <type_traits>
+#include <unordered_map>
+#include <unordered_set>
+#include <utility>
+#include <vector>
+#include <mutex>
+#include <exception>
+#include <bitset>
+#include <condition_variable>
+#include <functional>
+
+#ifndef USE_UTF8_INSTEAD_OF_CODECVT
+ #include <codecvt>
+#endif
+
+// Defines for the Guid class and other platform dependent stuff.
+#ifdef _WIN32
+ #ifdef _MSC_VER
+ #pragma warning (disable: 4250) // Class inherits by dominance.
+ #pragma warning (disable: 4512) // assignment operator could not be generated
+
+ #if _MSC_VER < 1900
+ // Before VS 2015 code like "while (true)" will create a (useless) warning in level 4.
+ #pragma warning (disable: 4127) // conditional expression is constant
+ #endif
+ #endif
+
+ #define GUID_WINDOWS
+
+ #ifdef _WIN64
+ typedef __int64 ssize_t;
+ #else
+ typedef __int32 ssize_t;
+ #endif
+
+ #if _MSC_VER >= 1900 && _MSC_VER < 2000
+ // VS 2015 has a known bug when using std::codecvt_utf8<char32_t>
+ // so we have to temporarily use __int32 instead.
+ // https://connect.microsoft.com/VisualStudio/feedback/details/1403302/unresolved-external-when-using-codecvt-utf8
+ typedef std::basic_string<__int32> i32string;
+
+ typedef i32string UTF32String;
+ #else
+ typedef std::u32string UTF32String;
+ #endif
+
+ #ifdef ANTLR4CPP_EXPORTS
+ #define ANTLR4CPP_PUBLIC __declspec(dllexport)
+ #else
+ #ifdef ANTLR4CPP_STATIC
+ #define ANTLR4CPP_PUBLIC
+ #else
+ #define ANTLR4CPP_PUBLIC __declspec(dllimport)
+ #endif
+ #endif
+
+ #if defined(_MSC_VER) && !defined(__clang__)
+ // clang-cl should escape this to prevent [ignored-attributes].
+ namespace std {
+ class ANTLR4CPP_PUBLIC exception; // Prevents warning C4275 from MSVC.
+ } // namespace std
+ #endif
+
+#elif defined(__APPLE__)
+ typedef std::u32string UTF32String;
+
+ #define GUID_CFUUID
+ #if __GNUC__ >= 4
+ #define ANTLR4CPP_PUBLIC __attribute__ ((visibility ("default")))
+ #else
+ #define ANTLR4CPP_PUBLIC
+ #endif
+#else
+ typedef std::u32string UTF32String;
+
+ #define GUID_LIBUUID
+ #if __GNUC__ >= 6
+ #define ANTLR4CPP_PUBLIC __attribute__ ((visibility ("default")))
+ #else
+ #define ANTLR4CPP_PUBLIC
+ #endif
+#endif
+
+#include "support/guid.h"
+#include "support/Declarations.h"
+
+#if !defined(HAS_NOEXCEPT)
+ #if defined(__clang__)
+ #if __has_feature(cxx_noexcept)
+ #define HAS_NOEXCEPT
+ #endif
+ #else
+ #if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
+ defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
+ #define HAS_NOEXCEPT
+ #endif
+ #endif
+
+ #ifdef HAS_NOEXCEPT
+ #define NOEXCEPT noexcept
+ #else
+ #define NOEXCEPT
+ #endif
+#endif
+
+// We have to undefine this symbol as ANTLR will use this name for own members and even
+// generated functions. Because EOF is a global macro we cannot use e.g. a namespace scope to disambiguate.
+#ifdef EOF
+#undef EOF
+#endif
+
+#define INVALID_INDEX std::numeric_limits<size_t>::max()
+template<class T> using Ref = std::shared_ptr<T>;
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+// This is the umbrella header for all ANTLR4 C++ runtime headers.
+
+#include "antlr4-common.h"
+
+#include "ANTLRErrorListener.h"
+#include "ANTLRErrorStrategy.h"
+#include "ANTLRFileStream.h"
+#include "ANTLRInputStream.h"
+#include "BailErrorStrategy.h"
+#include "BaseErrorListener.h"
+#include "BufferedTokenStream.h"
+#include "CharStream.h"
+#include "CommonToken.h"
+#include "CommonTokenFactory.h"
+#include "CommonTokenStream.h"
+#include "ConsoleErrorListener.h"
+#include "DefaultErrorStrategy.h"
+#include "DiagnosticErrorListener.h"
+#include "Exceptions.h"
+#include "FailedPredicateException.h"
+#include "InputMismatchException.h"
+#include "IntStream.h"
+#include "InterpreterRuleContext.h"
+#include "Lexer.h"
+#include "LexerInterpreter.h"
+#include "LexerNoViableAltException.h"
+#include "ListTokenSource.h"
+#include "NoViableAltException.h"
+#include "Parser.h"
+#include "ParserInterpreter.h"
+#include "ParserRuleContext.h"
+#include "ProxyErrorListener.h"
+#include "RecognitionException.h"
+#include "Recognizer.h"
+#include "RuleContext.h"
+#include "RuleContextWithAltNum.h"
+#include "RuntimeMetaData.h"
+#include "Token.h"
+#include "TokenFactory.h"
+#include "TokenSource.h"
+#include "TokenStream.h"
+#include "TokenStreamRewriter.h"
+#include "UnbufferedCharStream.h"
+#include "UnbufferedTokenStream.h"
+#include "Vocabulary.h"
+#include "Vocabulary.h"
+#include "WritableToken.h"
+#include "atn/ATN.h"
+#include "atn/ATNConfig.h"
+#include "atn/ATNConfigSet.h"
+#include "atn/ATNDeserializationOptions.h"
+#include "atn/ATNDeserializer.h"
+#include "atn/ATNSerializer.h"
+#include "atn/ATNSimulator.h"
+#include "atn/ATNState.h"
+#include "atn/ATNType.h"
+#include "atn/AbstractPredicateTransition.h"
+#include "atn/ActionTransition.h"
+#include "atn/AmbiguityInfo.h"
+#include "atn/ArrayPredictionContext.h"
+#include "atn/AtomTransition.h"
+#include "atn/BasicBlockStartState.h"
+#include "atn/BasicState.h"
+#include "atn/BlockEndState.h"
+#include "atn/BlockStartState.h"
+#include "atn/ContextSensitivityInfo.h"
+#include "atn/DecisionEventInfo.h"
+#include "atn/DecisionInfo.h"
+#include "atn/DecisionState.h"
+#include "atn/EmptyPredictionContext.h"
+#include "atn/EpsilonTransition.h"
+#include "atn/ErrorInfo.h"
+#include "atn/LL1Analyzer.h"
+#include "atn/LexerATNConfig.h"
+#include "atn/LexerATNSimulator.h"
+#include "atn/LexerAction.h"
+#include "atn/LexerActionExecutor.h"
+#include "atn/LexerActionType.h"
+#include "atn/LexerChannelAction.h"
+#include "atn/LexerCustomAction.h"
+#include "atn/LexerIndexedCustomAction.h"
+#include "atn/LexerModeAction.h"
+#include "atn/LexerMoreAction.h"
+#include "atn/LexerPopModeAction.h"
+#include "atn/LexerPushModeAction.h"
+#include "atn/LexerSkipAction.h"
+#include "atn/LexerTypeAction.h"
+#include "atn/LookaheadEventInfo.h"
+#include "atn/LoopEndState.h"
+#include "atn/NotSetTransition.h"
+#include "atn/OrderedATNConfigSet.h"
+#include "atn/ParseInfo.h"
+#include "atn/ParserATNSimulator.h"
+#include "atn/PlusBlockStartState.h"
+#include "atn/PlusLoopbackState.h"
+#include "atn/PrecedencePredicateTransition.h"
+#include "atn/PredicateEvalInfo.h"
+#include "atn/PredicateTransition.h"
+#include "atn/PredictionContext.h"
+#include "atn/PredictionMode.h"
+#include "atn/ProfilingATNSimulator.h"
+#include "atn/RangeTransition.h"
+#include "atn/RuleStartState.h"
+#include "atn/RuleStopState.h"
+#include "atn/RuleTransition.h"
+#include "atn/SemanticContext.h"
+#include "atn/SetTransition.h"
+#include "atn/SingletonPredictionContext.h"
+#include "atn/StarBlockStartState.h"
+#include "atn/StarLoopEntryState.h"
+#include "atn/StarLoopbackState.h"
+#include "atn/TokensStartState.h"
+#include "atn/Transition.h"
+#include "atn/WildcardTransition.h"
+#include "dfa/DFA.h"
+#include "dfa/DFASerializer.h"
+#include "dfa/DFAState.h"
+#include "dfa/LexerDFASerializer.h"
+#include "misc/InterpreterDataReader.h"
+#include "misc/Interval.h"
+#include "misc/IntervalSet.h"
+#include "misc/MurmurHash.h"
+#include "misc/Predicate.h"
+#include "support/Any.h"
+#include "support/Arrays.h"
+#include "support/BitSet.h"
+#include "support/CPPUtils.h"
+#include "support/StringUtils.h"
+#include "support/guid.h"
+#include "tree/AbstractParseTreeVisitor.h"
+#include "tree/ErrorNode.h"
+#include "tree/ErrorNodeImpl.h"
+#include "tree/ParseTree.h"
+#include "tree/ParseTreeListener.h"
+#include "tree/ParseTreeProperty.h"
+#include "tree/ParseTreeVisitor.h"
+#include "tree/ParseTreeWalker.h"
+#include "tree/TerminalNode.h"
+#include "tree/TerminalNodeImpl.h"
+#include "tree/Trees.h"
+#include "tree/pattern/Chunk.h"
+#include "tree/pattern/ParseTreeMatch.h"
+#include "tree/pattern/ParseTreePattern.h"
+#include "tree/pattern/ParseTreePatternMatcher.h"
+#include "tree/pattern/RuleTagToken.h"
+#include "tree/pattern/TagChunk.h"
+#include "tree/pattern/TextChunk.h"
+#include "tree/pattern/TokenTagToken.h"
+#include "tree/xpath/XPath.h"
+#include "tree/xpath/XPathElement.h"
+#include "tree/xpath/XPathLexer.h"
+#include "tree/xpath/XPathLexerErrorListener.h"
+#include "tree/xpath/XPathRuleAnywhereElement.h"
+#include "tree/xpath/XPathRuleElement.h"
+#include "tree/xpath/XPathTokenAnywhereElement.h"
+#include "tree/xpath/XPathTokenElement.h"
+#include "tree/xpath/XPathWildcardAnywhereElement.h"
+#include "tree/xpath/XPathWildcardElement.h"
+
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RuleContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ATN {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t INVALID_ALT_NUMBER = 0;
+#else
+ enum : size_t {
+ INVALID_ALT_NUMBER = 0,
+ };
+#endif
+
+ /// Used for runtime deserialization of ATNs from strings.
+ ATN();
+ ATN(ATN &&other);
+ ATN(ATNType grammarType, size_t maxTokenType);
+ virtual ~ATN();
+
+ std::vector<ATNState *> states;
+
+ /// Each subrule/rule is a decision point and we must track them so we
+ /// can go back later and build DFA predictors for them. This includes
+ /// all the rules, subrules, optional blocks, ()+, ()* etc...
+ std::vector<DecisionState *> decisionToState;
+
+ /// Maps from rule index to starting state number.
+ std::vector<RuleStartState *> ruleToStartState;
+
+ /// Maps from rule index to stop state number.
+ std::vector<RuleStopState *> ruleToStopState;
+
+ /// The type of the ATN.
+ ATNType grammarType;
+
+ /// The maximum value for any symbol recognized by a transition in the ATN.
+ size_t maxTokenType;
+
+ /// <summary>
+ /// For lexer ATNs, this maps the rule index to the resulting token type.
+ /// For parser ATNs, this maps the rule index to the generated bypass token
+ /// type if the
+ /// <seealso cref="ATNDeserializationOptions#isGenerateRuleBypassTransitions"/>
+ /// deserialization option was specified; otherwise, this is {@code null}.
+ /// </summary>
+ std::vector<size_t> ruleToTokenType;
+
+ /// For lexer ATNs, this is an array of {@link LexerAction} objects which may
+ /// be referenced by action transitions in the ATN.
+ std::vector<Ref<LexerAction>> lexerActions;
+
+ std::vector<TokensStartState *> modeToStartState;
+
+ ATN& operator = (ATN &other) NOEXCEPT;
+ ATN& operator = (ATN &&other) NOEXCEPT;
+
+ /// <summary>
+ /// Compute the set of valid tokens that can occur starting in state {@code s}.
+ /// If {@code ctx} is null, the set of tokens will not include what can follow
+ /// the rule surrounding {@code s}. In other words, the set will be
+ /// restricted to tokens reachable staying within {@code s}'s rule.
+ /// </summary>
+ virtual misc::IntervalSet nextTokens(ATNState *s, RuleContext *ctx) const;
+
+ /// <summary>
+ /// Compute the set of valid tokens that can occur starting in {@code s} and
+ /// staying in same rule. <seealso cref="Token#EPSILON"/> is in set if we reach end of
+ /// rule.
+ /// </summary>
+ virtual misc::IntervalSet const& nextTokens(ATNState *s) const;
+
+ virtual void addState(ATNState *state);
+
+ virtual void removeState(ATNState *state);
+
+ virtual int defineDecisionState(DecisionState *s);
+
+ virtual DecisionState *getDecisionState(size_t decision) const;
+
+ virtual size_t getNumberOfDecisions() const;
+
+ /// <summary>
+ /// Computes the set of input symbols which could follow ATN state number
+ /// {@code stateNumber} in the specified full {@code context}. This method
+ /// considers the complete parser context, but does not evaluate semantic
+ /// predicates (i.e. all predicates encountered during the calculation are
+ /// assumed true). If a path in the ATN exists from the starting state to the
+ /// <seealso cref="RuleStopState"/> of the outermost context without matching any
+ /// symbols, <seealso cref="Token#EOF"/> is added to the returned set.
+ /// <p/>
+ /// If {@code context} is {@code null}, it is treated as
+ /// <seealso cref="ParserRuleContext#EMPTY"/>.
+ /// </summary>
+ /// <param name="stateNumber"> the ATN state number </param>
+ /// <param name="context"> the full parse context </param>
+ /// <returns> The set of potentially valid input symbols which could follow the
+ /// specified state in the specified context. </returns>
+ /// <exception cref="IllegalArgumentException"> if the ATN does not contain a state with
+ /// number {@code stateNumber} </exception>
+ virtual misc::IntervalSet getExpectedTokens(size_t stateNumber, RuleContext *context) const;
+
+ std::string toString() const;
+
+ private:
+ mutable std::mutex _mutex;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// A tuple: (ATN state, predicted alt, syntactic, semantic context).
+ /// The syntactic context is a graph-structured stack node whose
+ /// path(s) to the root is the rule invocation(s)
+ /// chain used to arrive at the state. The semantic context is
+ /// the tree of semantic predicates encountered before reaching
+ /// an ATN state.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ATNConfig {
+ public:
+ struct Hasher
+ {
+ size_t operator()(ATNConfig const& k) const {
+ return k.hashCode();
+ }
+ };
+
+ struct Comparer {
+ bool operator()(ATNConfig const& lhs, ATNConfig const& rhs) const {
+ return (&lhs == &rhs) || (lhs == rhs);
+ }
+ };
+
+
+ using Set = std::unordered_set<Ref<ATNConfig>, Hasher, Comparer>;
+
+ /// The ATN state associated with this configuration.
+ ATNState * state;
+
+ /// What alt (or lexer rule) is predicted by this configuration.
+ const size_t alt;
+
+ /// The stack of invoking states leading to the rule/states associated
+ /// with this config. We track only those contexts pushed during
+ /// execution of the ATN simulator.
+ ///
+ /// Can be shared between multiple ANTConfig instances.
+ Ref<PredictionContext> context;
+
+ /**
+ * We cannot execute predicates dependent upon local context unless
+ * we know for sure we are in the correct context. Because there is
+ * no way to do this efficiently, we simply cannot evaluate
+ * dependent predicates unless we are in the rule that initially
+ * invokes the ATN simulator.
+ *
+ * <p>
+ * closure() tracks the depth of how far we dip into the outer context:
+ * depth > 0. Note that it may not be totally accurate depth since I
+ * don't ever decrement. TODO: make it a boolean then</p>
+ *
+ * <p>
+ * For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
+ * is also backed by this field. Since the field is publicly accessible, the
+ * highest bit which would not cause the value to become negative is used to
+ * store this field. This choice minimizes the risk that code which only
+ * compares this value to 0 would be affected by the new purpose of the
+ * flag. It also ensures the performance of the existing {@link ATNConfig}
+ * constructors as well as certain operations like
+ * {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
+ * <em>completely</em> unaffected by the change.</p>
+ */
+ size_t reachesIntoOuterContext;
+
+ /// Can be shared between multiple ATNConfig instances.
+ Ref<SemanticContext> semanticContext;
+
+ ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> const& context);
+ ATNConfig(ATNState *state, size_t alt, Ref<PredictionContext> const& context, Ref<SemanticContext> const& semanticContext);
+
+ ATNConfig(Ref<ATNConfig> const& c); // dup
+ ATNConfig(Ref<ATNConfig> const& c, ATNState *state);
+ ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<SemanticContext> const& semanticContext);
+ ATNConfig(Ref<ATNConfig> const& c, Ref<SemanticContext> const& semanticContext);
+ ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> const& context);
+ ATNConfig(Ref<ATNConfig> const& c, ATNState *state, Ref<PredictionContext> const& context, Ref<SemanticContext> const& semanticContext);
+
+ ATNConfig(ATNConfig const&) = default;
+ virtual ~ATNConfig();
+
+ virtual size_t hashCode() const;
+
+ /**
+ * This method gets the value of the {@link #reachesIntoOuterContext} field
+ * as it existed prior to the introduction of the
+ * {@link #isPrecedenceFilterSuppressed} method.
+ */
+ size_t getOuterContextDepth() const ;
+ bool isPrecedenceFilterSuppressed() const;
+ void setPrecedenceFilterSuppressed(bool value);
+
+ /// An ATN configuration is equal to another if both have
+ /// the same state, they predict the same alternative, and
+ /// syntactic/semantic contexts are the same.
+ bool operator == (const ATNConfig &other) const;
+ bool operator != (const ATNConfig &other) const;
+
+ virtual std::string toString();
+ std::string toString(bool showAlt);
+
+ private:
+ /**
+ * This field stores the bit mask for implementing the
+ * {@link #isPrecedenceFilterSuppressed} property as a bit within the
+ * existing {@link #reachesIntoOuterContext} field.
+ */
+#if __cplusplus >= 201703L
+ static constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
+#else
+ enum : size_t {
+ SUPPRESS_PRECEDENCE_FILTER = 0x40000000,
+ };
+#endif
+ };
+
+} // namespace atn
+} // namespace antlr4
+
+
+// Hash function for ATNConfig.
+
+namespace std {
+ using antlr4::atn::ATNConfig;
+
+ template <> struct hash<ATNConfig>
+ {
+ size_t operator() (const ATNConfig &x) const
+ {
+ return x.hashCode();
+ }
+ };
+
+ template <> struct hash<std::vector<Ref<ATNConfig>>>
+ {
+ size_t operator() (const std::vector<Ref<ATNConfig>> &vector) const
+ {
+ std::size_t seed = 0;
+ for (const auto &config : vector) {
+ seed ^= config->hashCode() + 0x9e3779b9 + (seed << 6) + (seed >> 2);
+ }
+ return seed;
+ }
+ };
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "support/BitSet.h"
+#include "atn/PredictionContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Specialized set that can track info about the set, with support for combining similar configurations using a
+ /// graph-structured stack.
+ class ANTLR4CPP_PUBLIC ATNConfigSet {
+ public:
+ /// Track the elements as they are added to the set; supports get(i)
+ std::vector<Ref<ATNConfig>> configs;
+
+ // TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
+ // TODO: can we track conflicts as they are added to save scanning configs later?
+ size_t uniqueAlt;
+
+ /** Currently this is only used when we detect SLL conflict; this does
+ * not necessarily represent the ambiguous alternatives. In fact,
+ * I should also point out that this seems to include predicated alternatives
+ * that have predicates that evaluate to false. Computed in computeTargetState().
+ */
+ antlrcpp::BitSet conflictingAlts;
+
+ // Used in parser and lexer. In lexer, it indicates we hit a pred
+ // while computing a closure operation. Don't make a DFA state from this.
+ bool hasSemanticContext;
+ bool dipsIntoOuterContext;
+
+ /// Indicates that this configuration set is part of a full context
+ /// LL prediction. It will be used to determine how to merge $. With SLL
+ /// it's a wildcard whereas it is not for LL context merge.
+ const bool fullCtx;
+
+ ATNConfigSet(bool fullCtx = true);
+ ATNConfigSet(const Ref<ATNConfigSet> &old);
+
+ virtual ~ATNConfigSet();
+
+ virtual bool add(const Ref<ATNConfig> &config);
+
+ /// <summary>
+ /// Adding a new config means merging contexts with existing configs for
+ /// {@code (s, i, pi, _)}, where {@code s} is the
+ /// <seealso cref="ATNConfig#state"/>, {@code i} is the <seealso cref="ATNConfig#alt"/>, and
+ /// {@code pi} is the <seealso cref="ATNConfig#semanticContext"/>. We use
+ /// {@code (s,i,pi)} as key.
+ /// <p/>
+ /// This method updates <seealso cref="#dipsIntoOuterContext"/> and
+ /// <seealso cref="#hasSemanticContext"/> when necessary.
+ /// </summary>
+ virtual bool add(const Ref<ATNConfig> &config, PredictionContextMergeCache *mergeCache);
+
+ virtual std::vector<ATNState *> getStates();
+
+ /**
+ * Gets the complete set of represented alternatives for the configuration
+ * set.
+ *
+ * @return the set of represented alternatives in this configuration set
+ *
+ * @since 4.3
+ */
+ antlrcpp::BitSet getAlts();
+ virtual std::vector<Ref<SemanticContext>> getPredicates();
+
+ virtual Ref<ATNConfig> get(size_t i) const;
+
+ virtual void optimizeConfigs(ATNSimulator *interpreter);
+
+ bool addAll(const Ref<ATNConfigSet> &other);
+
+ bool operator == (const ATNConfigSet &other);
+ virtual size_t hashCode();
+ virtual size_t size();
+ virtual bool isEmpty();
+ virtual void clear();
+ virtual bool isReadonly();
+ virtual void setReadonly(bool readonly);
+ virtual std::string toString();
+
+ protected:
+ /// Indicates that the set of configurations is read-only. Do not
+ /// allow any code to manipulate the set; DFA states will point at
+ /// the sets and they must not change. This does not protect the other
+ /// fields; in particular, conflictingAlts is set after
+ /// we've made this readonly.
+ bool _readonly;
+
+ virtual size_t getHash(ATNConfig *c); // Hash differs depending on set type.
+
+ private:
+ size_t _cachedHashCode;
+
+ /// All configs but hashed by (s, i, _, pi) not including context. Wiped out
+ /// when we go readonly as this set becomes a DFA state.
+ std::unordered_map<size_t, ATNConfig *> _configLookup;
+
+ void InitializeInstanceFields();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ATNDeserializationOptions {
+ private:
+ static ATNDeserializationOptions defaultOptions;
+
+ bool readOnly;
+ bool verifyATN;
+ bool generateRuleBypassTransitions;
+
+ public:
+ ATNDeserializationOptions();
+ ATNDeserializationOptions(ATNDeserializationOptions *options);
+ ATNDeserializationOptions(ATNDeserializationOptions const&) = default;
+ virtual ~ATNDeserializationOptions();
+ ATNDeserializationOptions& operator=(ATNDeserializationOptions const&) = default;
+
+ static const ATNDeserializationOptions& getDefaultOptions();
+
+ bool isReadOnly();
+
+ void makeReadOnly();
+
+ bool isVerifyATN();
+
+ void setVerifyATN(bool verify);
+
+ bool isGenerateRuleBypassTransitions();
+
+ void setGenerateRuleBypassTransitions(bool generate);
+
+ protected:
+ virtual void throwIfReadOnly();
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/ATNDeserializationOptions.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ATNDeserializer {
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t SERIALIZED_VERSION = 3;
+#else
+ enum : size_t {
+ SERIALIZED_VERSION = 3,
+ };
+#endif
+
+ /// This is the current serialized UUID.
+ // ml: defined as function to avoid the “static initialization order fiasco”.
+ static Guid SERIALIZED_UUID();
+
+ ATNDeserializer();
+ ATNDeserializer(const ATNDeserializationOptions& dso);
+ virtual ~ATNDeserializer();
+
+ static Guid toUUID(const unsigned short *data, size_t offset);
+
+ virtual ATN deserialize(const std::vector<uint16_t> &input);
+ virtual void verifyATN(const ATN &atn);
+
+ static void checkCondition(bool condition);
+ static void checkCondition(bool condition, const std::string &message);
+
+ static Transition *edgeFactory(const ATN &atn, size_t type, size_t src, size_t trg, size_t arg1, size_t arg2,
+ size_t arg3, const std::vector<misc::IntervalSet> &sets);
+
+ static ATNState *stateFactory(size_t type, size_t ruleIndex);
+
+ protected:
+ /// Determines if a particular serialized representation of an ATN supports
+ /// a particular feature, identified by the <seealso cref="UUID"/> used for serializing
+ /// the ATN at the time the feature was first introduced.
+ ///
+ /// <param name="feature"> The <seealso cref="UUID"/> marking the first time the feature was
+ /// supported in the serialized ATN. </param>
+ /// <param name="actualUuid"> The <seealso cref="UUID"/> of the actual serialized ATN which is
+ /// currently being deserialized. </param>
+ /// <returns> {@code true} if the {@code actualUuid} value represents a
+ /// serialized ATN at or after the feature identified by {@code feature} was
+ /// introduced; otherwise, {@code false}. </returns>
+ virtual bool isFeatureSupported(const Guid &feature, const Guid &actualUuid);
+ void markPrecedenceDecisions(const ATN &atn);
+ Ref<LexerAction> lexerActionFactory(LexerActionType type, int data1, int data2);
+
+ private:
+ /// This is the earliest supported serialized UUID.
+ static Guid BASE_SERIALIZED_UUID();
+
+ /// This UUID indicates an extension of <seealso cref="BASE_SERIALIZED_UUID"/> for the
+ /// addition of precedence predicates.
+ static Guid ADDED_PRECEDENCE_TRANSITIONS();
+
+ /**
+ * This UUID indicates an extension of ADDED_PRECEDENCE_TRANSITIONS
+ * for the addition of lexer actions encoded as a sequence of
+ * LexerAction instances.
+ */
+ static Guid ADDED_LEXER_ACTIONS();
+
+ /**
+ * This UUID indicates the serialized ATN contains two sets of
+ * IntervalSets, where the second set's values are encoded as
+ * 32-bit integers to support the full Unicode SMP range up to U+10FFFF.
+ */
+ static Guid ADDED_UNICODE_SMP();
+
+ /// This list contains all of the currently supported UUIDs, ordered by when
+ /// the feature first appeared in this branch.
+ static std::vector<Guid>& SUPPORTED_UUIDS();
+
+ ATNDeserializationOptions deserializationOptions;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ATNSerializer {
+ public:
+ ATN *atn;
+
+ ATNSerializer(ATN *atn);
+ ATNSerializer(ATN *atn, const std::vector<std::string> &tokenNames);
+ virtual ~ATNSerializer();
+
+ /// <summary>
+ /// Serialize state descriptors, edge descriptors, and decision->state map
+ /// into list of ints:
+ ///
+ /// grammar-type, (ANTLRParser.LEXER, ...)
+ /// max token type,
+ /// num states,
+ /// state-0-type ruleIndex, state-1-type ruleIndex, ... state-i-type
+ /// ruleIndex optional-arg ...
+ /// num rules,
+ /// rule-1-start-state rule-1-args, rule-2-start-state rule-2-args, ...
+ /// (args are token type,actionIndex in lexer else 0,0)
+ /// num modes,
+ /// mode-0-start-state, mode-1-start-state, ... (parser has 0 modes)
+ /// num sets
+ /// set-0-interval-count intervals, set-1-interval-count intervals, ...
+ /// num total edges,
+ /// src, trg, edge-type, edge arg1, optional edge arg2 (present always),
+ /// ...
+ /// num decisions,
+ /// decision-0-start-state, decision-1-start-state, ...
+ ///
+ /// Convenient to pack into unsigned shorts to make as Java string.
+ /// </summary>
+ virtual std::vector<size_t> serialize();
+
+ virtual std::string decode(const std::wstring& data);
+ virtual std::string getTokenName(size_t t);
+
+ /// Used by Java target to encode short/int array as chars in string.
+ static std::wstring getSerializedAsString(ATN *atn);
+ static std::vector<size_t> getSerialized(ATN *atn);
+
+ static std::string getDecoded(ATN *atn, std::vector<std::string> &tokenNames);
+
+ private:
+ std::vector<std::string> _tokenNames;
+
+ void serializeUUID(std::vector<size_t> &data, Guid uuid);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATN.h"
+#include "misc/IntervalSet.h"
+#include "support/CPPUtils.h"
+#include "atn/PredictionContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ATNSimulator {
+ public:
+ /// Must distinguish between missing edge and edge we know leads nowhere.
+ static const Ref<dfa::DFAState> ERROR;
+ const ATN &atn;
+
+ ATNSimulator(const ATN &atn, PredictionContextCache &sharedContextCache);
+ virtual ~ATNSimulator();
+
+ virtual void reset() = 0;
+
+ /**
+ * Clear the DFA cache used by the current instance. Since the DFA cache may
+ * be shared by multiple ATN simulators, this method may affect the
+ * performance (but not accuracy) of other parsers which are being used
+ * concurrently.
+ *
+ * @throws UnsupportedOperationException if the current instance does not
+ * support clearing the DFA.
+ *
+ * @since 4.3
+ */
+ virtual void clearDFA();
+ virtual PredictionContextCache& getSharedContextCache();
+ virtual Ref<PredictionContext> getCachedContext(Ref<PredictionContext> const& context);
+
+ /// @deprecated Use <seealso cref="ATNDeserializer#deserialize"/> instead.
+ static ATN deserialize(const std::vector<uint16_t> &data);
+
+ /// @deprecated Use <seealso cref="ATNDeserializer#checkCondition(boolean)"/> instead.
+ static void checkCondition(bool condition);
+
+ /// @deprecated Use <seealso cref="ATNDeserializer#checkCondition(boolean, String)"/> instead.
+ static void checkCondition(bool condition, const std::string &message);
+
+ /// @deprecated Use <seealso cref="ATNDeserializer#edgeFactory"/> instead.
+ static Transition *edgeFactory(const ATN &atn, int type, int src, int trg, int arg1, int arg2, int arg3,
+ const std::vector<misc::IntervalSet> &sets);
+
+ /// @deprecated Use <seealso cref="ATNDeserializer#stateFactory"/> instead.
+ static ATNState *stateFactory(int type, int ruleIndex);
+
+ protected:
+ static antlrcpp::SingleWriteMultipleReadLock _stateLock; // Lock for DFA states.
+ static antlrcpp::SingleWriteMultipleReadLock _edgeLock; // Lock for the sparse edge map in DFA states.
+
+ /// <summary>
+ /// The context cache maps all PredictionContext objects that are equals()
+ /// to a single cached copy. This cache is shared across all contexts
+ /// in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet
+ /// to use only cached nodes/graphs in addDFAState(). We don't want to
+ /// fill this during closure() since there are lots of contexts that
+ /// pop up but are not used ever again. It also greatly slows down closure().
+ /// <p/>
+ /// This cache makes a huge difference in memory and a little bit in speed.
+ /// For the Java grammar on java.*, it dropped the memory requirements
+ /// at the end from 25M to 16M. We don't store any of the full context
+ /// graphs in the DFA because they are limited to local context only,
+ /// but apparently there's a lot of repetition there as well. We optimize
+ /// the config contexts before storing the config set in the DFA states
+ /// by literally rebuilding them with cached subgraphs only.
+ /// <p/>
+ /// I tried a cache for use during closure operations, that was
+ /// whacked after each adaptivePredict(). It cost a little bit
+ /// more time I think and doesn't save on the overall footprint
+ /// so it's not worth the complexity.
+ /// </summary>
+ PredictionContextCache &_sharedContextCache;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "misc/IntervalSet.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// The following images show the relation of states and
+ /// <seealso cref="ATNState#transitions"/> for various grammar constructs.
+ ///
+ /// <ul>
+ ///
+ /// <li>Solid edges marked with an ε indicate a required
+ /// <seealso cref="EpsilonTransition"/>.</li>
+ ///
+ /// <li>Dashed edges indicate locations where any transition derived from
+ /// <seealso cref="Transition"/> might appear.</li>
+ ///
+ /// <li>Dashed nodes are place holders for either a sequence of linked
+ /// <seealso cref="BasicState"/> states or the inclusion of a block representing a nested
+ /// construct in one of the forms below.</li>
+ ///
+ /// <li>Nodes showing multiple outgoing alternatives with a {@code ...} support
+ /// any number of alternatives (one or more). Nodes without the {@code ...} only
+ /// support the exact number of alternatives shown in the diagram.</li>
+ ///
+ /// </ul>
+ ///
+ /// <h2>Basic Blocks</h2>
+ ///
+ /// <h3>Rule</h3>
+ ///
+ /// <embed src="images/Rule.svg" type="image/svg+xml"/>
+ ///
+ /// <h3>Block of 1 or more alternatives</h3>
+ ///
+ /// <embed src="images/Block.svg" type="image/svg+xml"/>
+ ///
+ /// <h2>Greedy Loops</h2>
+ ///
+ /// <h3>Greedy Closure: {@code (...)*}</h3>
+ ///
+ /// <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
+ ///
+ /// <h3>Greedy Positive Closure: {@code (...)+}</h3>
+ ///
+ /// <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
+ ///
+ /// <h3>Greedy Optional: {@code (...)?}</h3>
+ ///
+ /// <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
+ ///
+ /// <h2>Non-Greedy Loops</h2>
+ ///
+ /// <h3>Non-Greedy Closure: {@code (...)*?}</h3>
+ ///
+ /// <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
+ ///
+ /// <h3>Non-Greedy Positive Closure: {@code (...)+?}</h3>
+ ///
+ /// <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
+ ///
+ /// <h3>Non-Greedy Optional: {@code (...)??}</h3>
+ ///
+ /// <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ATN;
+
+ class ANTLR4CPP_PUBLIC ATNState {
+ public:
+ ATNState();
+ ATNState(ATNState const&) = delete;
+
+ virtual ~ATNState();
+
+ ATNState& operator=(ATNState const&) = delete;
+
+#if __cplusplus >= 201703L
+ static constexpr size_t INITIAL_NUM_TRANSITIONS = 4;
+ static constexpr size_t INVALID_STATE_NUMBER = std::numeric_limits<size_t>::max();
+#else
+ enum : size_t {
+ INITIAL_NUM_TRANSITIONS = 4,
+ INVALID_STATE_NUMBER = static_cast<size_t>(-1), // std::numeric_limits<size_t>::max(); doesn't work in VS 2013
+ };
+#endif
+
+ enum {
+ ATN_INVALID_TYPE = 0,
+ BASIC = 1,
+ RULE_START = 2,
+ BLOCK_START = 3,
+ PLUS_BLOCK_START = 4,
+ STAR_BLOCK_START = 5,
+ TOKEN_START = 6,
+ RULE_STOP = 7,
+ BLOCK_END = 8,
+ STAR_LOOP_BACK = 9,
+ STAR_LOOP_ENTRY = 10,
+ PLUS_LOOP_BACK = 11,
+ LOOP_END = 12
+ };
+
+ static const std::vector<std::string> serializationNames;
+
+ size_t stateNumber = INVALID_STATE_NUMBER;
+ size_t ruleIndex = 0; // at runtime, we don't have Rule objects
+ bool epsilonOnlyTransitions = false;
+
+ public:
+ virtual size_t hashCode();
+ bool operator == (const ATNState &other);
+
+ /// Track the transitions emanating from this ATN state.
+ std::vector<Transition*> transitions;
+
+ virtual bool isNonGreedyExitState();
+ virtual std::string toString() const;
+ virtual void addTransition(Transition *e);
+ virtual void addTransition(size_t index, Transition *e);
+ virtual Transition* removeTransition(size_t index);
+ virtual size_t getStateType() = 0;
+
+ private:
+ /// Used to cache lookahead during parsing, not used during construction.
+
+ misc::IntervalSet _nextTokenWithinRule;
+ std::atomic<bool> _nextTokenUpdated { false };
+
+ friend class ATN;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Represents the type of recognizer an ATN applies to.
+ enum class ATNType {
+ LEXER = 0,
+ PARSER = 1,
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTState;
+
+ class ANTLR4CPP_PUBLIC AbstractPredicateTransition : public Transition {
+
+ public:
+ AbstractPredicateTransition(ATNState *target);
+ ~AbstractPredicateTransition();
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ActionTransition final : public Transition {
+ public:
+ const size_t ruleIndex;
+ const size_t actionIndex;
+ const bool isCtxDependent; // e.g., $i ref in action
+
+ ActionTransition(ATNState *target, size_t ruleIndex);
+
+ ActionTransition(ATNState *target, size_t ruleIndex, size_t actionIndex, bool isCtxDependent);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool isEpsilon() const override;
+
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionEventInfo.h"
+#include "support/BitSet.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This class represents profiling event information for an ambiguity.
+ /// Ambiguities are decisions where a particular input resulted in an SLL
+ /// conflict, followed by LL prediction also reaching a conflict state
+ /// (indicating a true ambiguity in the grammar).
+ ///
+ /// <para>
+ /// This event may be reported during SLL prediction in cases where the
+ /// conflicting SLL configuration set provides sufficient information to
+ /// determine that the SLL conflict is truly an ambiguity. For example, if none
+ /// of the ATN configurations in the conflicting SLL configuration set have
+ /// traversed a global follow transition (i.e.
+ /// <seealso cref="ATNConfig#reachesIntoOuterContext"/> is 0 for all configurations), then
+ /// the result of SLL prediction for that input is known to be equivalent to the
+ /// result of LL prediction for that input.</para>
+ ///
+ /// <para>
+ /// In some cases, the minimum represented alternative in the conflicting LL
+ /// configuration set is not equal to the minimum represented alternative in the
+ /// conflicting SLL configuration set. Grammars and inputs which result in this
+ /// scenario are unable to use <seealso cref="PredictionMode#SLL"/>, which in turn means
+ /// they cannot use the two-stage parsing strategy to improve parsing performance
+ /// for that input.</para>
+ /// </summary>
+ /// <seealso cref= ParserATNSimulator#reportAmbiguity </seealso>
+ /// <seealso cref= ANTLRErrorListener#reportAmbiguity
+ ///
+ /// @since 4.3 </seealso>
+ class ANTLR4CPP_PUBLIC AmbiguityInfo : public DecisionEventInfo {
+ public:
+ /// The set of alternative numbers for this decision event that lead to a valid parse.
+ antlrcpp::BitSet ambigAlts;
+
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="AmbiguityInfo"/> class with the
+ /// specified detailed ambiguity information.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ /// <param name="configs"> The final configuration set identifying the ambiguous
+ /// alternatives for the current input </param>
+ /// <param name="ambigAlts"> The set of alternatives in the decision that lead to a valid parse.
+ /// The predicted alt is the min(ambigAlts) </param>
+ /// <param name="input"> The input token stream </param>
+ /// <param name="startIndex"> The start index for the current prediction </param>
+ /// <param name="stopIndex"> The index at which the ambiguity was identified during
+ /// prediction </param>
+ /// <param name="fullCtx"> {@code true} if the ambiguity was identified during LL
+ /// prediction; otherwise, {@code false} if the ambiguity was identified
+ /// during SLL prediction </param>
+ AmbiguityInfo(size_t decision, ATNConfigSet *configs, const antlrcpp::BitSet &ambigAlts, TokenStream *input,
+ size_t startIndex, size_t stopIndex, bool fullCtx);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/PredictionContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class SingletonPredictionContext;
+
+ class ANTLR4CPP_PUBLIC ArrayPredictionContext : public PredictionContext {
+ public:
+ /// Parent can be empty only if full ctx mode and we make an array
+ /// from EMPTY and non-empty. We merge EMPTY by using null parent and
+ /// returnState == EMPTY_RETURN_STATE.
+ // Also here: we use a strong reference to our parents to avoid having them freed prematurely.
+ // See also SinglePredictionContext.
+ const std::vector<Ref<PredictionContext>> parents;
+
+ /// Sorted for merge, no duplicates; if present, EMPTY_RETURN_STATE is always last.
+ const std::vector<size_t> returnStates;
+
+ ArrayPredictionContext(Ref<SingletonPredictionContext> const& a);
+ ArrayPredictionContext(std::vector<Ref<PredictionContext>> const& parents_, std::vector<size_t> const& returnStates);
+ virtual ~ArrayPredictionContext();
+
+ virtual bool isEmpty() const override;
+ virtual size_t size() const override;
+ virtual Ref<PredictionContext> getParent(size_t index) const override;
+ virtual size_t getReturnState(size_t index) const override;
+ bool operator == (const PredictionContext &o) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// TODO: make all transitions sets? no, should remove set edges.
+ class ANTLR4CPP_PUBLIC AtomTransition final : public Transition {
+ public:
+ /// The token type or character value; or, signifies special label.
+ const size_t _label;
+
+ AtomTransition(ATNState *target, size_t label);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual misc::IntervalSet label() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+#include "atn/BlockStartState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC BasicBlockStartState final : public BlockStartState {
+
+ public:
+ virtual size_t getStateType() override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC BasicState final : public ATNState {
+
+ public:
+ virtual size_t getStateType() override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Terminal node of a simple {@code (a|b|c)} block.
+ class ANTLR4CPP_PUBLIC BlockEndState final : public ATNState {
+ public:
+ BlockStartState *startState = nullptr;
+
+ BlockEndState();
+
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// The start of a regular {@code (...)} block.
+ class ANTLR4CPP_PUBLIC BlockStartState : public DecisionState {
+ public:
+ ~BlockStartState();
+ BlockEndState *endState = nullptr;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionEventInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This class represents profiling event information for a context sensitivity.
+ /// Context sensitivities are decisions where a particular input resulted in an
+ /// SLL conflict, but LL prediction produced a single unique alternative.
+ ///
+ /// <para>
+ /// In some cases, the unique alternative identified by LL prediction is not
+ /// equal to the minimum represented alternative in the conflicting SLL
+ /// configuration set. Grammars and inputs which result in this scenario are
+ /// unable to use <seealso cref="PredictionMode#SLL"/>, which in turn means they cannot use
+ /// the two-stage parsing strategy to improve parsing performance for that
+ /// input.</para>
+ /// </summary>
+ /// <seealso cref= ParserATNSimulator#reportContextSensitivity </seealso>
+ /// <seealso cref= ANTLRErrorListener#reportContextSensitivity
+ ///
+ /// @since 4.3 </seealso>
+ class ANTLR4CPP_PUBLIC ContextSensitivityInfo : public DecisionEventInfo {
+ public:
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="ContextSensitivityInfo"/> class
+ /// with the specified detailed context sensitivity information.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ /// <param name="configs"> The final configuration set containing the unique
+ /// alternative identified by full-context prediction </param>
+ /// <param name="input"> The input token stream </param>
+ /// <param name="startIndex"> The start index for the current prediction </param>
+ /// <param name="stopIndex"> The index at which the context sensitivity was
+ /// identified during full-context prediction </param>
+ ContextSensitivityInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, size_t stopIndex);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This is the base class for gathering detailed information about prediction
+ /// events which occur during parsing.
+ ///
+ /// Note that we could record the parser call stack at the time this event
+ /// occurred but in the presence of left recursive rules, the stack is kind of
+ /// meaningless. It's better to look at the individual configurations for their
+ /// individual stacks. Of course that is a <seealso cref="PredictionContext"/> object
+ /// not a parse tree node and so it does not have information about the extent
+ /// (start...stop) of the various subtrees. Examining the stack tops of all
+ /// configurations provide the return states for the rule invocations.
+ /// From there you can get the enclosing rule.
+ ///
+ /// @since 4.3
+ /// </summary>
+ class ANTLR4CPP_PUBLIC DecisionEventInfo {
+ public:
+ /// <summary>
+ /// The invoked decision number which this event is related to.
+ /// </summary>
+ /// <seealso cref= ATN#decisionToState </seealso>
+ const size_t decision;
+
+ /// <summary>
+ /// The configuration set containing additional information relevant to the
+ /// prediction state when the current event occurred, or {@code null} if no
+ /// additional information is relevant or available.
+ /// </summary>
+ const ATNConfigSet *configs;
+
+ /// <summary>
+ /// The input token stream which is being parsed.
+ /// </summary>
+ const TokenStream *input;
+
+ /// <summary>
+ /// The token index in the input stream at which the current prediction was
+ /// originally invoked.
+ /// </summary>
+ const size_t startIndex;
+
+ /// <summary>
+ /// The token index in the input stream at which the current event occurred.
+ /// </summary>
+ const size_t stopIndex;
+
+ /// <summary>
+ /// {@code true} if the current event occurred during LL prediction;
+ /// otherwise, {@code false} if the input occurred during SLL prediction.
+ /// </summary>
+ const bool fullCtx;
+
+ DecisionEventInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex,
+ size_t stopIndex, bool fullCtx);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ContextSensitivityInfo.h"
+#include "atn/AmbiguityInfo.h"
+#include "atn/PredicateEvalInfo.h"
+#include "atn/ErrorInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class LookaheadEventInfo;
+
+ /// <summary>
+ /// This class contains profiling gathered for a particular decision.
+ ///
+ /// <para>
+ /// Parsing performance in ANTLR 4 is heavily influenced by both static factors
+ /// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the
+ /// choice of input and the state of the DFA cache at the time profiling
+ /// operations are started). For best results, gather and use aggregate
+ /// statistics from a large sample of inputs representing the inputs expected in
+ /// production before using the results to make changes in the grammar.</para>
+ ///
+ /// @since 4.3
+ /// </summary>
+ class ANTLR4CPP_PUBLIC DecisionInfo {
+ public:
+ /// <summary>
+ /// The decision number, which is an index into <seealso cref="ATN#decisionToState"/>.
+ /// </summary>
+ const size_t decision;
+
+ /// <summary>
+ /// The total number of times <seealso cref="ParserATNSimulator#adaptivePredict"/> was
+ /// invoked for this decision.
+ /// </summary>
+ long long invocations = 0;
+
+ /// <summary>
+ /// The total time spent in <seealso cref="ParserATNSimulator#adaptivePredict"/> for
+ /// this decision, in nanoseconds.
+ ///
+ /// <para>
+ /// The value of this field contains the sum of differential results obtained
+ /// by <seealso cref="System#nanoTime()"/>, and is not adjusted to compensate for JIT
+ /// and/or garbage collection overhead. For best accuracy, use a modern JVM
+ /// implementation that provides precise results from
+ /// <seealso cref="System#nanoTime()"/>, and perform profiling in a separate process
+ /// which is warmed up by parsing the input prior to profiling. If desired,
+ /// call <seealso cref="ATNSimulator#clearDFA"/> to reset the DFA cache to its initial
+ /// state before starting the profiling measurement pass.</para>
+ /// </summary>
+ long long timeInPrediction = 0;
+
+ /// <summary>
+ /// The sum of the lookahead required for SLL prediction for this decision.
+ /// Note that SLL prediction is used before LL prediction for performance
+ /// reasons even when <seealso cref="PredictionMode#LL"/> or
+ /// <seealso cref="PredictionMode#LL_EXACT_AMBIG_DETECTION"/> is used.
+ /// </summary>
+ long long SLL_TotalLook = 0;
+
+ /// <summary>
+ /// Gets the minimum lookahead required for any single SLL prediction to
+ /// complete for this decision, by reaching a unique prediction, reaching an
+ /// SLL conflict state, or encountering a syntax error.
+ /// </summary>
+ long long SLL_MinLook = 0;
+
+ /// <summary>
+ /// Gets the maximum lookahead required for any single SLL prediction to
+ /// complete for this decision, by reaching a unique prediction, reaching an
+ /// SLL conflict state, or encountering a syntax error.
+ /// </summary>
+ long long SLL_MaxLook = 0;
+
+ /// Gets the <seealso cref="LookaheadEventInfo"/> associated with the event where the
+ /// <seealso cref="#SLL_MaxLook"/> value was set.
+ Ref<LookaheadEventInfo> SLL_MaxLookEvent;
+
+ /// <summary>
+ /// The sum of the lookahead required for LL prediction for this decision.
+ /// Note that LL prediction is only used when SLL prediction reaches a
+ /// conflict state.
+ /// </summary>
+ long long LL_TotalLook = 0;
+
+ /// <summary>
+ /// Gets the minimum lookahead required for any single LL prediction to
+ /// complete for this decision. An LL prediction completes when the algorithm
+ /// reaches a unique prediction, a conflict state (for
+ /// <seealso cref="PredictionMode#LL"/>, an ambiguity state (for
+ /// <seealso cref="PredictionMode#LL_EXACT_AMBIG_DETECTION"/>, or a syntax error.
+ /// </summary>
+ long long LL_MinLook = 0;
+
+ /// <summary>
+ /// Gets the maximum lookahead required for any single LL prediction to
+ /// complete for this decision. An LL prediction completes when the algorithm
+ /// reaches a unique prediction, a conflict state (for
+ /// <seealso cref="PredictionMode#LL"/>, an ambiguity state (for
+ /// <seealso cref="PredictionMode#LL_EXACT_AMBIG_DETECTION"/>, or a syntax error.
+ /// </summary>
+ long long LL_MaxLook = 0;
+
+ /// <summary>
+ /// Gets the <seealso cref="LookaheadEventInfo"/> associated with the event where the
+ /// <seealso cref="#LL_MaxLook"/> value was set.
+ /// </summary>
+ Ref<LookaheadEventInfo> LL_MaxLookEvent;
+
+ /// <summary>
+ /// A collection of <seealso cref="ContextSensitivityInfo"/> instances describing the
+ /// context sensitivities encountered during LL prediction for this decision.
+ /// </summary>
+ /// <seealso cref= ContextSensitivityInfo </seealso>
+ std::vector<ContextSensitivityInfo> contextSensitivities;
+
+ /// <summary>
+ /// A collection of <seealso cref="ErrorInfo"/> instances describing the parse errors
+ /// identified during calls to <seealso cref="ParserATNSimulator#adaptivePredict"/> for
+ /// this decision.
+ /// </summary>
+ /// <seealso cref= ErrorInfo </seealso>
+ std::vector<ErrorInfo> errors;
+
+ /// <summary>
+ /// A collection of <seealso cref="AmbiguityInfo"/> instances describing the
+ /// ambiguities encountered during LL prediction for this decision.
+ /// </summary>
+ /// <seealso cref= AmbiguityInfo </seealso>
+ std::vector<AmbiguityInfo> ambiguities;
+
+ /// <summary>
+ /// A collection of <seealso cref="PredicateEvalInfo"/> instances describing the
+ /// results of evaluating individual predicates during prediction for this
+ /// decision.
+ /// </summary>
+ /// <seealso cref= PredicateEvalInfo </seealso>
+ std::vector<PredicateEvalInfo> predicateEvals;
+
+ /// <summary>
+ /// The total number of ATN transitions required during SLL prediction for
+ /// this decision. An ATN transition is determined by the number of times the
+ /// DFA does not contain an edge that is required for prediction, resulting
+ /// in on-the-fly computation of that edge.
+ ///
+ /// <para>
+ /// If DFA caching of SLL transitions is employed by the implementation, ATN
+ /// computation may cache the computed edge for efficient lookup during
+ /// future parsing of this decision. Otherwise, the SLL parsing algorithm
+ /// will use ATN transitions exclusively.</para>
+ /// </summary>
+ /// <seealso cref= #SLL_ATNTransitions </seealso>
+ /// <seealso cref= ParserATNSimulator#computeTargetState </seealso>
+ /// <seealso cref= LexerATNSimulator#computeTargetState </seealso>
+ long long SLL_ATNTransitions = 0;
+
+ /// <summary>
+ /// The total number of DFA transitions required during SLL prediction for
+ /// this decision.
+ ///
+ /// <para>If the ATN simulator implementation does not use DFA caching for SLL
+ /// transitions, this value will be 0.</para>
+ /// </summary>
+ /// <seealso cref= ParserATNSimulator#getExistingTargetState </seealso>
+ /// <seealso cref= LexerATNSimulator#getExistingTargetState </seealso>
+ long long SLL_DFATransitions = 0;
+
+ /// <summary>
+ /// Gets the total number of times SLL prediction completed in a conflict
+ /// state, resulting in fallback to LL prediction.
+ ///
+ /// <para>Note that this value is not related to whether or not
+ /// <seealso cref="PredictionMode#SLL"/> may be used successfully with a particular
+ /// grammar. If the ambiguity resolution algorithm applied to the SLL
+ /// conflicts for this decision produce the same result as LL prediction for
+ /// this decision, <seealso cref="PredictionMode#SLL"/> would produce the same overall
+ /// parsing result as <seealso cref="PredictionMode#LL"/>.</para>
+ /// </summary>
+ long long LL_Fallback = 0;
+
+ /// <summary>
+ /// The total number of ATN transitions required during LL prediction for
+ /// this decision. An ATN transition is determined by the number of times the
+ /// DFA does not contain an edge that is required for prediction, resulting
+ /// in on-the-fly computation of that edge.
+ ///
+ /// <para>
+ /// If DFA caching of LL transitions is employed by the implementation, ATN
+ /// computation may cache the computed edge for efficient lookup during
+ /// future parsing of this decision. Otherwise, the LL parsing algorithm will
+ /// use ATN transitions exclusively.</para>
+ /// </summary>
+ /// <seealso cref= #LL_DFATransitions </seealso>
+ /// <seealso cref= ParserATNSimulator#computeTargetState </seealso>
+ /// <seealso cref= LexerATNSimulator#computeTargetState </seealso>
+ long long LL_ATNTransitions = 0;
+
+ /// <summary>
+ /// The total number of DFA transitions required during LL prediction for
+ /// this decision.
+ ///
+ /// <para>If the ATN simulator implementation does not use DFA caching for LL
+ /// transitions, this value will be 0.</para>
+ /// </summary>
+ /// <seealso cref= ParserATNSimulator#getExistingTargetState </seealso>
+ /// <seealso cref= LexerATNSimulator#getExistingTargetState </seealso>
+ long long LL_DFATransitions = 0;
+
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="DecisionInfo"/> class to contain
+ /// statistics for a particular decision.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ DecisionInfo(size_t decision);
+
+ std::string toString() const;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC DecisionState : public ATNState {
+ public:
+ int decision;
+ bool nonGreedy;
+
+ private:
+ void InitializeInstanceFields();
+
+ public:
+ DecisionState() {
+ InitializeInstanceFields();
+ }
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/SingletonPredictionContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC EmptyPredictionContext : public SingletonPredictionContext {
+ public:
+ EmptyPredictionContext();
+
+ virtual bool isEmpty() const override;
+ virtual size_t size() const override;
+ virtual Ref<PredictionContext> getParent(size_t index) const override;
+ virtual size_t getReturnState(size_t index) const override;
+ virtual std::string toString() const override;
+
+ virtual bool operator == (const PredictionContext &o) const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC EpsilonTransition final : public Transition {
+ public:
+ EpsilonTransition(ATNState *target);
+ EpsilonTransition(ATNState *target, size_t outermostPrecedenceReturn);
+
+ /**
+ * @return the rule index of a precedence rule for which this transition is
+ * returning from, where the precedence value is 0; otherwise, INVALID_INDEX.
+ *
+ * @see ATNConfig#isPrecedenceFilterSuppressed()
+ * @see ParserATNSimulator#applyPrecedenceFilter(ATNConfigSet)
+ * @since 4.4.1
+ */
+ size_t outermostPrecedenceReturn();
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool isEpsilon() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+
+ private:
+ const size_t _outermostPrecedenceReturn; // A rule index.
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionEventInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This class represents profiling event information for a syntax error
+ /// identified during prediction. Syntax errors occur when the prediction
+ /// algorithm is unable to identify an alternative which would lead to a
+ /// successful parse.
+ /// </summary>
+ /// <seealso cref= Parser#notifyErrorListeners(Token, String, RecognitionException) </seealso>
+ /// <seealso cref= ANTLRErrorListener#syntaxError
+ ///
+ /// @since 4.3 </seealso>
+ class ANTLR4CPP_PUBLIC ErrorInfo : public DecisionEventInfo {
+ public:
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="ErrorInfo"/> class with the
+ /// specified detailed syntax error information.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ /// <param name="configs"> The final configuration set reached during prediction
+ /// prior to reaching the <seealso cref="ATNSimulator#ERROR"/> state </param>
+ /// <param name="input"> The input token stream </param>
+ /// <param name="startIndex"> The start index for the current prediction </param>
+ /// <param name="stopIndex"> The index at which the syntax error was identified </param>
+ /// <param name="fullCtx"> {@code true} if the syntax error was identified during LL
+ /// prediction; otherwise, {@code false} if the syntax error was identified
+ /// during SLL prediction </param>
+ ErrorInfo(size_t decision, ATNConfigSet *configs, TokenStream *input, size_t startIndex, size_t stopIndex,
+ bool fullCtx);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Token.h"
+#include "support/BitSet.h"
+#include "atn/PredictionContext.h"
+#include "atn/ATNConfig.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC LL1Analyzer {
+ public:
+ /// Special value added to the lookahead sets to indicate that we hit
+ /// a predicate during analysis if {@code seeThruPreds==false}.
+#if __cplusplus >= 201703L
+ static constexpr size_t HIT_PRED = Token::INVALID_TYPE;
+#else
+ enum : size_t {
+ HIT_PRED = Token::INVALID_TYPE,
+ };
+#endif
+
+ const atn::ATN &_atn;
+
+ LL1Analyzer(const atn::ATN &atn);
+ virtual ~LL1Analyzer();
+
+ /// <summary>
+ /// Calculates the SLL(1) expected lookahead set for each outgoing transition
+ /// of an <seealso cref="ATNState"/>. The returned array has one element for each
+ /// outgoing transition in {@code s}. If the closure from transition
+ /// <em>i</em> leads to a semantic predicate before matching a symbol, the
+ /// element at index <em>i</em> of the result will be {@code null}.
+ /// </summary>
+ /// <param name="s"> the ATN state </param>
+ /// <returns> the expected symbols for each outgoing transition of {@code s}. </returns>
+ virtual std::vector<misc::IntervalSet> getDecisionLookahead(ATNState *s) const;
+
+ /// <summary>
+ /// Compute set of tokens that can follow {@code s} in the ATN in the
+ /// specified {@code ctx}.
+ /// <p/>
+ /// If {@code ctx} is {@code null} and the end of the rule containing
+ /// {@code s} is reached, <seealso cref="Token#EPSILON"/> is added to the result set.
+ /// If {@code ctx} is not {@code null} and the end of the outermost rule is
+ /// reached, <seealso cref="Token#EOF"/> is added to the result set.
+ /// </summary>
+ /// <param name="s"> the ATN state </param>
+ /// <param name="ctx"> the complete parser context, or {@code null} if the context
+ /// should be ignored
+ /// </param>
+ /// <returns> The set of tokens that can follow {@code s} in the ATN in the
+ /// specified {@code ctx}. </returns>
+ virtual misc::IntervalSet LOOK(ATNState *s, RuleContext *ctx) const;
+
+ /// <summary>
+ /// Compute set of tokens that can follow {@code s} in the ATN in the
+ /// specified {@code ctx}.
+ /// <p/>
+ /// If {@code ctx} is {@code null} and the end of the rule containing
+ /// {@code s} is reached, <seealso cref="Token#EPSILON"/> is added to the result set.
+ /// If {@code ctx} is not {@code null} and the end of the outermost rule is
+ /// reached, <seealso cref="Token#EOF"/> is added to the result set.
+ /// </summary>
+ /// <param name="s"> the ATN state </param>
+ /// <param name="stopState"> the ATN state to stop at. This can be a
+ /// <seealso cref="BlockEndState"/> to detect epsilon paths through a closure. </param>
+ /// <param name="ctx"> the complete parser context, or {@code null} if the context
+ /// should be ignored
+ /// </param>
+ /// <returns> The set of tokens that can follow {@code s} in the ATN in the
+ /// specified {@code ctx}. </returns>
+ virtual misc::IntervalSet LOOK(ATNState *s, ATNState *stopState, RuleContext *ctx) const;
+
+ /// <summary>
+ /// Compute set of tokens that can follow {@code s} in the ATN in the
+ /// specified {@code ctx}.
+ /// <p/>
+ /// If {@code ctx} is {@code null} and {@code stopState} or the end of the
+ /// rule containing {@code s} is reached, <seealso cref="Token#EPSILON"/> is added to
+ /// the result set. If {@code ctx} is not {@code null} and {@code addEOF} is
+ /// {@code true} and {@code stopState} or the end of the outermost rule is
+ /// reached, <seealso cref="Token#EOF"/> is added to the result set.
+ /// </summary>
+ /// <param name="s"> the ATN state. </param>
+ /// <param name="stopState"> the ATN state to stop at. This can be a
+ /// <seealso cref="BlockEndState"/> to detect epsilon paths through a closure. </param>
+ /// <param name="ctx"> The outer context, or {@code null} if the outer context should
+ /// not be used. </param>
+ /// <param name="look"> The result lookahead set. </param>
+ /// <param name="lookBusy"> A set used for preventing epsilon closures in the ATN
+ /// from causing a stack overflow. Outside code should pass
+ /// {@code new HashSet<ATNConfig>} for this argument. </param>
+ /// <param name="calledRuleStack"> A set used for preventing left recursion in the
+ /// ATN from causing a stack overflow. Outside code should pass
+ /// {@code new BitSet()} for this argument. </param>
+ /// <param name="seeThruPreds"> {@code true} to true semantic predicates as
+ /// implicitly {@code true} and "see through them", otherwise {@code false}
+ /// to treat semantic predicates as opaque and add <seealso cref="#HIT_PRED"/> to the
+ /// result if one is encountered. </param>
+ /// <param name="addEOF"> Add <seealso cref="Token#EOF"/> to the result if the end of the
+ /// outermost context is reached. This parameter has no effect if {@code ctx}
+ /// is {@code null}. </param>
+ protected:
+ virtual void _LOOK(ATNState *s, ATNState *stopState, Ref<PredictionContext> const& ctx, misc::IntervalSet &look,
+ ATNConfig::Set &lookBusy, antlrcpp::BitSet &calledRuleStack, bool seeThruPreds, bool addEOF) const;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNConfig.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC LexerATNConfig : public ATNConfig {
+ public:
+ LexerATNConfig(ATNState *state, int alt, Ref<PredictionContext> const& context);
+ LexerATNConfig(ATNState *state, int alt, Ref<PredictionContext> const& context, Ref<LexerActionExecutor> const& lexerActionExecutor);
+
+ LexerATNConfig(Ref<LexerATNConfig> const& c, ATNState *state);
+ LexerATNConfig(Ref<LexerATNConfig> const& c, ATNState *state, Ref<LexerActionExecutor> const& lexerActionExecutor);
+ LexerATNConfig(Ref<LexerATNConfig> const& c, ATNState *state, Ref<PredictionContext> const& context);
+
+ /**
+ * Gets the {@link LexerActionExecutor} capable of executing the embedded
+ * action(s) for the current configuration.
+ */
+ Ref<LexerActionExecutor> getLexerActionExecutor() const;
+ bool hasPassedThroughNonGreedyDecision();
+
+ virtual size_t hashCode() const override;
+
+ bool operator == (const LexerATNConfig& other) const;
+
+ private:
+ /**
+ * This is the backing field for {@link #getLexerActionExecutor}.
+ */
+ const Ref<LexerActionExecutor> _lexerActionExecutor;
+ const bool _passedThroughNonGreedyDecision;
+
+ static bool checkNonGreedyDecision(Ref<LexerATNConfig> const& source, ATNState *target);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNSimulator.h"
+#include "atn/LexerATNConfig.h"
+#include "atn/ATNConfigSet.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// "dup" of ParserInterpreter
+ class ANTLR4CPP_PUBLIC LexerATNSimulator : public ATNSimulator {
+ protected:
+ class SimState {
+ public:
+ virtual ~SimState();
+
+ protected:
+ size_t index;
+ size_t line;
+ size_t charPos;
+ dfa::DFAState *dfaState;
+ virtual void reset();
+ friend class LexerATNSimulator;
+
+ private:
+ void InitializeInstanceFields();
+
+ public:
+ SimState() {
+ InitializeInstanceFields();
+ }
+ };
+
+
+ public:
+#if __cplusplus >= 201703L
+ static constexpr size_t MIN_DFA_EDGE = 0;
+ static constexpr size_t MAX_DFA_EDGE = 127; // forces unicode to stay in ATN
+#else
+ enum : size_t {
+ MIN_DFA_EDGE = 0,
+ MAX_DFA_EDGE = 127, // forces unicode to stay in ATN
+ };
+#endif
+
+ protected:
+ /// <summary>
+ /// When we hit an accept state in either the DFA or the ATN, we
+ /// have to notify the character stream to start buffering characters
+ /// via <seealso cref="IntStream#mark"/> and record the current state. The current sim state
+ /// includes the current index into the input, the current line,
+ /// and current character position in that line. Note that the Lexer is
+ /// tracking the starting line and characterization of the token. These
+ /// variables track the "state" of the simulator when it hits an accept state.
+ /// <p/>
+ /// We track these variables separately for the DFA and ATN simulation
+ /// because the DFA simulation often has to fail over to the ATN
+ /// simulation. If the ATN simulation fails, we need the DFA to fall
+ /// back to its previously accepted state, if any. If the ATN succeeds,
+ /// then the ATN does the accept and the DFA simulator that invoked it
+ /// can simply return the predicted token type.
+ /// </summary>
+ Lexer *const _recog;
+
+ /// The current token's starting index into the character stream.
+ /// Shared across DFA to ATN simulation in case the ATN fails and the
+ /// DFA did not have a previous accept state. In this case, we use the
+ /// ATN-generated exception object.
+ size_t _startIndex;
+
+ /// line number 1..n within the input.
+ size_t _line;
+
+ /// The index of the character relative to the beginning of the line 0..n-1.
+ size_t _charPositionInLine;
+
+ public:
+ std::vector<dfa::DFA> &_decisionToDFA;
+
+ protected:
+ size_t _mode;
+
+ /// Used during DFA/ATN exec to record the most recent accept configuration info.
+ SimState _prevAccept;
+
+ public:
+ static int match_calls;
+
+ LexerATNSimulator(const ATN &atn, std::vector<dfa::DFA> &decisionToDFA, PredictionContextCache &sharedContextCache);
+ LexerATNSimulator(Lexer *recog, const ATN &atn, std::vector<dfa::DFA> &decisionToDFA, PredictionContextCache &sharedContextCache);
+ virtual ~LexerATNSimulator () {}
+
+ virtual void copyState(LexerATNSimulator *simulator);
+ virtual size_t match(CharStream *input, size_t mode);
+ virtual void reset() override;
+
+ virtual void clearDFA() override;
+
+ protected:
+ virtual size_t matchATN(CharStream *input);
+ virtual size_t execATN(CharStream *input, dfa::DFAState *ds0);
+
+ /// <summary>
+ /// Get an existing target state for an edge in the DFA. If the target state
+ /// for the edge has not yet been computed or is otherwise not available,
+ /// this method returns {@code null}.
+ /// </summary>
+ /// <param name="s"> The current DFA state </param>
+ /// <param name="t"> The next input symbol </param>
+ /// <returns> The existing target DFA state for the given input symbol
+ /// {@code t}, or {@code null} if the target state for this edge is not
+ /// already cached </returns>
+ virtual dfa::DFAState *getExistingTargetState(dfa::DFAState *s, size_t t);
+
+ /// <summary>
+ /// Compute a target state for an edge in the DFA, and attempt to add the
+ /// computed state and corresponding edge to the DFA.
+ /// </summary>
+ /// <param name="input"> The input stream </param>
+ /// <param name="s"> The current DFA state </param>
+ /// <param name="t"> The next input symbol
+ /// </param>
+ /// <returns> The computed target DFA state for the given input symbol
+ /// {@code t}. If {@code t} does not lead to a valid DFA state, this method
+ /// returns <seealso cref="#ERROR"/>. </returns>
+ virtual dfa::DFAState *computeTargetState(CharStream *input, dfa::DFAState *s, size_t t);
+
+ virtual size_t failOrAccept(CharStream *input, ATNConfigSet *reach, size_t t);
+
+ /// <summary>
+ /// Given a starting configuration set, figure out all ATN configurations
+ /// we can reach upon input {@code t}. Parameter {@code reach} is a return
+ /// parameter.
+ /// </summary>
+ void getReachableConfigSet(CharStream *input, ATNConfigSet *closure_, // closure_ as we have a closure() already
+ ATNConfigSet *reach, size_t t);
+
+ virtual void accept(CharStream *input, const Ref<LexerActionExecutor> &lexerActionExecutor, size_t startIndex, size_t index,
+ size_t line, size_t charPos);
+
+ virtual ATNState *getReachableTarget(Transition *trans, size_t t);
+
+ virtual std::unique_ptr<ATNConfigSet> computeStartState(CharStream *input, ATNState *p);
+
+ /// <summary>
+ /// Since the alternatives within any lexer decision are ordered by
+ /// preference, this method stops pursuing the closure as soon as an accept
+ /// state is reached. After the first accept state is reached by depth-first
+ /// search from {@code config}, all other (potentially reachable) states for
+ /// this rule would have a lower priority.
+ /// </summary>
+ /// <returns> {@code true} if an accept state is reached, otherwise
+ /// {@code false}. </returns>
+ virtual bool closure(CharStream *input, const Ref<LexerATNConfig> &config, ATNConfigSet *configs,
+ bool currentAltReachedAcceptState, bool speculative, bool treatEofAsEpsilon);
+
+ // side-effect: can alter configs.hasSemanticContext
+ virtual Ref<LexerATNConfig> getEpsilonTarget(CharStream *input, const Ref<LexerATNConfig> &config, Transition *t,
+ ATNConfigSet *configs, bool speculative, bool treatEofAsEpsilon);
+
+ /// <summary>
+ /// Evaluate a predicate specified in the lexer.
+ /// <p/>
+ /// If {@code speculative} is {@code true}, this method was called before
+ /// <seealso cref="#consume"/> for the matched character. This method should call
+ /// <seealso cref="#consume"/> before evaluating the predicate to ensure position
+ /// sensitive values, including <seealso cref="Lexer#getText"/>, <seealso cref="Lexer#getLine"/>,
+ /// and <seealso cref="Lexer#getCharPositionInLine"/>, properly reflect the current
+ /// lexer state. This method should restore {@code input} and the simulator
+ /// to the original state before returning (i.e. undo the actions made by the
+ /// call to <seealso cref="#consume"/>.
+ /// </summary>
+ /// <param name="input"> The input stream. </param>
+ /// <param name="ruleIndex"> The rule containing the predicate. </param>
+ /// <param name="predIndex"> The index of the predicate within the rule. </param>
+ /// <param name="speculative"> {@code true} if the current index in {@code input} is
+ /// one character before the predicate's location.
+ /// </param>
+ /// <returns> {@code true} if the specified predicate evaluates to
+ /// {@code true}. </returns>
+ virtual bool evaluatePredicate(CharStream *input, size_t ruleIndex, size_t predIndex, bool speculative);
+
+ virtual void captureSimState(CharStream *input, dfa::DFAState *dfaState);
+ virtual dfa::DFAState* addDFAEdge(dfa::DFAState *from, size_t t, ATNConfigSet *q);
+ virtual void addDFAEdge(dfa::DFAState *p, size_t t, dfa::DFAState *q);
+
+ /// <summary>
+ /// Add a new DFA state if there isn't one with this set of
+ /// configurations already. This method also detects the first
+ /// configuration containing an ATN rule stop state. Later, when
+ /// traversing the DFA, we will know which rule to accept.
+ /// </summary>
+ virtual dfa::DFAState *addDFAState(ATNConfigSet *configs);
+
+ public:
+ dfa::DFA& getDFA(size_t mode);
+
+ /// Get the text matched so far for the current token.
+ virtual std::string getText(CharStream *input);
+ virtual size_t getLine() const;
+ virtual void setLine(size_t line);
+ virtual size_t getCharPositionInLine();
+ virtual void setCharPositionInLine(size_t charPositionInLine);
+ virtual void consume(CharStream *input);
+ virtual std::string getTokenName(size_t t);
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerActionType.h"
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Represents a single action which can be executed following the successful
+ /// match of a lexer rule. Lexer actions are used for both embedded action syntax
+ /// and ANTLR 4's new lexer command syntax.
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerAction {
+ public:
+ virtual ~LexerAction();
+
+ /// <summary>
+ /// Gets the serialization type of the lexer action.
+ /// </summary>
+ /// <returns> The serialization type of the lexer action. </returns>
+ virtual LexerActionType getActionType() const = 0;
+
+ /// <summary>
+ /// Gets whether the lexer action is position-dependent. Position-dependent
+ /// actions may have different semantics depending on the <seealso cref="CharStream"/>
+ /// index at the time the action is executed.
+ ///
+ /// <para>Many lexer commands, including {@code type}, {@code skip}, and
+ /// {@code more}, do not check the input index during their execution.
+ /// Actions like this are position-independent, and may be stored more
+ /// efficiently as part of the <seealso cref="LexerATNConfig#lexerActionExecutor"/>.</para>
+ /// </summary>
+ /// <returns> {@code true} if the lexer action semantics can be affected by the
+ /// position of the input <seealso cref="CharStream"/> at the time it is executed;
+ /// otherwise, {@code false}. </returns>
+ virtual bool isPositionDependent() const = 0;
+
+ /// <summary>
+ /// Execute the lexer action in the context of the specified <seealso cref="Lexer"/>.
+ ///
+ /// <para>For position-dependent actions, the input stream must already be
+ /// positioned correctly prior to calling this method.</para>
+ /// </summary>
+ /// <param name="lexer"> The lexer instance. </param>
+ virtual void execute(Lexer *lexer) = 0;
+
+ virtual size_t hashCode() const = 0;
+ virtual bool operator == (const LexerAction &obj) const = 0;
+ virtual bool operator != (const LexerAction &obj) const {
+ return !(*this == obj);
+ }
+
+ virtual std::string toString() const = 0;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "CharStream.h"
+#include "atn/LexerAction.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Represents an executor for a sequence of lexer actions which traversed during
+ /// the matching operation of a lexer rule (token).
+ ///
+ /// <para>The executor tracks position information for position-dependent lexer actions
+ /// efficiently, ensuring that actions appearing only at the end of the rule do
+ /// not cause bloating of the <seealso cref="DFA"/> created for the lexer.</para>
+ class ANTLR4CPP_PUBLIC LexerActionExecutor : public std::enable_shared_from_this<LexerActionExecutor> {
+ public:
+ /// <summary>
+ /// Constructs an executor for a sequence of <seealso cref="LexerAction"/> actions. </summary>
+ /// <param name="lexerActions"> The lexer actions to execute. </param>
+ LexerActionExecutor(const std::vector<Ref<LexerAction>> &lexerActions);
+ virtual ~LexerActionExecutor();
+
+ /// <summary>
+ /// Creates a <seealso cref="LexerActionExecutor"/> which executes the actions for
+ /// the input {@code lexerActionExecutor} followed by a specified
+ /// {@code lexerAction}.
+ /// </summary>
+ /// <param name="lexerActionExecutor"> The executor for actions already traversed by
+ /// the lexer while matching a token within a particular
+ /// <seealso cref="LexerATNConfig"/>. If this is {@code null}, the method behaves as
+ /// though it were an empty executor. </param>
+ /// <param name="lexerAction"> The lexer action to execute after the actions
+ /// specified in {@code lexerActionExecutor}.
+ /// </param>
+ /// <returns> A <seealso cref="LexerActionExecutor"/> for executing the combine actions
+ /// of {@code lexerActionExecutor} and {@code lexerAction}. </returns>
+ static Ref<LexerActionExecutor> append(Ref<LexerActionExecutor> const& lexerActionExecutor,
+ Ref<LexerAction> const& lexerAction);
+
+ /// <summary>
+ /// Creates a <seealso cref="LexerActionExecutor"/> which encodes the current offset
+ /// for position-dependent lexer actions.
+ ///
+ /// <para>Normally, when the executor encounters lexer actions where
+ /// <seealso cref="LexerAction#isPositionDependent"/> returns {@code true}, it calls
+ /// <seealso cref="IntStream#seek"/> on the input <seealso cref="CharStream"/> to set the input
+ /// position to the <em>end</em> of the current token. This behavior provides
+ /// for efficient DFA representation of lexer actions which appear at the end
+ /// of a lexer rule, even when the lexer rule matches a variable number of
+ /// characters.</para>
+ ///
+ /// <para>Prior to traversing a match transition in the ATN, the current offset
+ /// from the token start index is assigned to all position-dependent lexer
+ /// actions which have not already been assigned a fixed offset. By storing
+ /// the offsets relative to the token start index, the DFA representation of
+ /// lexer actions which appear in the middle of tokens remains efficient due
+ /// to sharing among tokens of the same length, regardless of their absolute
+ /// position in the input stream.</para>
+ ///
+ /// <para>If the current executor already has offsets assigned to all
+ /// position-dependent lexer actions, the method returns {@code this}.</para>
+ /// </summary>
+ /// <param name="offset"> The current offset to assign to all position-dependent
+ /// lexer actions which do not already have offsets assigned.
+ /// </param>
+ /// <returns> A <seealso cref="LexerActionExecutor"/> which stores input stream offsets
+ /// for all position-dependent lexer actions. </returns>
+ virtual Ref<LexerActionExecutor> fixOffsetBeforeMatch(int offset);
+
+ /// <summary>
+ /// Gets the lexer actions to be executed by this executor. </summary>
+ /// <returns> The lexer actions to be executed by this executor. </returns>
+ virtual std::vector<Ref<LexerAction>> getLexerActions() const;
+
+ /// <summary>
+ /// Execute the actions encapsulated by this executor within the context of a
+ /// particular <seealso cref="Lexer"/>.
+ ///
+ /// <para>This method calls <seealso cref="IntStream#seek"/> to set the position of the
+ /// {@code input} <seealso cref="CharStream"/> prior to calling
+ /// <seealso cref="LexerAction#execute"/> on a position-dependent action. Before the
+ /// method returns, the input position will be restored to the same position
+ /// it was in when the method was invoked.</para>
+ /// </summary>
+ /// <param name="lexer"> The lexer instance. </param>
+ /// <param name="input"> The input stream which is the source for the current token.
+ /// When this method is called, the current <seealso cref="IntStream#index"/> for
+ /// {@code input} should be the start of the following token, i.e. 1
+ /// character past the end of the current token. </param>
+ /// <param name="startIndex"> The token start index. This value may be passed to
+ /// <seealso cref="IntStream#seek"/> to set the {@code input} position to the beginning
+ /// of the token. </param>
+ virtual void execute(Lexer *lexer, CharStream *input, size_t startIndex);
+
+ virtual size_t hashCode() const;
+ virtual bool operator == (const LexerActionExecutor &obj) const;
+ virtual bool operator != (const LexerActionExecutor &obj) const;
+
+ private:
+ const std::vector<Ref<LexerAction>> _lexerActions;
+
+ /// Caches the result of <seealso cref="#hashCode"/> since the hash code is an element
+ /// of the performance-critical <seealso cref="LexerATNConfig#hashCode"/> operation.
+ const size_t _hashCode;
+
+ size_t generateHashCode() const;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Represents the serialization type of a <seealso cref="LexerAction"/>.
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ enum class LexerActionType : size_t {
+ /// <summary>
+ /// The type of a <seealso cref="LexerChannelAction"/> action.
+ /// </summary>
+ CHANNEL,
+ /// <summary>
+ /// The type of a <seealso cref="LexerCustomAction"/> action.
+ /// </summary>
+ CUSTOM,
+ /// <summary>
+ /// The type of a <seealso cref="LexerModeAction"/> action.
+ /// </summary>
+ MODE,
+ /// <summary>
+ /// The type of a <seealso cref="LexerMoreAction"/> action.
+ /// </summary>
+ MORE,
+ /// <summary>
+ /// The type of a <seealso cref="LexerPopModeAction"/> action.
+ /// </summary>
+ POP_MODE,
+ /// <summary>
+ /// The type of a <seealso cref="LexerPushModeAction"/> action.
+ /// </summary>
+ PUSH_MODE,
+ /// <summary>
+ /// The type of a <seealso cref="LexerSkipAction"/> action.
+ /// </summary>
+ SKIP,
+ /// <summary>
+ /// The type of a <seealso cref="LexerTypeAction"/> action.
+ /// </summary>
+ TYPE,
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ using antlr4::Lexer;
+
+ /// <summary>
+ /// Implements the {@code channel} lexer action by calling
+ /// <seealso cref="Lexer#setChannel"/> with the assigned channel.
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerChannelAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a new {@code channel} action with the specified channel value. </summary>
+ /// <param name="channel"> The channel value to pass to <seealso cref="Lexer#setChannel"/>. </param>
+ LexerChannelAction(int channel);
+
+ /// <summary>
+ /// Gets the channel to use for the <seealso cref="Token"/> created by the lexer.
+ /// </summary>
+ /// <returns> The channel to use for the <seealso cref="Token"/> created by the lexer. </returns>
+ int getChannel() const;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#CHANNEL"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#setChannel"/> with the
+ /// value provided by <seealso cref="#getChannel"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const int _channel;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Executes a custom lexer action by calling <seealso cref="Recognizer#action"/> with the
+ /// rule and action indexes assigned to the custom action. The implementation of
+ /// a custom action is added to the generated code for the lexer in an override
+ /// of <seealso cref="Recognizer#action"/> when the grammar is compiled.
+ ///
+ /// <para>This class may represent embedded actions created with the <code>{...}</code>
+ /// syntax in ANTLR 4, as well as actions created for lexer commands where the
+ /// command argument could not be evaluated when the grammar was compiled.</para>
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerCustomAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a custom lexer action with the specified rule and action
+ /// indexes.
+ /// </summary>
+ /// <param name="ruleIndex"> The rule index to use for calls to
+ /// <seealso cref="Recognizer#action"/>. </param>
+ /// <param name="actionIndex"> The action index to use for calls to
+ /// <seealso cref="Recognizer#action"/>. </param>
+ LexerCustomAction(size_t ruleIndex, size_t actionIndex);
+
+ /// <summary>
+ /// Gets the rule index to use for calls to <seealso cref="Recognizer#action"/>.
+ /// </summary>
+ /// <returns> The rule index for the custom action. </returns>
+ size_t getRuleIndex() const;
+
+ /// <summary>
+ /// Gets the action index to use for calls to <seealso cref="Recognizer#action"/>.
+ /// </summary>
+ /// <returns> The action index for the custom action. </returns>
+ size_t getActionIndex() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#CUSTOM"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// Gets whether the lexer action is position-dependent. Position-dependent
+ /// actions may have different semantics depending on the <seealso cref="CharStream"/>
+ /// index at the time the action is executed.
+ ///
+ /// <para>Custom actions are position-dependent since they may represent a
+ /// user-defined embedded action which makes calls to methods like
+ /// <seealso cref="Lexer#getText"/>.</para>
+ /// </summary>
+ /// <returns> This method returns {@code true}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>Custom actions are implemented by calling <seealso cref="Lexer#action"/> with the
+ /// appropriate rule and action indexes.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const size_t _ruleIndex;
+ const size_t _actionIndex;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "RuleContext.h"
+#include "atn/LexerAction.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This implementation of <seealso cref="LexerAction"/> is used for tracking input offsets
+ /// for position-dependent actions within a <seealso cref="LexerActionExecutor"/>.
+ ///
+ /// <para>This action is not serialized as part of the ATN, and is only required for
+ /// position-dependent lexer actions which appear at a location other than the
+ /// end of a rule. For more information about DFA optimizations employed for
+ /// lexer actions, see <seealso cref="LexerActionExecutor#append"/> and
+ /// <seealso cref="LexerActionExecutor#fixOffsetBeforeMatch"/>.</para>
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerIndexedCustomAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a new indexed custom action by associating a character offset
+ /// with a <seealso cref="LexerAction"/>.
+ ///
+ /// <para>Note: This class is only required for lexer actions for which
+ /// <seealso cref="LexerAction#isPositionDependent"/> returns {@code true}.</para>
+ /// </summary>
+ /// <param name="offset"> The offset into the input <seealso cref="CharStream"/>, relative to
+ /// the token start index, at which the specified lexer action should be
+ /// executed. </param>
+ /// <param name="action"> The lexer action to execute at a particular offset in the
+ /// input <seealso cref="CharStream"/>. </param>
+ LexerIndexedCustomAction(int offset, Ref<LexerAction> const& action);
+
+ /// <summary>
+ /// Gets the location in the input <seealso cref="CharStream"/> at which the lexer
+ /// action should be executed. The value is interpreted as an offset relative
+ /// to the token start index.
+ /// </summary>
+ /// <returns> The location in the input <seealso cref="CharStream"/> at which the lexer
+ /// action should be executed. </returns>
+ int getOffset() const;
+
+ /// <summary>
+ /// Gets the lexer action to execute.
+ /// </summary>
+ /// <returns> A <seealso cref="LexerAction"/> object which executes the lexer action. </returns>
+ Ref<LexerAction> getAction() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// </summary>
+ /// <returns> This method returns the result of calling <seealso cref="#getActionType"/>
+ /// on the <seealso cref="LexerAction"/> returned by <seealso cref="#getAction"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code true}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ virtual void execute(Lexer *lexer) override;
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const int _offset;
+ const Ref<LexerAction> _action;
+ };
+
+} // namespace atn
+} // namespace antlr4
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Implements the {@code mode} lexer action by calling <seealso cref="Lexer#mode"/> with
+ /// the assigned mode.
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerModeAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a new {@code mode} action with the specified mode value. </summary>
+ /// <param name="mode"> The mode value to pass to <seealso cref="Lexer#mode"/>. </param>
+ LexerModeAction(int mode);
+
+ /// <summary>
+ /// Get the lexer mode this action should transition the lexer to.
+ /// </summary>
+ /// <returns> The lexer mode for this {@code mode} command. </returns>
+ int getMode();
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#MODE"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#mode"/> with the
+ /// value provided by <seealso cref="#getMode"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const int _mode;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Implements the {@code more} lexer action by calling <seealso cref="Lexer#more"/>.
+ ///
+ /// <para>The {@code more} command does not have any parameters, so this action is
+ /// implemented as a singleton instance exposed by <seealso cref="#INSTANCE"/>.</para>
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerMoreAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Provides a singleton instance of this parameterless lexer action.
+ /// </summary>
+ static const Ref<LexerMoreAction> getInstance();
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#MORE"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#more"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ /// Constructs the singleton instance of the lexer {@code more} command.
+ LexerMoreAction();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Implements the {@code popMode} lexer action by calling <seealso cref="Lexer#popMode"/>.
+ ///
+ /// <para>The {@code popMode} command does not have any parameters, so this action is
+ /// implemented as a singleton instance exposed by <seealso cref="#INSTANCE"/>.</para>
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerPopModeAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Provides a singleton instance of this parameterless lexer action.
+ /// </summary>
+ static const Ref<LexerPopModeAction> getInstance();
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#POP_MODE"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#popMode"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ /// Constructs the singleton instance of the lexer {@code popMode} command.
+ LexerPopModeAction();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Implements the {@code pushMode} lexer action by calling
+ /// <seealso cref="Lexer#pushMode"/> with the assigned mode.
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerPushModeAction final : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a new {@code pushMode} action with the specified mode value. </summary>
+ /// <param name="mode"> The mode value to pass to <seealso cref="Lexer#pushMode"/>. </param>
+ LexerPushModeAction(int mode);
+
+ /// <summary>
+ /// Get the lexer mode this action should transition the lexer to.
+ /// </summary>
+ /// <returns> The lexer mode for this {@code pushMode} command. </returns>
+ int getMode() const;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#PUSH_MODE"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#pushMode"/> with the
+ /// value provided by <seealso cref="#getMode"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const int _mode;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerAction.h"
+#include "atn/LexerActionType.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// Implements the {@code skip} lexer action by calling <seealso cref="Lexer#skip"/>.
+ ///
+ /// <para>The {@code skip} command does not have any parameters, so this action is
+ /// implemented as a singleton instance exposed by <seealso cref="#INSTANCE"/>.</para>
+ ///
+ /// @author Sam Harwell
+ /// @since 4.2
+ /// </summary>
+ class ANTLR4CPP_PUBLIC LexerSkipAction final : public LexerAction {
+ public:
+ /// Provides a singleton instance of this parameterless lexer action.
+ static const Ref<LexerSkipAction> getInstance();
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#SKIP"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#skip"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ /// Constructs the singleton instance of the lexer {@code skip} command.
+ LexerSkipAction();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/LexerActionType.h"
+#include "atn/LexerAction.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Implements the {@code type} lexer action by calling <seealso cref="Lexer#setType"/>
+ /// with the assigned type.
+ class ANTLR4CPP_PUBLIC LexerTypeAction : public LexerAction {
+ public:
+ /// <summary>
+ /// Constructs a new {@code type} action with the specified token type value. </summary>
+ /// <param name="type"> The type to assign to the token using <seealso cref="Lexer#setType"/>. </param>
+ LexerTypeAction(int type);
+
+ /// <summary>
+ /// Gets the type to assign to a token created by the lexer. </summary>
+ /// <returns> The type to assign to a token created by the lexer. </returns>
+ virtual int getType() const;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns <seealso cref="LexerActionType#TYPE"/>. </returns>
+ virtual LexerActionType getActionType() const override;
+
+ /// <summary>
+ /// {@inheritDoc} </summary>
+ /// <returns> This method returns {@code false}. </returns>
+ virtual bool isPositionDependent() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ ///
+ /// <para>This action is implemented by calling <seealso cref="Lexer#setType"/> with the
+ /// value provided by <seealso cref="#getType"/>.</para>
+ /// </summary>
+ virtual void execute(Lexer *lexer) override;
+
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const LexerAction &obj) const override;
+ virtual std::string toString() const override;
+
+ private:
+ const int _type;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionEventInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// This class represents profiling event information for tracking the lookahead
+ /// depth required in order to make a prediction.
+ class ANTLR4CPP_PUBLIC LookaheadEventInfo : public DecisionEventInfo {
+ public:
+ /// The alternative chosen by adaptivePredict(), not necessarily
+ /// the outermost alt shown for a rule; left-recursive rules have
+ /// user-level alts that differ from the rewritten rule with a (...) block
+ /// and a (..)* loop.
+ size_t predictedAlt = 0;
+
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="LookaheadEventInfo"/> class with
+ /// the specified detailed lookahead information.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ /// <param name="configs"> The final configuration set containing the necessary
+ /// information to determine the result of a prediction, or {@code null} if
+ /// the final configuration set is not available </param>
+ /// <param name="input"> The input token stream </param>
+ /// <param name="startIndex"> The start index for the current prediction </param>
+ /// <param name="stopIndex"> The index at which the prediction was finally made </param>
+ /// <param name="fullCtx"> {@code true} if the current lookahead is part of an LL
+ /// prediction; otherwise, {@code false} if the current lookahead is part of
+ /// an SLL prediction </param>
+ LookaheadEventInfo(size_t decision, ATNConfigSet *configs, size_t predictedAlt, TokenStream *input, size_t startIndex,
+ size_t stopIndex, bool fullCtx);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Mark the end of a * or + loop.
+ class ANTLR4CPP_PUBLIC LoopEndState final : public ATNState {
+ public:
+ ATNState *loopBackState = nullptr;
+
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/SetTransition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC NotSetTransition final : public SetTransition {
+ public:
+ NotSetTransition(ATNState *target, const misc::IntervalSet &set);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNConfigSet.h"
+#include "atn/ATNConfig.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC OrderedATNConfigSet : public ATNConfigSet {
+ protected:
+ virtual size_t getHash(ATNConfig *c) override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ProfilingATNSimulator;
+
+ /// This class provides access to specific and aggregate statistics gathered
+ /// during profiling of a parser.
+ class ANTLR4CPP_PUBLIC ParseInfo {
+ public:
+ ParseInfo(ProfilingATNSimulator *atnSimulator);
+ ParseInfo(ParseInfo const&) = default;
+ virtual ~ParseInfo();
+
+ ParseInfo& operator=(ParseInfo const&) = default;
+
+ /// <summary>
+ /// Gets an array of <seealso cref="DecisionInfo"/> instances containing the profiling
+ /// information gathered for each decision in the ATN.
+ /// </summary>
+ /// <returns> An array of <seealso cref="DecisionInfo"/> instances, indexed by decision
+ /// number. </returns>
+ virtual std::vector<DecisionInfo> getDecisionInfo();
+
+ /// <summary>
+ /// Gets the decision numbers for decisions that required one or more
+ /// full-context predictions during parsing. These are decisions for which
+ /// <seealso cref="DecisionInfo#LL_Fallback"/> is non-zero.
+ /// </summary>
+ /// <returns> A list of decision numbers which required one or more
+ /// full-context predictions during parsing. </returns>
+ virtual std::vector<size_t> getLLDecisions();
+
+ /// <summary>
+ /// Gets the total time spent during prediction across all decisions made
+ /// during parsing. This value is the sum of
+ /// <seealso cref="DecisionInfo#timeInPrediction"/> for all decisions.
+ /// </summary>
+ virtual long long getTotalTimeInPrediction();
+
+ /// <summary>
+ /// Gets the total number of SLL lookahead operations across all decisions
+ /// made during parsing. This value is the sum of
+ /// <seealso cref="DecisionInfo#SLL_TotalLook"/> for all decisions.
+ /// </summary>
+ virtual long long getTotalSLLLookaheadOps();
+
+ /// <summary>
+ /// Gets the total number of LL lookahead operations across all decisions
+ /// made during parsing. This value is the sum of
+ /// <seealso cref="DecisionInfo#LL_TotalLook"/> for all decisions.
+ /// </summary>
+ virtual long long getTotalLLLookaheadOps();
+
+ /// <summary>
+ /// Gets the total number of ATN lookahead operations for SLL prediction
+ /// across all decisions made during parsing.
+ /// </summary>
+ virtual long long getTotalSLLATNLookaheadOps();
+
+ /// <summary>
+ /// Gets the total number of ATN lookahead operations for LL prediction
+ /// across all decisions made during parsing.
+ /// </summary>
+ virtual long long getTotalLLATNLookaheadOps();
+
+ /// <summary>
+ /// Gets the total number of ATN lookahead operations for SLL and LL
+ /// prediction across all decisions made during parsing.
+ ///
+ /// <para>
+ /// This value is the sum of <seealso cref="#getTotalSLLATNLookaheadOps"/> and
+ /// <seealso cref="#getTotalLLATNLookaheadOps"/>.</para>
+ /// </summary>
+ virtual long long getTotalATNLookaheadOps();
+
+ /// <summary>
+ /// Gets the total number of DFA states stored in the DFA cache for all
+ /// decisions in the ATN.
+ /// </summary>
+ virtual size_t getDFASize();
+
+ /// <summary>
+ /// Gets the total number of DFA states stored in the DFA cache for a
+ /// particular decision.
+ /// </summary>
+ virtual size_t getDFASize(size_t decision);
+
+ protected:
+ const ProfilingATNSimulator *_atnSimulator; // non-owning, we are created by this simulator.
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "PredictionMode.h"
+#include "dfa/DFAState.h"
+#include "atn/ATNSimulator.h"
+#include "atn/PredictionContext.h"
+#include "SemanticContext.h"
+#include "atn/ATNConfig.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /**
+ * The embodiment of the adaptive LL(*), ALL(*), parsing strategy.
+ *
+ * <p>
+ * The basic complexity of the adaptive strategy makes it harder to understand.
+ * We begin with ATN simulation to build paths in a DFA. Subsequent prediction
+ * requests go through the DFA first. If they reach a state without an edge for
+ * the current symbol, the algorithm fails over to the ATN simulation to
+ * complete the DFA path for the current input (until it finds a conflict state
+ * or uniquely predicting state).</p>
+ *
+ * <p>
+ * All of that is done without using the outer context because we want to create
+ * a DFA that is not dependent upon the rule invocation stack when we do a
+ * prediction. One DFA works in all contexts. We avoid using context not
+ * necessarily because it's slower, although it can be, but because of the DFA
+ * caching problem. The closure routine only considers the rule invocation stack
+ * created during prediction beginning in the decision rule. For example, if
+ * prediction occurs without invoking another rule's ATN, there are no context
+ * stacks in the configurations. When lack of context leads to a conflict, we
+ * don't know if it's an ambiguity or a weakness in the strong LL(*) parsing
+ * strategy (versus full LL(*)).</p>
+ *
+ * <p>
+ * When SLL yields a configuration set with conflict, we rewind the input and
+ * retry the ATN simulation, this time using full outer context without adding
+ * to the DFA. Configuration context stacks will be the full invocation stacks
+ * from the start rule. If we get a conflict using full context, then we can
+ * definitively say we have a true ambiguity for that input sequence. If we
+ * don't get a conflict, it implies that the decision is sensitive to the outer
+ * context. (It is not context-sensitive in the sense of context-sensitive
+ * grammars.)</p>
+ *
+ * <p>
+ * The next time we reach this DFA state with an SLL conflict, through DFA
+ * simulation, we will again retry the ATN simulation using full context mode.
+ * This is slow because we can't save the results and have to "interpret" the
+ * ATN each time we get that input.</p>
+ *
+ * <p>
+ * <strong>CACHING FULL CONTEXT PREDICTIONS</strong></p>
+ *
+ * <p>
+ * We could cache results from full context to predicted alternative easily and
+ * that saves a lot of time but doesn't work in presence of predicates. The set
+ * of visible predicates from the ATN start state changes depending on the
+ * context, because closure can fall off the end of a rule. I tried to cache
+ * tuples (stack context, semantic context, predicted alt) but it was slower
+ * than interpreting and much more complicated. Also required a huge amount of
+ * memory. The goal is not to create the world's fastest parser anyway. I'd like
+ * to keep this algorithm simple. By launching multiple threads, we can improve
+ * the speed of parsing across a large number of files.</p>
+ *
+ * <p>
+ * There is no strict ordering between the amount of input used by SLL vs LL,
+ * which makes it really hard to build a cache for full context. Let's say that
+ * we have input A B C that leads to an SLL conflict with full context X. That
+ * implies that using X we might only use A B but we could also use A B C D to
+ * resolve conflict. Input A B C D could predict alternative 1 in one position
+ * in the input and A B C E could predict alternative 2 in another position in
+ * input. The conflicting SLL configurations could still be non-unique in the
+ * full context prediction, which would lead us to requiring more input than the
+ * original A B C. To make a prediction cache work, we have to track the exact
+ * input used during the previous prediction. That amounts to a cache that maps
+ * X to a specific DFA for that context.</p>
+ *
+ * <p>
+ * Something should be done for left-recursive expression predictions. They are
+ * likely LL(1) + pred eval. Easier to do the whole SLL unless error and retry
+ * with full LL thing Sam does.</p>
+ *
+ * <p>
+ * <strong>AVOIDING FULL CONTEXT PREDICTION</strong></p>
+ *
+ * <p>
+ * We avoid doing full context retry when the outer context is empty, we did not
+ * dip into the outer context by falling off the end of the decision state rule,
+ * or when we force SLL mode.</p>
+ *
+ * <p>
+ * As an example of the not dip into outer context case, consider as super
+ * constructor calls versus function calls. One grammar might look like
+ * this:</p>
+ *
+ * <pre>
+ * ctorBody
+ * : '{' superCall? stat* '}'
+ * ;
+ * </pre>
+ *
+ * <p>
+ * Or, you might see something like</p>
+ *
+ * <pre>
+ * stat
+ * : superCall ';'
+ * | expression ';'
+ * | ...
+ * ;
+ * </pre>
+ *
+ * <p>
+ * In both cases I believe that no closure operations will dip into the outer
+ * context. In the first case ctorBody in the worst case will stop at the '}'.
+ * In the 2nd case it should stop at the ';'. Both cases should stay within the
+ * entry rule and not dip into the outer context.</p>
+ *
+ * <p>
+ * <strong>PREDICATES</strong></p>
+ *
+ * <p>
+ * Predicates are always evaluated if present in either SLL or LL both. SLL and
+ * LL simulation deals with predicates differently. SLL collects predicates as
+ * it performs closure operations like ANTLR v3 did. It delays predicate
+ * evaluation until it reaches and accept state. This allows us to cache the SLL
+ * ATN simulation whereas, if we had evaluated predicates on-the-fly during
+ * closure, the DFA state configuration sets would be different and we couldn't
+ * build up a suitable DFA.</p>
+ *
+ * <p>
+ * When building a DFA accept state during ATN simulation, we evaluate any
+ * predicates and return the sole semantically valid alternative. If there is
+ * more than 1 alternative, we report an ambiguity. If there are 0 alternatives,
+ * we throw an exception. Alternatives without predicates act like they have
+ * true predicates. The simple way to think about it is to strip away all
+ * alternatives with false predicates and choose the minimum alternative that
+ * remains.</p>
+ *
+ * <p>
+ * When we start in the DFA and reach an accept state that's predicated, we test
+ * those and return the minimum semantically viable alternative. If no
+ * alternatives are viable, we throw an exception.</p>
+ *
+ * <p>
+ * During full LL ATN simulation, closure always evaluates predicates and
+ * on-the-fly. This is crucial to reducing the configuration set size during
+ * closure. It hits a landmine when parsing with the Java grammar, for example,
+ * without this on-the-fly evaluation.</p>
+ *
+ * <p>
+ * <strong>SHARING DFA</strong></p>
+ *
+ * <p>
+ * All instances of the same parser share the same decision DFAs through a
+ * static field. Each instance gets its own ATN simulator but they share the
+ * same {@link #decisionToDFA} field. They also share a
+ * {@link PredictionContextCache} object that makes sure that all
+ * {@link PredictionContext} objects are shared among the DFA states. This makes
+ * a big size difference.</p>
+ *
+ * <p>
+ * <strong>THREAD SAFETY</strong></p>
+ *
+ * <p>
+ * The {@link ParserATNSimulator} locks on the {@link #decisionToDFA} field when
+ * it adds a new DFA object to that array. {@link #addDFAEdge}
+ * locks on the DFA for the current decision when setting the
+ * {@link DFAState#edges} field. {@link #addDFAState} locks on
+ * the DFA for the current decision when looking up a DFA state to see if it
+ * already exists. We must make sure that all requests to add DFA states that
+ * are equivalent result in the same shared DFA object. This is because lots of
+ * threads will be trying to update the DFA at once. The
+ * {@link #addDFAState} method also locks inside the DFA lock
+ * but this time on the shared context cache when it rebuilds the
+ * configurations' {@link PredictionContext} objects using cached
+ * subgraphs/nodes. No other locking occurs, even during DFA simulation. This is
+ * safe as long as we can guarantee that all threads referencing
+ * {@code s.edge[t]} get the same physical target {@link DFAState}, or
+ * {@code null}. Once into the DFA, the DFA simulation does not reference the
+ * {@link DFA#states} map. It follows the {@link DFAState#edges} field to new
+ * targets. The DFA simulator will either find {@link DFAState#edges} to be
+ * {@code null}, to be non-{@code null} and {@code dfa.edges[t]} null, or
+ * {@code dfa.edges[t]} to be non-null. The
+ * {@link #addDFAEdge} method could be racing to set the field
+ * but in either case the DFA simulator works; if {@code null}, and requests ATN
+ * simulation. It could also race trying to get {@code dfa.edges[t]}, but either
+ * way it will work because it's not doing a test and set operation.</p>
+ *
+ * <p>
+ * <strong>Starting with SLL then failing to combined SLL/LL (Two-Stage
+ * Parsing)</strong></p>
+ *
+ * <p>
+ * Sam pointed out that if SLL does not give a syntax error, then there is no
+ * point in doing full LL, which is slower. We only have to try LL if we get a
+ * syntax error. For maximum speed, Sam starts the parser set to pure SLL
+ * mode with the {@link BailErrorStrategy}:</p>
+ *
+ * <pre>
+ * parser.{@link Parser#getInterpreter() getInterpreter()}.{@link #setPredictionMode setPredictionMode}{@code (}{@link PredictionMode#SLL}{@code )};
+ * parser.{@link Parser#setErrorHandler setErrorHandler}(new {@link BailErrorStrategy}());
+ * </pre>
+ *
+ * <p>
+ * If it does not get a syntax error, then we're done. If it does get a syntax
+ * error, we need to retry with the combined SLL/LL strategy.</p>
+ *
+ * <p>
+ * The reason this works is as follows. If there are no SLL conflicts, then the
+ * grammar is SLL (at least for that input set). If there is an SLL conflict,
+ * the full LL analysis must yield a set of viable alternatives which is a
+ * subset of the alternatives reported by SLL. If the LL set is a singleton,
+ * then the grammar is LL but not SLL. If the LL set is the same size as the SLL
+ * set, the decision is SLL. If the LL set has size > 1, then that decision
+ * is truly ambiguous on the current input. If the LL set is smaller, then the
+ * SLL conflict resolution might choose an alternative that the full LL would
+ * rule out as a possibility based upon better context information. If that's
+ * the case, then the SLL parse will definitely get an error because the full LL
+ * analysis says it's not viable. If SLL conflict resolution chooses an
+ * alternative within the LL set, them both SLL and LL would choose the same
+ * alternative because they both choose the minimum of multiple conflicting
+ * alternatives.</p>
+ *
+ * <p>
+ * Let's say we have a set of SLL conflicting alternatives {@code {1, 2, 3}} and
+ * a smaller LL set called <em>s</em>. If <em>s</em> is {@code {2, 3}}, then SLL
+ * parsing will get an error because SLL will pursue alternative 1. If
+ * <em>s</em> is {@code {1, 2}} or {@code {1, 3}} then both SLL and LL will
+ * choose the same alternative because alternative one is the minimum of either
+ * set. If <em>s</em> is {@code {2}} or {@code {3}} then SLL will get a syntax
+ * error. If <em>s</em> is {@code {1}} then SLL will succeed.</p>
+ *
+ * <p>
+ * Of course, if the input is invalid, then we will get an error for sure in
+ * both SLL and LL parsing. Erroneous input will therefore require 2 passes over
+ * the input.</p>
+ */
+ class ANTLR4CPP_PUBLIC ParserATNSimulator : public ATNSimulator {
+ public:
+ /// Testing only!
+ ParserATNSimulator(const ATN &atn, std::vector<dfa::DFA> &decisionToDFA,
+ PredictionContextCache &sharedContextCache);
+
+ ParserATNSimulator(Parser *parser, const ATN &atn, std::vector<dfa::DFA> &decisionToDFA,
+ PredictionContextCache &sharedContextCache);
+
+ virtual void reset() override;
+ virtual void clearDFA() override;
+ virtual size_t adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext);
+
+ static const bool TURN_OFF_LR_LOOP_ENTRY_BRANCH_OPT;
+
+ std::vector<dfa::DFA> &decisionToDFA;
+
+ /** Implements first-edge (loop entry) elimination as an optimization
+ * during closure operations. See antlr/antlr4#1398.
+ *
+ * The optimization is to avoid adding the loop entry config when
+ * the exit path can only lead back to the same
+ * StarLoopEntryState after popping context at the rule end state
+ * (traversing only epsilon edges, so we're still in closure, in
+ * this same rule).
+ *
+ * We need to detect any state that can reach loop entry on
+ * epsilon w/o exiting rule. We don't have to look at FOLLOW
+ * links, just ensure that all stack tops for config refer to key
+ * states in LR rule.
+ *
+ * To verify we are in the right situation we must first check
+ * closure is at a StarLoopEntryState generated during LR removal.
+ * Then we check that each stack top of context is a return state
+ * from one of these cases:
+ *
+ * 1. 'not' expr, '(' type ')' expr. The return state points at loop entry state
+ * 2. expr op expr. The return state is the block end of internal block of (...)*
+ * 3. 'between' expr 'and' expr. The return state of 2nd expr reference.
+ * That state points at block end of internal block of (...)*.
+ * 4. expr '?' expr ':' expr. The return state points at block end,
+ * which points at loop entry state.
+ *
+ * If any is true for each stack top, then closure does not add a
+ * config to the current config set for edge[0], the loop entry branch.
+ *
+ * Conditions fail if any context for the current config is:
+ *
+ * a. empty (we'd fall out of expr to do a global FOLLOW which could
+ * even be to some weird spot in expr) or,
+ * b. lies outside of expr or,
+ * c. lies within expr but at a state not the BlockEndState
+ * generated during LR removal
+ *
+ * Do we need to evaluate predicates ever in closure for this case?
+ *
+ * No. Predicates, including precedence predicates, are only
+ * evaluated when computing a DFA start state. I.e., only before
+ * the lookahead (but not parser) consumes a token.
+ *
+ * There are no epsilon edges allowed in LR rule alt blocks or in
+ * the "primary" part (ID here). If closure is in
+ * StarLoopEntryState any lookahead operation will have consumed a
+ * token as there are no epsilon-paths that lead to
+ * StarLoopEntryState. We do not have to evaluate predicates
+ * therefore if we are in the generated StarLoopEntryState of a LR
+ * rule. Note that when making a prediction starting at that
+ * decision point, decision d=2, compute-start-state performs
+ * closure starting at edges[0], edges[1] emanating from
+ * StarLoopEntryState. That means it is not performing closure on
+ * StarLoopEntryState during compute-start-state.
+ *
+ * How do we know this always gives same prediction answer?
+ *
+ * Without predicates, loop entry and exit paths are ambiguous
+ * upon remaining input +b (in, say, a+b). Either paths lead to
+ * valid parses. Closure can lead to consuming + immediately or by
+ * falling out of this call to expr back into expr and loop back
+ * again to StarLoopEntryState to match +b. In this special case,
+ * we choose the more efficient path, which is to take the bypass
+ * path.
+ *
+ * The lookahead language has not changed because closure chooses
+ * one path over the other. Both paths lead to consuming the same
+ * remaining input during a lookahead operation. If the next token
+ * is an operator, lookahead will enter the choice block with
+ * operators. If it is not, lookahead will exit expr. Same as if
+ * closure had chosen to enter the choice block immediately.
+ *
+ * Closure is examining one config (some loopentrystate, some alt,
+ * context) which means it is considering exactly one alt. Closure
+ * always copies the same alt to any derived configs.
+ *
+ * How do we know this optimization doesn't mess up precedence in
+ * our parse trees?
+ *
+ * Looking through expr from left edge of stat only has to confirm
+ * that an input, say, a+b+c; begins with any valid interpretation
+ * of an expression. The precedence actually doesn't matter when
+ * making a decision in stat seeing through expr. It is only when
+ * parsing rule expr that we must use the precedence to get the
+ * right interpretation and, hence, parse tree.
+ */
+ bool canDropLoopEntryEdgeInLeftRecursiveRule(ATNConfig *config) const;
+ virtual std::string getRuleName(size_t index);
+
+ virtual Ref<ATNConfig> precedenceTransition(Ref<ATNConfig> const& config, PrecedencePredicateTransition *pt,
+ bool collectPredicates, bool inContext, bool fullCtx);
+
+ void setPredictionMode(PredictionMode newMode);
+ PredictionMode getPredictionMode();
+
+ Parser* getParser();
+
+ virtual std::string getTokenName(size_t t);
+
+ virtual std::string getLookaheadName(TokenStream *input);
+
+ /// <summary>
+ /// Used for debugging in adaptivePredict around execATN but I cut
+ /// it out for clarity now that alg. works well. We can leave this
+ /// "dead" code for a bit.
+ /// </summary>
+ virtual void dumpDeadEndConfigs(NoViableAltException &nvae);
+
+ protected:
+ Parser *const parser;
+
+ /// <summary>
+ /// Each prediction operation uses a cache for merge of prediction contexts.
+ /// Don't keep around as it wastes huge amounts of memory. The merge cache
+ /// isn't synchronized but we're ok since two threads shouldn't reuse same
+ /// parser/atnsim object because it can only handle one input at a time.
+ /// This maps graphs a and b to merged result c. (a,b)->c. We can avoid
+ /// the merge if we ever see a and b again. Note that (b,a)->c should
+ /// also be examined during cache lookup.
+ /// </summary>
+ PredictionContextMergeCache mergeCache;
+
+ // LAME globals to avoid parameters!!!!! I need these down deep in predTransition
+ TokenStream *_input;
+ size_t _startIndex;
+ ParserRuleContext *_outerContext;
+ dfa::DFA *_dfa; // Reference into the decisionToDFA vector.
+
+ /// <summary>
+ /// Performs ATN simulation to compute a predicted alternative based
+ /// upon the remaining input, but also updates the DFA cache to avoid
+ /// having to traverse the ATN again for the same input sequence.
+ ///
+ /// There are some key conditions we're looking for after computing a new
+ /// set of ATN configs (proposed DFA state):
+ /// if the set is empty, there is no viable alternative for current symbol
+ /// does the state uniquely predict an alternative?
+ /// does the state have a conflict that would prevent us from
+ /// putting it on the work list?
+ ///
+ /// We also have some key operations to do:
+ /// add an edge from previous DFA state to potentially new DFA state, D,
+ /// upon current symbol but only if adding to work list, which means in all
+ /// cases except no viable alternative (and possibly non-greedy decisions?)
+ /// collecting predicates and adding semantic context to DFA accept states
+ /// adding rule context to context-sensitive DFA accept states
+ /// consuming an input symbol
+ /// reporting a conflict
+ /// reporting an ambiguity
+ /// reporting a context sensitivity
+ /// reporting insufficient predicates
+ ///
+ /// cover these cases:
+ /// dead end
+ /// single alt
+ /// single alt + preds
+ /// conflict
+ /// conflict + preds
+ /// </summary>
+ virtual size_t execATN(dfa::DFA &dfa, dfa::DFAState *s0, TokenStream *input, size_t startIndex,
+ ParserRuleContext *outerContext);
+
+ /// <summary>
+ /// Get an existing target state for an edge in the DFA. If the target state
+ /// for the edge has not yet been computed or is otherwise not available,
+ /// this method returns {@code null}.
+ /// </summary>
+ /// <param name="previousD"> The current DFA state </param>
+ /// <param name="t"> The next input symbol </param>
+ /// <returns> The existing target DFA state for the given input symbol
+ /// {@code t}, or {@code null} if the target state for this edge is not
+ /// already cached </returns>
+ virtual dfa::DFAState* getExistingTargetState(dfa::DFAState *previousD, size_t t);
+
+ /// <summary>
+ /// Compute a target state for an edge in the DFA, and attempt to add the
+ /// computed state and corresponding edge to the DFA.
+ /// </summary>
+ /// <param name="dfa"> The DFA </param>
+ /// <param name="previousD"> The current DFA state </param>
+ /// <param name="t"> The next input symbol
+ /// </param>
+ /// <returns> The computed target DFA state for the given input symbol
+ /// {@code t}. If {@code t} does not lead to a valid DFA state, this method
+ /// returns <seealso cref="#ERROR"/>. </returns>
+ virtual dfa::DFAState *computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, size_t t);
+
+ virtual void predicateDFAState(dfa::DFAState *dfaState, DecisionState *decisionState);
+
+ // comes back with reach.uniqueAlt set to a valid alt
+ virtual size_t execATNWithFullContext(dfa::DFA &dfa, dfa::DFAState *D, ATNConfigSet *s0,
+ TokenStream *input, size_t startIndex, ParserRuleContext *outerContext); // how far we got before failing over
+
+ virtual std::unique_ptr<ATNConfigSet> computeReachSet(ATNConfigSet *closure, size_t t, bool fullCtx);
+
+ /// <summary>
+ /// Return a configuration set containing only the configurations from
+ /// {@code configs} which are in a <seealso cref="RuleStopState"/>. If all
+ /// configurations in {@code configs} are already in a rule stop state, this
+ /// method simply returns {@code configs}.
+ /// <p/>
+ /// When {@code lookToEndOfRule} is true, this method uses
+ /// <seealso cref="ATN#nextTokens"/> for each configuration in {@code configs} which is
+ /// not already in a rule stop state to see if a rule stop state is reachable
+ /// from the configuration via epsilon-only transitions.
+ /// </summary>
+ /// <param name="configs"> the configuration set to update </param>
+ /// <param name="lookToEndOfRule"> when true, this method checks for rule stop states
+ /// reachable by epsilon-only transitions from each configuration in
+ /// {@code configs}.
+ /// </param>
+ /// <returns> {@code configs} if all configurations in {@code configs} are in a
+ /// rule stop state, otherwise return a new configuration set containing only
+ /// the configurations from {@code configs} which are in a rule stop state </returns>
+ virtual ATNConfigSet* removeAllConfigsNotInRuleStopState(ATNConfigSet *configs, bool lookToEndOfRule);
+
+ virtual std::unique_ptr<ATNConfigSet> computeStartState(ATNState *p, RuleContext *ctx, bool fullCtx);
+
+ /* parrt internal source braindump that doesn't mess up
+ * external API spec.
+
+ applyPrecedenceFilter is an optimization to avoid highly
+ nonlinear prediction of expressions and other left recursive
+ rules. The precedence predicates such as {3>=prec}? Are highly
+ context-sensitive in that they can only be properly evaluated
+ in the context of the proper prec argument. Without pruning,
+ these predicates are normal predicates evaluated when we reach
+ conflict state (or unique prediction). As we cannot evaluate
+ these predicates out of context, the resulting conflict leads
+ to full LL evaluation and nonlinear prediction which shows up
+ very clearly with fairly large expressions.
+
+ Example grammar:
+
+ e : e '*' e
+ | e '+' e
+ | INT
+ ;
+
+ We convert that to the following:
+
+ e[int prec]
+ : INT
+ ( {3>=prec}? '*' e[4]
+ | {2>=prec}? '+' e[3]
+ )*
+ ;
+
+ The (..)* loop has a decision for the inner block as well as
+ an enter or exit decision, which is what concerns us here. At
+ the 1st + of input 1+2+3, the loop entry sees both predicates
+ and the loop exit also sees both predicates by falling off the
+ edge of e. This is because we have no stack information with
+ SLL and find the follow of e, which will hit the return states
+ inside the loop after e[4] and e[3], which brings it back to
+ the enter or exit decision. In this case, we know that we
+ cannot evaluate those predicates because we have fallen off
+ the edge of the stack and will in general not know which prec
+ parameter is the right one to use in the predicate.
+
+ Because we have special information, that these are precedence
+ predicates, we can resolve them without failing over to full
+ LL despite their context sensitive nature. We make an
+ assumption that prec[-1] <= prec[0], meaning that the current
+ precedence level is greater than or equal to the precedence
+ level of recursive invocations above us in the stack. For
+ example, if predicate {3>=prec}? is true of the current prec,
+ then one option is to enter the loop to match it now. The
+ other option is to exit the loop and the left recursive rule
+ to match the current operator in rule invocation further up
+ the stack. But, we know that all of those prec are lower or
+ the same value and so we can decide to enter the loop instead
+ of matching it later. That means we can strip out the other
+ configuration for the exit branch.
+
+ So imagine we have (14,1,$,{2>=prec}?) and then
+ (14,2,$-dipsIntoOuterContext,{2>=prec}?). The optimization
+ allows us to collapse these two configurations. We know that
+ if {2>=prec}? is true for the current prec parameter, it will
+ also be true for any prec from an invoking e call, indicated
+ by dipsIntoOuterContext. As the predicates are both true, we
+ have the option to evaluate them early in the decision start
+ state. We do this by stripping both predicates and choosing to
+ enter the loop as it is consistent with the notion of operator
+ precedence. It's also how the full LL conflict resolution
+ would work.
+
+ The solution requires a different DFA start state for each
+ precedence level.
+
+ The basic filter mechanism is to remove configurations of the
+ form (p, 2, pi) if (p, 1, pi) exists for the same p and pi. In
+ other words, for the same ATN state and predicate context,
+ remove any configuration associated with an exit branch if
+ there is a configuration associated with the enter branch.
+
+ It's also the case that the filter evaluates precedence
+ predicates and resolves conflicts according to precedence
+ levels. For example, for input 1+2+3 at the first +, we see
+ prediction filtering
+
+ [(11,1,[$],{3>=prec}?), (14,1,[$],{2>=prec}?), (5,2,[$],up=1),
+ (11,2,[$],up=1), (14,2,[$],up=1)],hasSemanticContext=true,dipsIntoOuterContext
+
+ to
+
+ [(11,1,[$]), (14,1,[$]), (5,2,[$],up=1)],dipsIntoOuterContext
+
+ This filters because {3>=prec}? evals to true and collapses
+ (11,1,[$],{3>=prec}?) and (11,2,[$],up=1) since early conflict
+ resolution based upon rules of operator precedence fits with
+ our usual match first alt upon conflict.
+
+ We noticed a problem where a recursive call resets precedence
+ to 0. Sam's fix: each config has flag indicating if it has
+ returned from an expr[0] call. then just don't filter any
+ config with that flag set. flag is carried along in
+ closure(). so to avoid adding field, set bit just under sign
+ bit of dipsIntoOuterContext (SUPPRESS_PRECEDENCE_FILTER).
+ With the change you filter "unless (p, 2, pi) was reached
+ after leaving the rule stop state of the LR rule containing
+ state p, corresponding to a rule invocation with precedence
+ level 0"
+ */
+
+ /**
+ * This method transforms the start state computed by
+ * {@link #computeStartState} to the special start state used by a
+ * precedence DFA for a particular precedence value. The transformation
+ * process applies the following changes to the start state's configuration
+ * set.
+ *
+ * <ol>
+ * <li>Evaluate the precedence predicates for each configuration using
+ * {@link SemanticContext#evalPrecedence}.</li>
+ * <li>When {@link ATNConfig#isPrecedenceFilterSuppressed} is {@code false},
+ * remove all configurations which predict an alternative greater than 1,
+ * for which another configuration that predicts alternative 1 is in the
+ * same ATN state with the same prediction context. This transformation is
+ * valid for the following reasons:
+ * <ul>
+ * <li>The closure block cannot contain any epsilon transitions which bypass
+ * the body of the closure, so all states reachable via alternative 1 are
+ * part of the precedence alternatives of the transformed left-recursive
+ * rule.</li>
+ * <li>The "primary" portion of a left recursive rule cannot contain an
+ * epsilon transition, so the only way an alternative other than 1 can exist
+ * in a state that is also reachable via alternative 1 is by nesting calls
+ * to the left-recursive rule, with the outer calls not being at the
+ * preferred precedence level. The
+ * {@link ATNConfig#isPrecedenceFilterSuppressed} property marks ATN
+ * configurations which do not meet this condition, and therefore are not
+ * eligible for elimination during the filtering process.</li>
+ * </ul>
+ * </li>
+ * </ol>
+ *
+ * <p>
+ * The prediction context must be considered by this filter to address
+ * situations like the following.
+ * </p>
+ * <code>
+ * <pre>
+ * grammar TA;
+ * prog: statement* EOF;
+ * statement: letterA | statement letterA 'b' ;
+ * letterA: 'a';
+ * </pre>
+ * </code>
+ * <p>
+ * If the above grammar, the ATN state immediately before the token
+ * reference {@code 'a'} in {@code letterA} is reachable from the left edge
+ * of both the primary and closure blocks of the left-recursive rule
+ * {@code statement}. The prediction context associated with each of these
+ * configurations distinguishes between them, and prevents the alternative
+ * which stepped out to {@code prog} (and then back in to {@code statement}
+ * from being eliminated by the filter.
+ * </p>
+ *
+ * @param configs The configuration set computed by
+ * {@link #computeStartState} as the start state for the DFA.
+ * @return The transformed configuration set representing the start state
+ * for a precedence DFA at a particular precedence level (determined by
+ * calling {@link Parser#getPrecedence}).
+ */
+ std::unique_ptr<ATNConfigSet> applyPrecedenceFilter(ATNConfigSet *configs);
+
+ virtual ATNState *getReachableTarget(Transition *trans, size_t ttype);
+
+ virtual std::vector<Ref<SemanticContext>> getPredsForAmbigAlts(const antlrcpp::BitSet &ambigAlts,
+ ATNConfigSet *configs, size_t nalts);
+
+ virtual std::vector<dfa::DFAState::PredPrediction*> getPredicatePredictions(const antlrcpp::BitSet &ambigAlts,
+ std::vector<Ref<SemanticContext>> const& altToPred);
+
+ /**
+ * This method is used to improve the localization of error messages by
+ * choosing an alternative rather than throwing a
+ * {@link NoViableAltException} in particular prediction scenarios where the
+ * {@link #ERROR} state was reached during ATN simulation.
+ *
+ * <p>
+ * The default implementation of this method uses the following
+ * algorithm to identify an ATN configuration which successfully parsed the
+ * decision entry rule. Choosing such an alternative ensures that the
+ * {@link ParserRuleContext} returned by the calling rule will be complete
+ * and valid, and the syntax error will be reported later at a more
+ * localized location.</p>
+ *
+ * <ul>
+ * <li>If a syntactically valid path or paths reach the end of the decision rule and
+ * they are semantically valid if predicated, return the min associated alt.</li>
+ * <li>Else, if a semantically invalid but syntactically valid path exist
+ * or paths exist, return the minimum associated alt.
+ * </li>
+ * <li>Otherwise, return {@link ATN#INVALID_ALT_NUMBER}.</li>
+ * </ul>
+ *
+ * <p>
+ * In some scenarios, the algorithm described above could predict an
+ * alternative which will result in a {@link FailedPredicateException} in
+ * the parser. Specifically, this could occur if the <em>only</em> configuration
+ * capable of successfully parsing to the end of the decision rule is
+ * blocked by a semantic predicate. By choosing this alternative within
+ * {@link #adaptivePredict} instead of throwing a
+ * {@link NoViableAltException}, the resulting
+ * {@link FailedPredicateException} in the parser will identify the specific
+ * predicate which is preventing the parser from successfully parsing the
+ * decision rule, which helps developers identify and correct logic errors
+ * in semantic predicates.
+ * </p>
+ *
+ * @param configs The ATN configurations which were valid immediately before
+ * the {@link #ERROR} state was reached
+ * @param outerContext The is the \gamma_0 initial parser context from the paper
+ * or the parser stack at the instant before prediction commences.
+ *
+ * @return The value to return from {@link #adaptivePredict}, or
+ * {@link ATN#INVALID_ALT_NUMBER} if a suitable alternative was not
+ * identified and {@link #adaptivePredict} should report an error instead.
+ */
+ size_t getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule(ATNConfigSet *configs,
+ ParserRuleContext *outerContext);
+
+ virtual size_t getAltThatFinishedDecisionEntryRule(ATNConfigSet *configs);
+
+ /** Walk the list of configurations and split them according to
+ * those that have preds evaluating to true/false. If no pred, assume
+ * true pred and include in succeeded set. Returns Pair of sets.
+ *
+ * Create a new set so as not to alter the incoming parameter.
+ *
+ * Assumption: the input stream has been restored to the starting point
+ * prediction, which is where predicates need to evaluate.
+ */
+ std::pair<ATNConfigSet *, ATNConfigSet *> splitAccordingToSemanticValidity(ATNConfigSet *configs,
+ ParserRuleContext *outerContext);
+
+ /// <summary>
+ /// Look through a list of predicate/alt pairs, returning alts for the
+ /// pairs that win. A {@code NONE} predicate indicates an alt containing an
+ /// unpredicated config which behaves as "always true." If !complete
+ /// then we stop at the first predicate that evaluates to true. This
+ /// includes pairs with null predicates.
+ /// </summary>
+ virtual antlrcpp::BitSet evalSemanticContext(std::vector<dfa::DFAState::PredPrediction*> predPredictions,
+ ParserRuleContext *outerContext, bool complete);
+
+ /**
+ * Evaluate a semantic context within a specific parser context.
+ *
+ * <p>
+ * This method might not be called for every semantic context evaluated
+ * during the prediction process. In particular, we currently do not
+ * evaluate the following but it may change in the future:</p>
+ *
+ * <ul>
+ * <li>Precedence predicates (represented by
+ * {@link SemanticContext.PrecedencePredicate}) are not currently evaluated
+ * through this method.</li>
+ * <li>Operator predicates (represented by {@link SemanticContext.AND} and
+ * {@link SemanticContext.OR}) are evaluated as a single semantic
+ * context, rather than evaluating the operands individually.
+ * Implementations which require evaluation results from individual
+ * predicates should override this method to explicitly handle evaluation of
+ * the operands within operator predicates.</li>
+ * </ul>
+ *
+ * @param pred The semantic context to evaluate
+ * @param parserCallStack The parser context in which to evaluate the
+ * semantic context
+ * @param alt The alternative which is guarded by {@code pred}
+ * @param fullCtx {@code true} if the evaluation is occurring during LL
+ * prediction; otherwise, {@code false} if the evaluation is occurring
+ * during SLL prediction
+ *
+ * @since 4.3
+ */
+ virtual bool evalSemanticContext(Ref<SemanticContext> const& pred, ParserRuleContext *parserCallStack,
+ size_t alt, bool fullCtx);
+
+ /* TODO: If we are doing predicates, there is no point in pursuing
+ closure operations if we reach a DFA state that uniquely predicts
+ alternative. We will not be caching that DFA state and it is a
+ waste to pursue the closure. Might have to advance when we do
+ ambig detection thought :(
+ */
+ virtual void closure(Ref<ATNConfig> const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy,
+ bool collectPredicates, bool fullCtx, bool treatEofAsEpsilon);
+
+ virtual void closureCheckingStopState(Ref<ATNConfig> const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy,
+ bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon);
+
+ /// Do the actual work of walking epsilon edges.
+ virtual void closure_(Ref<ATNConfig> const& config, ATNConfigSet *configs, ATNConfig::Set &closureBusy,
+ bool collectPredicates, bool fullCtx, int depth, bool treatEofAsEpsilon);
+
+ virtual Ref<ATNConfig> getEpsilonTarget(Ref<ATNConfig> const& config, Transition *t, bool collectPredicates,
+ bool inContext, bool fullCtx, bool treatEofAsEpsilon);
+ virtual Ref<ATNConfig> actionTransition(Ref<ATNConfig> const& config, ActionTransition *t);
+
+ virtual Ref<ATNConfig> predTransition(Ref<ATNConfig> const& config, PredicateTransition *pt, bool collectPredicates,
+ bool inContext, bool fullCtx);
+
+ virtual Ref<ATNConfig> ruleTransition(Ref<ATNConfig> const& config, RuleTransition *t);
+
+ /**
+ * Gets a {@link BitSet} containing the alternatives in {@code configs}
+ * which are part of one or more conflicting alternative subsets.
+ *
+ * @param configs The {@link ATNConfigSet} to analyze.
+ * @return The alternatives in {@code configs} which are part of one or more
+ * conflicting alternative subsets. If {@code configs} does not contain any
+ * conflicting subsets, this method returns an empty {@link BitSet}.
+ */
+ virtual antlrcpp::BitSet getConflictingAlts(ATNConfigSet *configs);
+
+ /// <summary>
+ /// Sam pointed out a problem with the previous definition, v3, of
+ /// ambiguous states. If we have another state associated with conflicting
+ /// alternatives, we should keep going. For example, the following grammar
+ ///
+ /// s : (ID | ID ID?) ';' ;
+ ///
+ /// When the ATN simulation reaches the state before ';', it has a DFA
+ /// state that looks like: [12|1|[], 6|2|[], 12|2|[]]. Naturally
+ /// 12|1|[] and 12|2|[] conflict, but we cannot stop processing this node
+ /// because alternative to has another way to continue, via [6|2|[]].
+ /// The key is that we have a single state that has config's only associated
+ /// with a single alternative, 2, and crucially the state transitions
+ /// among the configurations are all non-epsilon transitions. That means
+ /// we don't consider any conflicts that include alternative 2. So, we
+ /// ignore the conflict between alts 1 and 2. We ignore a set of
+ /// conflicting alts when there is an intersection with an alternative
+ /// associated with a single alt state in the state->config-list map.
+ ///
+ /// It's also the case that we might have two conflicting configurations but
+ /// also a 3rd nonconflicting configuration for a different alternative:
+ /// [1|1|[], 1|2|[], 8|3|[]]. This can come about from grammar:
+ ///
+ /// a : A | A | A B ;
+ ///
+ /// After matching input A, we reach the stop state for rule A, state 1.
+ /// State 8 is the state right before B. Clearly alternatives 1 and 2
+ /// conflict and no amount of further lookahead will separate the two.
+ /// However, alternative 3 will be able to continue and so we do not
+ /// stop working on this state. In the previous example, we're concerned
+ /// with states associated with the conflicting alternatives. Here alt
+ /// 3 is not associated with the conflicting configs, but since we can continue
+ /// looking for input reasonably, I don't declare the state done. We
+ /// ignore a set of conflicting alts when we have an alternative
+ /// that we still need to pursue.
+ /// </summary>
+
+ virtual antlrcpp::BitSet getConflictingAltsOrUniqueAlt(ATNConfigSet *configs);
+
+ virtual NoViableAltException noViableAlt(TokenStream *input, ParserRuleContext *outerContext,
+ ATNConfigSet *configs, size_t startIndex, bool deleteConfigs);
+
+ static size_t getUniqueAlt(ATNConfigSet *configs);
+
+ /// <summary>
+ /// Add an edge to the DFA, if possible. This method calls
+ /// <seealso cref="#addDFAState"/> to ensure the {@code to} state is present in the
+ /// DFA. If {@code from} is {@code null}, or if {@code t} is outside the
+ /// range of edges that can be represented in the DFA tables, this method
+ /// returns without adding the edge to the DFA.
+ /// <p/>
+ /// If {@code to} is {@code null}, this method returns {@code null}.
+ /// Otherwise, this method returns the <seealso cref="DFAState"/> returned by calling
+ /// <seealso cref="#addDFAState"/> for the {@code to} state.
+ /// </summary>
+ /// <param name="dfa"> The DFA </param>
+ /// <param name="from"> The source state for the edge </param>
+ /// <param name="t"> The input symbol </param>
+ /// <param name="to"> The target state for the edge
+ /// </param>
+ /// <returns> If {@code to} is {@code null}, this method returns {@code null};
+ /// otherwise this method returns the result of calling <seealso cref="#addDFAState"/>
+ /// on {@code to} </returns>
+ virtual dfa::DFAState *addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from, ssize_t t, dfa::DFAState *to);
+
+ /// <summary>
+ /// Add state {@code D} to the DFA if it is not already present, and return
+ /// the actual instance stored in the DFA. If a state equivalent to {@code D}
+ /// is already in the DFA, the existing state is returned. Otherwise this
+ /// method returns {@code D} after adding it to the DFA.
+ /// <p/>
+ /// If {@code D} is <seealso cref="#ERROR"/>, this method returns <seealso cref="#ERROR"/> and
+ /// does not change the DFA.
+ /// </summary>
+ /// <param name="dfa"> The dfa </param>
+ /// <param name="D"> The DFA state to add </param>
+ /// <returns> The state stored in the DFA. This will be either the existing
+ /// state if {@code D} is already in the DFA, or {@code D} itself if the
+ /// state was not already present. </returns>
+ virtual dfa::DFAState *addDFAState(dfa::DFA &dfa, dfa::DFAState *D);
+
+ virtual void reportAttemptingFullContext(dfa::DFA &dfa, const antlrcpp::BitSet &conflictingAlts,
+ ATNConfigSet *configs, size_t startIndex, size_t stopIndex);
+
+ virtual void reportContextSensitivity(dfa::DFA &dfa, size_t prediction, ATNConfigSet *configs,
+ size_t startIndex, size_t stopIndex);
+
+ /// If context sensitive parsing, we know it's ambiguity not conflict.
+ virtual void reportAmbiguity(dfa::DFA &dfa,
+ dfa::DFAState *D, // the DFA state from execATN() that had SLL conflicts
+ size_t startIndex, size_t stopIndex,
+ bool exact,
+ const antlrcpp::BitSet &ambigAlts,
+ ATNConfigSet *configs); // configs that LL not SLL considered conflicting
+
+ private:
+ // SLL, LL, or LL + exact ambig detection?
+ PredictionMode _mode;
+
+ static bool getLrLoopSetting();
+ void InitializeInstanceFields();
+ };
+
+} // namespace atn
+} // namespace antlr4
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/BlockStartState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Start of {@code (A|B|...)+} loop. Technically a decision state, but
+ /// we don't use for code generation; somebody might need it, so I'm defining
+ /// it for completeness. In reality, the <seealso cref="PlusLoopbackState"/> node is the
+ /// real decision-making note for {@code A+}.
+ class ANTLR4CPP_PUBLIC PlusBlockStartState final : public BlockStartState {
+ public:
+ PlusLoopbackState *loopBackState = nullptr;
+
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// Decision state for {@code A+} and {@code (A|B)+}. It has two transitions:
+ /// one to the loop back to start of the block and one to exit.
+ class ANTLR4CPP_PUBLIC PlusLoopbackState final : public DecisionState {
+
+ public:
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/AbstractPredicateTransition.h"
+#include "SemanticContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC PrecedencePredicateTransition final : public AbstractPredicateTransition {
+ public:
+ const int precedence;
+
+ PrecedencePredicateTransition(ATNState *target, int precedence);
+
+ virtual SerializationType getSerializationType() const override;
+ virtual bool isEpsilon() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+ Ref<SemanticContext::PrecedencePredicate> getPredicate() const;
+ virtual std::string toString() const override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionEventInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// This class represents profiling event information for semantic predicate
+ /// evaluations which occur during prediction.
+ /// </summary>
+ /// <seealso cref= ParserATNSimulator#evalSemanticContext
+ ///
+ /// @since 4.3 </seealso>
+ class ANTLR4CPP_PUBLIC PredicateEvalInfo : public DecisionEventInfo {
+ public:
+ /// The semantic context which was evaluated.
+ const Ref<SemanticContext> semctx;
+
+ /// <summary>
+ /// The alternative number for the decision which is guarded by the semantic
+ /// context <seealso cref="#semctx"/>. Note that other ATN
+ /// configurations may predict the same alternative which are guarded by
+ /// other semantic contexts and/or <seealso cref="SemanticContext#NONE"/>.
+ /// </summary>
+ const size_t predictedAlt;
+
+ /// The result of evaluating the semantic context <seealso cref="#semctx"/>.
+ const bool evalResult;
+
+ /// <summary>
+ /// Constructs a new instance of the <seealso cref="PredicateEvalInfo"/> class with the
+ /// specified detailed predicate evaluation information.
+ /// </summary>
+ /// <param name="decision"> The decision number </param>
+ /// <param name="input"> The input token stream </param>
+ /// <param name="startIndex"> The start index for the current prediction </param>
+ /// <param name="stopIndex"> The index at which the predicate evaluation was
+ /// triggered. Note that the input stream may be reset to other positions for
+ /// the actual evaluation of individual predicates. </param>
+ /// <param name="semctx"> The semantic context which was evaluated </param>
+ /// <param name="evalResult"> The results of evaluating the semantic context </param>
+ /// <param name="predictedAlt"> The alternative number for the decision which is
+ /// guarded by the semantic context {@code semctx}. See <seealso cref="#predictedAlt"/>
+ /// for more information. </param>
+ /// <param name="fullCtx"> {@code true} if the semantic context was
+ /// evaluated during LL prediction; otherwise, {@code false} if the semantic
+ /// context was evaluated during SLL prediction
+ /// </param>
+ /// <seealso cref= ParserATNSimulator#evalSemanticContext(SemanticContext, ParserRuleContext, int, boolean) </seealso>
+ /// <seealso cref= SemanticContext#eval(Recognizer, RuleContext) </seealso>
+ PredicateEvalInfo(size_t decision, TokenStream *input, size_t startIndex, size_t stopIndex,
+ Ref<SemanticContext> const& semctx, bool evalResult, size_t predictedAlt, bool fullCtx);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/AbstractPredicateTransition.h"
+#include "SemanticContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// TODO: this is old comment:
+ /// A tree of semantic predicates from the grammar AST if label==SEMPRED.
+ /// In the ATN, labels will always be exactly one predicate, but the DFA
+ /// may have to combine a bunch of them as it collects predicates from
+ /// multiple ATN configurations into a single DFA state.
+ class ANTLR4CPP_PUBLIC PredicateTransition final : public AbstractPredicateTransition {
+ public:
+ const size_t ruleIndex;
+ const size_t predIndex;
+ const bool isCtxDependent; // e.g., $i ref in pred
+
+ PredicateTransition(ATNState *target, size_t ruleIndex, size_t predIndex, bool isCtxDependent);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool isEpsilon() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ Ref<SemanticContext::Predicate> getPredicate() const;
+
+ virtual std::string toString() const override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Recognizer.h"
+#include "atn/ATN.h"
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ struct PredictionContextHasher;
+ struct PredictionContextComparer;
+ class PredictionContextMergeCache;
+
+ typedef std::unordered_set<Ref<PredictionContext>, PredictionContextHasher, PredictionContextComparer> PredictionContextCache;
+
+ class ANTLR4CPP_PUBLIC PredictionContext {
+ public:
+ /// Represents $ in local context prediction, which means wildcard.
+ /// *+x = *.
+ static const Ref<PredictionContext> EMPTY;
+
+ /// Represents $ in an array in full context mode, when $
+ /// doesn't mean wildcard: $ + x = [$,x]. Here,
+ /// $ = EMPTY_RETURN_STATE.
+ // ml: originally Integer.MAX_VALUE, which would be -1 for us, but this is already used in places where
+ // -1 is converted to unsigned, so we use a different value here. Any value does the job provided it doesn't
+ // conflict with real return states.
+#if __cplusplus >= 201703L
+ static constexpr size_t EMPTY_RETURN_STATE = std::numeric_limits<size_t>::max() - 9;
+#else
+ enum : size_t {
+ EMPTY_RETURN_STATE = static_cast<size_t>(-10), // std::numeric_limits<size_t>::max() - 9; doesn't work in VS 2013
+ };
+#endif
+
+ private:
+#if __cplusplus >= 201703L
+ static constexpr size_t INITIAL_HASH = 1;
+#else
+ enum : size_t {
+ INITIAL_HASH = 1,
+ };
+#endif
+
+ public:
+ static size_t globalNodeCount;
+ const size_t id;
+
+ /// <summary>
+ /// Stores the computed hash code of this <seealso cref="PredictionContext"/>. The hash
+ /// code is computed in parts to match the following reference algorithm.
+ ///
+ /// <pre>
+ /// private int referenceHashCode() {
+ /// int hash = <seealso cref="MurmurHash#initialize"/>(<seealso cref="#INITIAL_HASH"/>);
+ ///
+ /// for (int i = 0; i < <seealso cref="#size()"/>; i++) {
+ /// hash = <seealso cref="MurmurHash#update"/>(hash, <seealso cref="#getParent"/>(i));
+ /// }
+ ///
+ /// for (int i = 0; i < <seealso cref="#size()"/>; i++) {
+ /// hash = <seealso cref="MurmurHash#update"/>(hash, <seealso cref="#getReturnState"/>(i));
+ /// }
+ ///
+ /// hash = <seealso cref="MurmurHash#finish"/>(hash, 2 * <seealso cref="#size()"/>);
+ /// return hash;
+ /// }
+ /// </pre>
+ /// </summary>
+ const size_t cachedHashCode;
+
+ protected:
+ PredictionContext(size_t cachedHashCode);
+ ~PredictionContext();
+
+ public:
+ /// Convert a RuleContext tree to a PredictionContext graph.
+ /// Return EMPTY if outerContext is empty.
+ static Ref<PredictionContext> fromRuleContext(const ATN &atn, RuleContext *outerContext);
+
+ virtual size_t size() const = 0;
+ virtual Ref<PredictionContext> getParent(size_t index) const = 0;
+ virtual size_t getReturnState(size_t index) const = 0;
+
+ virtual bool operator == (const PredictionContext &o) const = 0;
+
+ /// This means only the EMPTY (wildcard? not sure) context is in set.
+ virtual bool isEmpty() const;
+ virtual bool hasEmptyPath() const;
+ virtual size_t hashCode() const;
+
+ protected:
+ static size_t calculateEmptyHashCode();
+ static size_t calculateHashCode(Ref<PredictionContext> parent, size_t returnState);
+ static size_t calculateHashCode(const std::vector<Ref<PredictionContext>> &parents,
+ const std::vector<size_t> &returnStates);
+
+ public:
+ // dispatch
+ static Ref<PredictionContext> merge(const Ref<PredictionContext> &a, const Ref<PredictionContext> &b,
+ bool rootIsWildcard, PredictionContextMergeCache *mergeCache);
+
+ /// <summary>
+ /// Merge two <seealso cref="SingletonPredictionContext"/> instances.
+ ///
+ /// <p/>
+ ///
+ /// Stack tops equal, parents merge is same; return left graph.<br/>
+ /// <embed src="images/SingletonMerge_SameRootSamePar.svg" type="image/svg+xml"/>
+ ///
+ /// <p/>
+ ///
+ /// Same stack top, parents differ; merge parents giving array node, then
+ /// remainders of those graphs. A new root node is created to point to the
+ /// merged parents.<br/>
+ /// <embed src="images/SingletonMerge_SameRootDiffPar.svg" type="image/svg+xml"/>
+ ///
+ /// <p/>
+ ///
+ /// Different stack tops pointing to same parent. Make array node for the
+ /// root where both element in the root point to the same (original)
+ /// parent.<br/>
+ /// <embed src="images/SingletonMerge_DiffRootSamePar.svg" type="image/svg+xml"/>
+ ///
+ /// <p/>
+ ///
+ /// Different stack tops pointing to different parents. Make array node for
+ /// the root where each element points to the corresponding original
+ /// parent.<br/>
+ /// <embed src="images/SingletonMerge_DiffRootDiffPar.svg" type="image/svg+xml"/>
+ /// </summary>
+ /// <param name="a"> the first <seealso cref="SingletonPredictionContext"/> </param>
+ /// <param name="b"> the second <seealso cref="SingletonPredictionContext"/> </param>
+ /// <param name="rootIsWildcard"> {@code true} if this is a local-context merge,
+ /// otherwise false to indicate a full-context merge </param>
+ /// <param name="mergeCache"> </param>
+ static Ref<PredictionContext> mergeSingletons(const Ref<SingletonPredictionContext> &a,
+ const Ref<SingletonPredictionContext> &b, bool rootIsWildcard, PredictionContextMergeCache *mergeCache);
+
+ /**
+ * Handle case where at least one of {@code a} or {@code b} is
+ * {@link #EMPTY}. In the following diagrams, the symbol {@code $} is used
+ * to represent {@link #EMPTY}.
+ *
+ * <h2>Local-Context Merges</h2>
+ *
+ * <p>These local-context merge operations are used when {@code rootIsWildcard}
+ * is true.</p>
+ *
+ * <p>{@link #EMPTY} is superset of any graph; return {@link #EMPTY}.<br>
+ * <embed src="images/LocalMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
+ *
+ * <p>{@link #EMPTY} and anything is {@code #EMPTY}, so merged parent is
+ * {@code #EMPTY}; return left graph.<br>
+ * <embed src="images/LocalMerge_EmptyParent.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Special case of last merge if local context.<br>
+ * <embed src="images/LocalMerge_DiffRoots.svg" type="image/svg+xml"/></p>
+ *
+ * <h2>Full-Context Merges</h2>
+ *
+ * <p>These full-context merge operations are used when {@code rootIsWildcard}
+ * is false.</p>
+ *
+ * <p><embed src="images/FullMerge_EmptyRoots.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Must keep all contexts; {@link #EMPTY} in array is a special value (and
+ * null parent).<br>
+ * <embed src="images/FullMerge_EmptyRoot.svg" type="image/svg+xml"/></p>
+ *
+ * <p><embed src="images/FullMerge_SameRoot.svg" type="image/svg+xml"/></p>
+ *
+ * @param a the first {@link SingletonPredictionContext}
+ * @param b the second {@link SingletonPredictionContext}
+ * @param rootIsWildcard {@code true} if this is a local-context merge,
+ * otherwise false to indicate a full-context merge
+ */
+ static Ref<PredictionContext> mergeRoot(const Ref<SingletonPredictionContext> &a,
+ const Ref<SingletonPredictionContext> &b, bool rootIsWildcard);
+
+ /**
+ * Merge two {@link ArrayPredictionContext} instances.
+ *
+ * <p>Different tops, different parents.<br>
+ * <embed src="images/ArrayMerge_DiffTopDiffPar.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Shared top, same parents.<br>
+ * <embed src="images/ArrayMerge_ShareTopSamePar.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Shared top, different parents.<br>
+ * <embed src="images/ArrayMerge_ShareTopDiffPar.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Shared top, all shared parents.<br>
+ * <embed src="images/ArrayMerge_ShareTopSharePar.svg" type="image/svg+xml"/></p>
+ *
+ * <p>Equal tops, merge parents and reduce top to
+ * {@link SingletonPredictionContext}.<br>
+ * <embed src="images/ArrayMerge_EqualTop.svg" type="image/svg+xml"/></p>
+ */
+ static Ref<PredictionContext> mergeArrays(const Ref<ArrayPredictionContext> &a,
+ const Ref<ArrayPredictionContext> &b, bool rootIsWildcard, PredictionContextMergeCache *mergeCache);
+
+ protected:
+ /// Make pass over all M parents; merge any equal() ones.
+ /// @returns true if the list has been changed (i.e. duplicates where found).
+ static bool combineCommonParents(std::vector<Ref<PredictionContext>> &parents);
+
+ public:
+ static std::string toDOTString(const Ref<PredictionContext> &context);
+
+ static Ref<PredictionContext> getCachedContext(const Ref<PredictionContext> &context,
+ PredictionContextCache &contextCache,
+ std::map<Ref<PredictionContext>, Ref<PredictionContext>> &visited);
+
+ // ter's recursive version of Sam's getAllNodes()
+ static std::vector<Ref<PredictionContext>> getAllContextNodes(const Ref<PredictionContext> &context);
+ static void getAllContextNodes_(const Ref<PredictionContext> &context,
+ std::vector<Ref<PredictionContext>> &nodes, std::set<PredictionContext *> &visited);
+
+ virtual std::string toString() const;
+ virtual std::string toString(Recognizer *recog) const;
+
+ std::vector<std::string> toStrings(Recognizer *recognizer, int currentState);
+ std::vector<std::string> toStrings(Recognizer *recognizer, const Ref<PredictionContext> &stop, int currentState);
+ };
+
+ struct PredictionContextHasher {
+ size_t operator () (const Ref<PredictionContext> &k) const {
+ return k->hashCode();
+ }
+ };
+
+ struct PredictionContextComparer {
+ bool operator () (const Ref<PredictionContext> &lhs, const Ref<PredictionContext> &rhs) const
+ {
+ if (lhs == rhs) // Object identity.
+ return true;
+ return (lhs->hashCode() == rhs->hashCode()) && (*lhs == *rhs);
+ }
+ };
+
+ class PredictionContextMergeCache {
+ public:
+ Ref<PredictionContext> put(Ref<PredictionContext> const& key1, Ref<PredictionContext> const& key2,
+ Ref<PredictionContext> const& value);
+ Ref<PredictionContext> get(Ref<PredictionContext> const& key1, Ref<PredictionContext> const& key2);
+
+ void clear();
+ std::string toString() const;
+ size_t count() const;
+
+ private:
+ std::unordered_map<Ref<PredictionContext>,
+ std::unordered_map<Ref<PredictionContext>, Ref<PredictionContext>, PredictionContextHasher, PredictionContextComparer>,
+ PredictionContextHasher, PredictionContextComparer> _data;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "support/BitSet.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /**
+ * This enumeration defines the prediction modes available in ANTLR 4 along with
+ * utility methods for analyzing configuration sets for conflicts and/or
+ * ambiguities.
+ */
+ enum class PredictionMode {
+ /**
+ * The SLL(*) prediction mode. This prediction mode ignores the current
+ * parser context when making predictions. This is the fastest prediction
+ * mode, and provides correct results for many grammars. This prediction
+ * mode is more powerful than the prediction mode provided by ANTLR 3, but
+ * may result in syntax errors for grammar and input combinations which are
+ * not SLL.
+ *
+ * <p>
+ * When using this prediction mode, the parser will either return a correct
+ * parse tree (i.e. the same parse tree that would be returned with the
+ * {@link #LL} prediction mode), or it will report a syntax error. If a
+ * syntax error is encountered when using the {@link #SLL} prediction mode,
+ * it may be due to either an actual syntax error in the input or indicate
+ * that the particular combination of grammar and input requires the more
+ * powerful {@link #LL} prediction abilities to complete successfully.</p>
+ *
+ * <p>
+ * This prediction mode does not provide any guarantees for prediction
+ * behavior for syntactically-incorrect inputs.</p>
+ */
+ SLL,
+
+ /**
+ * The LL(*) prediction mode. This prediction mode allows the current parser
+ * context to be used for resolving SLL conflicts that occur during
+ * prediction. This is the fastest prediction mode that guarantees correct
+ * parse results for all combinations of grammars with syntactically correct
+ * inputs.
+ *
+ * <p>
+ * When using this prediction mode, the parser will make correct decisions
+ * for all syntactically-correct grammar and input combinations. However, in
+ * cases where the grammar is truly ambiguous this prediction mode might not
+ * report a precise answer for <em>exactly which</em> alternatives are
+ * ambiguous.</p>
+ *
+ * <p>
+ * This prediction mode does not provide any guarantees for prediction
+ * behavior for syntactically-incorrect inputs.</p>
+ */
+ LL,
+
+ /**
+ * The LL(*) prediction mode with exact ambiguity detection. In addition to
+ * the correctness guarantees provided by the {@link #LL} prediction mode,
+ * this prediction mode instructs the prediction algorithm to determine the
+ * complete and exact set of ambiguous alternatives for every ambiguous
+ * decision encountered while parsing.
+ *
+ * <p>
+ * This prediction mode may be used for diagnosing ambiguities during
+ * grammar development. Due to the performance overhead of calculating sets
+ * of ambiguous alternatives, this prediction mode should be avoided when
+ * the exact results are not necessary.</p>
+ *
+ * <p>
+ * This prediction mode does not provide any guarantees for prediction
+ * behavior for syntactically-incorrect inputs.</p>
+ */
+ LL_EXACT_AMBIG_DETECTION
+ };
+
+ class ANTLR4CPP_PUBLIC PredictionModeClass {
+ public:
+ /**
+ * Computes the SLL prediction termination condition.
+ *
+ * <p>
+ * This method computes the SLL prediction termination condition for both of
+ * the following cases.</p>
+ *
+ * <ul>
+ * <li>The usual SLL+LL fallback upon SLL conflict</li>
+ * <li>Pure SLL without LL fallback</li>
+ * </ul>
+ *
+ * <p><strong>COMBINED SLL+LL PARSING</strong></p>
+ *
+ * <p>When LL-fallback is enabled upon SLL conflict, correct predictions are
+ * ensured regardless of how the termination condition is computed by this
+ * method. Due to the substantially higher cost of LL prediction, the
+ * prediction should only fall back to LL when the additional lookahead
+ * cannot lead to a unique SLL prediction.</p>
+ *
+ * <p>Assuming combined SLL+LL parsing, an SLL configuration set with only
+ * conflicting subsets should fall back to full LL, even if the
+ * configuration sets don't resolve to the same alternative (e.g.
+ * {@code {1,2}} and {@code {3,4}}. If there is at least one non-conflicting
+ * configuration, SLL could continue with the hopes that more lookahead will
+ * resolve via one of those non-conflicting configurations.</p>
+ *
+ * <p>Here's the prediction termination rule them: SLL (for SLL+LL parsing)
+ * stops when it sees only conflicting configuration subsets. In contrast,
+ * full LL keeps going when there is uncertainty.</p>
+ *
+ * <p><strong>HEURISTIC</strong></p>
+ *
+ * <p>As a heuristic, we stop prediction when we see any conflicting subset
+ * unless we see a state that only has one alternative associated with it.
+ * The single-alt-state thing lets prediction continue upon rules like
+ * (otherwise, it would admit defeat too soon):</p>
+ *
+ * <p>{@code [12|1|[], 6|2|[], 12|2|[]]. s : (ID | ID ID?) ';' ;}</p>
+ *
+ * <p>When the ATN simulation reaches the state before {@code ';'}, it has a
+ * DFA state that looks like: {@code [12|1|[], 6|2|[], 12|2|[]]}. Naturally
+ * {@code 12|1|[]} and {@code 12|2|[]} conflict, but we cannot stop
+ * processing this node because alternative to has another way to continue,
+ * via {@code [6|2|[]]}.</p>
+ *
+ * <p>It also let's us continue for this rule:</p>
+ *
+ * <p>{@code [1|1|[], 1|2|[], 8|3|[]] a : A | A | A B ;}</p>
+ *
+ * <p>After matching input A, we reach the stop state for rule A, state 1.
+ * State 8 is the state right before B. Clearly alternatives 1 and 2
+ * conflict and no amount of further lookahead will separate the two.
+ * However, alternative 3 will be able to continue and so we do not stop
+ * working on this state. In the previous example, we're concerned with
+ * states associated with the conflicting alternatives. Here alt 3 is not
+ * associated with the conflicting configs, but since we can continue
+ * looking for input reasonably, don't declare the state done.</p>
+ *
+ * <p><strong>PURE SLL PARSING</strong></p>
+ *
+ * <p>To handle pure SLL parsing, all we have to do is make sure that we
+ * combine stack contexts for configurations that differ only by semantic
+ * predicate. From there, we can do the usual SLL termination heuristic.</p>
+ *
+ * <p><strong>PREDICATES IN SLL+LL PARSING</strong></p>
+ *
+ * <p>SLL decisions don't evaluate predicates until after they reach DFA stop
+ * states because they need to create the DFA cache that works in all
+ * semantic situations. In contrast, full LL evaluates predicates collected
+ * during start state computation so it can ignore predicates thereafter.
+ * This means that SLL termination detection can totally ignore semantic
+ * predicates.</p>
+ *
+ * <p>Implementation-wise, {@link ATNConfigSet} combines stack contexts but not
+ * semantic predicate contexts so we might see two configurations like the
+ * following.</p>
+ *
+ * <p>{@code (s, 1, x, {}), (s, 1, x', {p})}</p>
+ *
+ * <p>Before testing these configurations against others, we have to merge
+ * {@code x} and {@code x'} (without modifying the existing configurations).
+ * For example, we test {@code (x+x')==x''} when looking for conflicts in
+ * the following configurations.</p>
+ *
+ * <p>{@code (s, 1, x, {}), (s, 1, x', {p}), (s, 2, x'', {})}</p>
+ *
+ * <p>If the configuration set has predicates (as indicated by
+ * {@link ATNConfigSet#hasSemanticContext}), this algorithm makes a copy of
+ * the configurations to strip out all of the predicates so that a standard
+ * {@link ATNConfigSet} will merge everything ignoring predicates.</p>
+ */
+ static bool hasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet *configs);
+
+ /// <summary>
+ /// Checks if any configuration in {@code configs} is in a
+ /// <seealso cref="RuleStopState"/>. Configurations meeting this condition have
+ /// reached
+ /// the end of the decision rule (local context) or end of start rule (full
+ /// context).
+ /// </summary>
+ /// <param name="configs"> the configuration set to test </param>
+ /// <returns> {@code true} if any configuration in {@code configs} is in a
+ /// <seealso cref="RuleStopState"/>, otherwise {@code false} </returns>
+ static bool hasConfigInRuleStopState(ATNConfigSet *configs);
+
+ /// <summary>
+ /// Checks if all configurations in {@code configs} are in a
+ /// <seealso cref="RuleStopState"/>. Configurations meeting this condition have
+ /// reached
+ /// the end of the decision rule (local context) or end of start rule (full
+ /// context).
+ /// </summary>
+ /// <param name="configs"> the configuration set to test </param>
+ /// <returns> {@code true} if all configurations in {@code configs} are in a
+ /// <seealso cref="RuleStopState"/>, otherwise {@code false} </returns>
+ static bool allConfigsInRuleStopStates(ATNConfigSet *configs);
+
+ /**
+ * Full LL prediction termination.
+ *
+ * <p>Can we stop looking ahead during ATN simulation or is there some
+ * uncertainty as to which alternative we will ultimately pick, after
+ * consuming more input? Even if there are partial conflicts, we might know
+ * that everything is going to resolve to the same minimum alternative. That
+ * means we can stop since no more lookahead will change that fact. On the
+ * other hand, there might be multiple conflicts that resolve to different
+ * minimums. That means we need more look ahead to decide which of those
+ * alternatives we should predict.</p>
+ *
+ * <p>The basic idea is to split the set of configurations {@code C}, into
+ * conflicting subsets {@code (s, _, ctx, _)} and singleton subsets with
+ * non-conflicting configurations. Two configurations conflict if they have
+ * identical {@link ATNConfig#state} and {@link ATNConfig#context} values
+ * but different {@link ATNConfig#alt} value, e.g. {@code (s, i, ctx, _)}
+ * and {@code (s, j, ctx, _)} for {@code i!=j}.</p>
+ *
+ * <p>Reduce these configuration subsets to the set of possible alternatives.
+ * You can compute the alternative subsets in one pass as follows:</p>
+ *
+ * <p>{@code A_s,ctx = {i | (s, i, ctx, _)}} for each configuration in
+ * {@code C} holding {@code s} and {@code ctx} fixed.</p>
+ *
+ * <p>Or in pseudo-code, for each configuration {@code c} in {@code C}:</p>
+ *
+ * <pre>
+ * map[c] U= c.{@link ATNConfig#alt alt} # map hash/equals uses s and x, not
+ * alt and not pred
+ * </pre>
+ *
+ * <p>The values in {@code map} are the set of {@code A_s,ctx} sets.</p>
+ *
+ * <p>If {@code |A_s,ctx|=1} then there is no conflict associated with
+ * {@code s} and {@code ctx}.</p>
+ *
+ * <p>Reduce the subsets to singletons by choosing a minimum of each subset. If
+ * the union of these alternative subsets is a singleton, then no amount of
+ * more lookahead will help us. We will always pick that alternative. If,
+ * however, there is more than one alternative, then we are uncertain which
+ * alternative to predict and must continue looking for resolution. We may
+ * or may not discover an ambiguity in the future, even if there are no
+ * conflicting subsets this round.</p>
+ *
+ * <p>The biggest sin is to terminate early because it means we've made a
+ * decision but were uncertain as to the eventual outcome. We haven't used
+ * enough lookahead. On the other hand, announcing a conflict too late is no
+ * big deal; you will still have the conflict. It's just inefficient. It
+ * might even look until the end of file.</p>
+ *
+ * <p>No special consideration for semantic predicates is required because
+ * predicates are evaluated on-the-fly for full LL prediction, ensuring that
+ * no configuration contains a semantic context during the termination
+ * check.</p>
+ *
+ * <p><strong>CONFLICTING CONFIGS</strong></p>
+ *
+ * <p>Two configurations {@code (s, i, x)} and {@code (s, j, x')}, conflict
+ * when {@code i!=j} but {@code x=x'}. Because we merge all
+ * {@code (s, i, _)} configurations together, that means that there are at
+ * most {@code n} configurations associated with state {@code s} for
+ * {@code n} possible alternatives in the decision. The merged stacks
+ * complicate the comparison of configuration contexts {@code x} and
+ * {@code x'}. Sam checks to see if one is a subset of the other by calling
+ * merge and checking to see if the merged result is either {@code x} or
+ * {@code x'}. If the {@code x} associated with lowest alternative {@code i}
+ * is the superset, then {@code i} is the only possible prediction since the
+ * others resolve to {@code min(i)} as well. However, if {@code x} is
+ * associated with {@code j>i} then at least one stack configuration for
+ * {@code j} is not in conflict with alternative {@code i}. The algorithm
+ * should keep going, looking for more lookahead due to the uncertainty.</p>
+ *
+ * <p>For simplicity, I'm doing a equality check between {@code x} and
+ * {@code x'} that lets the algorithm continue to consume lookahead longer
+ * than necessary. The reason I like the equality is of course the
+ * simplicity but also because that is the test you need to detect the
+ * alternatives that are actually in conflict.</p>
+ *
+ * <p><strong>CONTINUE/STOP RULE</strong></p>
+ *
+ * <p>Continue if union of resolved alternative sets from non-conflicting and
+ * conflicting alternative subsets has more than one alternative. We are
+ * uncertain about which alternative to predict.</p>
+ *
+ * <p>The complete set of alternatives, {@code [i for (_,i,_)]}, tells us which
+ * alternatives are still in the running for the amount of input we've
+ * consumed at this point. The conflicting sets let us to strip away
+ * configurations that won't lead to more states because we resolve
+ * conflicts to the configuration with a minimum alternate for the
+ * conflicting set.</p>
+ *
+ * <p><strong>CASES</strong></p>
+ *
+ * <ul>
+ *
+ * <li>no conflicts and more than 1 alternative in set => continue</li>
+ *
+ * <li> {@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s, 3, z)},
+ * {@code (s', 1, y)}, {@code (s', 2, y)} yields non-conflicting set
+ * {@code {3}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
+ * {@code {1,3}} => continue
+ * </li>
+ *
+ * <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
+ * {@code (s', 2, y)}, {@code (s'', 1, z)} yields non-conflicting set
+ * {@code {1}} U conflicting sets {@code min({1,2})} U {@code min({1,2})} =
+ * {@code {1}} => stop and predict 1</li>
+ *
+ * <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 1, y)},
+ * {@code (s', 2, y)} yields conflicting, reduced sets {@code {1}} U
+ * {@code {1}} = {@code {1}} => stop and predict 1, can announce
+ * ambiguity {@code {1,2}}</li>
+ *
+ * <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 2, y)},
+ * {@code (s', 3, y)} yields conflicting, reduced sets {@code {1}} U
+ * {@code {2}} = {@code {1,2}} => continue</li>
+ *
+ * <li>{@code (s, 1, x)}, {@code (s, 2, x)}, {@code (s', 3, y)},
+ * {@code (s', 4, y)} yields conflicting, reduced sets {@code {1}} U
+ * {@code {3}} = {@code {1,3}} => continue</li>
+ *
+ * </ul>
+ *
+ * <p><strong>EXACT AMBIGUITY DETECTION</strong></p>
+ *
+ * <p>If all states report the same conflicting set of alternatives, then we
+ * know we have the exact ambiguity set.</p>
+ *
+ * <p><code>|A_<em>i</em>|>1</code> and
+ * <code>A_<em>i</em> = A_<em>j</em></code> for all <em>i</em>, <em>j</em>.</p>
+ *
+ * <p>In other words, we continue examining lookahead until all {@code A_i}
+ * have more than one alternative and all {@code A_i} are the same. If
+ * {@code A={{1,2}, {1,3}}}, then regular LL prediction would terminate
+ * because the resolved set is {@code {1}}. To determine what the real
+ * ambiguity is, we have to know whether the ambiguity is between one and
+ * two or one and three so we keep going. We can only stop prediction when
+ * we need exact ambiguity detection when the sets look like
+ * {@code A={{1,2}}} or {@code {{1,2},{1,2}}}, etc...</p>
+ */
+ static size_t resolvesToJustOneViableAlt(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Determines if every alternative subset in {@code altsets} contains more
+ /// than one alternative.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ /// <returns> {@code true} if every <seealso cref="BitSet"/> in {@code altsets}
+ /// has
+ /// <seealso cref="BitSet#cardinality cardinality"/> > 1, otherwise {@code
+ /// false} </returns>
+ static bool allSubsetsConflict(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Determines if any single alternative subset in {@code altsets} contains
+ /// exactly one alternative.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ /// <returns> {@code true} if {@code altsets} contains a <seealso
+ /// cref="BitSet"/> with
+ /// <seealso cref="BitSet#cardinality cardinality"/> 1, otherwise {@code false}
+ /// </returns>
+ static bool hasNonConflictingAltSet(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Determines if any single alternative subset in {@code altsets} contains
+ /// more than one alternative.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ /// <returns> {@code true} if {@code altsets} contains a <seealso
+ /// cref="BitSet"/> with
+ /// <seealso cref="BitSet#cardinality cardinality"/> > 1, otherwise {@code
+ /// false} </returns>
+ static bool hasConflictingAltSet(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Determines if every alternative subset in {@code altsets} is equivalent.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ /// <returns> {@code true} if every member of {@code altsets} is equal to the
+ /// others, otherwise {@code false} </returns>
+ static bool allSubsetsEqual(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Returns the unique alternative predicted by all alternative subsets in
+ /// {@code altsets}. If no such alternative exists, this method returns
+ /// <seealso cref="ATN#INVALID_ALT_NUMBER"/>.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ static size_t getUniqueAlt(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /// <summary>
+ /// Gets the complete set of represented alternatives for a collection of
+ /// alternative subsets. This method returns the union of each <seealso
+ /// cref="BitSet"/>
+ /// in {@code altsets}.
+ /// </summary>
+ /// <param name="altsets"> a collection of alternative subsets </param>
+ /// <returns> the set of represented alternatives in {@code altsets} </returns>
+ static antlrcpp::BitSet getAlts(const std::vector<antlrcpp::BitSet> &altsets);
+
+ /** Get union of all alts from configs. @since 4.5.1 */
+ static antlrcpp::BitSet getAlts(ATNConfigSet *configs);
+
+ /// <summary>
+ /// This function gets the conflicting alt subsets from a configuration set.
+ /// For each configuration {@code c} in {@code configs}:
+ ///
+ /// <pre>
+ /// map[c] U= c.<seealso cref="ATNConfig#alt alt"/> # map hash/equals uses s and
+ /// x, not
+ /// alt and not pred
+ /// </pre>
+ /// </summary>
+ static std::vector<antlrcpp::BitSet> getConflictingAltSubsets(ATNConfigSet *configs);
+
+ /// <summary>
+ /// Get a map from state to alt subset from a configuration set. For each
+ /// configuration {@code c} in {@code configs}:
+ ///
+ /// <pre>
+ /// map[c.<seealso cref="ATNConfig#state state"/>] U= c.<seealso
+ /// cref="ATNConfig#alt alt"/>
+ /// </pre>
+ /// </summary>
+ static std::map<ATNState*, antlrcpp::BitSet> getStateToAltMap(ATNConfigSet *configs);
+
+ static bool hasStateAssociatedWithOneAlt(ATNConfigSet *configs);
+
+ static size_t getSingleViableAlt(const std::vector<antlrcpp::BitSet> &altsets);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ParserATNSimulator.h"
+#include "atn/DecisionInfo.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC ProfilingATNSimulator : public ParserATNSimulator {
+ public:
+ ProfilingATNSimulator(Parser *parser);
+
+ virtual size_t adaptivePredict(TokenStream *input, size_t decision, ParserRuleContext *outerContext) override;
+
+ virtual std::vector<DecisionInfo> getDecisionInfo() const;
+ virtual dfa::DFAState* getCurrentState() const;
+
+ protected:
+ std::vector<DecisionInfo> _decisions;
+
+ int _sllStopIndex = 0;
+ int _llStopIndex = 0;
+
+ size_t _currentDecision = 0;
+ dfa::DFAState *_currentState;
+
+ /// <summary>
+ /// At the point of LL failover, we record how SLL would resolve the conflict so that
+ /// we can determine whether or not a decision / input pair is context-sensitive.
+ /// If LL gives a different result than SLL's predicted alternative, we have a
+ /// context sensitivity for sure. The converse is not necessarily true, however.
+ /// It's possible that after conflict resolution chooses minimum alternatives,
+ /// SLL could get the same answer as LL. Regardless of whether or not the result indicates
+ /// an ambiguity, it is not treated as a context sensitivity because LL prediction
+ /// was not required in order to produce a correct prediction for this decision and input sequence.
+ /// It may in fact still be a context sensitivity but we don't know by looking at the
+ /// minimum alternatives for the current input.
+ /// </summary>
+ size_t conflictingAltResolvedBySLL = 0;
+
+ virtual dfa::DFAState* getExistingTargetState(dfa::DFAState *previousD, size_t t) override;
+ virtual dfa::DFAState* computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, size_t t) override;
+ virtual std::unique_ptr<ATNConfigSet> computeReachSet(ATNConfigSet *closure, size_t t, bool fullCtx) override;
+ virtual bool evalSemanticContext(Ref<SemanticContext> const& pred, ParserRuleContext *parserCallStack,
+ size_t alt, bool fullCtx) override;
+ virtual void reportAttemptingFullContext(dfa::DFA &dfa, const antlrcpp::BitSet &conflictingAlts, ATNConfigSet *configs,
+ size_t startIndex, size_t stopIndex) override;
+ virtual void reportContextSensitivity(dfa::DFA &dfa, size_t prediction, ATNConfigSet *configs,
+ size_t startIndex, size_t stopIndex) override;
+ virtual void reportAmbiguity(dfa::DFA &dfa, dfa::DFAState *D, size_t startIndex, size_t stopIndex, bool exact,
+ const antlrcpp::BitSet &ambigAlts, ATNConfigSet *configs) override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC RangeTransition final : public Transition {
+ public:
+ const size_t from;
+ const size_t to;
+
+ RangeTransition(ATNState *target, size_t from, size_t to);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual misc::IntervalSet label() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC RuleStartState final : public ATNState {
+ public:
+ RuleStartState();
+
+ RuleStopState *stopState = nullptr;
+ bool isLeftRecursiveRule = false;
+
+ virtual size_t getStateType() override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// The last node in the ATN for a rule, unless that rule is the start symbol.
+ /// In that case, there is one transition to EOF. Later, we might encode
+ /// references to all calls to this rule to compute FOLLOW sets for
+ /// error handling.
+ class ANTLR4CPP_PUBLIC RuleStopState final : public ATNState {
+
+ public:
+ virtual size_t getStateType() override;
+
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC RuleTransition : public Transition {
+ public:
+ /// Ptr to the rule definition object for this rule ref.
+ const size_t ruleIndex; // no Rule object at runtime
+
+ const int precedence;
+
+ /// What node to begin computations following ref to rule.
+ ATNState *followState;
+
+ /// @deprecated Use
+ /// <seealso cref="#RuleTransition(RuleStartState, size_t, int, ATNState)"/> instead.
+ RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, ATNState *followState);
+
+ RuleTransition(RuleStartState *ruleStart, size_t ruleIndex, int precedence, ATNState *followState);
+ RuleTransition(RuleTransition const&) = delete;
+ RuleTransition& operator=(RuleTransition const&) = delete;
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool isEpsilon() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Recognizer.h"
+#include "support/CPPUtils.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// A tree structure used to record the semantic context in which
+ /// an ATN configuration is valid. It's either a single predicate,
+ /// a conjunction "p1 && p2", or a sum of products "p1||p2".
+ ///
+ /// I have scoped the AND, OR, and Predicate subclasses of
+ /// SemanticContext within the scope of this outer class.
+ class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this<SemanticContext> {
+ public:
+ struct Hasher
+ {
+ size_t operator()(Ref<SemanticContext> const& k) const {
+ return k->hashCode();
+ }
+ };
+
+ struct Comparer {
+ bool operator()(Ref<SemanticContext> const& lhs, Ref<SemanticContext> const& rhs) const {
+ if (lhs == rhs)
+ return true;
+ return (lhs->hashCode() == rhs->hashCode()) && (*lhs == *rhs);
+ }
+ };
+
+
+ using Set = std::unordered_set<Ref<SemanticContext>, Hasher, Comparer>;
+
+ /**
+ * The default {@link SemanticContext}, which is semantically equivalent to
+ * a predicate of the form {@code {true}?}.
+ */
+ static const Ref<SemanticContext> NONE;
+
+ virtual ~SemanticContext();
+
+ virtual size_t hashCode() const = 0;
+ virtual std::string toString() const = 0;
+ virtual bool operator == (const SemanticContext &other) const = 0;
+ virtual bool operator != (const SemanticContext &other) const;
+
+ /// <summary>
+ /// For context independent predicates, we evaluate them without a local
+ /// context (i.e., null context). That way, we can evaluate them without
+ /// having to create proper rule-specific context during prediction (as
+ /// opposed to the parser, which creates them naturally). In a practical
+ /// sense, this avoids a cast exception from RuleContext to myruleContext.
+ /// <p/>
+ /// For context dependent predicates, we must pass in a local context so that
+ /// references such as $arg evaluate properly as _localctx.arg. We only
+ /// capture context dependent predicates in the context in which we begin
+ /// prediction, so we passed in the outer context here in case of context
+ /// dependent predicate evaluation.
+ /// </summary>
+ virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) = 0;
+
+ /**
+ * Evaluate the precedence predicates for the context and reduce the result.
+ *
+ * @param parser The parser instance.
+ * @param parserCallStack
+ * @return The simplified semantic context after precedence predicates are
+ * evaluated, which will be one of the following values.
+ * <ul>
+ * <li>{@link #NONE}: if the predicate simplifies to {@code true} after
+ * precedence predicates are evaluated.</li>
+ * <li>{@code null}: if the predicate simplifies to {@code false} after
+ * precedence predicates are evaluated.</li>
+ * <li>{@code this}: if the semantic context is not changed as a result of
+ * precedence predicate evaluation.</li>
+ * <li>A non-{@code null} {@link SemanticContext}: the new simplified
+ * semantic context after precedence predicates are evaluated.</li>
+ * </ul>
+ */
+ virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack);
+
+ static Ref<SemanticContext> And(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
+
+ /// See also: ParserATNSimulator::getPredsForAmbigAlts.
+ static Ref<SemanticContext> Or(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
+
+ class Predicate;
+ class PrecedencePredicate;
+ class Operator;
+ class AND;
+ class OR;
+
+ private:
+ static std::vector<Ref<PrecedencePredicate>> filterPrecedencePredicates(const Set &collection);
+ };
+
+ class ANTLR4CPP_PUBLIC SemanticContext::Predicate : public SemanticContext {
+ public:
+ const size_t ruleIndex;
+ const size_t predIndex;
+ const bool isCtxDependent; // e.g., $i ref in pred
+
+ protected:
+ Predicate();
+
+ public:
+ Predicate(size_t ruleIndex, size_t predIndex, bool isCtxDependent);
+
+ virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const SemanticContext &other) const override;
+ virtual std::string toString() const override;
+ };
+
+ class ANTLR4CPP_PUBLIC SemanticContext::PrecedencePredicate : public SemanticContext {
+ public:
+ const int precedence;
+
+ protected:
+ PrecedencePredicate();
+
+ public:
+ PrecedencePredicate(int precedence);
+
+ virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual int compareTo(PrecedencePredicate *o);
+ virtual size_t hashCode() const override;
+ virtual bool operator == (const SemanticContext &other) const override;
+ virtual std::string toString() const override;
+ };
+
+ /**
+ * This is the base class for semantic context "operators", which operate on
+ * a collection of semantic context "operands".
+ *
+ * @since 4.3
+ */
+ class ANTLR4CPP_PUBLIC SemanticContext::Operator : public SemanticContext {
+ public:
+ virtual ~Operator() override;
+
+ /**
+ * Gets the operands for the semantic context operator.
+ *
+ * @return a collection of {@link SemanticContext} operands for the
+ * operator.
+ *
+ * @since 4.3
+ */
+
+ virtual std::vector<Ref<SemanticContext>> getOperands() const = 0;
+ };
+
+ /**
+ * A semantic context which is true whenever none of the contained contexts
+ * is false.
+ */
+ class ANTLR4CPP_PUBLIC SemanticContext::AND : public SemanticContext::Operator {
+ public:
+ std::vector<Ref<SemanticContext>> opnds;
+
+ AND(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b) ;
+
+ virtual std::vector<Ref<SemanticContext>> getOperands() const override;
+ virtual bool operator == (const SemanticContext &other) const override;
+ virtual size_t hashCode() const override;
+
+ /**
+ * The evaluation of predicates by this context is short-circuiting, but
+ * unordered.</p>
+ */
+ virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual std::string toString() const override;
+ };
+
+ /**
+ * A semantic context which is true whenever at least one of the contained
+ * contexts is true.
+ */
+ class ANTLR4CPP_PUBLIC SemanticContext::OR : public SemanticContext::Operator {
+ public:
+ std::vector<Ref<SemanticContext>> opnds;
+
+ OR(Ref<SemanticContext> const& a, Ref<SemanticContext> const& b);
+
+ virtual std::vector<Ref<SemanticContext>> getOperands() const override;
+ virtual bool operator == (const SemanticContext &other) const override;
+ virtual size_t hashCode() const override;
+
+ /**
+ * The evaluation of predicates by this context is short-circuiting, but
+ * unordered.
+ */
+ virtual bool eval(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual Ref<SemanticContext> evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) override;
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
+
+// Hash function for SemanticContext, used in the MurmurHash::update function
+
+namespace std {
+ using antlr4::atn::SemanticContext;
+
+ template <> struct hash<SemanticContext>
+ {
+ size_t operator () (SemanticContext &x) const
+ {
+ return x.hashCode();
+ }
+ };
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// A transition containing a set of values. </summary>
+ class ANTLR4CPP_PUBLIC SetTransition : public Transition {
+ public:
+ const misc::IntervalSet set;
+
+ SetTransition(ATNState *target, const misc::IntervalSet &set);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual misc::IntervalSet label() const override;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/PredictionContext.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC SingletonPredictionContext : public PredictionContext {
+ public:
+ // Usually a parent is linked via a weak ptr. Not so here as we have kinda reverse reference chain.
+ // There are no child contexts stored here and often the parent context is left dangling when it's
+ // owning ATNState is released. In order to avoid having this context released as well (leaving all other contexts
+ // which got this one as parent with a null reference) we use a shared_ptr here instead, to keep those left alone
+ // parent contexts alive.
+ const Ref<PredictionContext> parent;
+ const size_t returnState;
+
+ SingletonPredictionContext(Ref<PredictionContext> const& parent, size_t returnState);
+ virtual ~SingletonPredictionContext();
+
+ static Ref<SingletonPredictionContext> create(Ref<PredictionContext> const& parent, size_t returnState);
+
+ virtual size_t size() const override;
+ virtual Ref<PredictionContext> getParent(size_t index) const override;
+ virtual size_t getReturnState(size_t index) const override;
+ virtual bool operator == (const PredictionContext &o) const override;
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/BlockStartState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// The block that begins a closure loop.
+ class ANTLR4CPP_PUBLIC StarBlockStartState final : public BlockStartState {
+
+ public:
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC StarLoopEntryState final : public DecisionState {
+ public:
+ StarLoopEntryState();
+
+ /**
+ * Indicates whether this state can benefit from a precedence DFA during SLL
+ * decision making.
+ *
+ * <p>This is a computed property that is calculated during ATN deserialization
+ * and stored for use in {@link ParserATNSimulator} and
+ * {@link ParserInterpreter}.</p>
+ *
+ * @see DFA#isPrecedenceDfa()
+ */
+ bool isPrecedenceDecision = false;
+
+ StarLoopbackState *loopBackState = nullptr;
+
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/ATNState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC StarLoopbackState final : public ATNState {
+ public:
+ StarLoopEntryState *getLoopEntryState();
+
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/DecisionState.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// The Tokens rule start state linking to each lexer rule start state.
+ class ANTLR4CPP_PUBLIC TokensStartState final : public DecisionState {
+
+ public:
+ virtual size_t getStateType() override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "misc/IntervalSet.h"
+
+namespace antlr4 {
+namespace atn {
+
+ /// <summary>
+ /// An ATN transition between any two ATN states. Subclasses define
+ /// atom, set, epsilon, action, predicate, rule transitions.
+ /// <p/>
+ /// This is a one way link. It emanates from a state (usually via a list of
+ /// transitions) and has a target state.
+ /// <p/>
+ /// Since we never have to change the ATN transitions once we construct it,
+ /// we can fix these transitions as specific classes. The DFA transitions
+ /// on the other hand need to update the labels as it adds transitions to
+ /// the states. We'll use the term Edge for the DFA to distinguish them from
+ /// ATN transitions.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC Transition {
+ public:
+ // constants for serialization
+ enum SerializationType {
+ EPSILON = 1,
+ RANGE = 2,
+ RULE = 3,
+ PREDICATE = 4, // e.g., {isType(input.LT(1))}?
+ ATOM = 5,
+ ACTION = 6,
+ SET = 7, // ~(A|B) or ~atom, wildcard, which convert to next 2
+ NOT_SET = 8,
+ WILDCARD = 9,
+ PRECEDENCE = 10,
+ };
+
+ static const std::vector<std::string> serializationNames;
+
+ /// The target of this transition.
+ // ml: this is a reference into the ATN.
+ ATNState *target;
+
+ virtual ~Transition();
+
+ protected:
+ Transition(ATNState *target);
+
+ public:
+ virtual SerializationType getSerializationType() const = 0;
+
+ /**
+ * Determines if the transition is an "epsilon" transition.
+ *
+ * <p>The default implementation returns {@code false}.</p>
+ *
+ * @return {@code true} if traversing this transition in the ATN does not
+ * consume an input symbol; otherwise, {@code false} if traversing this
+ * transition consumes (matches) an input symbol.
+ */
+ virtual bool isEpsilon() const;
+ virtual misc::IntervalSet label() const;
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const = 0;
+
+ virtual std::string toString() const;
+
+ Transition(Transition const&) = delete;
+ Transition& operator=(Transition const&) = delete;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "atn/Transition.h"
+
+namespace antlr4 {
+namespace atn {
+
+ class ANTLR4CPP_PUBLIC WildcardTransition final : public Transition {
+ public:
+ WildcardTransition(ATNState *target);
+
+ virtual SerializationType getSerializationType() const override;
+
+ virtual bool matches(size_t symbol, size_t minVocabSymbol, size_t maxVocabSymbol) const override;
+
+ virtual std::string toString() const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "dfa/DFAState.h"
+
+namespace antlrcpp {
+ class SingleWriteMultipleReadLock;
+}
+
+namespace antlr4 {
+namespace dfa {
+
+ class ANTLR4CPP_PUBLIC DFA {
+ public:
+ /// A set of all DFA states. Use a map so we can get old state back.
+ /// Set only allows you to see if it's there.
+
+ /// From which ATN state did we create this DFA?
+ atn::DecisionState *atnStartState;
+ std::unordered_set<DFAState *, DFAState::Hasher, DFAState::Comparer> states; // States are owned by this class.
+ DFAState *s0;
+ size_t decision;
+
+ DFA(atn::DecisionState *atnStartState);
+ DFA(atn::DecisionState *atnStartState, size_t decision);
+ DFA(const DFA &other) = delete;
+ DFA(DFA &&other);
+ virtual ~DFA();
+
+ /**
+ * Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
+ * start state {@link #s0} which is not stored in {@link #states}. The
+ * {@link DFAState#edges} array for this start state contains outgoing edges
+ * supplying individual start states corresponding to specific precedence
+ * values.
+ *
+ * @return {@code true} if this is a precedence DFA; otherwise,
+ * {@code false}.
+ * @see Parser#getPrecedence()
+ */
+ bool isPrecedenceDfa() const;
+
+ /**
+ * Get the start state for a specific precedence value.
+ *
+ * @param precedence The current precedence.
+ * @return The start state corresponding to the specified precedence, or
+ * {@code null} if no start state exists for the specified precedence.
+ *
+ * @throws IllegalStateException if this is not a precedence DFA.
+ * @see #isPrecedenceDfa()
+ */
+ DFAState* getPrecedenceStartState(int precedence) const;
+
+ /**
+ * Set the start state for a specific precedence value.
+ *
+ * @param precedence The current precedence.
+ * @param startState The start state corresponding to the specified
+ * precedence.
+ *
+ * @throws IllegalStateException if this is not a precedence DFA.
+ * @see #isPrecedenceDfa()
+ */
+ void setPrecedenceStartState(int precedence, DFAState *startState, antlrcpp::SingleWriteMultipleReadLock &lock);
+
+ /// Return a list of all states in this DFA, ordered by state number.
+ virtual std::vector<DFAState *> getStates() const;
+
+ /**
+ * @deprecated Use {@link #toString(Vocabulary)} instead.
+ */
+ virtual std::string toString(const std::vector<std::string>& tokenNames);
+ std::string toString(const Vocabulary &vocabulary) const;
+
+ virtual std::string toLexerString();
+
+ private:
+ /**
+ * {@code true} if this DFA is for a precedence decision; otherwise,
+ * {@code false}. This is the backing field for {@link #isPrecedenceDfa}.
+ */
+ bool _precedenceDfa;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Vocabulary.h"
+
+namespace antlr4 {
+namespace dfa {
+
+ /// A DFA walker that knows how to dump them to serialized strings.
+ class ANTLR4CPP_PUBLIC DFASerializer {
+ public:
+ DFASerializer(const DFA *dfa, const std::vector<std::string>& tnames);
+ DFASerializer(const DFA *dfa, const Vocabulary &vocabulary);
+ virtual ~DFASerializer();
+
+ virtual std::string toString() const;
+
+ protected:
+ virtual std::string getEdgeLabel(size_t i) const;
+ virtual std::string getStateString(DFAState *s) const;
+
+ private:
+ const DFA *_dfa;
+ const Vocabulary &_vocabulary;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace dfa {
+
+ /// <summary>
+ /// A DFA state represents a set of possible ATN configurations.
+ /// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
+ /// to keep track of all possible states the ATN can be in after
+ /// reading each input symbol. That is to say, after reading
+ /// input a1a2..an, the DFA is in a state that represents the
+ /// subset T of the states of the ATN that are reachable from the
+ /// ATN's start state along some path labeled a1a2..an."
+ /// In conventional NFA->DFA conversion, therefore, the subset T
+ /// would be a bitset representing the set of states the
+ /// ATN could be in. We need to track the alt predicted by each
+ /// state as well, however. More importantly, we need to maintain
+ /// a stack of states, tracking the closure operations as they
+ /// jump from rule to rule, emulating rule invocations (method calls).
+ /// I have to add a stack to simulate the proper lookahead sequences for
+ /// the underlying LL grammar from which the ATN was derived.
+ /// <p/>
+ /// I use a set of ATNConfig objects not simple states. An ATNConfig
+ /// is both a state (ala normal conversion) and a RuleContext describing
+ /// the chain of rules (if any) followed to arrive at that state.
+ /// <p/>
+ /// A DFA state may have multiple references to a particular state,
+ /// but with different ATN contexts (with same or different alts)
+ /// meaning that state was reached via a different set of rule invocations.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC DFAState {
+ public:
+ class PredPrediction {
+ public:
+ Ref<atn::SemanticContext> pred; // never null; at least SemanticContext.NONE
+ int alt;
+
+ PredPrediction(const Ref<atn::SemanticContext> &pred, int alt);
+ virtual ~PredPrediction();
+
+ virtual std::string toString();
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+ int stateNumber;
+
+ std::unique_ptr<atn::ATNConfigSet> configs;
+
+ /// {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1)
+ /// <seealso cref="Token#EOF"/> maps to {@code edges[0]}.
+ // ml: this is a sparse list, so we use a map instead of a vector.
+ // Watch out: we no longer have the -1 offset, as it isn't needed anymore.
+ std::unordered_map<size_t, DFAState *> edges;
+
+ bool isAcceptState;
+
+ /// if accept state, what ttype do we match or alt do we predict?
+ /// This is set to <seealso cref="ATN#INVALID_ALT_NUMBER"/> when <seealso cref="#predicates"/>{@code !=null} or
+ /// <seealso cref="#requiresFullContext"/>.
+ size_t prediction;
+
+ Ref<atn::LexerActionExecutor> lexerActionExecutor;
+
+ /// <summary>
+ /// Indicates that this state was created during SLL prediction that
+ /// discovered a conflict between the configurations in the state. Future
+ /// <seealso cref="ParserATNSimulator#execATN"/> invocations immediately jumped doing
+ /// full context prediction if this field is true.
+ /// </summary>
+ bool requiresFullContext;
+
+ /// <summary>
+ /// During SLL parsing, this is a list of predicates associated with the
+ /// ATN configurations of the DFA state. When we have predicates,
+ /// <seealso cref="#requiresFullContext"/> is {@code false} since full context prediction evaluates predicates
+ /// on-the-fly. If this is not null, then <seealso cref="#prediction"/> is
+ /// <seealso cref="ATN#INVALID_ALT_NUMBER"/>.
+ /// <p/>
+ /// We only use these for non-<seealso cref="#requiresFullContext"/> but conflicting states. That
+ /// means we know from the context (it's $ or we don't dip into outer
+ /// context) that it's an ambiguity not a conflict.
+ /// <p/>
+ /// This list is computed by <seealso cref="ParserATNSimulator#predicateDFAState"/>.
+ /// </summary>
+ std::vector<PredPrediction *> predicates;
+
+ /// Map a predicate to a predicted alternative.
+ DFAState();
+ DFAState(int state);
+ DFAState(std::unique_ptr<atn::ATNConfigSet> configs);
+ virtual ~DFAState();
+
+ /// <summary>
+ /// Get the set of all alts mentioned by all ATN configurations in this
+ /// DFA state.
+ /// </summary>
+ virtual std::set<size_t> getAltSet();
+
+ virtual size_t hashCode() const;
+
+ /// Two DFAState instances are equal if their ATN configuration sets
+ /// are the same. This method is used to see if a state already exists.
+ ///
+ /// Because the number of alternatives and number of ATN configurations are
+ /// finite, there is a finite number of DFA states that can be processed.
+ /// This is necessary to show that the algorithm terminates.
+ ///
+ /// Cannot test the DFA state numbers here because in
+ /// ParserATNSimulator#addDFAState we need to know if any other state
+ /// exists that has this exact set of ATN configurations. The
+ /// stateNumber is irrelevant.
+ bool operator == (const DFAState &o) const;
+
+ virtual std::string toString();
+
+ struct Hasher
+ {
+ size_t operator()(DFAState *k) const {
+ return k->hashCode();
+ }
+ };
+
+ struct Comparer {
+ bool operator()(DFAState *lhs, DFAState *rhs) const
+ {
+ return *lhs == *rhs;
+ }
+ };
+
+ private:
+ void InitializeInstanceFields();
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "dfa/DFASerializer.h"
+
+namespace antlr4 {
+namespace dfa {
+
+ class ANTLR4CPP_PUBLIC LexerDFASerializer : public DFASerializer {
+ public:
+ LexerDFASerializer(DFA *dfa);
+ virtual ~LexerDFASerializer();
+
+ protected:
+ virtual std::string getEdgeLabel(size_t i) const override;
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace misc {
+
+ struct InterpreterData {
+ atn::ATN atn;
+ dfa::Vocabulary vocabulary;
+ std::vector<std::string> ruleNames;
+ std::vector<std::string> channels; // Only valid for lexer grammars.
+ std::vector<std::string> modes; // ditto
+
+ InterpreterData() {}; // For invalid content.
+ InterpreterData(std::vector<std::string> const& literalNames, std::vector<std::string> const& symbolicNames);
+ };
+
+ // A class to read plain text interpreter data produced by ANTLR.
+ class ANTLR4CPP_PUBLIC InterpreterDataReader {
+ public:
+ static InterpreterData parseFile(std::string const& fileName);
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace misc {
+
+ // Helpers to convert certain unsigned symbols (e.g. Token::EOF) to their original numeric value (e.g. -1)
+ // and vice versa. This is needed mostly for intervals to keep their original order and for toString()
+ // methods to print the original numeric value (e.g. for tests).
+ size_t numericToSymbol(ssize_t v);
+ ssize_t symbolToNumeric(size_t v);
+
+ /// An immutable inclusive interval a..b
+ class ANTLR4CPP_PUBLIC Interval {
+ public:
+ static const Interval INVALID;
+
+ // Must stay signed to guarantee the correct sort order.
+ ssize_t a;
+ ssize_t b;
+
+ Interval();
+ explicit Interval(size_t a_, size_t b_); // For unsigned -> signed mappings.
+ Interval(ssize_t a_, ssize_t b_);
+
+ /// return number of elements between a and b inclusively. x..x is length 1.
+ /// if b < a, then length is 0. 9..10 has length 2.
+ size_t length() const;
+
+ bool operator == (const Interval &other) const;
+
+ size_t hashCode() const;
+
+ /// <summary>
+ /// Does this start completely before other? Disjoint </summary>
+ bool startsBeforeDisjoint(const Interval &other) const;
+
+ /// <summary>
+ /// Does this start at or before other? Nondisjoint </summary>
+ bool startsBeforeNonDisjoint(const Interval &other) const;
+
+ /// <summary>
+ /// Does this.a start after other.b? May or may not be disjoint </summary>
+ bool startsAfter(const Interval &other) const;
+
+ /// <summary>
+ /// Does this start completely after other? Disjoint </summary>
+ bool startsAfterDisjoint(const Interval &other) const;
+
+ /// <summary>
+ /// Does this start after other? NonDisjoint </summary>
+ bool startsAfterNonDisjoint(const Interval &other) const;
+
+ /// <summary>
+ /// Are both ranges disjoint? I.e., no overlap? </summary>
+ bool disjoint(const Interval &other) const;
+
+ /// <summary>
+ /// Are two intervals adjacent such as 0..41 and 42..42? </summary>
+ bool adjacent(const Interval &other) const;
+
+ bool properlyContains(const Interval &other) const;
+
+ /// <summary>
+ /// Return the interval computed from combining this and other </summary>
+ Interval Union(const Interval &other) const;
+
+ /// <summary>
+ /// Return the interval in common between this and o </summary>
+ Interval intersection(const Interval &other) const;
+
+ std::string toString() const;
+
+ private:
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "misc/Interval.h"
+#include "Exceptions.h"
+
+namespace antlr4 {
+namespace misc {
+
+ /**
+ * This class implements the {@link IntSet} backed by a sorted array of
+ * non-overlapping intervals. It is particularly efficient for representing
+ * large collections of numbers, where the majority of elements appear as part
+ * of a sequential range of numbers that are all part of the set. For example,
+ * the set { 1, 2, 3, 4, 7, 8 } may be represented as { [1, 4], [7, 8] }.
+ *
+ * <p>
+ * This class is able to represent sets containing any combination of values in
+ * the range {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE}
+ * (inclusive).</p>
+ */
+ class ANTLR4CPP_PUBLIC IntervalSet {
+ public:
+ static IntervalSet const COMPLETE_CHAR_SET;
+ static IntervalSet const EMPTY_SET;
+
+ private:
+ /// The list of sorted, disjoint intervals.
+ std::vector<Interval> _intervals;
+
+ explicit IntervalSet(std::vector<Interval>&& intervals);
+
+ public:
+ IntervalSet();
+ IntervalSet(IntervalSet const& set);
+ IntervalSet(IntervalSet&& set);
+
+ template<typename T1, typename... T_NEXT>
+ IntervalSet(int, T1 t1, T_NEXT&&... next) : IntervalSet() {
+ // The first int argument is an ignored count for compatibility
+ // with the previous varargs based interface.
+ addItems(t1, std::forward<T_NEXT>(next)...);
+ }
+
+ IntervalSet& operator=(IntervalSet const& set);
+ IntervalSet& operator=(IntervalSet&& set);
+
+ /// Create a set with a single element, el.
+ static IntervalSet of(ssize_t a);
+
+ /// Create a set with all ints within range [a..b] (inclusive)
+ static IntervalSet of(ssize_t a, ssize_t b);
+
+ void clear();
+
+ /// Add a single element to the set. An isolated element is stored
+ /// as a range el..el.
+ void add(ssize_t el);
+
+ /// Add interval; i.e., add all integers from a to b to set.
+ /// If b<a, do nothing.
+ /// Keep list in sorted order (by left range value).
+ /// If overlap, combine ranges. For example,
+ /// If this is {1..5, 10..20}, adding 6..7 yields
+ /// {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}.
+ void add(ssize_t a, ssize_t b);
+
+ /// combine all sets in the array returned the or'd value
+ static IntervalSet Or(const std::vector<IntervalSet> &sets);
+
+ // Copy on write so we can cache a..a intervals and sets of that.
+ void add(const Interval &addition);
+ IntervalSet& addAll(const IntervalSet &set);
+
+ template<typename T1, typename... T_NEXT>
+ void addItems(T1 t1, T_NEXT&&... next) {
+ add(t1);
+ addItems(std::forward<T_NEXT>(next)...);
+ }
+
+ IntervalSet complement(ssize_t minElement, ssize_t maxElement) const;
+
+ /// Given the set of possible values (rather than, say UNICODE or MAXINT),
+ /// return a new set containing all elements in vocabulary, but not in
+ /// this. The computation is (vocabulary - this).
+ ///
+ /// 'this' is assumed to be either a subset or equal to vocabulary.
+ IntervalSet complement(const IntervalSet &vocabulary) const;
+
+ /// Compute this-other via this&~other.
+ /// Return a new set containing all elements in this but not in other.
+ /// other is assumed to be a subset of this;
+ /// anything that is in other but not in this will be ignored.
+ IntervalSet subtract(const IntervalSet &other) const;
+
+ /**
+ * Compute the set difference between two interval sets. The specific
+ * operation is {@code left - right}. If either of the input sets is
+ * {@code null}, it is treated as though it was an empty set.
+ */
+ static IntervalSet subtract(const IntervalSet &left, const IntervalSet &right);
+
+ IntervalSet Or(const IntervalSet &a) const;
+
+ /// Return a new set with the intersection of this set with other. Because
+ /// the intervals are sorted, we can use an iterator for each list and
+ /// just walk them together. This is roughly O(min(n,m)) for interval
+ /// list lengths n and m.
+ IntervalSet And(const IntervalSet &other) const;
+
+ /// Is el in any range of this set?
+ bool contains(size_t el) const; // For mapping of e.g. Token::EOF to -1 etc.
+ bool contains(ssize_t el) const;
+
+ /// return true if this set has no members
+ bool isEmpty() const;
+
+ /// If this set is a single integer, return it otherwise Token.INVALID_TYPE.
+ ssize_t getSingleElement() const;
+
+ /**
+ * Returns the maximum value contained in the set.
+ *
+ * @return the maximum value contained in the set. If the set is empty, this
+ * method returns {@link Token#INVALID_TYPE}.
+ */
+ ssize_t getMaxElement() const;
+
+ /**
+ * Returns the minimum value contained in the set.
+ *
+ * @return the minimum value contained in the set. If the set is empty, this
+ * method returns {@link Token#INVALID_TYPE}.
+ */
+ ssize_t getMinElement() const;
+
+ /// <summary>
+ /// Return a list of Interval objects. </summary>
+ std::vector<Interval> const& getIntervals() const;
+
+ size_t hashCode() const;
+
+ /// Are two IntervalSets equal? Because all intervals are sorted
+ /// and disjoint, equals is a simple linear walk over both lists
+ /// to make sure they are the same.
+ bool operator == (const IntervalSet &other) const;
+ std::string toString() const;
+ std::string toString(bool elemAreChar) const;
+
+ /**
+ * @deprecated Use {@link #toString(Vocabulary)} instead.
+ */
+ std::string toString(const std::vector<std::string> &tokenNames) const;
+ std::string toString(const dfa::Vocabulary &vocabulary) const;
+
+ protected:
+ /**
+ * @deprecated Use {@link #elementName(Vocabulary, int)} instead.
+ */
+ std::string elementName(const std::vector<std::string> &tokenNames, ssize_t a) const;
+ std::string elementName(const dfa::Vocabulary &vocabulary, ssize_t a) const;
+
+ public:
+ size_t size() const;
+ std::vector<ssize_t> toList() const;
+ std::set<ssize_t> toSet() const;
+
+ /// Get the ith element of ordered set. Used only by RandomPhrase so
+ /// don't bother to implement if you're not doing that for a new
+ /// ANTLR code gen target.
+ ssize_t get(size_t i) const;
+ void remove(size_t el); // For mapping of e.g. Token::EOF to -1 etc.
+ void remove(ssize_t el);
+
+ private:
+ void addItems() { /* No-op */ }
+ };
+
+} // namespace atn
+} // namespace antlr4
+
+// Hash function for IntervalSet.
+
+namespace std {
+ using antlr4::misc::IntervalSet;
+
+ template <> struct hash<IntervalSet>
+ {
+ size_t operator() (const IntervalSet &x) const
+ {
+ return x.hashCode();
+ }
+ };
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace misc {
+
+ class ANTLR4CPP_PUBLIC MurmurHash {
+
+ private:
+#if __cplusplus >= 201703L
+ static constexpr size_t DEFAULT_SEED = 0;
+#else
+ enum : size_t {
+ DEFAULT_SEED = 0,
+ };
+#endif
+
+ /// Initialize the hash using the default seed value.
+ /// Returns the intermediate hash value.
+ public:
+ static size_t initialize();
+
+ /// Initialize the hash using the specified seed.
+ static size_t initialize(size_t seed);
+
+ /// Update the intermediate hash value for the next input {@code value}.
+ /// <param name="hash"> the intermediate hash value </param>
+ /// <param name="value"> the value to add to the current hash </param>
+ /// Returns the updated intermediate hash value.
+ static size_t update(size_t hash, size_t value);
+
+ /**
+ * Update the intermediate hash value for the next input {@code value}.
+ *
+ * @param hash the intermediate hash value
+ * @param value the value to add to the current hash
+ * @return the updated intermediate hash value
+ */
+ template <class T>
+ static size_t update(size_t hash, Ref<T> const& value) {
+ return update(hash, value != nullptr ? value->hashCode() : 0);
+ }
+
+ template <class T>
+ static size_t update(size_t hash, T *value) {
+ return update(hash, value != nullptr ? value->hashCode() : 0);
+ }
+
+ /// <summary>
+ /// Apply the final computation steps to the intermediate value {@code hash}
+ /// to form the final result of the MurmurHash 3 hash function.
+ /// </summary>
+ /// <param name="hash"> the intermediate hash value </param>
+ /// <param name="entryCount"> the number of calls to update() before calling finish() </param>
+ /// <returns> the final hash result </returns>
+ static size_t finish(size_t hash, size_t entryCount);
+
+ /// Utility function to compute the hash code of an array using the MurmurHash3 algorithm.
+ ///
+ /// @param <T> the array element type </param>
+ /// <param name="data"> the array data </param>
+ /// <param name="seed"> the seed for the MurmurHash algorithm </param>
+ /// <returns> the hash code of the data </returns>
+ template<typename T> // where T is C array type
+ static size_t hashCode(const std::vector<Ref<T>> &data, size_t seed) {
+ size_t hash = initialize(seed);
+ for (auto entry : data) {
+ hash = update(hash, entry->hashCode());
+ }
+
+ return finish(hash, data.size());
+ }
+ };
+
+} // namespace atn
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace misc {
+
+ class ANTLR4CPP_PUBLIC Predicate {
+ public:
+ virtual ~Predicate();
+
+ virtual bool test(tree::ParseTree *t) = 0;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+// A standard C++ class loosely modeled after boost::Any.
+
+#pragma once
+
+#include "antlr4-common.h"
+
+#ifdef _MSC_VER
+ #pragma warning(push)
+ #pragma warning(disable: 4521) // 'antlrcpp::Any': multiple copy constructors specified
+#endif
+
+namespace antlrcpp {
+
+template<class T>
+ using StorageType = typename std::decay<T>::type;
+
+struct ANTLR4CPP_PUBLIC Any
+{
+ bool isNull() const { return _ptr == nullptr; }
+ bool isNotNull() const { return _ptr != nullptr; }
+
+ Any() : _ptr(nullptr) {
+ }
+
+ Any(Any& that) : _ptr(that.clone()) {
+ }
+
+ Any(Any&& that) : _ptr(that._ptr) {
+ that._ptr = nullptr;
+ }
+
+ Any(const Any& that) : _ptr(that.clone()) {
+ }
+
+ Any(const Any&& that) : _ptr(that.clone()) {
+ }
+
+ template<typename U>
+ Any(U&& value) : _ptr(new Derived<StorageType<U>>(std::forward<U>(value))) {
+ }
+
+ template<class U>
+ bool is() const {
+ auto derived = getDerived<U>(false);
+
+ return derived != nullptr;
+ }
+
+ template<class U>
+ StorageType<U>& as() {
+ auto derived = getDerived<U>(true);
+
+ return derived->value;
+ }
+
+ template<class U>
+ const StorageType<U>& as() const {
+ auto derived = getDerived<U>(true);
+
+ return derived->value;
+ }
+
+ template<class U>
+ operator U() {
+ return as<StorageType<U>>();
+ }
+
+ template<class U>
+ operator const U() const {
+ return as<const StorageType<U>>();
+ }
+
+ Any& operator = (const Any& a) {
+ if (_ptr == a._ptr)
+ return *this;
+
+ auto * old_ptr = _ptr;
+ _ptr = a.clone();
+
+ if (old_ptr)
+ delete old_ptr;
+
+ return *this;
+ }
+
+ Any& operator = (Any&& a) {
+ if (_ptr == a._ptr)
+ return *this;
+
+ std::swap(_ptr, a._ptr);
+
+ return *this;
+ }
+
+ virtual ~Any();
+
+ virtual bool equals(Any other) const {
+ return _ptr == other._ptr;
+ }
+
+private:
+ struct Base {
+ virtual ~Base() {};
+ virtual Base* clone() const = 0;
+ };
+
+ template<typename T>
+ struct Derived : Base
+ {
+ template<typename U> Derived(U&& value_) : value(std::forward<U>(value_)) {
+ }
+
+ T value;
+
+ Base* clone() const {
+ return clone<>();
+ }
+
+ private:
+ template<int N = 0, typename std::enable_if<N == N && std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
+ Base* clone() const {
+ return new Derived<T>(value);
+ }
+
+ template<int N = 0, typename std::enable_if<N == N && !std::is_nothrow_copy_constructible<T>::value, int>::type = 0>
+ Base* clone() const {
+ return nullptr;
+ }
+
+ };
+
+ Base* clone() const
+ {
+ if (_ptr)
+ return _ptr->clone();
+ else
+ return nullptr;
+ }
+
+ template<class U>
+ Derived<StorageType<U>>* getDerived(bool checkCast) const {
+ typedef StorageType<U> T;
+
+ auto derived = dynamic_cast<Derived<T>*>(_ptr);
+
+ if (checkCast && !derived)
+ throw std::bad_cast();
+
+ return derived;
+ }
+
+ Base *_ptr;
+
+};
+
+ template<> inline
+ Any::Any(std::nullptr_t&& ) : _ptr(nullptr) {
+ }
+
+
+} // namespace antlrcpp
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlrcpp {
+
+ class ANTLR4CPP_PUBLIC Arrays {
+ public:
+
+ static std::string listToString(const std::vector<std::string> &list, const std::string &separator);
+
+ template <typename T>
+ static bool equals(const std::vector<T> &a, const std::vector<T> &b) {
+ if (a.size() != b.size())
+ return false;
+
+ for (size_t i = 0; i < a.size(); ++i)
+ if (!(a[i] == b[i]))
+ return false;
+
+ return true;
+ }
+
+ template <typename T>
+ static bool equals(const std::vector<T *> &a, const std::vector<T *> &b) {
+ if (a.size() != b.size())
+ return false;
+
+ for (size_t i = 0; i < a.size(); ++i) {
+ if (a[i] == b[i])
+ continue;
+ if (!(*a[i] == *b[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ template <typename T>
+ static bool equals(const std::vector<Ref<T>> &a, const std::vector<Ref<T>> &b) {
+ if (a.size() != b.size())
+ return false;
+
+ for (size_t i = 0; i < a.size(); ++i) {
+ if (!a[i] && !b[i])
+ continue;
+ if (!a[i] || !b[i])
+ return false;
+ if (a[i] == b[i])
+ continue;
+
+ if (!(*a[i] == *b[i]))
+ return false;
+ }
+
+ return true;
+ }
+
+ template <typename T>
+ static std::string toString(const std::vector<T> &source) {
+ std::string result = "[";
+ bool firstEntry = true;
+ for (auto &value : source) {
+ result += value.toString();
+ if (firstEntry) {
+ result += ", ";
+ firstEntry = false;
+ }
+ }
+ return result + "]";
+ }
+
+ template <typename T>
+ static std::string toString(const std::vector<Ref<T>> &source) {
+ std::string result = "[";
+ bool firstEntry = true;
+ for (auto &value : source) {
+ result += value->toString();
+ if (firstEntry) {
+ result += ", ";
+ firstEntry = false;
+ }
+ }
+ return result + "]";
+ }
+
+ template <typename T>
+ static std::string toString(const std::vector<T *> &source) {
+ std::string result = "[";
+ bool firstEntry = true;
+ for (auto value : source) {
+ result += value->toString();
+ if (firstEntry) {
+ result += ", ";
+ firstEntry = false;
+ }
+ }
+ return result + "]";
+ }
+
+ };
+
+ template <>
+ std::string Arrays::toString(const std::vector<antlr4::tree::ParseTree *> &source);
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlrcpp {
+
+ class ANTLR4CPP_PUBLIC BitSet : public std::bitset<2048> {
+ public:
+ size_t nextSetBit(size_t pos) const {
+ for (size_t i = pos; i < size(); i++){
+ if (test(i)) {
+ return i;
+ }
+ }
+
+ return INVALID_INDEX;
+ }
+
+ // Prints a list of every index for which the bitset contains a bit in true.
+ friend std::wostream& operator << (std::wostream& os, const BitSet& obj)
+ {
+ os << "{";
+ size_t total = obj.count();
+ for (size_t i = 0; i < obj.size(); i++){
+ if (obj.test(i)){
+ os << i;
+ --total;
+ if (total > 1){
+ os << ", ";
+ }
+ }
+ }
+
+ os << "}";
+ return os;
+ }
+
+ static std::string subStringRepresentation(const std::vector<BitSet>::iterator &begin,
+ const std::vector<BitSet>::iterator &end) {
+ std::string result;
+ std::vector<BitSet>::iterator vectorIterator;
+
+ for (vectorIterator = begin; vectorIterator != end; vectorIterator++) {
+ result += vectorIterator->toString();
+ }
+ // Grab the end
+ result += end->toString();
+
+ return result;
+ }
+
+ std::string toString(){
+ std::stringstream stream;
+ stream << "{";
+ bool valueAdded = false;
+ for (size_t i = 0; i < size(); ++i){
+ if (test(i)){
+ if (valueAdded) {
+ stream << ", ";
+ }
+ stream << i;
+ valueAdded = true;
+ }
+ }
+
+ stream << "}";
+ return stream.str();
+ }
+
+ };
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlrcpp {
+
+ std::string join(std::vector<std::string> strings, const std::string &separator);
+ std::map<std::string, size_t> toMap(const std::vector<std::string> &keys);
+ std::string escapeWhitespace(std::string str, bool escapeSpaces);
+ std::string toHexString(const int t);
+ std::string arrayToString(const std::vector<std::string> &data);
+ std::string replaceString(const std::string &s, const std::string &from, const std::string &to);
+ std::vector<std::string> split(const std::string &s, const std::string &sep, int count);
+ std::string indent(const std::string &s, const std::string &indentation, bool includingFirst = true);
+
+ // Using RAII + a lambda to implement a "finally" replacement.
+ struct FinalAction {
+ FinalAction(std::function<void ()> f) : _cleanUp { f } {}
+ FinalAction(FinalAction &&other) :
+ _cleanUp(std::move(other._cleanUp)), _enabled(other._enabled) {
+ other._enabled = false; // Don't trigger the lambda after ownership has moved.
+ }
+ ~FinalAction() { if (_enabled) _cleanUp(); }
+
+ void disable() { _enabled = false; }
+ private:
+ std::function<void ()> _cleanUp;
+ bool _enabled {true};
+ };
+
+ ANTLR4CPP_PUBLIC FinalAction finally(std::function<void ()> f);
+
+ // Convenience functions to avoid lengthy dynamic_cast() != nullptr checks in many places.
+ template <typename T1, typename T2>
+ inline bool is(T2 *obj) { // For pointer types.
+ return dynamic_cast<typename std::add_const<T1>::type>(obj) != nullptr;
+ }
+
+ template <typename T1, typename T2>
+ inline bool is(Ref<T2> const& obj) { // For shared pointers.
+ return dynamic_cast<T1 *>(obj.get()) != nullptr;
+ }
+
+ template <typename T>
+ std::string toString(const T &o) {
+ std::stringstream ss;
+ // typeid gives the mangled class name, but that's all what's possible
+ // in a portable way.
+ ss << typeid(o).name() << "@" << std::hex << reinterpret_cast<uintptr_t>(&o);
+ return ss.str();
+ }
+
+ // Get the error text from an exception pointer or the current exception.
+ std::string what(std::exception_ptr eptr = std::current_exception());
+
+ class SingleWriteMultipleReadLock {
+ public:
+ void readLock();
+ void readUnlock();
+ void writeLock();
+ void writeUnlock();
+
+ private:
+ std::condition_variable _readerGate;
+ std::condition_variable _writerGate;
+
+ std::mutex _mutex;
+ size_t _activeReaders = 0;
+ size_t _waitingWriters = 0;
+ size_t _activeWriters = 0;
+ };
+
+} // namespace antlrcpp
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+namespace antlr4 {
+ class ANTLRErrorListener;
+ class ANTLRErrorStrategy;
+ class ANTLRFileStream;
+ class ANTLRInputStream;
+ class BailErrorStrategy;
+ class BaseErrorListener;
+ class BufferedTokenStream;
+ class CharStream;
+ class CommonToken;
+ class CommonTokenFactory;
+ class CommonTokenStream;
+ class ConsoleErrorListener;
+ class DefaultErrorStrategy;
+ class DiagnosticErrorListener;
+ class EmptyStackException;
+ class FailedPredicateException;
+ class IllegalArgumentException;
+ class IllegalStateException;
+ class InputMismatchException;
+ class IntStream;
+ class InterpreterRuleContext;
+ class Lexer;
+ class LexerInterpreter;
+ class LexerNoViableAltException;
+ class ListTokenSource;
+ class NoSuchElementException;
+ class NoViableAltException;
+ class NullPointerException;
+ class ParseCancellationException;
+ class Parser;
+ class ParserInterpreter;
+ class ParserRuleContext;
+ class ProxyErrorListener;
+ class RecognitionException;
+ class Recognizer;
+ class RuleContext;
+ class Token;
+ template<typename Symbol> class TokenFactory;
+ class TokenSource;
+ class TokenStream;
+ class TokenStreamRewriter;
+ class UnbufferedCharStream;
+ class UnbufferedTokenStream;
+ class WritableToken;
+
+ namespace misc {
+ class InterpreterDataReader;
+ class Interval;
+ class IntervalSet;
+ class MurmurHash;
+ class Utils;
+ class Predicate;
+ }
+ namespace atn {
+ class ATN;
+ class ATNConfig;
+ class ATNConfigSet;
+ class ATNDeserializationOptions;
+ class ATNDeserializer;
+ class ATNSerializer;
+ class ATNSimulator;
+ class ATNState;
+ enum class ATNType;
+ class AbstractPredicateTransition;
+ class ActionTransition;
+ class ArrayPredictionContext;
+ class AtomTransition;
+ class BasicBlockStartState;
+ class BasicState;
+ class BlockEndState;
+ class BlockStartState;
+ class DecisionState;
+ class EmptyPredictionContext;
+ class EpsilonTransition;
+ class LL1Analyzer;
+ class LexerAction;
+ class LexerActionExecutor;
+ class LexerATNConfig;
+ class LexerATNSimulator;
+ class LexerMoreAction;
+ class LexerPopModeAction;
+ class LexerSkipAction;
+ class LookaheadEventInfo;
+ class LoopEndState;
+ class NotSetTransition;
+ class OrderedATNConfigSet;
+ class ParseInfo;
+ class ParserATNSimulator;
+ class PlusBlockStartState;
+ class PlusLoopbackState;
+ class PrecedencePredicateTransition;
+ class PredicateTransition;
+ class PredictionContext;
+ enum class PredictionMode;
+ class PredictionModeClass;
+ class RangeTransition;
+ class RuleStartState;
+ class RuleStopState;
+ class RuleTransition;
+ class SemanticContext;
+ class SetTransition;
+ class SingletonPredictionContext;
+ class StarBlockStartState;
+ class StarLoopEntryState;
+ class StarLoopbackState;
+ class TokensStartState;
+ class Transition;
+ class WildcardTransition;
+ }
+ namespace dfa {
+ class DFA;
+ class DFASerializer;
+ class DFAState;
+ class LexerDFASerializer;
+ class Vocabulary;
+ }
+ namespace tree {
+ class AbstractParseTreeVisitor;
+ class ErrorNode;
+ class ErrorNodeImpl;
+ class ParseTree;
+ class ParseTreeListener;
+ template<typename T> class ParseTreeProperty;
+ class ParseTreeVisitor;
+ class ParseTreeWalker;
+ class SyntaxTree;
+ class TerminalNode;
+ class TerminalNodeImpl;
+ class Tree;
+ class Trees;
+
+ namespace pattern {
+ class Chunk;
+ class ParseTreeMatch;
+ class ParseTreePattern;
+ class ParseTreePatternMatcher;
+ class RuleTagToken;
+ class TagChunk;
+ class TextChunk;
+ class TokenTagToken;
+ }
+
+ namespace xpath {
+ class XPath;
+ class XPathElement;
+ class XPathLexerErrorListener;
+ class XPathRuleAnywhereElement;
+ class XPathRuleElement;
+ class XPathTokenAnywhereElement;
+ class XPathTokenElement;
+ class XPathWildcardAnywhereElement;
+ class XPathWildcardElement;
+ }
+ }
+}
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+#ifdef USE_UTF8_INSTEAD_OF_CODECVT
+#include "utf8.h"
+#endif
+
+namespace antlrcpp {
+
+ // For all conversions utf8 <-> utf32.
+ // I wouldn't prefer wstring_convert because: according to
+ // https://en.cppreference.com/w/cpp/locale/wstring_convert,
+ // wstring_convert is deprecated in C++17.
+ // utfcpp (https://github.com/nemtrif/utfcpp) is a substitution.
+#ifndef USE_UTF8_INSTEAD_OF_CODECVT
+ // VS 2015 and VS 2017 have different bugs in std::codecvt_utf8<char32_t> (VS 2013 works fine).
+ #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
+ typedef std::wstring_convert<std::codecvt_utf8<__int32>, __int32> UTF32Converter;
+ #else
+ typedef std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> UTF32Converter;
+ #endif
+#endif
+
+ // The conversion functions fails in VS2017, so we explicitly use a workaround.
+ template<typename T>
+ inline std::string utf32_to_utf8(T const& data)
+ {
+ #ifndef USE_UTF8_INSTEAD_OF_CODECVT
+ // Don't make the converter static or we have to serialize access to it.
+ thread_local UTF32Converter converter;
+
+ #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
+ const auto p = reinterpret_cast<const int32_t *>(data.data());
+ return converter.to_bytes(p, p + data.size());
+ #else
+ return converter.to_bytes(data);
+ #endif
+ #else
+ std::string narrow;
+ utf8::utf32to8(data.begin(), data.end(), std::back_inserter(narrow));
+ return narrow;
+ #endif
+ }
+
+ inline UTF32String utf8_to_utf32(const char* first, const char* last)
+ {
+ #ifndef USE_UTF8_INSTEAD_OF_CODECVT
+ thread_local UTF32Converter converter;
+
+ #if defined(_MSC_VER) && _MSC_VER >= 1900 && _MSC_VER < 2000
+ auto r = converter.from_bytes(first, last);
+ i32string s = reinterpret_cast<const int32_t *>(r.data());
+ return s;
+ #else
+ std::u32string s = converter.from_bytes(first, last);
+ return s;
+ #endif
+ #else
+ UTF32String wide;
+ utf8::utf8to32(first, last, std::back_inserter(wide));
+ return wide;
+ #endif
+ }
+
+ void replaceAll(std::string &str, std::string const& from, std::string const& to);
+
+ // string <-> wstring conversion (UTF-16), e.g. for use with Window's wide APIs.
+ ANTLR4CPP_PUBLIC std::string ws2s(std::wstring const& wstr);
+ ANTLR4CPP_PUBLIC std::wstring s2ws(std::string const& str);
+}
--- /dev/null
+/*
+ The MIT License (MIT)
+
+ Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy
+ of this software and associated documentation files (the "Software"), to deal
+ in the Software without restriction, including without limitation the rights
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in
+ all copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ THE SOFTWARE.
+ */
+#pragma once
+
+#include <iostream>
+#include <vector>
+#include <sstream>
+#include <string>
+#include <iomanip>
+#include <stdint.h>
+
+#ifdef GUID_ANDROID
+#include <jni.h>
+#endif
+
+// Class to represent a GUID/UUID. Each instance acts as a wrapper around a
+// 16 byte value that can be passed around by value. It also supports
+// conversion to string (via the stream operator <<) and conversion from a
+// string via constructor.
+class Guid
+{
+public:
+
+ // create a guid from vector of bytes
+ Guid(const std::vector<unsigned char> &bytes);
+
+ // create a guid from array of bytes
+ Guid(const unsigned char *bytes);
+
+ // Create a guid from array of words.
+ Guid(const uint16_t *bytes, bool reverse);
+
+ // create a guid from string
+ Guid(const std::string &fromString);
+
+ // create empty guid
+ Guid();
+
+ // copy constructor
+ Guid(const Guid &other);
+
+ // overload assignment operator
+ Guid &operator=(const Guid &other);
+
+ // overload equality and inequality operator
+ bool operator==(const Guid &other) const;
+ bool operator!=(const Guid &other) const;
+
+ const std::string toString() const;
+ std::vector<unsigned char>::const_iterator begin() { return _bytes.begin(); }
+ std::vector<unsigned char>::const_iterator end() { return _bytes.end(); }
+ std::vector<unsigned char>::const_reverse_iterator rbegin() { return _bytes.rbegin(); }
+ std::vector<unsigned char>::const_reverse_iterator rend() { return _bytes.rend(); }
+
+
+private:
+
+ // actual data
+ std::vector<unsigned char> _bytes;
+
+ // make the << operator a friend so it can access _bytes
+ friend std::ostream &operator<<(std::ostream &s, const Guid &guid);
+};
+
+// Class that can create new guids. The only reason this exists instead of
+// just a global "newGuid" function is because some platforms will require
+// that there is some attached context. In the case of android, we need to
+// know what JNIEnv is being used to call back to Java, but the newGuid()
+// function would no longer be cross-platform if we parameterized the android
+// version. Instead, construction of the GuidGenerator may be different on
+// each platform, but the use of newGuid is uniform.
+class GuidGenerator
+{
+public:
+#ifdef GUID_ANDROID
+ GuidGenerator(JNIEnv *env);
+#else
+ GuidGenerator() { }
+#endif
+
+ Guid newGuid();
+
+#ifdef GUID_ANDROID
+private:
+ JNIEnv *_env;
+ jclass _uuidClass;
+ jmethodID _newGuidMethod;
+ jmethodID _mostSignificantBitsMethod;
+ jmethodID _leastSignificantBitsMethod;
+#endif
+};
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/ParseTreeVisitor.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC AbstractParseTreeVisitor : public ParseTreeVisitor {
+ public:
+ /// The default implementation calls <seealso cref="ParseTree#accept"/> on the
+ /// specified tree.
+ virtual antlrcpp::Any visit(ParseTree *tree) override {
+ return tree->accept(this);
+ }
+
+ /**
+ * <p>The default implementation initializes the aggregate result to
+ * {@link #defaultResult defaultResult()}. Before visiting each child, it
+ * calls {@link #shouldVisitNextChild shouldVisitNextChild}; if the result
+ * is {@code false} no more children are visited and the current aggregate
+ * result is returned. After visiting a child, the aggregate result is
+ * updated by calling {@link #aggregateResult aggregateResult} with the
+ * previous aggregate result and the result of visiting the child.</p>
+ *
+ * <p>The default implementation is not safe for use in visitors that modify
+ * the tree structure. Visitors that modify the tree should override this
+ * method to behave properly in respect to the specific algorithm in use.</p>
+ */
+ virtual antlrcpp::Any visitChildren(ParseTree *node) override {
+ antlrcpp::Any result = defaultResult();
+ size_t n = node->children.size();
+ for (size_t i = 0; i < n; i++) {
+ if (!shouldVisitNextChild(node, result)) {
+ break;
+ }
+
+ antlrcpp::Any childResult = node->children[i]->accept(this);
+ result = aggregateResult(result, childResult);
+ }
+
+ return result;
+ }
+
+ /// The default implementation returns the result of
+ /// <seealso cref="#defaultResult defaultResult"/>.
+ virtual antlrcpp::Any visitTerminal(TerminalNode * /*node*/) override {
+ return defaultResult();
+ }
+
+ /// The default implementation returns the result of
+ /// <seealso cref="#defaultResult defaultResult"/>.
+ virtual antlrcpp::Any visitErrorNode(ErrorNode * /*node*/) override {
+ return defaultResult();
+ }
+
+ protected:
+ /// <summary>
+ /// Gets the default value returned by visitor methods. This value is
+ /// returned by the default implementations of
+ /// <seealso cref="#visitTerminal visitTerminal"/>, <seealso cref="#visitErrorNode visitErrorNode"/>.
+ /// The default implementation of <seealso cref="#visitChildren visitChildren"/>
+ /// initializes its aggregate result to this value.
+ /// <p/>
+ /// The base implementation returns {@code null}.
+ /// </summary>
+ /// <returns> The default value returned by visitor methods. </returns>
+ virtual antlrcpp::Any defaultResult() {
+ return nullptr; // support isNotNull
+ }
+
+ /// <summary>
+ /// Aggregates the results of visiting multiple children of a node. After
+ /// either all children are visited or <seealso cref="#shouldVisitNextChild"/> returns
+ /// {@code false}, the aggregate value is returned as the result of
+ /// <seealso cref="#visitChildren"/>.
+ /// <p/>
+ /// The default implementation returns {@code nextResult}, meaning
+ /// <seealso cref="#visitChildren"/> will return the result of the last child visited
+ /// (or return the initial value if the node has no children).
+ /// </summary>
+ /// <param name="aggregate"> The previous aggregate value. In the default
+ /// implementation, the aggregate value is initialized to
+ /// <seealso cref="#defaultResult"/>, which is passed as the {@code aggregate} argument
+ /// to this method after the first child node is visited. </param>
+ /// <param name="nextResult"> The result of the immediately preceeding call to visit
+ /// a child node.
+ /// </param>
+ /// <returns> The updated aggregate result. </returns>
+ virtual antlrcpp::Any aggregateResult(antlrcpp::Any /*aggregate*/, const antlrcpp::Any &nextResult) {
+ return nextResult;
+ }
+
+ /// <summary>
+ /// This method is called after visiting each child in
+ /// <seealso cref="#visitChildren"/>. This method is first called before the first
+ /// child is visited; at that point {@code currentResult} will be the initial
+ /// value (in the default implementation, the initial value is returned by a
+ /// call to <seealso cref="#defaultResult"/>. This method is not called after the last
+ /// child is visited.
+ /// <p/>
+ /// The default implementation always returns {@code true}, indicating that
+ /// {@code visitChildren} should only return after all children are visited.
+ /// One reason to override this method is to provide a "short circuit"
+ /// evaluation option for situations where the result of visiting a single
+ /// child has the potential to determine the result of the visit operation as
+ /// a whole.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ParseTree"/> whose children are currently being
+ /// visited. </param>
+ /// <param name="currentResult"> The current aggregate result of the children visited
+ /// to the current point.
+ /// </param>
+ /// <returns> {@code true} to continue visiting children. Otherwise return
+ /// {@code false} to stop visiting children and immediately return the
+ /// current aggregate result from <seealso cref="#visitChildren"/>. </returns>
+ virtual bool shouldVisitNextChild(ParseTree * /*node*/, const antlrcpp::Any &/*currentResult*/) {
+ return true;
+ }
+
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC ErrorNode : public virtual TerminalNode {
+ public:
+ ~ErrorNode() override;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/ErrorNode.h"
+#include "tree/TerminalNodeImpl.h"
+#include "misc/Interval.h"
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// Represents a token that was consumed during resynchronization
+ /// rather than during a valid match operation. For example,
+ /// we will create this kind of a node during single token insertion
+ /// and deletion as well as during "consume until error recovery set"
+ /// upon no viable alternative exceptions.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ErrorNodeImpl : public virtual TerminalNodeImpl, public virtual ErrorNode {
+ public:
+ ErrorNodeImpl(Token *token);
+ ~ErrorNodeImpl() override;
+
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/*
+ * [The "BSD license"]
+ * Copyright (c) 2012 Terence Parr
+ * Copyright (c) 2012 Sam Harwell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+#include "tree/ParseTreeWalker.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ParseTreeListener;
+
+ /**
+ * An iterative (read: non-recursive) pre-order and post-order tree walker that
+ * doesn't use the thread stack but heap-based stacks. Makes it possible to
+ * process deeply nested parse trees.
+ */
+ class ANTLR4CPP_PUBLIC IterativeParseTreeWalker : public ParseTreeWalker {
+ public:
+ virtual void walk(ParseTreeListener *listener, ParseTree *t) const override;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// An interface to access the tree of <seealso cref="RuleContext"/> objects created
+ /// during a parse that makes the data structure look like a simple parse tree.
+ /// This node represents both internal nodes, rule invocations,
+ /// and leaf nodes, token matches.
+ ///
+ /// The payload is either a <seealso cref="Token"/> or a <seealso cref="RuleContext"/> object.
+ // ml: This class unites 4 Java classes: RuleNode, ParseTree, SyntaxTree and Tree.
+ class ANTLR4CPP_PUBLIC ParseTree {
+ public:
+ ParseTree();
+ ParseTree(ParseTree const&) = delete;
+ virtual ~ParseTree() {}
+
+ ParseTree& operator=(ParseTree const&) = delete;
+
+ /// The parent of this node. If the return value is null, then this
+ /// node is the root of the tree.
+ ParseTree *parent;
+
+ /// If we are debugging or building a parse tree for a visitor,
+ /// we need to track all of the tokens and rule invocations associated
+ /// with this rule's context. This is empty for parsing w/o tree constr.
+ /// operation because we don't the need to track the details about
+ /// how we parse this rule.
+ // ml: memory is not managed here, but by the owning class. This is just for the structure.
+ std::vector<ParseTree *> children;
+
+ /// Print out a whole tree, not just a node, in LISP format
+ /// {@code (root child1 .. childN)}. Print just a node if this is a leaf.
+ virtual std::string toStringTree(bool pretty = false) = 0;
+ virtual std::string toString() = 0;
+
+ /// Specialize toStringTree so that it can print out more information
+ /// based upon the parser.
+ virtual std::string toStringTree(Parser *parser, bool pretty = false) = 0;
+
+ virtual bool operator == (const ParseTree &other) const;
+
+ /// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method.
+ // ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function.
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) = 0;
+
+ /// Return the combined text of all leaf nodes. Does not get any
+ /// off-channel tokens (if any) so won't return whitespace and
+ /// comments if they are sent to parser on hidden channel.
+ virtual std::string getText() = 0;
+
+ /**
+ * Return an {@link Interval} indicating the index in the
+ * {@link TokenStream} of the first and last token associated with this
+ * subtree. If this node is a leaf, then the interval represents a single
+ * token and has interval i..i for token index i.
+ *
+ * <p>An interval of i..i-1 indicates an empty interval at position
+ * i in the input stream, where 0 <= i <= the size of the input
+ * token stream. Currently, the code base can only have i=0..n-1 but
+ * in concept one could have an empty interval after EOF. </p>
+ *
+ * <p>If source interval is unknown, this returns {@link Interval#INVALID}.</p>
+ *
+ * <p>As a weird special case, the source interval for rules matched after
+ * EOF is unspecified.</p>
+ */
+ virtual misc::Interval getSourceInterval() = 0;
+ };
+
+ // A class to help managing ParseTree instances without the need of a shared_ptr.
+ class ANTLR4CPP_PUBLIC ParseTreeTracker {
+ public:
+ template<typename T, typename ... Args>
+ T* createInstance(Args&& ... args) {
+ static_assert(std::is_base_of<ParseTree, T>::value, "Argument must be a parse tree type");
+ T* result = new T(args...);
+ _allocated.push_back(result);
+ return result;
+ }
+
+ void reset() {
+ for (auto * entry : _allocated)
+ delete entry;
+ _allocated.clear();
+ }
+
+ private:
+ std::vector<ParseTree *> _allocated;
+ };
+
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /** This interface describes the minimal core of methods triggered
+ * by {@link ParseTreeWalker}. E.g.,
+ *
+ * ParseTreeWalker walker = new ParseTreeWalker();
+ * walker.walk(myParseTreeListener, myParseTree); <-- triggers events in your listener
+ *
+ * If you want to trigger events in multiple listeners during a single
+ * tree walk, you can use the ParseTreeDispatcher object available at
+ *
+ * https://github.com/antlr/antlr4/issues/841
+ */
+ class ANTLR4CPP_PUBLIC ParseTreeListener {
+ public:
+ virtual ~ParseTreeListener();
+
+ virtual void visitTerminal(TerminalNode *node) = 0;
+ virtual void visitErrorNode(ErrorNode *node) = 0;
+ virtual void enterEveryRule(ParserRuleContext *ctx) = 0;
+ virtual void exitEveryRule(ParserRuleContext *ctx) = 0;
+
+ bool operator == (const ParseTreeListener &other) {
+ return this == &other;
+ }
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// Associate a property with a parse tree node. Useful with parse tree listeners
+ /// that need to associate values with particular tree nodes, kind of like
+ /// specifying a return value for the listener event method that visited a
+ /// particular node. Example:
+ ///
+ /// <pre>
+ /// ParseTreeProperty<Integer> values = new ParseTreeProperty<Integer>();
+ /// values.put(tree, 36);
+ /// int x = values.get(tree);
+ /// values.removeFrom(tree);
+ /// </pre>
+ ///
+ /// You would make one decl (values here) in the listener and use lots of times
+ /// in your event methods.
+ /// </summary>
+ template<typename V>
+ class ANTLR4CPP_PUBLIC ParseTreeProperty {
+ public:
+ virtual ~ParseTreeProperty() {}
+ virtual V get(ParseTree *node) {
+ return _annotations[node];
+ }
+ virtual void put(ParseTree *node, V value) {
+ _annotations[node] = value;
+ }
+ virtual V removeFrom(ParseTree *node) {
+ auto value = _annotations[node];
+ _annotations.erase(node);
+ return value;
+ }
+
+ protected:
+ std::map<ParseTree*, V> _annotations;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "support/Any.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// <summary>
+ /// This interface defines the basic notion of a parse tree visitor. Generated
+ /// visitors implement this interface and the {@code XVisitor} interface for
+ /// grammar {@code X}.
+ /// </summary>
+ /// @param <T> The return type of the visit operation. Use <seealso cref="Void"/> for
+ /// operations with no return type. </param>
+ // ml: no template parameter here, to avoid the need for virtual template functions. Instead we have our Any class.
+ class ANTLR4CPP_PUBLIC ParseTreeVisitor {
+ public:
+ virtual ~ParseTreeVisitor();
+
+ /// <summary>
+ /// Visit a parse tree, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="tree"> The <seealso cref="ParseTree"/> to visit. </param>
+ /// <returns> The result of visiting the parse tree. </returns>
+ virtual antlrcpp::Any visit(ParseTree *tree) = 0;
+
+ /// <summary>
+ /// Visit the children of a node, and return a user-defined result of the
+ /// operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ParseTree"/> whose children should be visited. </param>
+ /// <returns> The result of visiting the children of the node. </returns>
+ virtual antlrcpp::Any visitChildren(ParseTree *node) = 0;
+
+ /// <summary>
+ /// Visit a terminal node, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="TerminalNode"/> to visit. </param>
+ /// <returns> The result of visiting the node. </returns>
+ virtual antlrcpp::Any visitTerminal(TerminalNode *node) = 0;
+
+ /// <summary>
+ /// Visit an error node, and return a user-defined result of the operation.
+ /// </summary>
+ /// <param name="node"> The <seealso cref="ErrorNode"/> to visit. </param>
+ /// <returns> The result of visiting the node. </returns>
+ virtual antlrcpp::Any visitErrorNode(ErrorNode *node) = 0;
+
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC ParseTreeWalker {
+ public:
+ static ParseTreeWalker &DEFAULT;
+
+ virtual ~ParseTreeWalker();
+
+ /**
+ * <summary>
+ * Performs a walk on the given parse tree starting at the root and going down recursively
+ * with depth-first search. On each node, <seealso cref="ParseTreeWalker#enterRule"/> is called before
+ * recursively walking down into child nodes, then
+ * <seealso cref="ParseTreeWalker#exitRule"/> is called after the recursive call to wind up.
+ * </summary>
+ * <param name='listener'> The listener used by the walker to process grammar rules </param>
+ * <param name='t'> The parse tree to be walked on </param>
+ */
+ virtual void walk(ParseTreeListener *listener, ParseTree *t) const;
+
+ protected:
+
+ /**
+ * <summary>
+ * Enters a grammar rule by first triggering the generic event <seealso cref="ParseTreeListener#enterEveryRule"/>
+ * then by triggering the event specific to the given parse tree node
+ * </summary>
+ * <param name='listener'> The listener responding to the trigger events </param>
+ * <param name='r'> The grammar rule containing the rule context </param>
+ */
+ virtual void enterRule(ParseTreeListener *listener, ParseTree *r) const;
+
+ /**
+ * <summary>
+ * Exits a grammar rule by first triggering the event specific to the given parse tree node
+ * then by triggering the generic event <seealso cref="ParseTreeListener#exitEveryRule"/>
+ * </summary>
+ * <param name='listener'> The listener responding to the trigger events </param>
+ * <param name='r'> The grammar rule containing the rule context </param>
+ */
+ virtual void exitRule(ParseTreeListener *listener, ParseTree *r) const;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/ParseTree.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC TerminalNode : public ParseTree {
+ public:
+ ~TerminalNode() override;
+
+ virtual Token* getSymbol() = 0;
+
+ /** Set the parent for this leaf node.
+ *
+ * Technically, this is not backward compatible as it changes
+ * the interface but no one was able to create custom
+ * TerminalNodes anyway so I'm adding as it improves internal
+ * code quality.
+ *
+ * @since 4.7
+ */
+ virtual void setParent(RuleContext *parent) = 0;
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+
+namespace antlr4 {
+namespace tree {
+
+ class ANTLR4CPP_PUBLIC TerminalNodeImpl : public virtual TerminalNode {
+ public:
+ Token *symbol;
+
+ TerminalNodeImpl(Token *symbol);
+
+ virtual Token* getSymbol() override;
+ virtual void setParent(RuleContext *parent) override;
+ virtual misc::Interval getSourceInterval() override;
+
+ virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
+
+ virtual std::string getText() override;
+ virtual std::string toStringTree(Parser *parser, bool pretty = false) override;
+ virtual std::string toString() override;
+ virtual std::string toStringTree(bool pretty = false) override;
+
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "tree/TerminalNode.h"
+#include "ParserRuleContext.h"
+#include "Recognizer.h"
+
+namespace antlr4 {
+namespace tree {
+
+ /// A set of utility routines useful for all kinds of ANTLR trees.
+ class ANTLR4CPP_PUBLIC Trees {
+ public:
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, bool pretty = false);
+
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, Parser *recog, bool pretty = false);
+
+ /// Print out a whole tree in LISP form. getNodeText is used on the
+ /// node payloads to get the text for the nodes. Detect
+ /// parse trees and extract data appropriately.
+ static std::string toStringTree(ParseTree *t, const std::vector<std::string> &ruleNames, bool pretty = false);
+ static std::string getNodeText(ParseTree *t, Parser *recog);
+ static std::string getNodeText(ParseTree *t, const std::vector<std::string> &ruleNames);
+
+ /// Return a list of all ancestors of this node. The first node of
+ /// list is the root and the last is the parent of this node.
+ static std::vector<ParseTree *> getAncestors(ParseTree *t);
+
+ /** Return true if t is u's parent or a node on path to root from u.
+ * Use == not equals().
+ *
+ * @since 4.5.1
+ */
+ static bool isAncestorOf(ParseTree *t, ParseTree *u);
+ static std::vector<ParseTree *> findAllTokenNodes(ParseTree *t, size_t ttype);
+ static std::vector<ParseTree *> findAllRuleNodes(ParseTree *t, size_t ruleIndex);
+ static std::vector<ParseTree *> findAllNodes(ParseTree *t, size_t index, bool findTokens);
+
+ /** Get all descendents; includes t itself.
+ *
+ * @since 4.5.1
+ */
+ static std::vector<ParseTree *> getDescendants(ParseTree *t);
+
+ /** @deprecated */
+ static std::vector<ParseTree *> descendants(ParseTree *t);
+
+ /** Find smallest subtree of t enclosing range startTokenIndex..stopTokenIndex
+ * inclusively using postorder traversal. Recursive depth-first-search.
+ *
+ * @since 4.5.1
+ */
+ static ParserRuleContext* getRootOfSubtreeEnclosingRegion(ParseTree *t,
+ size_t startTokenIndex, // inclusive
+ size_t stopTokenIndex); // inclusive
+
+ /** Return first node satisfying the pred
+ *
+ * @since 4.5.1
+ */
+ static ParseTree* findNodeSuchThat(ParseTree *t, Ref<misc::Predicate> const& pred);
+
+ private:
+ Trees();
+ };
+
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A chunk is either a token tag, a rule tag, or a span of literal text within a
+ /// tree pattern.
+ /// <p/>
+ /// The method <seealso cref="ParseTreePatternMatcher#split(String)"/> returns a list of
+ /// chunks in preparation for creating a token stream by
+ /// <seealso cref="ParseTreePatternMatcher#tokenize(String)"/>. From there, we get a parse
+ /// tree from with <seealso cref="ParseTreePatternMatcher#compile(String, int)"/>. These
+ /// chunks are converted to <seealso cref="RuleTagToken"/>, <seealso cref="TokenTagToken"/>, or the
+ /// regular tokens of the text surrounding the tags.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC Chunk {
+ public:
+ Chunk() = default;
+ Chunk(Chunk const&) = default;
+ virtual ~Chunk();
+
+ Chunk& operator=(Chunk const&) = default;
+
+ /// This method returns a text representation of the tag chunk. Labeled tags
+ /// are returned in the form {@code label:tag}, and unlabeled tags are
+ /// returned as just the tag name.
+ virtual std::string toString() {
+ std::string str;
+ return str;
+ }
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// Represents the result of matching a ParseTree against a tree pattern.
+ class ANTLR4CPP_PUBLIC ParseTreeMatch {
+ private:
+ /// This is the backing field for getTree().
+ ParseTree *_tree;
+
+ /// This is the backing field for getPattern().
+ const ParseTreePattern &_pattern;
+
+ /// This is the backing field for getLabels().
+ std::map<std::string, std::vector<ParseTree *>> _labels;
+
+ /// This is the backing field for getMismatchedNode().
+ ParseTree *_mismatchedNode;
+
+ public:
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="ParseTreeMatch"/> from the specified
+ /// parse tree and pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against the pattern. </param>
+ /// <param name="pattern"> The parse tree pattern. </param>
+ /// <param name="labels"> A mapping from label names to collections of
+ /// <seealso cref="ParseTree"/> objects located by the tree pattern matching process. </param>
+ /// <param name="mismatchedNode"> The first node which failed to match the tree
+ /// pattern during the matching process.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tree} is {@code null} </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code pattern} is {@code null} </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code labels} is {@code null} </exception>
+ ParseTreeMatch(ParseTree *tree, ParseTreePattern const& pattern,
+ const std::map<std::string, std::vector<ParseTree *>> &labels, ParseTree *mismatchedNode);
+ ParseTreeMatch(ParseTreeMatch const&) = default;
+ virtual ~ParseTreeMatch();
+
+ /// <summary>
+ /// Get the last node associated with a specific {@code label}.
+ /// <p/>
+ /// For example, for pattern {@code <id:ID>}, {@code get("id")} returns the
+ /// node matched for that {@code ID}. If more than one node
+ /// matched the specified label, only the last is returned. If there is
+ /// no node associated with the label, this returns {@code null}.
+ /// <p/>
+ /// Pattern tags like {@code <ID>} and {@code <expr>} without labels are
+ /// considered to be labeled with {@code ID} and {@code expr}, respectively.
+ /// </summary>
+ /// <param name="labe"> The label to check.
+ /// </param>
+ /// <returns> The last <seealso cref="ParseTree"/> to match a tag with the specified
+ /// label, or {@code null} if no parse tree matched a tag with the label. </returns>
+ virtual ParseTree* get(const std::string &label);
+
+ /// <summary>
+ /// Return all nodes matching a rule or token tag with the specified label.
+ /// <p/>
+ /// If the {@code label} is the name of a parser rule or token in the
+ /// grammar, the resulting list will contain both the parse trees matching
+ /// rule or tags explicitly labeled with the label and the complete set of
+ /// parse trees matching the labeled and unlabeled tags in the pattern for
+ /// the parser rule or token. For example, if {@code label} is {@code "foo"},
+ /// the result will contain <em>all</em> of the following.
+ ///
+ /// <ul>
+ /// <li>Parse tree nodes matching tags of the form {@code <foo:anyRuleName>} and
+ /// {@code <foo:AnyTokenName>}.</li>
+ /// <li>Parse tree nodes matching tags of the form {@code <anyLabel:foo>}.</li>
+ /// <li>Parse tree nodes matching tags of the form {@code <foo>}.</li>
+ /// </ul>
+ /// </summary>
+ /// <param name="labe"> The label.
+ /// </param>
+ /// <returns> A collection of all <seealso cref="ParseTree"/> nodes matching tags with
+ /// the specified {@code label}. If no nodes matched the label, an empty list
+ /// is returned. </returns>
+ virtual std::vector<ParseTree *> getAll(const std::string &label);
+
+ /// <summary>
+ /// Return a mapping from label → [list of nodes].
+ /// <p/>
+ /// The map includes special entries corresponding to the names of rules and
+ /// tokens referenced in tags in the original pattern. For additional
+ /// information, see the description of <seealso cref="#getAll(String)"/>.
+ /// </summary>
+ /// <returns> A mapping from labels to parse tree nodes. If the parse tree
+ /// pattern did not contain any rule or token tags, this map will be empty. </returns>
+ virtual std::map<std::string, std::vector<ParseTree *>>& getLabels();
+
+ /// <summary>
+ /// Get the node at which we first detected a mismatch.
+ /// </summary>
+ /// <returns> the node at which we first detected a mismatch, or {@code null}
+ /// if the match was successful. </returns>
+ virtual ParseTree* getMismatchedNode();
+
+ /// <summary>
+ /// Gets a value indicating whether the match operation succeeded.
+ /// </summary>
+ /// <returns> {@code true} if the match operation succeeded; otherwise,
+ /// {@code false}. </returns>
+ virtual bool succeeded();
+
+ /// <summary>
+ /// Get the tree pattern we are matching against.
+ /// </summary>
+ /// <returns> The tree pattern we are matching against. </returns>
+ virtual const ParseTreePattern& getPattern();
+
+ /// <summary>
+ /// Get the parse tree we are trying to match to a pattern.
+ /// </summary>
+ /// <returns> The <seealso cref="ParseTree"/> we are trying to match to a pattern. </returns>
+ virtual ParseTree* getTree();
+
+ virtual std::string toString();
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A pattern like {@code <ID> = <expr>;} converted to a <seealso cref="ParseTree"/> by
+ /// <seealso cref="ParseTreePatternMatcher#compile(String, int)"/>.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParseTreePattern {
+ public:
+ /// <summary>
+ /// Construct a new instance of the <seealso cref="ParseTreePattern"/> class.
+ /// </summary>
+ /// <param name="matcher"> The <seealso cref="ParseTreePatternMatcher"/> which created this
+ /// tree pattern. </param>
+ /// <param name="pattern"> The tree pattern in concrete syntax form. </param>
+ /// <param name="patternRuleIndex"> The parser rule which serves as the root of the
+ /// tree pattern. </param>
+ /// <param name="patternTree"> The tree pattern in <seealso cref="ParseTree"/> form. </param>
+ ParseTreePattern(ParseTreePatternMatcher *matcher, const std::string &pattern, int patternRuleIndex,
+ ParseTree *patternTree);
+ ParseTreePattern(ParseTreePattern const&) = default;
+ virtual ~ParseTreePattern();
+
+ /// <summary>
+ /// Match a specific parse tree against this tree pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against this tree pattern. </param>
+ /// <returns> A <seealso cref="ParseTreeMatch"/> object describing the result of the
+ /// match operation. The <seealso cref="ParseTreeMatch#succeeded()"/> method can be
+ /// used to determine whether or not the match was successful. </returns>
+ virtual ParseTreeMatch match(ParseTree *tree);
+
+ /// <summary>
+ /// Determine whether or not a parse tree matches this tree pattern.
+ /// </summary>
+ /// <param name="tree"> The parse tree to match against this tree pattern. </param>
+ /// <returns> {@code true} if {@code tree} is a match for the current tree
+ /// pattern; otherwise, {@code false}. </returns>
+ virtual bool matches(ParseTree *tree);
+
+ /// Find all nodes using XPath and then try to match those subtrees against
+ /// this tree pattern.
+ /// @param tree The ParseTree to match against this pattern.
+ /// @param xpath An expression matching the nodes
+ ///
+ /// @returns A collection of ParseTreeMatch objects describing the
+ /// successful matches. Unsuccessful matches are omitted from the result,
+ /// regardless of the reason for the failure.
+ virtual std::vector<ParseTreeMatch> findAll(ParseTree *tree, const std::string &xpath);
+
+ /// <summary>
+ /// Get the <seealso cref="ParseTreePatternMatcher"/> which created this tree pattern.
+ /// </summary>
+ /// <returns> The <seealso cref="ParseTreePatternMatcher"/> which created this tree
+ /// pattern. </returns>
+ virtual ParseTreePatternMatcher *getMatcher() const;
+
+ /// <summary>
+ /// Get the tree pattern in concrete syntax form.
+ /// </summary>
+ /// <returns> The tree pattern in concrete syntax form. </returns>
+ virtual std::string getPattern() const;
+
+ /// <summary>
+ /// Get the parser rule which serves as the outermost rule for the tree
+ /// pattern.
+ /// </summary>
+ /// <returns> The parser rule which serves as the outermost rule for the tree
+ /// pattern. </returns>
+ virtual int getPatternRuleIndex() const;
+
+ /// <summary>
+ /// Get the tree pattern as a <seealso cref="ParseTree"/>. The rule and token tags from
+ /// the pattern are present in the parse tree as terminal nodes with a symbol
+ /// of type <seealso cref="RuleTagToken"/> or <seealso cref="TokenTagToken"/>.
+ /// </summary>
+ /// <returns> The tree pattern as a <seealso cref="ParseTree"/>. </returns>
+ virtual ParseTree* getPatternTree() const;
+
+ private:
+ const int patternRuleIndex;
+
+ /// This is the backing field for <seealso cref="#getPattern()"/>.
+ const std::string _pattern;
+
+ /// This is the backing field for <seealso cref="#getPatternTree()"/>.
+ ParseTree *_patternTree;
+
+ /// This is the backing field for <seealso cref="#getMatcher()"/>.
+ ParseTreePatternMatcher *const _matcher;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Exceptions.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A tree pattern matching mechanism for ANTLR <seealso cref="ParseTree"/>s.
+ /// <p/>
+ /// Patterns are strings of source input text with special tags representing
+ /// token or rule references such as:
+ /// <p/>
+ /// {@code <ID> = <expr>;}
+ /// <p/>
+ /// Given a pattern start rule such as {@code statement}, this object constructs
+ /// a <seealso cref="ParseTree"/> with placeholders for the {@code ID} and {@code expr}
+ /// subtree. Then the <seealso cref="#match"/> routines can compare an actual
+ /// <seealso cref="ParseTree"/> from a parse with this pattern. Tag {@code <ID>} matches
+ /// any {@code ID} token and tag {@code <expr>} references the result of the
+ /// {@code expr} rule (generally an instance of {@code ExprContext}.
+ /// <p/>
+ /// Pattern {@code x = 0;} is a similar pattern that matches the same pattern
+ /// except that it requires the identifier to be {@code x} and the expression to
+ /// be {@code 0}.
+ /// <p/>
+ /// The <seealso cref="#matches"/> routines return {@code true} or {@code false} based
+ /// upon a match for the tree rooted at the parameter sent in. The
+ /// <seealso cref="#match"/> routines return a <seealso cref="ParseTreeMatch"/> object that
+ /// contains the parse tree, the parse tree pattern, and a map from tag name to
+ /// matched nodes (more below). A subtree that fails to match, returns with
+ /// <seealso cref="ParseTreeMatch#mismatchedNode"/> set to the first tree node that did not
+ /// match.
+ /// <p/>
+ /// For efficiency, you can compile a tree pattern in string form to a
+ /// <seealso cref="ParseTreePattern"/> object.
+ /// <p/>
+ /// See {@code TestParseTreeMatcher} for lots of examples.
+ /// <seealso cref="ParseTreePattern"/> has two static helper methods:
+ /// <seealso cref="ParseTreePattern#findAll"/> and <seealso cref="ParseTreePattern#match"/> that
+ /// are easy to use but not super efficient because they create new
+ /// <seealso cref="ParseTreePatternMatcher"/> objects each time and have to compile the
+ /// pattern in string form before using it.
+ /// <p/>
+ /// The lexer and parser that you pass into the <seealso cref="ParseTreePatternMatcher"/>
+ /// constructor are used to parse the pattern in string form. The lexer converts
+ /// the {@code <ID> = <expr>;} into a sequence of four tokens (assuming lexer
+ /// throws out whitespace or puts it on a hidden channel). Be aware that the
+ /// input stream is reset for the lexer (but not the parser; a
+ /// <seealso cref="ParserInterpreter"/> is created to parse the input.). Any user-defined
+ /// fields you have put into the lexer might get changed when this mechanism asks
+ /// it to scan the pattern string.
+ /// <p/>
+ /// Normally a parser does not accept token {@code <expr>} as a valid
+ /// {@code expr} but, from the parser passed in, we create a special version of
+ /// the underlying grammar representation (an <seealso cref="ATN"/>) that allows imaginary
+ /// tokens representing rules ({@code <expr>}) to match entire rules. We call
+ /// these <em>bypass alternatives</em>.
+ /// <p/>
+ /// Delimiters are {@code <} and {@code >}, with {@code \} as the escape string
+ /// by default, but you can set them to whatever you want using
+ /// <seealso cref="#setDelimiters"/>. You must escape both start and stop strings
+ /// {@code \<} and {@code \>}.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC ParseTreePatternMatcher {
+ public:
+ class CannotInvokeStartRule : public RuntimeException {
+ public:
+ CannotInvokeStartRule(const RuntimeException &e);
+ ~CannotInvokeStartRule();
+ };
+
+ // Fixes https://github.com/antlr/antlr4/issues/413
+ // "Tree pattern compilation doesn't check for a complete parse"
+ class StartRuleDoesNotConsumeFullPattern : public RuntimeException {
+ public:
+ StartRuleDoesNotConsumeFullPattern() = default;
+ StartRuleDoesNotConsumeFullPattern(StartRuleDoesNotConsumeFullPattern const&) = default;
+ ~StartRuleDoesNotConsumeFullPattern();
+
+ StartRuleDoesNotConsumeFullPattern& operator=(StartRuleDoesNotConsumeFullPattern const&) = default;
+ };
+
+ /// Constructs a <seealso cref="ParseTreePatternMatcher"/> or from a <seealso cref="Lexer"/> and
+ /// <seealso cref="Parser"/> object. The lexer input stream is altered for tokenizing
+ /// the tree patterns. The parser is used as a convenient mechanism to get
+ /// the grammar name, plus token, rule names.
+ ParseTreePatternMatcher(Lexer *lexer, Parser *parser);
+ virtual ~ParseTreePatternMatcher();
+
+ /// <summary>
+ /// Set the delimiters used for marking rule and token tags within concrete
+ /// syntax used by the tree pattern parser.
+ /// </summary>
+ /// <param name="start"> The start delimiter. </param>
+ /// <param name="stop"> The stop delimiter. </param>
+ /// <param name="escapeLeft"> The escape sequence to use for escaping a start or stop delimiter.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code start} is {@code null} or empty. </exception>
+ /// <exception cref="IllegalArgumentException"> if {@code stop} is {@code null} or empty. </exception>
+ virtual void setDelimiters(const std::string &start, const std::string &stop, const std::string &escapeLeft);
+
+ /// <summary>
+ /// Does {@code pattern} matched as rule {@code patternRuleIndex} match {@code tree}? </summary>
+ virtual bool matches(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Does {@code pattern} matched as rule patternRuleIndex match tree? Pass in a
+ /// compiled pattern instead of a string representation of a tree pattern.
+ /// </summary>
+ virtual bool matches(ParseTree *tree, const ParseTreePattern &pattern);
+
+ /// <summary>
+ /// Compare {@code pattern} matched as rule {@code patternRuleIndex} against
+ /// {@code tree} and return a <seealso cref="ParseTreeMatch"/> object that contains the
+ /// matched elements, or the node at which the match failed.
+ /// </summary>
+ virtual ParseTreeMatch match(ParseTree *tree, const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Compare {@code pattern} matched against {@code tree} and return a
+ /// <seealso cref="ParseTreeMatch"/> object that contains the matched elements, or the
+ /// node at which the match failed. Pass in a compiled pattern instead of a
+ /// string representation of a tree pattern.
+ /// </summary>
+ virtual ParseTreeMatch match(ParseTree *tree, const ParseTreePattern &pattern);
+
+ /// <summary>
+ /// For repeated use of a tree pattern, compile it to a
+ /// <seealso cref="ParseTreePattern"/> using this method.
+ /// </summary>
+ virtual ParseTreePattern compile(const std::string &pattern, int patternRuleIndex);
+
+ /// <summary>
+ /// Used to convert the tree pattern string into a series of tokens. The
+ /// input stream is reset.
+ /// </summary>
+ virtual Lexer* getLexer();
+
+ /// <summary>
+ /// Used to collect to the grammar file name, token names, rule names for
+ /// used to parse the pattern into a parse tree.
+ /// </summary>
+ virtual Parser* getParser();
+
+ // ---- SUPPORT CODE ----
+
+ virtual std::vector<std::unique_ptr<Token>> tokenize(const std::string &pattern);
+
+ /// Split "<ID> = <e:expr>;" into 4 chunks for tokenizing by tokenize().
+ virtual std::vector<Chunk> split(const std::string &pattern);
+
+ protected:
+ std::string _start;
+ std::string _stop;
+ std::string _escape; // e.g., \< and \> must escape BOTH!
+
+ /// Recursively walk {@code tree} against {@code patternTree}, filling
+ /// {@code match.}<seealso cref="ParseTreeMatch#labels labels"/>.
+ ///
+ /// <returns> the first node encountered in {@code tree} which does not match
+ /// a corresponding node in {@code patternTree}, or {@code null} if the match
+ /// was successful. The specific node returned depends on the matching
+ /// algorithm used by the implementation, and may be overridden. </returns>
+ virtual ParseTree* matchImpl(ParseTree *tree, ParseTree *patternTree, std::map<std::string, std::vector<ParseTree *>> &labels);
+
+ /// Is t <expr> subtree?
+ virtual RuleTagToken* getRuleTagToken(ParseTree *t);
+
+ private:
+ Lexer *_lexer;
+ Parser *_parser;
+
+ void InitializeInstanceFields();
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Token.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A <seealso cref="Token"/> object representing an entire subtree matched by a parser
+ /// rule; e.g., {@code <expr>}. These tokens are created for <seealso cref="TagChunk"/>
+ /// chunks where the tag corresponds to a parser rule.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC RuleTagToken : public Token {
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getRuleName"/>.
+ /// </summary>
+ private:
+ const std::string ruleName;
+
+ /// The token type for the current token. This is the token type assigned to
+ /// the bypass alternative for the rule during ATN deserialization.
+ const size_t bypassTokenType;
+
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ const std::string label;
+
+ public:
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="RuleTagToken"/> with the specified rule
+ /// name and bypass token type and no label.
+ /// </summary>
+ /// <param name="ruleName"> The name of the parser rule this rule tag matches. </param>
+ /// <param name="bypassTokenType"> The bypass token type assigned to the parser rule.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code ruleName} is {@code null}
+ /// or empty. </exception>
+ RuleTagToken(const std::string &ruleName, int bypassTokenType); //this(ruleName, bypassTokenType, nullptr);
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="RuleTagToken"/> with the specified rule
+ /// name, bypass token type, and label.
+ /// </summary>
+ /// <param name="ruleName"> The name of the parser rule this rule tag matches. </param>
+ /// <param name="bypassTokenType"> The bypass token type assigned to the parser rule. </param>
+ /// <param name="label"> The label associated with the rule tag, or {@code null} if
+ /// the rule tag is unlabeled.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code ruleName} is {@code null}
+ /// or empty. </exception>
+ RuleTagToken(const std::string &ruleName, size_t bypassTokenType, const std::string &label);
+
+ /// <summary>
+ /// Gets the name of the rule associated with this rule tag.
+ /// </summary>
+ /// <returns> The name of the parser rule associated with this rule tag. </returns>
+ std::string getRuleName() const;
+
+ /// <summary>
+ /// Gets the label associated with the rule tag.
+ /// </summary>
+ /// <returns> The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag. </returns>
+ std::string getLabel() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// Rule tag tokens are always placed on the <seealso cref="#DEFAULT_CHANNE"/>.
+ /// </summary>
+ virtual size_t getChannel() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// This method returns the rule tag formatted with {@code <} and {@code >}
+ /// delimiters.
+ /// </summary>
+ virtual std::string getText() const override;
+
+ /// Rule tag tokens have types assigned according to the rule bypass
+ /// transitions created during ATN deserialization.
+ virtual size_t getType() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns 0.
+ virtual size_t getLine() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getCharPositionInLine() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getTokenIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getStartIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns INVALID_INDEX.
+ virtual size_t getStopIndex() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns {@code null}.
+ virtual TokenSource *getTokenSource() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> always returns {@code null}.
+ virtual CharStream *getInputStream() const override;
+
+ /// The implementation for <seealso cref="RuleTagToken"/> returns a string of the form {@code ruleName:bypassTokenType}.
+ virtual std::string toString() const override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Chunk.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// Represents a placeholder tag in a tree pattern. A tag can have any of the
+ /// following forms.
+ ///
+ /// <ul>
+ /// <li>{@code expr}: An unlabeled placeholder for a parser rule {@code expr}.</li>
+ /// <li>{@code ID}: An unlabeled placeholder for a token of type {@code ID}.</li>
+ /// <li>{@code e:expr}: A labeled placeholder for a parser rule {@code expr}.</li>
+ /// <li>{@code id:ID}: A labeled placeholder for a token of type {@code ID}.</li>
+ /// </ul>
+ ///
+ /// This class does not perform any validation on the tag or label names aside
+ /// from ensuring that the tag is a non-null, non-empty string.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TagChunk : public Chunk {
+ public:
+ /// <summary>
+ /// Construct a new instance of <seealso cref="TagChunk"/> using the specified tag and
+ /// no label.
+ /// </summary>
+ /// <param name="tag"> The tag, which should be the name of a parser rule or token
+ /// type.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tag} is {@code null} or
+ /// empty. </exception>
+ TagChunk(const std::string &tag);
+ virtual ~TagChunk();
+
+ /// <summary>
+ /// Construct a new instance of <seealso cref="TagChunk"/> using the specified label
+ /// and tag.
+ /// </summary>
+ /// <param name="label"> The label for the tag. If this is {@code null}, the
+ /// <seealso cref="TagChunk"/> represents an unlabeled tag. </param>
+ /// <param name="tag"> The tag, which should be the name of a parser rule or token
+ /// type.
+ /// </param>
+ /// <exception cref="IllegalArgumentException"> if {@code tag} is {@code null} or
+ /// empty. </exception>
+ TagChunk(const std::string &label, const std::string &tag);
+
+ /// <summary>
+ /// Get the tag for this chunk.
+ /// </summary>
+ /// <returns> The tag for the chunk. </returns>
+ std::string getTag();
+
+ /// <summary>
+ /// Get the label, if any, assigned to this chunk.
+ /// </summary>
+ /// <returns> The label assigned to this chunk, or {@code null} if no label is
+ /// assigned to the chunk. </returns>
+ std::string getLabel();
+
+ /// <summary>
+ /// This method returns a text representation of the tag chunk. Labeled tags
+ /// are returned in the form {@code label:tag}, and unlabeled tags are
+ /// returned as just the tag name.
+ /// </summary>
+ virtual std::string toString() override;
+
+ private:
+ /// This is the backing field for <seealso cref="#getTag"/>.
+ const std::string _tag;
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ /// </summary>
+ const std::string _label;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "Chunk.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// Represents a span of raw text (concrete syntax) between tags in a tree
+ /// pattern string.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TextChunk : public Chunk {
+ private:
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getText"/>.
+ /// </summary>
+ const std::string text;
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TextChunk"/> with the specified text.
+ /// </summary>
+ /// <param name="text"> The text of this chunk. </param>
+ /// <exception cref="IllegalArgumentException"> if {@code text} is {@code null}. </exception>
+ public:
+ TextChunk(const std::string &text);
+ virtual ~TextChunk();
+
+ /// <summary>
+ /// Gets the raw text of this chunk.
+ /// </summary>
+ /// <returns> The text of the chunk. </returns>
+ std::string getText();
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TextChunk"/> returns the result of
+ /// <seealso cref="#getText()"/> in single quotes.
+ /// </summary>
+ virtual std::string toString() override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "CommonToken.h"
+
+namespace antlr4 {
+namespace tree {
+namespace pattern {
+
+ /// <summary>
+ /// A <seealso cref="Token"/> object representing a token of a particular type; e.g.,
+ /// {@code <ID>}. These tokens are created for <seealso cref="TagChunk"/> chunks where the
+ /// tag corresponds to a lexer rule or token type.
+ /// </summary>
+ class ANTLR4CPP_PUBLIC TokenTagToken : public CommonToken {
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getTokenName"/>.
+ /// </summary>
+ private:
+ const std::string tokenName;
+ /// <summary>
+ /// This is the backing field for <seealso cref="#getLabe"/>.
+ /// </summary>
+ const std::string label;
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TokenTagToken"/> for an unlabeled tag
+ /// with the specified token name and type.
+ /// </summary>
+ /// <param name="tokenName"> The token name. </param>
+ /// <param name="type"> The token type. </param>
+ public:
+ TokenTagToken(const std::string &tokenName, int type); //this(tokenName, type, nullptr);
+
+ /// <summary>
+ /// Constructs a new instance of <seealso cref="TokenTagToken"/> with the specified
+ /// token name, type, and label.
+ /// </summary>
+ /// <param name="tokenName"> The token name. </param>
+ /// <param name="type"> The token type. </param>
+ /// <param name="label"> The label associated with the token tag, or {@code null} if
+ /// the token tag is unlabeled. </param>
+ TokenTagToken(const std::string &tokenName, int type, const std::string &label);
+
+ /// <summary>
+ /// Gets the token name. </summary>
+ /// <returns> The token name. </returns>
+ std::string getTokenName() const;
+
+ /// <summary>
+ /// Gets the label associated with the rule tag.
+ /// </summary>
+ /// <returns> The name of the label associated with the rule tag, or
+ /// {@code null} if this is an unlabeled rule tag. </returns>
+ std::string getLabel() const;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TokenTagToken"/> returns the token tag
+ /// formatted with {@code <} and {@code >} delimiters.
+ /// </summary>
+ virtual std::string getText() const override;
+
+ /// <summary>
+ /// {@inheritDoc}
+ /// <p/>
+ /// The implementation for <seealso cref="TokenTagToken"/> returns a string of the form
+ /// {@code tokenName:type}.
+ /// </summary>
+ virtual std::string toString() const override;
+ };
+
+} // namespace pattern
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ /// Represent a subset of XPath XML path syntax for use in identifying nodes in
+ /// parse trees.
+ ///
+ /// <para>
+ /// Split path into words and separators {@code /} and {@code //} via ANTLR
+ /// itself then walk path elements from left to right. At each separator-word
+ /// pair, find set of nodes. Next stage uses those as work list.</para>
+ ///
+ /// <para>
+ /// The basic interface is
+ /// <seealso cref="XPath#findAll ParseTree.findAll"/>{@code (tree, pathString, parser)}.
+ /// But that is just shorthand for:</para>
+ ///
+ /// <pre>
+ /// <seealso cref="XPath"/> p = new <seealso cref="XPath#XPath XPath"/>(parser, pathString);
+ /// return p.<seealso cref="#evaluate evaluate"/>(tree);
+ /// </pre>
+ ///
+ /// <para>
+ /// See {@code org.antlr.v4.test.TestXPath} for descriptions. In short, this
+ /// allows operators:</para>
+ ///
+ /// <dl>
+ /// <dt>/</dt> <dd>root</dd>
+ /// <dt>//</dt> <dd>anywhere</dd>
+ /// <dt>!</dt> <dd>invert; this must appear directly after root or anywhere
+ /// operator</dd>
+ /// </dl>
+ ///
+ /// <para>
+ /// and path elements:</para>
+ ///
+ /// <dl>
+ /// <dt>ID</dt> <dd>token name</dd>
+ /// <dt>'string'</dt> <dd>any string literal token from the grammar</dd>
+ /// <dt>expr</dt> <dd>rule name</dd>
+ /// <dt>*</dt> <dd>wildcard matching any node</dd>
+ /// </dl>
+ ///
+ /// <para>
+ /// Whitespace is not allowed.</para>
+
+ class ANTLR4CPP_PUBLIC XPath {
+ public:
+ static const std::string WILDCARD; // word not operator/separator
+ static const std::string NOT; // word for invert operator
+
+ XPath(Parser *parser, const std::string &path);
+ virtual ~XPath() {}
+
+ // TODO: check for invalid token/rule names, bad syntax
+ virtual std::vector<std::unique_ptr<XPathElement>> split(const std::string &path);
+
+ static std::vector<ParseTree *> findAll(ParseTree *tree, std::string const& xpath, Parser *parser);
+
+ /// Return a list of all nodes starting at {@code t} as root that satisfy the
+ /// path. The root {@code /} is relative to the node passed to
+ /// <seealso cref="#evaluate"/>.
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t);
+
+ protected:
+ std::string _path;
+ Parser *_parser;
+
+ /// Convert word like {@code *} or {@code ID} or {@code expr} to a path
+ /// element. {@code anywhere} is {@code true} if {@code //} precedes the
+ /// word.
+ virtual std::unique_ptr<XPathElement> getXPathElement(Token *wordToken, bool anywhere);
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "antlr4-common.h"
+
+namespace antlr4 {
+namespace tree {
+ class ParseTree;
+
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathElement {
+ public:
+ /// Construct element like {@code /ID} or {@code ID} or {@code /*} etc...
+ /// op is null if just node
+ XPathElement(const std::string &nodeName);
+ XPathElement(XPathElement const&) = default;
+ virtual ~XPathElement();
+
+ XPathElement& operator=(XPathElement const&) = default;
+
+ /// Given tree rooted at {@code t} return all nodes matched by this path
+ /// element.
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t);
+ virtual std::string toString() const;
+
+ void setInvert(bool value);
+
+ protected:
+ std::string _nodeName;
+ bool _invert = false;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+#pragma once
+
+
+#include "antlr4-runtime.h"
+
+
+
+
+class XPathLexer : public antlr4::Lexer {
+public:
+ enum {
+ TOKEN_REF = 1, RULE_REF = 2, ANYWHERE = 3, ROOT = 4, WILDCARD = 5, BANG = 6,
+ ID = 7, STRING = 8
+ };
+
+ XPathLexer(antlr4::CharStream *input);
+ ~XPathLexer();
+
+ virtual std::string getGrammarFileName() const override;
+ virtual const std::vector<std::string>& getRuleNames() const override;
+
+ virtual const std::vector<std::string>& getChannelNames() const override;
+ virtual const std::vector<std::string>& getModeNames() const override;
+ virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead
+ virtual antlr4::dfa::Vocabulary& getVocabulary() const override;
+
+ virtual const std::vector<uint16_t> getSerializedATN() const override;
+ virtual const antlr4::atn::ATN& getATN() const override;
+
+ virtual void action(antlr4::RuleContext *context, size_t ruleIndex, size_t actionIndex) override;
+private:
+ static std::vector<antlr4::dfa::DFA> _decisionToDFA;
+ static antlr4::atn::PredictionContextCache _sharedContextCache;
+ static std::vector<std::string> _ruleNames;
+ static std::vector<std::string> _tokenNames;
+ static std::vector<std::string> _channelNames;
+ static std::vector<std::string> _modeNames;
+
+ static std::vector<std::string> _literalNames;
+ static std::vector<std::string> _symbolicNames;
+ static antlr4::dfa::Vocabulary _vocabulary;
+ static antlr4::atn::ATN _atn;
+ static std::vector<uint16_t> _serializedATN;
+
+
+ // Individual action functions triggered by action() above.
+ void IDAction(antlr4::RuleContext *context, size_t actionIndex);
+
+ // Individual semantic predicate functions triggered by sempred() above.
+
+ struct Initializer {
+ Initializer();
+ };
+ static Initializer _init;
+};
+
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "BaseErrorListener.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathLexerErrorListener : public BaseErrorListener {
+ public:
+ virtual void syntaxError(Recognizer *recognizer, Token *offendingSymbol, size_t line,
+ size_t charPositionInLine, const std::string &msg, std::exception_ptr e) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ /// Either {@code ID} at start of path or {@code ...//ID} in middle of path.
+ class ANTLR4CPP_PUBLIC XPathRuleAnywhereElement : public XPathElement {
+ public:
+ XPathRuleAnywhereElement(const std::string &ruleName, int ruleIndex);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ int _ruleIndex = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathRuleElement : public XPathElement {
+ public:
+ XPathRuleElement(const std::string &ruleName, size_t ruleIndex);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ size_t _ruleIndex = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathTokenAnywhereElement : public XPathElement {
+ protected:
+ int tokenType = 0;
+ public:
+ XPathTokenAnywhereElement(const std::string &tokenName, int tokenType);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathTokenElement : public XPathElement {
+ public:
+ XPathTokenElement(const std::string &tokenName, size_t tokenType);
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+
+ protected:
+ size_t _tokenType = 0;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathWildcardAnywhereElement : public XPathElement {
+ public:
+ XPathWildcardAnywhereElement();
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
+ * Use of this file is governed by the BSD 3-clause license that
+ * can be found in the LICENSE.txt file in the project root.
+ */
+
+#pragma once
+
+#include "XPathElement.h"
+
+namespace antlr4 {
+namespace tree {
+namespace xpath {
+
+ class ANTLR4CPP_PUBLIC XPathWildcardElement : public XPathElement {
+ public:
+ XPathWildcardElement();
+
+ virtual std::vector<ParseTree *> evaluate(ParseTree *t) override;
+ };
+
+} // namespace xpath
+} // namespace tree
+} // namespace antlr4
--- /dev/null
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "utf8/checked.h"
+#include "utf8/unchecked.h"
+
+#endif // header guard
--- /dev/null
+// Copyright 2006-2016 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+#include <stdexcept>
+
+namespace utf8
+{
+ // Base for the exceptions that may be thrown from the library
+ class exception : public ::std::exception {
+ };
+
+ // Exceptions that may be thrown from the library functions.
+ class invalid_code_point : public exception {
+ uint32_t cp;
+ public:
+ invalid_code_point(uint32_t codepoint) : cp(codepoint) {}
+ virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid code point"; }
+ uint32_t code_point() const {return cp;}
+ };
+
+ class invalid_utf8 : public exception {
+ uint8_t u8;
+ public:
+ invalid_utf8 (uint8_t u) : u8(u) {}
+ virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid UTF-8"; }
+ uint8_t utf8_octet() const {return u8;}
+ };
+
+ class invalid_utf16 : public exception {
+ uint16_t u16;
+ public:
+ invalid_utf16 (uint16_t u) : u16(u) {}
+ virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid UTF-16"; }
+ uint16_t utf16_word() const {return u16;}
+ };
+
+ class not_enough_room : public exception {
+ public:
+ virtual const char* what() const NOEXCEPT OVERRIDE { return "Not enough space"; }
+ };
+
+ /// The library API - functions intended to be called by the users
+
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (!utf8::internal::is_code_point_valid(cp))
+ throw invalid_code_point(cp);
+
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
+ {
+ while (start != end) {
+ octet_iterator sequence_start = start;
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ for (octet_iterator it = sequence_start; it != start; ++it)
+ *out++ = *it;
+ break;
+ case internal::NOT_ENOUGH_ROOM:
+ out = utf8::append (replacement, out);
+ start = end;
+ break;
+ case internal::INVALID_LEAD:
+ out = utf8::append (replacement, out);
+ ++start;
+ break;
+ case internal::INCOMPLETE_SEQUENCE:
+ case internal::OVERLONG_SEQUENCE:
+ case internal::INVALID_CODE_POINT:
+ out = utf8::append (replacement, out);
+ ++start;
+ // just one replacement mark for the sequence
+ while (start != end && utf8::internal::is_trail(*start))
+ ++start;
+ break;
+ }
+ }
+ return out;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
+ {
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
+ return utf8::replace_invalid(start, end, out, replacement_marker);
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it, octet_iterator end)
+ {
+ uint32_t cp = 0;
+ internal::utf_error err_code = utf8::internal::validate_next(it, end, cp);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ break;
+ case internal::NOT_ENOUGH_ROOM :
+ throw not_enough_room();
+ case internal::INVALID_LEAD :
+ case internal::INCOMPLETE_SEQUENCE :
+ case internal::OVERLONG_SEQUENCE :
+ throw invalid_utf8(*it);
+ case internal::INVALID_CODE_POINT :
+ throw invalid_code_point(cp);
+ }
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it, octet_iterator end)
+ {
+ return utf8::next(it, end);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it, octet_iterator start)
+ {
+ // can't do much if it == start
+ if (it == start)
+ throw not_enough_room();
+
+ octet_iterator end = it;
+ // Go back until we hit either a lead octet or start
+ while (utf8::internal::is_trail(*(--it)))
+ if (it == start)
+ throw invalid_utf8(*it); // error - no lead byte in the sequence
+ return utf8::peek_next(it, end);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n, octet_iterator end)
+ {
+ const distance_type zero(0);
+ if (n < zero) {
+ // backward
+ for (distance_type i = n; i < zero; ++i)
+ utf8::prior(it, end);
+ } else {
+ // forward
+ for (distance_type i = zero; i < n; ++i)
+ utf8::next(it, end);
+ }
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::next(first, last);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ if (start != end) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ if (utf8::internal::is_trail_surrogate(trail_surrogate))
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ else
+ throw invalid_utf16(static_cast<uint16_t>(trail_surrogate));
+ }
+ else
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ }
+ // Lone trail surrogate
+ else if (utf8::internal::is_trail_surrogate(cp))
+ throw invalid_utf16(static_cast<uint16_t>(cp));
+
+ result = utf8::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start < end) {
+ uint32_t cp = utf8::next(start, end);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start < end)
+ (*result++) = utf8::next(start, end);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator {
+ octet_iterator it;
+ octet_iterator range_start;
+ octet_iterator range_end;
+ public:
+ typedef uint32_t value_type;
+ typedef uint32_t* pointer;
+ typedef uint32_t& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ iterator () {}
+ explicit iterator (const octet_iterator& octet_it,
+ const octet_iterator& rangestart,
+ const octet_iterator& rangeend) :
+ it(octet_it), range_start(rangestart), range_end(rangeend)
+ {
+ if (it < range_start || it > range_end)
+ throw std::out_of_range("Invalid utf-8 iterator position");
+ }
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::next(temp, range_end);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ if (range_start != rhs.range_start || range_end != rhs.range_end)
+ throw std::logic_error("Comparing utf-8 iterators defined with different ranges");
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ utf8::next(it, range_end);
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ utf8::next(it, range_end);
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::prior(it, range_start);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::prior(it, range_start);
+ return temp;
+ }
+ }; // class iterator
+
+} // namespace utf8
+
+#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
+#include "cpp11.h"
+#endif // C++ 11 or later
+
+#endif //header guard
+
--- /dev/null
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_CORE_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include <iterator>
+
+// Determine the C++ standard version.
+// If the user defines UTF_CPP_CPLUSPLUS, use that.
+// Otherwise, trust the unreliable predefined macro __cplusplus
+
+#if !defined UTF_CPP_CPLUSPLUS
+ #define UTF_CPP_CPLUSPLUS __cplusplus
+#endif
+
+#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
+ #define OVERRIDE override
+ #define NOEXCEPT noexcept
+#else // C++ 98/03
+ #define OVERRIDE
+ #define NOEXCEPT throw()
+#endif // C++ 11 or later
+
+
+namespace utf8
+{
+ // The typedefs for 8-bit, 16-bit and 32-bit unsigned integers
+ // You may need to change them to match your system.
+ // These typedefs have the same names as ones from cstdint, or boost/cstdint
+ typedef unsigned char uint8_t;
+ typedef unsigned short uint16_t;
+ typedef unsigned int uint32_t;
+
+// Helper code - not intended to be directly called by the library users. May be changed at any time
+namespace internal
+{
+ // Unicode constants
+ // Leading (high) surrogates: 0xd800 - 0xdbff
+ // Trailing (low) surrogates: 0xdc00 - 0xdfff
+ const uint16_t LEAD_SURROGATE_MIN = 0xd800u;
+ const uint16_t LEAD_SURROGATE_MAX = 0xdbffu;
+ const uint16_t TRAIL_SURROGATE_MIN = 0xdc00u;
+ const uint16_t TRAIL_SURROGATE_MAX = 0xdfffu;
+ const uint16_t LEAD_OFFSET = 0xd7c0u; // LEAD_SURROGATE_MIN - (0x10000 >> 10)
+ const uint32_t SURROGATE_OFFSET = 0xfca02400u; // 0x10000u - (LEAD_SURROGATE_MIN << 10) - TRAIL_SURROGATE_MIN
+
+ // Maximum valid value for a Unicode code point
+ const uint32_t CODE_POINT_MAX = 0x0010ffffu;
+
+ template<typename octet_type>
+ inline uint8_t mask8(octet_type oc)
+ {
+ return static_cast<uint8_t>(0xff & oc);
+ }
+ template<typename u16_type>
+ inline uint16_t mask16(u16_type oc)
+ {
+ return static_cast<uint16_t>(0xffff & oc);
+ }
+ template<typename octet_type>
+ inline bool is_trail(octet_type oc)
+ {
+ return ((utf8::internal::mask8(oc) >> 6) == 0x2);
+ }
+
+ template <typename u16>
+ inline bool is_lead_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= LEAD_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_trail_surrogate(u16 cp)
+ {
+ return (cp >= TRAIL_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u16>
+ inline bool is_surrogate(u16 cp)
+ {
+ return (cp >= LEAD_SURROGATE_MIN && cp <= TRAIL_SURROGATE_MAX);
+ }
+
+ template <typename u32>
+ inline bool is_code_point_valid(u32 cp)
+ {
+ return (cp <= CODE_POINT_MAX && !utf8::internal::is_surrogate(cp));
+ }
+
+ template <typename octet_iterator>
+ inline typename std::iterator_traits<octet_iterator>::difference_type
+ sequence_length(octet_iterator lead_it)
+ {
+ uint8_t lead = utf8::internal::mask8(*lead_it);
+ if (lead < 0x80)
+ return 1;
+ else if ((lead >> 5) == 0x6)
+ return 2;
+ else if ((lead >> 4) == 0xe)
+ return 3;
+ else if ((lead >> 3) == 0x1e)
+ return 4;
+ else
+ return 0;
+ }
+
+ template <typename octet_difference_type>
+ inline bool is_overlong_sequence(uint32_t cp, octet_difference_type length)
+ {
+ if (cp < 0x80) {
+ if (length != 1)
+ return true;
+ }
+ else if (cp < 0x800) {
+ if (length != 2)
+ return true;
+ }
+ else if (cp < 0x10000) {
+ if (length != 3)
+ return true;
+ }
+
+ return false;
+ }
+
+ enum utf_error {UTF8_OK, NOT_ENOUGH_ROOM, INVALID_LEAD, INCOMPLETE_SEQUENCE, OVERLONG_SEQUENCE, INVALID_CODE_POINT};
+
+ /// Helper for get_sequence_x
+ template <typename octet_iterator>
+ utf_error increase_safely(octet_iterator& it, octet_iterator end)
+ {
+ if (++it == end)
+ return NOT_ENOUGH_ROOM;
+
+ if (!utf8::internal::is_trail(*it))
+ return INCOMPLETE_SEQUENCE;
+
+ return UTF8_OK;
+ }
+
+ #define UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(IT, END) {utf_error ret = increase_safely(IT, END); if (ret != UTF8_OK) return ret;}
+
+ /// get_sequence_x functions decode utf-8 sequences of the length x
+ template <typename octet_iterator>
+ utf_error get_sequence_1(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_2(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 6) & 0x7ff) + ((*it) & 0x3f);
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_3(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ template <typename octet_iterator>
+ utf_error get_sequence_4(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ code_point = utf8::internal::mask8(*it);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point = ((code_point << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (utf8::internal::mask8(*it) << 6) & 0xfff;
+
+ UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR(it, end)
+
+ code_point += (*it) & 0x3f;
+
+ return UTF8_OK;
+ }
+
+ #undef UTF8_CPP_INCREASE_AND_RETURN_ON_ERROR
+
+ template <typename octet_iterator>
+ utf_error validate_next(octet_iterator& it, octet_iterator end, uint32_t& code_point)
+ {
+ if (it == end)
+ return NOT_ENOUGH_ROOM;
+
+ // Save the original value of it so we can go back in case of failure
+ // Of course, it does not make much sense with i.e. stream iterators
+ octet_iterator original_it = it;
+
+ uint32_t cp = 0;
+ // Determine the sequence length based on the lead octet
+ typedef typename std::iterator_traits<octet_iterator>::difference_type octet_difference_type;
+ const octet_difference_type length = utf8::internal::sequence_length(it);
+
+ // Get trail octets and calculate the code point
+ utf_error err = UTF8_OK;
+ switch (length) {
+ case 0:
+ return INVALID_LEAD;
+ case 1:
+ err = utf8::internal::get_sequence_1(it, end, cp);
+ break;
+ case 2:
+ err = utf8::internal::get_sequence_2(it, end, cp);
+ break;
+ case 3:
+ err = utf8::internal::get_sequence_3(it, end, cp);
+ break;
+ case 4:
+ err = utf8::internal::get_sequence_4(it, end, cp);
+ break;
+ }
+
+ if (err == UTF8_OK) {
+ // Decoding succeeded. Now, security checks...
+ if (utf8::internal::is_code_point_valid(cp)) {
+ if (!utf8::internal::is_overlong_sequence(cp, length)){
+ // Passed! Return here.
+ code_point = cp;
+ ++it;
+ return UTF8_OK;
+ }
+ else
+ err = OVERLONG_SEQUENCE;
+ }
+ else
+ err = INVALID_CODE_POINT;
+ }
+
+ // Failure branch - restore the original value of the iterator
+ it = original_it;
+ return err;
+ }
+
+ template <typename octet_iterator>
+ inline utf_error validate_next(octet_iterator& it, octet_iterator end) {
+ uint32_t ignored;
+ return utf8::internal::validate_next(it, end, ignored);
+ }
+
+} // namespace internal
+
+ /// The library API - functions intended to be called by the users
+
+ // Byte order mark
+ const uint8_t bom[] = {0xef, 0xbb, 0xbf};
+
+ template <typename octet_iterator>
+ octet_iterator find_invalid(octet_iterator start, octet_iterator end)
+ {
+ octet_iterator result = start;
+ while (result != end) {
+ utf8::internal::utf_error err_code = utf8::internal::validate_next(result, end);
+ if (err_code != internal::UTF8_OK)
+ return result;
+ }
+ return result;
+ }
+
+ template <typename octet_iterator>
+ inline bool is_valid(octet_iterator start, octet_iterator end)
+ {
+ return (utf8::find_invalid(start, end) == end);
+ }
+
+ template <typename octet_iterator>
+ inline bool starts_with_bom (octet_iterator it, octet_iterator end)
+ {
+ return (
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[0]) &&
+ ((it != end) && (utf8::internal::mask8(*it++)) == bom[1]) &&
+ ((it != end) && (utf8::internal::mask8(*it)) == bom[2])
+ );
+ }
+} // namespace utf8
+
+#endif // header guard
+
+
--- /dev/null
+// Copyright 2018 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
+#define UTF8_FOR_CPP_a184c22c_d012_11e8_a8d5_f2801f1b9fd1
+
+#include "checked.h"
+#include <string>
+
+namespace utf8
+{
+
+ inline void append(char32_t cp, std::string& s)
+ {
+ append(uint32_t(cp), std::back_inserter(s));
+ }
+
+ inline std::string utf16to8(const std::u16string& s)
+ {
+ std::string result;
+ utf16to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u16string utf8to16(const std::string& s)
+ {
+ std::u16string result;
+ utf8to16(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::string utf32to8(const std::u32string& s)
+ {
+ std::string result;
+ utf32to8(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::u32string utf8to32(const std::string& s)
+ {
+ std::u32string result;
+ utf8to32(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline std::size_t find_invalid(const std::string& s)
+ {
+ std::string::const_iterator invalid = find_invalid(s.begin(), s.end());
+ return (invalid == s.end()) ? std::string::npos : (invalid - s.begin());
+ }
+
+ inline bool is_valid(const std::string& s)
+ {
+ return is_valid(s.begin(), s.end());
+ }
+
+ inline std::string replace_invalid(const std::string& s, char32_t replacement)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result), replacement);
+ return result;
+ }
+
+ inline std::string replace_invalid(const std::string& s)
+ {
+ std::string result;
+ replace_invalid(s.begin(), s.end(), std::back_inserter(result));
+ return result;
+ }
+
+ inline bool starts_with_bom(const std::string& s)
+ {
+ return starts_with_bom(s.begin(), s.end());
+ }
+
+} // namespace utf8
+
+#endif // header guard
+
--- /dev/null
+// Copyright 2006 Nemanja Trifunovic
+
+/*
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
+*/
+
+
+#ifndef UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+#define UTF8_FOR_CPP_UNCHECKED_H_2675DCD0_9480_4c0c_B92A_CC14C027B731
+
+#include "core.h"
+
+namespace utf8
+{
+ namespace unchecked
+ {
+ template <typename octet_iterator>
+ octet_iterator append(uint32_t cp, octet_iterator result)
+ {
+ if (cp < 0x80) // one octet
+ *(result++) = static_cast<uint8_t>(cp);
+ else if (cp < 0x800) { // two octets
+ *(result++) = static_cast<uint8_t>((cp >> 6) | 0xc0);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else if (cp < 0x10000) { // three octets
+ *(result++) = static_cast<uint8_t>((cp >> 12) | 0xe0);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ else { // four octets
+ *(result++) = static_cast<uint8_t>((cp >> 18) | 0xf0);
+ *(result++) = static_cast<uint8_t>(((cp >> 12) & 0x3f)| 0x80);
+ *(result++) = static_cast<uint8_t>(((cp >> 6) & 0x3f) | 0x80);
+ *(result++) = static_cast<uint8_t>((cp & 0x3f) | 0x80);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out, uint32_t replacement)
+ {
+ while (start != end) {
+ octet_iterator sequence_start = start;
+ internal::utf_error err_code = utf8::internal::validate_next(start, end);
+ switch (err_code) {
+ case internal::UTF8_OK :
+ for (octet_iterator it = sequence_start; it != start; ++it)
+ *out++ = *it;
+ break;
+ case internal::NOT_ENOUGH_ROOM:
+ out = utf8::unchecked::append (replacement, out);
+ start = end;
+ break;
+ case internal::INVALID_LEAD:
+ out = utf8::unchecked::append (replacement, out);
+ ++start;
+ break;
+ case internal::INCOMPLETE_SEQUENCE:
+ case internal::OVERLONG_SEQUENCE:
+ case internal::INVALID_CODE_POINT:
+ out = utf8::unchecked::append (replacement, out);
+ ++start;
+ // just one replacement mark for the sequence
+ while (start != end && utf8::internal::is_trail(*start))
+ ++start;
+ break;
+ }
+ }
+ return out;
+ }
+
+ template <typename octet_iterator, typename output_iterator>
+ inline output_iterator replace_invalid(octet_iterator start, octet_iterator end, output_iterator out)
+ {
+ static const uint32_t replacement_marker = utf8::internal::mask16(0xfffd);
+ return utf8::unchecked::replace_invalid(start, end, out, replacement_marker);
+ }
+
+ template <typename octet_iterator>
+ uint32_t next(octet_iterator& it)
+ {
+ uint32_t cp = utf8::internal::mask8(*it);
+ typename std::iterator_traits<octet_iterator>::difference_type length = utf8::internal::sequence_length(it);
+ switch (length) {
+ case 1:
+ break;
+ case 2:
+ it++;
+ cp = ((cp << 6) & 0x7ff) + ((*it) & 0x3f);
+ break;
+ case 3:
+ ++it;
+ cp = ((cp << 12) & 0xffff) + ((utf8::internal::mask8(*it) << 6) & 0xfff);
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ case 4:
+ ++it;
+ cp = ((cp << 18) & 0x1fffff) + ((utf8::internal::mask8(*it) << 12) & 0x3ffff);
+ ++it;
+ cp += (utf8::internal::mask8(*it) << 6) & 0xfff;
+ ++it;
+ cp += (*it) & 0x3f;
+ break;
+ }
+ ++it;
+ return cp;
+ }
+
+ template <typename octet_iterator>
+ uint32_t peek_next(octet_iterator it)
+ {
+ return utf8::unchecked::next(it);
+ }
+
+ template <typename octet_iterator>
+ uint32_t prior(octet_iterator& it)
+ {
+ while (utf8::internal::is_trail(*(--it))) ;
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+
+ template <typename octet_iterator, typename distance_type>
+ void advance (octet_iterator& it, distance_type n)
+ {
+ const distance_type zero(0);
+ if (n < zero) {
+ // backward
+ for (distance_type i = n; i < zero; ++i)
+ utf8::unchecked::prior(it);
+ } else {
+ // forward
+ for (distance_type i = zero; i < n; ++i)
+ utf8::unchecked::next(it);
+ }
+ }
+
+ template <typename octet_iterator>
+ typename std::iterator_traits<octet_iterator>::difference_type
+ distance (octet_iterator first, octet_iterator last)
+ {
+ typename std::iterator_traits<octet_iterator>::difference_type dist;
+ for (dist = 0; first < last; ++dist)
+ utf8::unchecked::next(first);
+ return dist;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ octet_iterator utf16to8 (u16bit_iterator start, u16bit_iterator end, octet_iterator result)
+ {
+ while (start != end) {
+ uint32_t cp = utf8::internal::mask16(*start++);
+ // Take care of surrogate pairs first
+ if (utf8::internal::is_lead_surrogate(cp)) {
+ uint32_t trail_surrogate = utf8::internal::mask16(*start++);
+ cp = (cp << 10) + trail_surrogate + internal::SURROGATE_OFFSET;
+ }
+ result = utf8::unchecked::append(cp, result);
+ }
+ return result;
+ }
+
+ template <typename u16bit_iterator, typename octet_iterator>
+ u16bit_iterator utf8to16 (octet_iterator start, octet_iterator end, u16bit_iterator result)
+ {
+ while (start < end) {
+ uint32_t cp = utf8::unchecked::next(start);
+ if (cp > 0xffff) { //make a surrogate pair
+ *result++ = static_cast<uint16_t>((cp >> 10) + internal::LEAD_OFFSET);
+ *result++ = static_cast<uint16_t>((cp & 0x3ff) + internal::TRAIL_SURROGATE_MIN);
+ }
+ else
+ *result++ = static_cast<uint16_t>(cp);
+ }
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ octet_iterator utf32to8 (u32bit_iterator start, u32bit_iterator end, octet_iterator result)
+ {
+ while (start != end)
+ result = utf8::unchecked::append(*(start++), result);
+
+ return result;
+ }
+
+ template <typename octet_iterator, typename u32bit_iterator>
+ u32bit_iterator utf8to32 (octet_iterator start, octet_iterator end, u32bit_iterator result)
+ {
+ while (start < end)
+ (*result++) = utf8::unchecked::next(start);
+
+ return result;
+ }
+
+ // The iterator class
+ template <typename octet_iterator>
+ class iterator {
+ octet_iterator it;
+ public:
+ typedef uint32_t value_type;
+ typedef uint32_t* pointer;
+ typedef uint32_t& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::bidirectional_iterator_tag iterator_category;
+ iterator () {}
+ explicit iterator (const octet_iterator& octet_it): it(octet_it) {}
+ // the default "big three" are OK
+ octet_iterator base () const { return it; }
+ uint32_t operator * () const
+ {
+ octet_iterator temp = it;
+ return utf8::unchecked::next(temp);
+ }
+ bool operator == (const iterator& rhs) const
+ {
+ return (it == rhs.it);
+ }
+ bool operator != (const iterator& rhs) const
+ {
+ return !(operator == (rhs));
+ }
+ iterator& operator ++ ()
+ {
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return *this;
+ }
+ iterator operator ++ (int)
+ {
+ iterator temp = *this;
+ ::std::advance(it, utf8::internal::sequence_length(it));
+ return temp;
+ }
+ iterator& operator -- ()
+ {
+ utf8::unchecked::prior(it);
+ return *this;
+ }
+ iterator operator -- (int)
+ {
+ iterator temp = *this;
+ utf8::unchecked::prior(it);
+ return temp;
+ }
+ }; // class iterator
+
+ } // namespace utf8::unchecked
+} // namespace utf8
+
+
+#endif // header guard
+
--- /dev/null
+# C++ target for ANTLR 4
+
+This folder contains the C++ runtime support for ANTLR. See [the canonical antlr4 repository](https://github.com/antlr/antlr4) for in depth detail about how to use ANTLR 4.
+
+## Authors and major contributors
+
+ANTLR 4 is the result of substantial effort of the following people:
+
+* [Terence Parr](http://www.cs.usfca.edu/~parrt/), parrt@cs.usfca.edu
+ ANTLR project lead and supreme dictator for life
+ [University of San Francisco](http://www.usfca.edu/)
+* [Sam Harwell](http://tunnelvisionlabs.com/)
+ Tool co-author, Java and C# target)
+
+The C++ target has been the work of the following people:
+
+* Dan McLaughlin, dan.mclaughlin@gmail.com (initial port, got code to compile)
+* David Sisson, dsisson@google.com (initial port, made the runtime C++ tests runnable)
+* [Mike Lischke](www.soft-gems.net), mike@lischke-online.de (brought the initial port to a working library, made most runtime tests passing)
+
+## Other contributors
+
+* Marcin Szalowicz, mszalowicz@mailplus.pl (cmake build setup)
+* Tim O'Callaghan, timo@linux.com (additional superbuild cmake pattern script)
+
+## Project Status
+
+* Building on macOS, Windows, Android and Linux
+* No errors and warnings
+* Library linking
+* Some unit tests in the macOS project, for important base classes with almost 100% code coverage.
+* All memory allocations checked
+* Simple command line demo application working on all supported platforms.
+* All runtime tests pass.
+
+### Build + Usage Notes
+
+The minimum C++ version to compile the ANTLR C++ runtime with is C++11. The supplied projects can built the runtime either as static or dynamic library, as both 32bit and 64bit arch. The macOS project contains a target for iOS and can also be built using cmake (instead of XCode).
+
+Include the antlr4-runtime.h umbrella header in your target application to get everything needed to use the library.
+
+If you are compiling with cmake, the minimum version required is cmake 2.8.
+By default, the libraries produced by the CMake build target C++11. If you want to target a different C++ standard, you can explicitly pass the standard - e.g. `-DCMAKE_CXX_STANDARD=17`.
+
+#### Compiling on Windows with Visual Studio using he Visual Studio projects
+Simply open the VS project from the runtime folder (VS 2013+) and build it.
+
+#### Compiling on Windows using cmake with Visual Studio VS2017 and later
+Use the "Open Folder" Feature from the File->Open->Folder menu to open the runtime/Cpp directory.
+It will automatically use the CMake description to open up a Visual Studio Solution.
+
+#### Compiling on macOS
+Either open the included XCode project and build that or use the cmake compilation as described for linux.
+
+#### Compiling on Android
+Try run cmake -DCMAKE_ANDROID_NDK=/folder/of/android_ndkr17_and_above -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_API=14 -DCMAKE_ANDROID_ARCH_ABI=x86 -DCMAKE_ANDROID_STL_TYPE=c++_shared -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang -DCMAKE_BUILD_TYPE=Release /folder/antlr4_src_dir -G Ninja.
+
+#### Compiling on Linux
+- cd \<antlr4-dir\>/runtime/Cpp (this is where this readme is located)
+- mkdir build && mkdir run && cd build
+- cmake .. -DANTLR_JAR_LOCATION=full/path/to/antlr4-4.5.4-SNAPSHOT.jar -DWITH_DEMO=True
+- make
+- DESTDIR=\<antlr4-dir\>/runtime/Cpp/run make install
+
+If you don't want to build the demo then simply run cmake without parameters.
+There is another cmake script available in the subfolder cmake/ for those who prefer the superbuild cmake pattern.
+
+#### CMake Package support
+If the CMake variable 'ANTLR4_INSTALL' is set, CMake Packages will be build and installed during the install step.
+They expose two packages: antlr4_runtime and antlr4_generator which can be referenced to ease up the use of the
+ANTLR Generator and runtime.
+Use and Sample can be found [here](cmake/Antlr4Package.md)
--- /dev/null
+token literal names:
+null
+'var'
+':'
+'='
+'func'
+'('
+')'
+','
+'{'
+'}'
+'struct'
+'if'
+'while'
+'return'
+'['
+']'
+'.'
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+BINARY_OPERATOR
+INTLIT
+NAME
+WS
+NEWLINE
+
+rule names:
+prog
+decl
+varDecl
+var
+type
+funcDecl
+func
+parameter
+firstParameter
+additionalParameter
+body
+structDecl
+structMember
+structVar
+structMethod
+stmt
+conditional
+ifCond
+loop
+whileLoop
+assignment
+returnStmt
+expr
+nonOpExpr
+nonSubscriptExpr
+funcCall
+operatorExpr
+binaryOperator
+identifier
+literal
+subscript
+memberAccess
+parenExpr
+funcName
+varName
+typeName
+structName
+
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 3, 23, 257, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23, 9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9, 28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33, 4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 3, 2, 6, 2, 78, 10, 2, 13, 2, 14, 2, 79, 3, 2, 3, 2, 3, 3, 3, 3, 3, 3, 5, 3, 87, 10, 3, 3, 4, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 5, 5, 98, 10, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 7, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 8, 3, 9, 3, 9, 7, 9, 116, 10, 9, 12, 9, 14, 9, 119, 11, 9, 5, 9, 121, 10, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 7, 12, 130, 10, 12, 12, 12, 14, 12, 133, 11, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 7, 13, 141, 10, 13, 12, 13, 14, 13, 144, 11, 13, 3, 13, 3, 13, 3, 14, 3, 14, 5, 14, 150, 10, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 162, 10, 17, 3, 18, 3, 18, 3, 19, 3, 19, 3, 19, 3, 19, 3, 20, 3, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 23, 3, 23, 3, 23, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 3, 24, 5, 24, 190, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 5, 25, 198, 10, 25, 3, 26, 3, 26, 3, 26, 3, 26, 5, 26, 204, 10, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 7, 27, 211, 10, 27, 12, 27, 14, 27, 214, 11, 27, 5, 27, 216, 10, 27, 3, 27, 3, 27, 3, 28, 3, 28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 7, 29, 227, 10, 29, 12, 29, 14, 29, 230, 11, 29, 3, 30, 3, 30, 3, 31, 3, 31, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 33, 3, 33, 3, 33, 3, 33, 3, 34, 3, 34, 3, 34, 3, 34, 3, 35, 3, 35, 3, 36, 3, 36, 3, 37, 3, 37, 3, 38, 3, 38, 3, 38, 2, 2, 39, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 2, 2, 2, 250, 2, 77, 3, 2, 2, 2, 4, 86, 3, 2, 2, 2, 6, 88, 3, 2, 2, 2, 8, 91, 3, 2, 2, 2, 10, 99, 3, 2, 2, 2, 12, 101, 3, 2, 2, 2, 14, 104, 3, 2, 2, 2, 16, 120, 3, 2, 2, 2, 18, 122, 3, 2, 2, 2, 20, 124, 3, 2, 2, 2, 22, 127, 3, 2, 2, 2, 24, 136, 3, 2, 2, 2, 26, 149, 3, 2, 2, 2, 28, 151, 3, 2, 2, 2, 30, 153, 3, 2, 2, 2, 32, 161, 3, 2, 2, 2, 34, 163, 3, 2, 2, 2, 36, 165, 3, 2, 2, 2, 38, 169, 3, 2, 2, 2, 40, 171, 3, 2, 2, 2, 42, 175, 3, 2, 2, 2, 44, 179, 3, 2, 2, 2, 46, 189, 3, 2, 2, 2, 48, 197, 3, 2, 2, 2, 50, 203, 3, 2, 2, 2, 52, 205, 3, 2, 2, 2, 54, 219, 3, 2, 2, 2, 56, 221, 3, 2, 2, 2, 58, 231, 3, 2, 2, 2, 60, 233, 3, 2, 2, 2, 62, 235, 3, 2, 2, 2, 64, 240, 3, 2, 2, 2, 66, 244, 3, 2, 2, 2, 68, 248, 3, 2, 2, 2, 70, 250, 3, 2, 2, 2, 72, 252, 3, 2, 2, 2, 74, 254, 3, 2, 2, 2, 76, 78, 5, 4, 3, 2, 77, 76, 3, 2, 2, 2, 78, 79, 3, 2, 2, 2, 79, 77, 3, 2, 2, 2, 79, 80, 3, 2, 2, 2, 80, 81, 3, 2, 2, 2, 81, 82, 7, 2, 2, 3, 82, 3, 3, 2, 2, 2, 83, 87, 5, 6, 4, 2, 84, 87, 5, 12, 7, 2, 85, 87, 5, 24, 13, 2, 86, 83, 3, 2, 2, 2, 86, 84, 3, 2, 2, 2, 86, 85, 3, 2, 2, 2, 87, 5, 3, 2, 2, 2, 88, 89, 7, 3, 2, 2, 89, 90, 5, 8, 5, 2, 90, 7, 3, 2, 2, 2, 91, 92, 5, 70, 36, 2, 92, 93, 7, 4, 2, 2, 93, 94, 5, 10, 6, 2, 94, 97, 3, 2, 2, 2, 95, 96, 7, 5, 2, 2, 96, 98, 5, 46, 24, 2, 97, 95, 3, 2, 2, 2, 97, 98, 3, 2, 2, 2, 98, 9, 3, 2, 2, 2, 99, 100, 5, 72, 37, 2, 100, 11, 3, 2, 2, 2, 101, 102, 7, 6, 2, 2, 102, 103, 5, 14, 8, 2, 103, 13, 3, 2, 2, 2, 104, 105, 5, 68, 35, 2, 105, 106, 7, 7, 2, 2, 106, 107, 5, 16, 9, 2, 107, 108, 7, 8, 2, 2, 108, 109, 7, 4, 2, 2, 109, 110, 5, 10, 6, 2, 110, 111, 3, 2, 2, 2, 111, 112, 5, 22, 12, 2, 112, 15, 3, 2, 2, 2, 113, 117, 5, 18, 10, 2, 114, 116, 5, 20, 11, 2, 115, 114, 3, 2, 2, 2, 116, 119, 3, 2, 2, 2, 117, 115, 3, 2, 2, 2, 117, 118, 3, 2, 2, 2, 118, 121, 3, 2, 2, 2, 119, 117, 3, 2, 2, 2, 120, 113, 3, 2, 2, 2, 120, 121, 3, 2, 2, 2, 121, 17, 3, 2, 2, 2, 122, 123, 5, 8, 5, 2, 123, 19, 3, 2, 2, 2, 124, 125, 7, 9, 2, 2, 125, 126, 5, 8, 5, 2, 126, 21, 3, 2, 2, 2, 127, 131, 7, 10, 2, 2, 128, 130, 5, 32, 17, 2, 129, 128, 3, 2, 2, 2, 130, 133, 3, 2, 2, 2, 131, 129, 3, 2, 2, 2, 131, 132, 3, 2, 2, 2, 132, 134, 3, 2, 2, 2, 133, 131, 3, 2, 2, 2, 134, 135, 7, 11, 2, 2, 135, 23, 3, 2, 2, 2, 136, 137, 7, 12, 2, 2, 137, 138, 5, 74, 38, 2, 138, 142, 7, 10, 2, 2, 139, 141, 5, 26, 14, 2, 140, 139, 3, 2, 2, 2, 141, 144, 3, 2, 2, 2, 142, 140, 3, 2, 2, 2, 142, 143, 3, 2, 2, 2, 143, 145, 3, 2, 2, 2, 144, 142, 3, 2, 2, 2, 145, 146, 7, 11, 2, 2, 146, 25, 3, 2, 2, 2, 147, 150, 5, 28, 15, 2, 148, 150, 5, 30, 16, 2, 149, 147, 3, 2, 2, 2, 149, 148, 3, 2, 2, 2, 150, 27, 3, 2, 2, 2, 151, 152, 5, 8, 5, 2, 152, 29, 3, 2, 2, 2, 153, 154, 5, 14, 8, 2, 154, 31, 3, 2, 2, 2, 155, 162, 5, 6, 4, 2, 156, 162, 5, 34, 18, 2, 157, 162, 5, 38, 20, 2, 158, 162, 5, 42, 22, 2, 159, 162, 5, 44, 23, 2, 160, 162, 5, 46, 24, 2, 161, 155, 3, 2, 2, 2, 161, 156, 3, 2, 2, 2, 161, 157, 3, 2, 2, 2, 161, 158, 3, 2, 2, 2, 161, 159, 3, 2, 2, 2, 161, 160, 3, 2, 2, 2, 162, 33, 3, 2, 2, 2, 163, 164, 5, 36, 19, 2, 164, 35, 3, 2, 2, 2, 165, 166, 7, 13, 2, 2, 166, 167, 5, 46, 24, 2, 167, 168, 5, 22, 12, 2, 168, 37, 3, 2, 2, 2, 169, 170, 5, 40, 21, 2, 170, 39, 3, 2, 2, 2, 171, 172, 7, 14, 2, 2, 172, 173, 5, 46, 24, 2, 173, 174, 5, 22, 12, 2, 174, 41, 3, 2, 2, 2, 175, 176, 5, 58, 30, 2, 176, 177, 7, 5, 2, 2, 177, 178, 5, 46, 24, 2, 178, 43, 3, 2, 2, 2, 179, 180, 7, 15, 2, 2, 180, 181, 5, 46, 24, 2, 181, 45, 3, 2, 2, 2, 182, 190, 5, 52, 27, 2, 183, 190, 5, 60, 31, 2, 184, 190, 5, 58, 30, 2, 185, 190, 5, 62, 32, 2, 186, 190, 5, 64, 33, 2, 187, 190, 5, 66, 34, 2, 188, 190, 5, 54, 28, 2, 189, 182, 3, 2, 2, 2, 189, 183, 3, 2, 2, 2, 189, 184, 3, 2, 2, 2, 189, 185, 3, 2, 2, 2, 189, 186, 3, 2, 2, 2, 189, 187, 3, 2, 2, 2, 189, 188, 3, 2, 2, 2, 190, 47, 3, 2, 2, 2, 191, 198, 5, 52, 27, 2, 192, 198, 5, 60, 31, 2, 193, 198, 5, 58, 30, 2, 194, 198, 5, 62, 32, 2, 195, 198, 5, 64, 33, 2, 196, 198, 5, 66, 34, 2, 197, 191, 3, 2, 2, 2, 197, 192, 3, 2, 2, 2, 197, 193, 3, 2, 2, 2, 197, 194, 3, 2, 2, 2, 197, 195, 3, 2, 2, 2, 197, 196, 3, 2, 2, 2, 198, 49, 3, 2, 2, 2, 199, 204, 5, 52, 27, 2, 200, 204, 5, 58, 30, 2, 201, 204, 5, 64, 33, 2, 202, 204, 5, 66, 34, 2, 203, 199, 3, 2, 2, 2, 203, 200, 3, 2, 2, 2, 203, 201, 3, 2, 2, 2, 203, 202, 3, 2, 2, 2, 204, 51, 3, 2, 2, 2, 205, 206, 5, 68, 35, 2, 206, 215, 7, 7, 2, 2, 207, 212, 5, 46, 24, 2, 208, 209, 7, 9, 2, 2, 209, 211, 5, 46, 24, 2, 210, 208, 3, 2, 2, 2, 211, 214, 3, 2, 2, 2, 212, 210, 3, 2, 2, 2, 212, 213, 3, 2, 2, 2, 213, 216, 3, 2, 2, 2, 214, 212, 3, 2, 2, 2, 215, 207, 3, 2, 2, 2, 215, 216, 3, 2, 2, 2, 216, 217, 3, 2, 2, 2, 217, 218, 7, 8, 2, 2, 218, 53, 3, 2, 2, 2, 219, 220, 5, 56, 29, 2, 220, 55, 3, 2, 2, 2, 221, 222, 5, 48, 25, 2, 222, 223, 7, 19, 2, 2, 223, 228, 5, 48, 25, 2, 224, 225, 7, 19, 2, 2, 225, 227, 5, 48, 25, 2, 226, 224, 3, 2, 2, 2, 227, 230, 3, 2, 2, 2, 228, 226, 3, 2, 2, 2, 228, 229, 3, 2, 2, 2, 229, 57, 3, 2, 2, 2, 230, 228, 3, 2, 2, 2, 231, 232, 5, 70, 36, 2, 232, 59, 3, 2, 2, 2, 233, 234, 7, 20, 2, 2, 234, 61, 3, 2, 2, 2, 235, 236, 5, 50, 26, 2, 236, 237, 7, 16, 2, 2, 237, 238, 5, 46, 24, 2, 238, 239, 7, 17, 2, 2, 239, 63, 3, 2, 2, 2, 240, 241, 5, 58, 30, 2, 241, 242, 7, 18, 2, 2, 242, 243, 5, 58, 30, 2, 243, 65, 3, 2, 2, 2, 244, 245, 7, 7, 2, 2, 245, 246, 5, 46, 24, 2, 246, 247, 7, 8, 2, 2, 247, 67, 3, 2, 2, 2, 248, 249, 7, 21, 2, 2, 249, 69, 3, 2, 2, 2, 250, 251, 7, 21, 2, 2, 251, 71, 3, 2, 2, 2, 252, 253, 7, 21, 2, 2, 253, 73, 3, 2, 2, 2, 254, 255, 7, 21, 2, 2, 255, 75, 3, 2, 2, 2, 17, 79, 86, 97, 117, 120, 131, 142, 149, 161, 189, 197, 203, 212, 215, 228]
\ No newline at end of file
--- /dev/null
+T__0=1\r
+T__1=2\r
+T__2=3\r
+T__3=4\r
+T__4=5\r
+T__5=6\r
+T__6=7\r
+T__7=8\r
+T__8=9\r
+T__9=10\r
+T__10=11\r
+T__11=12\r
+T__12=13\r
+T__13=14\r
+T__14=15\r
+T__15=16\r
+BINARY_OPERATOR=17\r
+INTLIT=18\r
+NAME=19\r
+WS=20\r
+NEWLINE=21\r
+'var'=1\r
+':'=2\r
+'='=3\r
+'func'=4\r
+'('=5\r
+')'=6\r
+','=7\r
+'{'=8\r
+'}'=9\r
+'struct'=10\r
+'if'=11\r
+'while'=12\r
+'return'=13\r
+'['=14\r
+']'=15\r
+'.'=16\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+\r
+#include "TocBaseListener.h"\r
+\r
+\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+#pragma once\r
+\r
+\r
+#include "antlr4-runtime.h"\r
+#include "TocListener.h"\r
+\r
+\r
+/**\r
+ * This class provides an empty implementation of TocListener,\r
+ * which can be extended to create a listener which only needs to handle a subset\r
+ * of the available methods.\r
+ */\r
+class TocBaseListener : public TocListener {\r
+public:\r
+\r
+ virtual void enterProg(TocParser::ProgContext * /*ctx*/) override { }\r
+ virtual void exitProg(TocParser::ProgContext * /*ctx*/) override { }\r
+\r
+ virtual void enterDecl(TocParser::DeclContext * /*ctx*/) override { }\r
+ virtual void exitDecl(TocParser::DeclContext * /*ctx*/) override { }\r
+\r
+ virtual void enterVarDecl(TocParser::VarDeclContext * /*ctx*/) override { }\r
+ virtual void exitVarDecl(TocParser::VarDeclContext * /*ctx*/) override { }\r
+\r
+ virtual void enterVar(TocParser::VarContext * /*ctx*/) override { }\r
+ virtual void exitVar(TocParser::VarContext * /*ctx*/) override { }\r
+\r
+ virtual void enterType(TocParser::TypeContext * /*ctx*/) override { }\r
+ virtual void exitType(TocParser::TypeContext * /*ctx*/) override { }\r
+\r
+ virtual void enterFuncDecl(TocParser::FuncDeclContext * /*ctx*/) override { }\r
+ virtual void exitFuncDecl(TocParser::FuncDeclContext * /*ctx*/) override { }\r
+\r
+ virtual void enterFunc(TocParser::FuncContext * /*ctx*/) override { }\r
+ virtual void exitFunc(TocParser::FuncContext * /*ctx*/) override { }\r
+\r
+ virtual void enterParameter(TocParser::ParameterContext * /*ctx*/) override { }\r
+ virtual void exitParameter(TocParser::ParameterContext * /*ctx*/) override { }\r
+\r
+ virtual void enterFirstParameter(TocParser::FirstParameterContext * /*ctx*/) override { }\r
+ virtual void exitFirstParameter(TocParser::FirstParameterContext * /*ctx*/) override { }\r
+\r
+ virtual void enterAdditionalParameter(TocParser::AdditionalParameterContext * /*ctx*/) override { }\r
+ virtual void exitAdditionalParameter(TocParser::AdditionalParameterContext * /*ctx*/) override { }\r
+\r
+ virtual void enterBody(TocParser::BodyContext * /*ctx*/) override { }\r
+ virtual void exitBody(TocParser::BodyContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStructDecl(TocParser::StructDeclContext * /*ctx*/) override { }\r
+ virtual void exitStructDecl(TocParser::StructDeclContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStructMember(TocParser::StructMemberContext * /*ctx*/) override { }\r
+ virtual void exitStructMember(TocParser::StructMemberContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStructVar(TocParser::StructVarContext * /*ctx*/) override { }\r
+ virtual void exitStructVar(TocParser::StructVarContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStructMethod(TocParser::StructMethodContext * /*ctx*/) override { }\r
+ virtual void exitStructMethod(TocParser::StructMethodContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStmt(TocParser::StmtContext * /*ctx*/) override { }\r
+ virtual void exitStmt(TocParser::StmtContext * /*ctx*/) override { }\r
+\r
+ virtual void enterConditional(TocParser::ConditionalContext * /*ctx*/) override { }\r
+ virtual void exitConditional(TocParser::ConditionalContext * /*ctx*/) override { }\r
+\r
+ virtual void enterIfCond(TocParser::IfCondContext * /*ctx*/) override { }\r
+ virtual void exitIfCond(TocParser::IfCondContext * /*ctx*/) override { }\r
+\r
+ virtual void enterLoop(TocParser::LoopContext * /*ctx*/) override { }\r
+ virtual void exitLoop(TocParser::LoopContext * /*ctx*/) override { }\r
+\r
+ virtual void enterWhileLoop(TocParser::WhileLoopContext * /*ctx*/) override { }\r
+ virtual void exitWhileLoop(TocParser::WhileLoopContext * /*ctx*/) override { }\r
+\r
+ virtual void enterAssignment(TocParser::AssignmentContext * /*ctx*/) override { }\r
+ virtual void exitAssignment(TocParser::AssignmentContext * /*ctx*/) override { }\r
+\r
+ virtual void enterReturnStmt(TocParser::ReturnStmtContext * /*ctx*/) override { }\r
+ virtual void exitReturnStmt(TocParser::ReturnStmtContext * /*ctx*/) override { }\r
+\r
+ virtual void enterExpr(TocParser::ExprContext * /*ctx*/) override { }\r
+ virtual void exitExpr(TocParser::ExprContext * /*ctx*/) override { }\r
+\r
+ virtual void enterNonOpExpr(TocParser::NonOpExprContext * /*ctx*/) override { }\r
+ virtual void exitNonOpExpr(TocParser::NonOpExprContext * /*ctx*/) override { }\r
+\r
+ virtual void enterNonSubscriptExpr(TocParser::NonSubscriptExprContext * /*ctx*/) override { }\r
+ virtual void exitNonSubscriptExpr(TocParser::NonSubscriptExprContext * /*ctx*/) override { }\r
+\r
+ virtual void enterFuncCall(TocParser::FuncCallContext * /*ctx*/) override { }\r
+ virtual void exitFuncCall(TocParser::FuncCallContext * /*ctx*/) override { }\r
+\r
+ virtual void enterOperatorExpr(TocParser::OperatorExprContext * /*ctx*/) override { }\r
+ virtual void exitOperatorExpr(TocParser::OperatorExprContext * /*ctx*/) override { }\r
+\r
+ virtual void enterBinaryOperator(TocParser::BinaryOperatorContext * /*ctx*/) override { }\r
+ virtual void exitBinaryOperator(TocParser::BinaryOperatorContext * /*ctx*/) override { }\r
+\r
+ virtual void enterIdentifier(TocParser::IdentifierContext * /*ctx*/) override { }\r
+ virtual void exitIdentifier(TocParser::IdentifierContext * /*ctx*/) override { }\r
+\r
+ virtual void enterLiteral(TocParser::LiteralContext * /*ctx*/) override { }\r
+ virtual void exitLiteral(TocParser::LiteralContext * /*ctx*/) override { }\r
+\r
+ virtual void enterSubscript(TocParser::SubscriptContext * /*ctx*/) override { }\r
+ virtual void exitSubscript(TocParser::SubscriptContext * /*ctx*/) override { }\r
+\r
+ virtual void enterMemberAccess(TocParser::MemberAccessContext * /*ctx*/) override { }\r
+ virtual void exitMemberAccess(TocParser::MemberAccessContext * /*ctx*/) override { }\r
+\r
+ virtual void enterParenExpr(TocParser::ParenExprContext * /*ctx*/) override { }\r
+ virtual void exitParenExpr(TocParser::ParenExprContext * /*ctx*/) override { }\r
+\r
+ virtual void enterFuncName(TocParser::FuncNameContext * /*ctx*/) override { }\r
+ virtual void exitFuncName(TocParser::FuncNameContext * /*ctx*/) override { }\r
+\r
+ virtual void enterVarName(TocParser::VarNameContext * /*ctx*/) override { }\r
+ virtual void exitVarName(TocParser::VarNameContext * /*ctx*/) override { }\r
+\r
+ virtual void enterTypeName(TocParser::TypeNameContext * /*ctx*/) override { }\r
+ virtual void exitTypeName(TocParser::TypeNameContext * /*ctx*/) override { }\r
+\r
+ virtual void enterStructName(TocParser::StructNameContext * /*ctx*/) override { }\r
+ virtual void exitStructName(TocParser::StructNameContext * /*ctx*/) override { }\r
+\r
+\r
+ virtual void enterEveryRule(antlr4::ParserRuleContext * /*ctx*/) override { }\r
+ virtual void exitEveryRule(antlr4::ParserRuleContext * /*ctx*/) override { }\r
+ virtual void visitTerminal(antlr4::tree::TerminalNode * /*node*/) override { }\r
+ virtual void visitErrorNode(antlr4::tree::ErrorNode * /*node*/) override { }\r
+\r
+};\r
+\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+\r
+#include "TocLexer.h"\r
+\r
+\r
+using namespace antlr4;\r
+\r
+\r
+TocLexer::TocLexer(CharStream *input) : Lexer(input) {\r
+ _interpreter = new atn::LexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);\r
+}\r
+\r
+TocLexer::~TocLexer() {\r
+ delete _interpreter;\r
+}\r
+\r
+std::string TocLexer::getGrammarFileName() const {\r
+ return "Toc.g4";\r
+}\r
+\r
+const std::vector<std::string>& TocLexer::getRuleNames() const {\r
+ return _ruleNames;\r
+}\r
+\r
+const std::vector<std::string>& TocLexer::getChannelNames() const {\r
+ return _channelNames;\r
+}\r
+\r
+const std::vector<std::string>& TocLexer::getModeNames() const {\r
+ return _modeNames;\r
+}\r
+\r
+const std::vector<std::string>& TocLexer::getTokenNames() const {\r
+ return _tokenNames;\r
+}\r
+\r
+dfa::Vocabulary& TocLexer::getVocabulary() const {\r
+ return _vocabulary;\r
+}\r
+\r
+const std::vector<uint16_t> TocLexer::getSerializedATN() const {\r
+ return _serializedATN;\r
+}\r
+\r
+const atn::ATN& TocLexer::getATN() const {\r
+ return _atn;\r
+}\r
+\r
+\r
+\r
+\r
+// Static vars and initialization.\r
+std::vector<dfa::DFA> TocLexer::_decisionToDFA;\r
+atn::PredictionContextCache TocLexer::_sharedContextCache;\r
+\r
+// We own the ATN which in turn owns the ATN states.\r
+atn::ATN TocLexer::_atn;\r
+std::vector<uint16_t> TocLexer::_serializedATN;\r
+\r
+std::vector<std::string> TocLexer::_ruleNames = {\r
+ "T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "T__8", \r
+ "T__9", "T__10", "T__11", "T__12", "T__13", "T__14", "T__15", "BINARY_OPERATOR", \r
+ "INTLIT", "NAME", "WS", "NEWLINE"\r
+};\r
+\r
+std::vector<std::string> TocLexer::_channelNames = {\r
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN"\r
+};\r
+\r
+std::vector<std::string> TocLexer::_modeNames = {\r
+ "DEFAULT_MODE"\r
+};\r
+\r
+std::vector<std::string> TocLexer::_literalNames = {\r
+ "", "'var'", "':'", "'='", "'func'", "'('", "')'", "','", "'{'", "'}'", \r
+ "'struct'", "'if'", "'while'", "'return'", "'['", "']'", "'.'"\r
+};\r
+\r
+std::vector<std::string> TocLexer::_symbolicNames = {\r
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "BINARY_OPERATOR", \r
+ "INTLIT", "NAME", "WS", "NEWLINE"\r
+};\r
+\r
+dfa::Vocabulary TocLexer::_vocabulary(_literalNames, _symbolicNames);\r
+\r
+std::vector<std::string> TocLexer::_tokenNames;\r
+\r
+TocLexer::Initializer::Initializer() {\r
+ // This code could be in a static initializer lambda, but VS doesn't allow access to private class members from there.\r
+ for (size_t i = 0; i < _symbolicNames.size(); ++i) {\r
+ std::string name = _vocabulary.getLiteralName(i);\r
+ if (name.empty()) {\r
+ name = _vocabulary.getSymbolicName(i);\r
+ }\r
+\r
+ if (name.empty()) {\r
+ _tokenNames.push_back("<INVALID>");\r
+ } else {\r
+ _tokenNames.push_back(name);\r
+ }\r
+ }\r
+\r
+ static const uint16_t serializedATNSegment0[] = {\r
+ 0x3, 0x608b, 0xa72a, 0x8133, 0xb9ed, 0x417c, 0x3be7, 0x7786, 0x5964, \r
+ 0x2, 0x17, 0x82, 0x8, 0x1, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, \r
+ 0x4, 0x4, 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, \r
+ 0x7, 0x9, 0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x4, 0xa, \r
+ 0x9, 0xa, 0x4, 0xb, 0x9, 0xb, 0x4, 0xc, 0x9, 0xc, 0x4, 0xd, 0x9, \r
+ 0xd, 0x4, 0xe, 0x9, 0xe, 0x4, 0xf, 0x9, 0xf, 0x4, 0x10, 0x9, 0x10, \r
+ 0x4, 0x11, 0x9, 0x11, 0x4, 0x12, 0x9, 0x12, 0x4, 0x13, 0x9, 0x13, \r
+ 0x4, 0x14, 0x9, 0x14, 0x4, 0x15, 0x9, 0x15, 0x4, 0x16, 0x9, 0x16, \r
+ 0x3, 0x2, 0x3, 0x2, 0x3, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, \r
+ 0x4, 0x3, 0x4, 0x3, 0x5, 0x3, 0x5, 0x3, 0x5, 0x3, 0x5, 0x3, 0x5, \r
+ 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x3, 0x8, 0x3, 0x8, 0x3, \r
+ 0x9, 0x3, 0x9, 0x3, 0xa, 0x3, 0xa, 0x3, 0xb, 0x3, 0xb, 0x3, 0xb, \r
+ 0x3, 0xb, 0x3, 0xb, 0x3, 0xb, 0x3, 0xb, 0x3, 0xc, 0x3, 0xc, 0x3, \r
+ 0xc, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, \r
+ 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, 0xe, 0x3, \r
+ 0xe, 0x3, 0xf, 0x3, 0xf, 0x3, 0x10, 0x3, 0x10, 0x3, 0x11, 0x3, 0x11, \r
+ 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, 0x3, 0x12, \r
+ 0x5, 0x12, 0x68, 0xa, 0x12, 0x3, 0x13, 0x5, 0x13, 0x6b, 0xa, 0x13, \r
+ 0x3, 0x13, 0x6, 0x13, 0x6e, 0xa, 0x13, 0xd, 0x13, 0xe, 0x13, 0x6f, \r
+ 0x3, 0x14, 0x6, 0x14, 0x73, 0xa, 0x14, 0xd, 0x14, 0xe, 0x14, 0x74, \r
+ 0x3, 0x15, 0x6, 0x15, 0x78, 0xa, 0x15, 0xd, 0x15, 0xe, 0x15, 0x79, \r
+ 0x3, 0x15, 0x3, 0x15, 0x3, 0x16, 0x6, 0x16, 0x7f, 0xa, 0x16, 0xd, \r
+ 0x16, 0xe, 0x16, 0x80, 0x2, 0x2, 0x17, 0x3, 0x3, 0x5, 0x4, 0x7, 0x5, \r
+ 0x9, 0x6, 0xb, 0x7, 0xd, 0x8, 0xf, 0x9, 0x11, 0xa, 0x13, 0xb, 0x15, \r
+ 0xc, 0x17, 0xd, 0x19, 0xe, 0x1b, 0xf, 0x1d, 0x10, 0x1f, 0x11, 0x21, \r
+ 0x12, 0x23, 0x13, 0x25, 0x14, 0x27, 0x15, 0x29, 0x16, 0x2b, 0x17, \r
+ 0x3, 0x2, 0x9, 0x5, 0x2, 0x2c, 0x2d, 0x2f, 0x2f, 0x31, 0x31, 0x4, \r
+ 0x2, 0x3e, 0x3e, 0x40, 0x40, 0x4, 0x2, 0x2d, 0x2d, 0x2f, 0x2f, 0x3, \r
+ 0x2, 0x32, 0x3b, 0x5, 0x2, 0x32, 0x3b, 0x43, 0x5c, 0x63, 0x7c, 0x5, \r
+ 0x2, 0xb, 0xc, 0xf, 0xf, 0x22, 0x22, 0x4, 0x2, 0xc, 0xc, 0xf, 0xf, \r
+ 0x2, 0x89, 0x2, 0x3, 0x3, 0x2, 0x2, 0x2, 0x2, 0x5, 0x3, 0x2, 0x2, \r
+ 0x2, 0x2, 0x7, 0x3, 0x2, 0x2, 0x2, 0x2, 0x9, 0x3, 0x2, 0x2, 0x2, \r
+ 0x2, 0xb, 0x3, 0x2, 0x2, 0x2, 0x2, 0xd, 0x3, 0x2, 0x2, 0x2, 0x2, \r
+ 0xf, 0x3, 0x2, 0x2, 0x2, 0x2, 0x11, 0x3, 0x2, 0x2, 0x2, 0x2, 0x13, \r
+ 0x3, 0x2, 0x2, 0x2, 0x2, 0x15, 0x3, 0x2, 0x2, 0x2, 0x2, 0x17, 0x3, \r
+ 0x2, 0x2, 0x2, 0x2, 0x19, 0x3, 0x2, 0x2, 0x2, 0x2, 0x1b, 0x3, 0x2, \r
+ 0x2, 0x2, 0x2, 0x1d, 0x3, 0x2, 0x2, 0x2, 0x2, 0x1f, 0x3, 0x2, 0x2, \r
+ 0x2, 0x2, 0x21, 0x3, 0x2, 0x2, 0x2, 0x2, 0x23, 0x3, 0x2, 0x2, 0x2, \r
+ 0x2, 0x25, 0x3, 0x2, 0x2, 0x2, 0x2, 0x27, 0x3, 0x2, 0x2, 0x2, 0x2, \r
+ 0x29, 0x3, 0x2, 0x2, 0x2, 0x2, 0x2b, 0x3, 0x2, 0x2, 0x2, 0x3, 0x2d, \r
+ 0x3, 0x2, 0x2, 0x2, 0x5, 0x31, 0x3, 0x2, 0x2, 0x2, 0x7, 0x33, 0x3, \r
+ 0x2, 0x2, 0x2, 0x9, 0x35, 0x3, 0x2, 0x2, 0x2, 0xb, 0x3a, 0x3, 0x2, \r
+ 0x2, 0x2, 0xd, 0x3c, 0x3, 0x2, 0x2, 0x2, 0xf, 0x3e, 0x3, 0x2, 0x2, \r
+ 0x2, 0x11, 0x40, 0x3, 0x2, 0x2, 0x2, 0x13, 0x42, 0x3, 0x2, 0x2, 0x2, \r
+ 0x15, 0x44, 0x3, 0x2, 0x2, 0x2, 0x17, 0x4b, 0x3, 0x2, 0x2, 0x2, 0x19, \r
+ 0x4e, 0x3, 0x2, 0x2, 0x2, 0x1b, 0x54, 0x3, 0x2, 0x2, 0x2, 0x1d, 0x5b, \r
+ 0x3, 0x2, 0x2, 0x2, 0x1f, 0x5d, 0x3, 0x2, 0x2, 0x2, 0x21, 0x5f, 0x3, \r
+ 0x2, 0x2, 0x2, 0x23, 0x67, 0x3, 0x2, 0x2, 0x2, 0x25, 0x6a, 0x3, 0x2, \r
+ 0x2, 0x2, 0x27, 0x72, 0x3, 0x2, 0x2, 0x2, 0x29, 0x77, 0x3, 0x2, 0x2, \r
+ 0x2, 0x2b, 0x7e, 0x3, 0x2, 0x2, 0x2, 0x2d, 0x2e, 0x7, 0x78, 0x2, \r
+ 0x2, 0x2e, 0x2f, 0x7, 0x63, 0x2, 0x2, 0x2f, 0x30, 0x7, 0x74, 0x2, \r
+ 0x2, 0x30, 0x4, 0x3, 0x2, 0x2, 0x2, 0x31, 0x32, 0x7, 0x3c, 0x2, 0x2, \r
+ 0x32, 0x6, 0x3, 0x2, 0x2, 0x2, 0x33, 0x34, 0x7, 0x3f, 0x2, 0x2, 0x34, \r
+ 0x8, 0x3, 0x2, 0x2, 0x2, 0x35, 0x36, 0x7, 0x68, 0x2, 0x2, 0x36, 0x37, \r
+ 0x7, 0x77, 0x2, 0x2, 0x37, 0x38, 0x7, 0x70, 0x2, 0x2, 0x38, 0x39, \r
+ 0x7, 0x65, 0x2, 0x2, 0x39, 0xa, 0x3, 0x2, 0x2, 0x2, 0x3a, 0x3b, 0x7, \r
+ 0x2a, 0x2, 0x2, 0x3b, 0xc, 0x3, 0x2, 0x2, 0x2, 0x3c, 0x3d, 0x7, 0x2b, \r
+ 0x2, 0x2, 0x3d, 0xe, 0x3, 0x2, 0x2, 0x2, 0x3e, 0x3f, 0x7, 0x2e, 0x2, \r
+ 0x2, 0x3f, 0x10, 0x3, 0x2, 0x2, 0x2, 0x40, 0x41, 0x7, 0x7d, 0x2, \r
+ 0x2, 0x41, 0x12, 0x3, 0x2, 0x2, 0x2, 0x42, 0x43, 0x7, 0x7f, 0x2, \r
+ 0x2, 0x43, 0x14, 0x3, 0x2, 0x2, 0x2, 0x44, 0x45, 0x7, 0x75, 0x2, \r
+ 0x2, 0x45, 0x46, 0x7, 0x76, 0x2, 0x2, 0x46, 0x47, 0x7, 0x74, 0x2, \r
+ 0x2, 0x47, 0x48, 0x7, 0x77, 0x2, 0x2, 0x48, 0x49, 0x7, 0x65, 0x2, \r
+ 0x2, 0x49, 0x4a, 0x7, 0x76, 0x2, 0x2, 0x4a, 0x16, 0x3, 0x2, 0x2, \r
+ 0x2, 0x4b, 0x4c, 0x7, 0x6b, 0x2, 0x2, 0x4c, 0x4d, 0x7, 0x68, 0x2, \r
+ 0x2, 0x4d, 0x18, 0x3, 0x2, 0x2, 0x2, 0x4e, 0x4f, 0x7, 0x79, 0x2, \r
+ 0x2, 0x4f, 0x50, 0x7, 0x6a, 0x2, 0x2, 0x50, 0x51, 0x7, 0x6b, 0x2, \r
+ 0x2, 0x51, 0x52, 0x7, 0x6e, 0x2, 0x2, 0x52, 0x53, 0x7, 0x67, 0x2, \r
+ 0x2, 0x53, 0x1a, 0x3, 0x2, 0x2, 0x2, 0x54, 0x55, 0x7, 0x74, 0x2, \r
+ 0x2, 0x55, 0x56, 0x7, 0x67, 0x2, 0x2, 0x56, 0x57, 0x7, 0x76, 0x2, \r
+ 0x2, 0x57, 0x58, 0x7, 0x77, 0x2, 0x2, 0x58, 0x59, 0x7, 0x74, 0x2, \r
+ 0x2, 0x59, 0x5a, 0x7, 0x70, 0x2, 0x2, 0x5a, 0x1c, 0x3, 0x2, 0x2, \r
+ 0x2, 0x5b, 0x5c, 0x7, 0x5d, 0x2, 0x2, 0x5c, 0x1e, 0x3, 0x2, 0x2, \r
+ 0x2, 0x5d, 0x5e, 0x7, 0x5f, 0x2, 0x2, 0x5e, 0x20, 0x3, 0x2, 0x2, \r
+ 0x2, 0x5f, 0x60, 0x7, 0x30, 0x2, 0x2, 0x60, 0x22, 0x3, 0x2, 0x2, \r
+ 0x2, 0x61, 0x68, 0x9, 0x2, 0x2, 0x2, 0x62, 0x63, 0x7, 0x3f, 0x2, \r
+ 0x2, 0x63, 0x68, 0x7, 0x3f, 0x2, 0x2, 0x64, 0x65, 0x7, 0x23, 0x2, \r
+ 0x2, 0x65, 0x68, 0x7, 0x3f, 0x2, 0x2, 0x66, 0x68, 0x9, 0x3, 0x2, \r
+ 0x2, 0x67, 0x61, 0x3, 0x2, 0x2, 0x2, 0x67, 0x62, 0x3, 0x2, 0x2, 0x2, \r
+ 0x67, 0x64, 0x3, 0x2, 0x2, 0x2, 0x67, 0x66, 0x3, 0x2, 0x2, 0x2, 0x68, \r
+ 0x24, 0x3, 0x2, 0x2, 0x2, 0x69, 0x6b, 0x9, 0x4, 0x2, 0x2, 0x6a, 0x69, \r
+ 0x3, 0x2, 0x2, 0x2, 0x6a, 0x6b, 0x3, 0x2, 0x2, 0x2, 0x6b, 0x6d, 0x3, \r
+ 0x2, 0x2, 0x2, 0x6c, 0x6e, 0x9, 0x5, 0x2, 0x2, 0x6d, 0x6c, 0x3, 0x2, \r
+ 0x2, 0x2, 0x6e, 0x6f, 0x3, 0x2, 0x2, 0x2, 0x6f, 0x6d, 0x3, 0x2, 0x2, \r
+ 0x2, 0x6f, 0x70, 0x3, 0x2, 0x2, 0x2, 0x70, 0x26, 0x3, 0x2, 0x2, 0x2, \r
+ 0x71, 0x73, 0x9, 0x6, 0x2, 0x2, 0x72, 0x71, 0x3, 0x2, 0x2, 0x2, 0x73, \r
+ 0x74, 0x3, 0x2, 0x2, 0x2, 0x74, 0x72, 0x3, 0x2, 0x2, 0x2, 0x74, 0x75, \r
+ 0x3, 0x2, 0x2, 0x2, 0x75, 0x28, 0x3, 0x2, 0x2, 0x2, 0x76, 0x78, 0x9, \r
+ 0x7, 0x2, 0x2, 0x77, 0x76, 0x3, 0x2, 0x2, 0x2, 0x78, 0x79, 0x3, 0x2, \r
+ 0x2, 0x2, 0x79, 0x77, 0x3, 0x2, 0x2, 0x2, 0x79, 0x7a, 0x3, 0x2, 0x2, \r
+ 0x2, 0x7a, 0x7b, 0x3, 0x2, 0x2, 0x2, 0x7b, 0x7c, 0x8, 0x15, 0x2, \r
+ 0x2, 0x7c, 0x2a, 0x3, 0x2, 0x2, 0x2, 0x7d, 0x7f, 0x9, 0x8, 0x2, 0x2, \r
+ 0x7e, 0x7d, 0x3, 0x2, 0x2, 0x2, 0x7f, 0x80, 0x3, 0x2, 0x2, 0x2, 0x80, \r
+ 0x7e, 0x3, 0x2, 0x2, 0x2, 0x80, 0x81, 0x3, 0x2, 0x2, 0x2, 0x81, 0x2c, \r
+ 0x3, 0x2, 0x2, 0x2, 0xa, 0x2, 0x67, 0x6a, 0x6f, 0x72, 0x74, 0x79, \r
+ 0x80, 0x3, 0x8, 0x2, 0x2, \r
+ };\r
+\r
+ _serializedATN.insert(_serializedATN.end(), serializedATNSegment0,\r
+ serializedATNSegment0 + sizeof(serializedATNSegment0) / sizeof(serializedATNSegment0[0]));\r
+\r
+\r
+ atn::ATNDeserializer deserializer;\r
+ _atn = deserializer.deserialize(_serializedATN);\r
+\r
+ size_t count = _atn.getNumberOfDecisions();\r
+ _decisionToDFA.reserve(count);\r
+ for (size_t i = 0; i < count; i++) { \r
+ _decisionToDFA.emplace_back(_atn.getDecisionState(i), i);\r
+ }\r
+}\r
+\r
+TocLexer::Initializer TocLexer::_init;\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+#pragma once\r
+\r
+\r
+#include "antlr4-runtime.h"\r
+\r
+\r
+\r
+\r
+class TocLexer : public antlr4::Lexer {\r
+public:\r
+ enum {\r
+ T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, \r
+ T__7 = 8, T__8 = 9, T__9 = 10, T__10 = 11, T__11 = 12, T__12 = 13, T__13 = 14, \r
+ T__14 = 15, T__15 = 16, BINARY_OPERATOR = 17, INTLIT = 18, NAME = 19, \r
+ WS = 20, NEWLINE = 21\r
+ };\r
+\r
+ explicit TocLexer(antlr4::CharStream *input);\r
+ ~TocLexer();\r
+\r
+ virtual std::string getGrammarFileName() const override;\r
+ virtual const std::vector<std::string>& getRuleNames() const override;\r
+\r
+ virtual const std::vector<std::string>& getChannelNames() const override;\r
+ virtual const std::vector<std::string>& getModeNames() const override;\r
+ virtual const std::vector<std::string>& getTokenNames() const override; // deprecated, use vocabulary instead\r
+ virtual antlr4::dfa::Vocabulary& getVocabulary() const override;\r
+\r
+ virtual const std::vector<uint16_t> getSerializedATN() const override;\r
+ virtual const antlr4::atn::ATN& getATN() const override;\r
+\r
+private:\r
+ static std::vector<antlr4::dfa::DFA> _decisionToDFA;\r
+ static antlr4::atn::PredictionContextCache _sharedContextCache;\r
+ static std::vector<std::string> _ruleNames;\r
+ static std::vector<std::string> _tokenNames;\r
+ static std::vector<std::string> _channelNames;\r
+ static std::vector<std::string> _modeNames;\r
+\r
+ static std::vector<std::string> _literalNames;\r
+ static std::vector<std::string> _symbolicNames;\r
+ static antlr4::dfa::Vocabulary _vocabulary;\r
+ static antlr4::atn::ATN _atn;\r
+ static std::vector<uint16_t> _serializedATN;\r
+\r
+\r
+ // Individual action functions triggered by action() above.\r
+\r
+ // Individual semantic predicate functions triggered by sempred() above.\r
+\r
+ struct Initializer {\r
+ Initializer();\r
+ };\r
+ static Initializer _init;\r
+};\r
+\r
--- /dev/null
+token literal names:
+null
+'var'
+':'
+'='
+'func'
+'('
+')'
+','
+'{'
+'}'
+'struct'
+'if'
+'while'
+'return'
+'['
+']'
+'.'
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+null
+BINARY_OPERATOR
+INTLIT
+NAME
+WS
+NEWLINE
+
+rule names:
+T__0
+T__1
+T__2
+T__3
+T__4
+T__5
+T__6
+T__7
+T__8
+T__9
+T__10
+T__11
+T__12
+T__13
+T__14
+T__15
+BINARY_OPERATOR
+INTLIT
+NAME
+WS
+NEWLINE
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 23, 130, 8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7, 9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12, 4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4, 18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 3, 2, 3, 2, 3, 2, 3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 5, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8, 3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 12, 3, 12, 3, 12, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 13, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 14, 3, 15, 3, 15, 3, 16, 3, 16, 3, 17, 3, 17, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 104, 10, 18, 3, 19, 5, 19, 107, 10, 19, 3, 19, 6, 19, 110, 10, 19, 13, 19, 14, 19, 111, 3, 20, 6, 20, 115, 10, 20, 13, 20, 14, 20, 116, 3, 21, 6, 21, 120, 10, 21, 13, 21, 14, 21, 121, 3, 21, 3, 21, 3, 22, 6, 22, 127, 10, 22, 13, 22, 14, 22, 128, 2, 2, 23, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17, 10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35, 19, 37, 20, 39, 21, 41, 22, 43, 23, 3, 2, 9, 5, 2, 44, 45, 47, 47, 49, 49, 4, 2, 62, 62, 64, 64, 4, 2, 45, 45, 47, 47, 3, 2, 50, 59, 5, 2, 50, 59, 67, 92, 99, 124, 5, 2, 11, 12, 15, 15, 34, 34, 4, 2, 12, 12, 15, 15, 2, 137, 2, 3, 3, 2, 2, 2, 2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2, 2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2, 2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2, 2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3, 2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43, 3, 2, 2, 2, 3, 45, 3, 2, 2, 2, 5, 49, 3, 2, 2, 2, 7, 51, 3, 2, 2, 2, 9, 53, 3, 2, 2, 2, 11, 58, 3, 2, 2, 2, 13, 60, 3, 2, 2, 2, 15, 62, 3, 2, 2, 2, 17, 64, 3, 2, 2, 2, 19, 66, 3, 2, 2, 2, 21, 68, 3, 2, 2, 2, 23, 75, 3, 2, 2, 2, 25, 78, 3, 2, 2, 2, 27, 84, 3, 2, 2, 2, 29, 91, 3, 2, 2, 2, 31, 93, 3, 2, 2, 2, 33, 95, 3, 2, 2, 2, 35, 103, 3, 2, 2, 2, 37, 106, 3, 2, 2, 2, 39, 114, 3, 2, 2, 2, 41, 119, 3, 2, 2, 2, 43, 126, 3, 2, 2, 2, 45, 46, 7, 120, 2, 2, 46, 47, 7, 99, 2, 2, 47, 48, 7, 116, 2, 2, 48, 4, 3, 2, 2, 2, 49, 50, 7, 60, 2, 2, 50, 6, 3, 2, 2, 2, 51, 52, 7, 63, 2, 2, 52, 8, 3, 2, 2, 2, 53, 54, 7, 104, 2, 2, 54, 55, 7, 119, 2, 2, 55, 56, 7, 112, 2, 2, 56, 57, 7, 101, 2, 2, 57, 10, 3, 2, 2, 2, 58, 59, 7, 42, 2, 2, 59, 12, 3, 2, 2, 2, 60, 61, 7, 43, 2, 2, 61, 14, 3, 2, 2, 2, 62, 63, 7, 46, 2, 2, 63, 16, 3, 2, 2, 2, 64, 65, 7, 125, 2, 2, 65, 18, 3, 2, 2, 2, 66, 67, 7, 127, 2, 2, 67, 20, 3, 2, 2, 2, 68, 69, 7, 117, 2, 2, 69, 70, 7, 118, 2, 2, 70, 71, 7, 116, 2, 2, 71, 72, 7, 119, 2, 2, 72, 73, 7, 101, 2, 2, 73, 74, 7, 118, 2, 2, 74, 22, 3, 2, 2, 2, 75, 76, 7, 107, 2, 2, 76, 77, 7, 104, 2, 2, 77, 24, 3, 2, 2, 2, 78, 79, 7, 121, 2, 2, 79, 80, 7, 106, 2, 2, 80, 81, 7, 107, 2, 2, 81, 82, 7, 110, 2, 2, 82, 83, 7, 103, 2, 2, 83, 26, 3, 2, 2, 2, 84, 85, 7, 116, 2, 2, 85, 86, 7, 103, 2, 2, 86, 87, 7, 118, 2, 2, 87, 88, 7, 119, 2, 2, 88, 89, 7, 116, 2, 2, 89, 90, 7, 112, 2, 2, 90, 28, 3, 2, 2, 2, 91, 92, 7, 93, 2, 2, 92, 30, 3, 2, 2, 2, 93, 94, 7, 95, 2, 2, 94, 32, 3, 2, 2, 2, 95, 96, 7, 48, 2, 2, 96, 34, 3, 2, 2, 2, 97, 104, 9, 2, 2, 2, 98, 99, 7, 63, 2, 2, 99, 104, 7, 63, 2, 2, 100, 101, 7, 35, 2, 2, 101, 104, 7, 63, 2, 2, 102, 104, 9, 3, 2, 2, 103, 97, 3, 2, 2, 2, 103, 98, 3, 2, 2, 2, 103, 100, 3, 2, 2, 2, 103, 102, 3, 2, 2, 2, 104, 36, 3, 2, 2, 2, 105, 107, 9, 4, 2, 2, 106, 105, 3, 2, 2, 2, 106, 107, 3, 2, 2, 2, 107, 109, 3, 2, 2, 2, 108, 110, 9, 5, 2, 2, 109, 108, 3, 2, 2, 2, 110, 111, 3, 2, 2, 2, 111, 109, 3, 2, 2, 2, 111, 112, 3, 2, 2, 2, 112, 38, 3, 2, 2, 2, 113, 115, 9, 6, 2, 2, 114, 113, 3, 2, 2, 2, 115, 116, 3, 2, 2, 2, 116, 114, 3, 2, 2, 2, 116, 117, 3, 2, 2, 2, 117, 40, 3, 2, 2, 2, 118, 120, 9, 7, 2, 2, 119, 118, 3, 2, 2, 2, 120, 121, 3, 2, 2, 2, 121, 119, 3, 2, 2, 2, 121, 122, 3, 2, 2, 2, 122, 123, 3, 2, 2, 2, 123, 124, 8, 21, 2, 2, 124, 42, 3, 2, 2, 2, 125, 127, 9, 8, 2, 2, 126, 125, 3, 2, 2, 2, 127, 128, 3, 2, 2, 2, 128, 126, 3, 2, 2, 2, 128, 129, 3, 2, 2, 2, 129, 44, 3, 2, 2, 2, 10, 2, 103, 106, 111, 114, 116, 121, 128, 3, 8, 2, 2]
\ No newline at end of file
--- /dev/null
+T__0=1\r
+T__1=2\r
+T__2=3\r
+T__3=4\r
+T__4=5\r
+T__5=6\r
+T__6=7\r
+T__7=8\r
+T__8=9\r
+T__9=10\r
+T__10=11\r
+T__11=12\r
+T__12=13\r
+T__13=14\r
+T__14=15\r
+T__15=16\r
+BINARY_OPERATOR=17\r
+INTLIT=18\r
+NAME=19\r
+WS=20\r
+NEWLINE=21\r
+'var'=1\r
+':'=2\r
+'='=3\r
+'func'=4\r
+'('=5\r
+')'=6\r
+','=7\r
+'{'=8\r
+'}'=9\r
+'struct'=10\r
+'if'=11\r
+'while'=12\r
+'return'=13\r
+'['=14\r
+']'=15\r
+'.'=16\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+\r
+#include "TocListener.h"\r
+\r
+\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+#pragma once\r
+\r
+\r
+#include "antlr4-runtime.h"\r
+#include "TocParser.h"\r
+\r
+\r
+/**\r
+ * This interface defines an abstract listener for a parse tree produced by TocParser.\r
+ */\r
+class TocListener : public antlr4::tree::ParseTreeListener {\r
+public:\r
+\r
+ virtual void enterProg(TocParser::ProgContext *ctx) = 0;\r
+ virtual void exitProg(TocParser::ProgContext *ctx) = 0;\r
+\r
+ virtual void enterDecl(TocParser::DeclContext *ctx) = 0;\r
+ virtual void exitDecl(TocParser::DeclContext *ctx) = 0;\r
+\r
+ virtual void enterVarDecl(TocParser::VarDeclContext *ctx) = 0;\r
+ virtual void exitVarDecl(TocParser::VarDeclContext *ctx) = 0;\r
+\r
+ virtual void enterVar(TocParser::VarContext *ctx) = 0;\r
+ virtual void exitVar(TocParser::VarContext *ctx) = 0;\r
+\r
+ virtual void enterType(TocParser::TypeContext *ctx) = 0;\r
+ virtual void exitType(TocParser::TypeContext *ctx) = 0;\r
+\r
+ virtual void enterFuncDecl(TocParser::FuncDeclContext *ctx) = 0;\r
+ virtual void exitFuncDecl(TocParser::FuncDeclContext *ctx) = 0;\r
+\r
+ virtual void enterFunc(TocParser::FuncContext *ctx) = 0;\r
+ virtual void exitFunc(TocParser::FuncContext *ctx) = 0;\r
+\r
+ virtual void enterParameter(TocParser::ParameterContext *ctx) = 0;\r
+ virtual void exitParameter(TocParser::ParameterContext *ctx) = 0;\r
+\r
+ virtual void enterFirstParameter(TocParser::FirstParameterContext *ctx) = 0;\r
+ virtual void exitFirstParameter(TocParser::FirstParameterContext *ctx) = 0;\r
+\r
+ virtual void enterAdditionalParameter(TocParser::AdditionalParameterContext *ctx) = 0;\r
+ virtual void exitAdditionalParameter(TocParser::AdditionalParameterContext *ctx) = 0;\r
+\r
+ virtual void enterBody(TocParser::BodyContext *ctx) = 0;\r
+ virtual void exitBody(TocParser::BodyContext *ctx) = 0;\r
+\r
+ virtual void enterStructDecl(TocParser::StructDeclContext *ctx) = 0;\r
+ virtual void exitStructDecl(TocParser::StructDeclContext *ctx) = 0;\r
+\r
+ virtual void enterStructMember(TocParser::StructMemberContext *ctx) = 0;\r
+ virtual void exitStructMember(TocParser::StructMemberContext *ctx) = 0;\r
+\r
+ virtual void enterStructVar(TocParser::StructVarContext *ctx) = 0;\r
+ virtual void exitStructVar(TocParser::StructVarContext *ctx) = 0;\r
+\r
+ virtual void enterStructMethod(TocParser::StructMethodContext *ctx) = 0;\r
+ virtual void exitStructMethod(TocParser::StructMethodContext *ctx) = 0;\r
+\r
+ virtual void enterStmt(TocParser::StmtContext *ctx) = 0;\r
+ virtual void exitStmt(TocParser::StmtContext *ctx) = 0;\r
+\r
+ virtual void enterConditional(TocParser::ConditionalContext *ctx) = 0;\r
+ virtual void exitConditional(TocParser::ConditionalContext *ctx) = 0;\r
+\r
+ virtual void enterIfCond(TocParser::IfCondContext *ctx) = 0;\r
+ virtual void exitIfCond(TocParser::IfCondContext *ctx) = 0;\r
+\r
+ virtual void enterLoop(TocParser::LoopContext *ctx) = 0;\r
+ virtual void exitLoop(TocParser::LoopContext *ctx) = 0;\r
+\r
+ virtual void enterWhileLoop(TocParser::WhileLoopContext *ctx) = 0;\r
+ virtual void exitWhileLoop(TocParser::WhileLoopContext *ctx) = 0;\r
+\r
+ virtual void enterAssignment(TocParser::AssignmentContext *ctx) = 0;\r
+ virtual void exitAssignment(TocParser::AssignmentContext *ctx) = 0;\r
+\r
+ virtual void enterReturnStmt(TocParser::ReturnStmtContext *ctx) = 0;\r
+ virtual void exitReturnStmt(TocParser::ReturnStmtContext *ctx) = 0;\r
+\r
+ virtual void enterExpr(TocParser::ExprContext *ctx) = 0;\r
+ virtual void exitExpr(TocParser::ExprContext *ctx) = 0;\r
+\r
+ virtual void enterNonOpExpr(TocParser::NonOpExprContext *ctx) = 0;\r
+ virtual void exitNonOpExpr(TocParser::NonOpExprContext *ctx) = 0;\r
+\r
+ virtual void enterNonSubscriptExpr(TocParser::NonSubscriptExprContext *ctx) = 0;\r
+ virtual void exitNonSubscriptExpr(TocParser::NonSubscriptExprContext *ctx) = 0;\r
+\r
+ virtual void enterFuncCall(TocParser::FuncCallContext *ctx) = 0;\r
+ virtual void exitFuncCall(TocParser::FuncCallContext *ctx) = 0;\r
+\r
+ virtual void enterOperatorExpr(TocParser::OperatorExprContext *ctx) = 0;\r
+ virtual void exitOperatorExpr(TocParser::OperatorExprContext *ctx) = 0;\r
+\r
+ virtual void enterBinaryOperator(TocParser::BinaryOperatorContext *ctx) = 0;\r
+ virtual void exitBinaryOperator(TocParser::BinaryOperatorContext *ctx) = 0;\r
+\r
+ virtual void enterIdentifier(TocParser::IdentifierContext *ctx) = 0;\r
+ virtual void exitIdentifier(TocParser::IdentifierContext *ctx) = 0;\r
+\r
+ virtual void enterLiteral(TocParser::LiteralContext *ctx) = 0;\r
+ virtual void exitLiteral(TocParser::LiteralContext *ctx) = 0;\r
+\r
+ virtual void enterSubscript(TocParser::SubscriptContext *ctx) = 0;\r
+ virtual void exitSubscript(TocParser::SubscriptContext *ctx) = 0;\r
+\r
+ virtual void enterMemberAccess(TocParser::MemberAccessContext *ctx) = 0;\r
+ virtual void exitMemberAccess(TocParser::MemberAccessContext *ctx) = 0;\r
+\r
+ virtual void enterParenExpr(TocParser::ParenExprContext *ctx) = 0;\r
+ virtual void exitParenExpr(TocParser::ParenExprContext *ctx) = 0;\r
+\r
+ virtual void enterFuncName(TocParser::FuncNameContext *ctx) = 0;\r
+ virtual void exitFuncName(TocParser::FuncNameContext *ctx) = 0;\r
+\r
+ virtual void enterVarName(TocParser::VarNameContext *ctx) = 0;\r
+ virtual void exitVarName(TocParser::VarNameContext *ctx) = 0;\r
+\r
+ virtual void enterTypeName(TocParser::TypeNameContext *ctx) = 0;\r
+ virtual void exitTypeName(TocParser::TypeNameContext *ctx) = 0;\r
+\r
+ virtual void enterStructName(TocParser::StructNameContext *ctx) = 0;\r
+ virtual void exitStructName(TocParser::StructNameContext *ctx) = 0;\r
+\r
+\r
+};\r
+\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+\r
+#include "TocListener.h"\r
+\r
+#include "TocParser.h"\r
+\r
+\r
+using namespace antlrcpp;\r
+using namespace antlr4;\r
+\r
+TocParser::TocParser(TokenStream *input) : Parser(input) {\r
+ _interpreter = new atn::ParserATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);\r
+}\r
+\r
+TocParser::~TocParser() {\r
+ delete _interpreter;\r
+}\r
+\r
+std::string TocParser::getGrammarFileName() const {\r
+ return "Toc.g4";\r
+}\r
+\r
+const std::vector<std::string>& TocParser::getRuleNames() const {\r
+ return _ruleNames;\r
+}\r
+\r
+dfa::Vocabulary& TocParser::getVocabulary() const {\r
+ return _vocabulary;\r
+}\r
+\r
+\r
+//----------------- ProgContext ------------------------------------------------------------------\r
+\r
+TocParser::ProgContext::ProgContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::ProgContext::EOF() {\r
+ return getToken(TocParser::EOF, 0);\r
+}\r
+\r
+std::vector<TocParser::DeclContext *> TocParser::ProgContext::decl() {\r
+ return getRuleContexts<TocParser::DeclContext>();\r
+}\r
+\r
+TocParser::DeclContext* TocParser::ProgContext::decl(size_t i) {\r
+ return getRuleContext<TocParser::DeclContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::ProgContext::getRuleIndex() const {\r
+ return TocParser::RuleProg;\r
+}\r
+\r
+void TocParser::ProgContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterProg(this);\r
+}\r
+\r
+void TocParser::ProgContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitProg(this);\r
+}\r
+\r
+TocParser::ProgContext* TocParser::prog() {\r
+ ProgContext *_localctx = _tracker.createInstance<ProgContext>(_ctx, getState());\r
+ enterRule(_localctx, 0, TocParser::RuleProg);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(75); \r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ do {\r
+ setState(74);\r
+ decl();\r
+ setState(77); \r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ } while ((((_la & ~ 0x3fULL) == 0) &&\r
+ ((1ULL << _la) & ((1ULL << TocParser::T__0)\r
+ | (1ULL << TocParser::T__3)\r
+ | (1ULL << TocParser::T__9))) != 0));\r
+ setState(79);\r
+ match(TocParser::EOF);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- DeclContext ------------------------------------------------------------------\r
+\r
+TocParser::DeclContext::DeclContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarDeclContext* TocParser::DeclContext::varDecl() {\r
+ return getRuleContext<TocParser::VarDeclContext>(0);\r
+}\r
+\r
+TocParser::FuncDeclContext* TocParser::DeclContext::funcDecl() {\r
+ return getRuleContext<TocParser::FuncDeclContext>(0);\r
+}\r
+\r
+TocParser::StructDeclContext* TocParser::DeclContext::structDecl() {\r
+ return getRuleContext<TocParser::StructDeclContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::DeclContext::getRuleIndex() const {\r
+ return TocParser::RuleDecl;\r
+}\r
+\r
+void TocParser::DeclContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterDecl(this);\r
+}\r
+\r
+void TocParser::DeclContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitDecl(this);\r
+}\r
+\r
+TocParser::DeclContext* TocParser::decl() {\r
+ DeclContext *_localctx = _tracker.createInstance<DeclContext>(_ctx, getState());\r
+ enterRule(_localctx, 2, TocParser::RuleDecl);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ setState(84);\r
+ _errHandler->sync(this);\r
+ switch (_input->LA(1)) {\r
+ case TocParser::T__0: {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(81);\r
+ varDecl();\r
+ break;\r
+ }\r
+\r
+ case TocParser::T__3: {\r
+ enterOuterAlt(_localctx, 2);\r
+ setState(82);\r
+ funcDecl();\r
+ break;\r
+ }\r
+\r
+ case TocParser::T__9: {\r
+ enterOuterAlt(_localctx, 3);\r
+ setState(83);\r
+ structDecl();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ throw NoViableAltException(this);\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- VarDeclContext ------------------------------------------------------------------\r
+\r
+TocParser::VarDeclContext::VarDeclContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarContext* TocParser::VarDeclContext::var() {\r
+ return getRuleContext<TocParser::VarContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::VarDeclContext::getRuleIndex() const {\r
+ return TocParser::RuleVarDecl;\r
+}\r
+\r
+void TocParser::VarDeclContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterVarDecl(this);\r
+}\r
+\r
+void TocParser::VarDeclContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitVarDecl(this);\r
+}\r
+\r
+TocParser::VarDeclContext* TocParser::varDecl() {\r
+ VarDeclContext *_localctx = _tracker.createInstance<VarDeclContext>(_ctx, getState());\r
+ enterRule(_localctx, 4, TocParser::RuleVarDecl);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(86);\r
+ match(TocParser::T__0);\r
+ setState(87);\r
+ var();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- VarContext ------------------------------------------------------------------\r
+\r
+TocParser::VarContext::VarContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarNameContext* TocParser::VarContext::varName() {\r
+ return getRuleContext<TocParser::VarNameContext>(0);\r
+}\r
+\r
+TocParser::TypeContext* TocParser::VarContext::type() {\r
+ return getRuleContext<TocParser::TypeContext>(0);\r
+}\r
+\r
+TocParser::ExprContext* TocParser::VarContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::VarContext::getRuleIndex() const {\r
+ return TocParser::RuleVar;\r
+}\r
+\r
+void TocParser::VarContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterVar(this);\r
+}\r
+\r
+void TocParser::VarContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitVar(this);\r
+}\r
+\r
+TocParser::VarContext* TocParser::var() {\r
+ VarContext *_localctx = _tracker.createInstance<VarContext>(_ctx, getState());\r
+ enterRule(_localctx, 6, TocParser::RuleVar);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(89);\r
+ varName();\r
+\r
+ setState(90);\r
+ match(TocParser::T__1);\r
+ setState(91);\r
+ type();\r
+ setState(95);\r
+ _errHandler->sync(this);\r
+\r
+ _la = _input->LA(1);\r
+ if (_la == TocParser::T__2) {\r
+ setState(93);\r
+ match(TocParser::T__2);\r
+ setState(94);\r
+ expr();\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- TypeContext ------------------------------------------------------------------\r
+\r
+TocParser::TypeContext::TypeContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::TypeNameContext* TocParser::TypeContext::typeName() {\r
+ return getRuleContext<TocParser::TypeNameContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::TypeContext::getRuleIndex() const {\r
+ return TocParser::RuleType;\r
+}\r
+\r
+void TocParser::TypeContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterType(this);\r
+}\r
+\r
+void TocParser::TypeContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitType(this);\r
+}\r
+\r
+TocParser::TypeContext* TocParser::type() {\r
+ TypeContext *_localctx = _tracker.createInstance<TypeContext>(_ctx, getState());\r
+ enterRule(_localctx, 8, TocParser::RuleType);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(97);\r
+ typeName();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- FuncDeclContext ------------------------------------------------------------------\r
+\r
+TocParser::FuncDeclContext::FuncDeclContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncContext* TocParser::FuncDeclContext::func() {\r
+ return getRuleContext<TocParser::FuncContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::FuncDeclContext::getRuleIndex() const {\r
+ return TocParser::RuleFuncDecl;\r
+}\r
+\r
+void TocParser::FuncDeclContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterFuncDecl(this);\r
+}\r
+\r
+void TocParser::FuncDeclContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitFuncDecl(this);\r
+}\r
+\r
+TocParser::FuncDeclContext* TocParser::funcDecl() {\r
+ FuncDeclContext *_localctx = _tracker.createInstance<FuncDeclContext>(_ctx, getState());\r
+ enterRule(_localctx, 10, TocParser::RuleFuncDecl);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(99);\r
+ match(TocParser::T__3);\r
+ setState(100);\r
+ func();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- FuncContext ------------------------------------------------------------------\r
+\r
+TocParser::FuncContext::FuncContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncNameContext* TocParser::FuncContext::funcName() {\r
+ return getRuleContext<TocParser::FuncNameContext>(0);\r
+}\r
+\r
+TocParser::ParameterContext* TocParser::FuncContext::parameter() {\r
+ return getRuleContext<TocParser::ParameterContext>(0);\r
+}\r
+\r
+TocParser::BodyContext* TocParser::FuncContext::body() {\r
+ return getRuleContext<TocParser::BodyContext>(0);\r
+}\r
+\r
+TocParser::TypeContext* TocParser::FuncContext::type() {\r
+ return getRuleContext<TocParser::TypeContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::FuncContext::getRuleIndex() const {\r
+ return TocParser::RuleFunc;\r
+}\r
+\r
+void TocParser::FuncContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterFunc(this);\r
+}\r
+\r
+void TocParser::FuncContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitFunc(this);\r
+}\r
+\r
+TocParser::FuncContext* TocParser::func() {\r
+ FuncContext *_localctx = _tracker.createInstance<FuncContext>(_ctx, getState());\r
+ enterRule(_localctx, 12, TocParser::RuleFunc);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(102);\r
+ funcName();\r
+ setState(103);\r
+ match(TocParser::T__4);\r
+ setState(104);\r
+ parameter();\r
+ setState(105);\r
+ match(TocParser::T__5);\r
+\r
+ setState(106);\r
+ match(TocParser::T__1);\r
+ setState(107);\r
+ type();\r
+ setState(109);\r
+ body();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- ParameterContext ------------------------------------------------------------------\r
+\r
+TocParser::ParameterContext::ParameterContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FirstParameterContext* TocParser::ParameterContext::firstParameter() {\r
+ return getRuleContext<TocParser::FirstParameterContext>(0);\r
+}\r
+\r
+std::vector<TocParser::AdditionalParameterContext *> TocParser::ParameterContext::additionalParameter() {\r
+ return getRuleContexts<TocParser::AdditionalParameterContext>();\r
+}\r
+\r
+TocParser::AdditionalParameterContext* TocParser::ParameterContext::additionalParameter(size_t i) {\r
+ return getRuleContext<TocParser::AdditionalParameterContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::ParameterContext::getRuleIndex() const {\r
+ return TocParser::RuleParameter;\r
+}\r
+\r
+void TocParser::ParameterContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterParameter(this);\r
+}\r
+\r
+void TocParser::ParameterContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitParameter(this);\r
+}\r
+\r
+TocParser::ParameterContext* TocParser::parameter() {\r
+ ParameterContext *_localctx = _tracker.createInstance<ParameterContext>(_ctx, getState());\r
+ enterRule(_localctx, 14, TocParser::RuleParameter);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(118);\r
+ _errHandler->sync(this);\r
+\r
+ _la = _input->LA(1);\r
+ if (_la == TocParser::NAME) {\r
+ setState(111);\r
+ firstParameter();\r
+ setState(115);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ while (_la == TocParser::T__6) {\r
+ setState(112);\r
+ additionalParameter();\r
+ setState(117);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ }\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- FirstParameterContext ------------------------------------------------------------------\r
+\r
+TocParser::FirstParameterContext::FirstParameterContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarContext* TocParser::FirstParameterContext::var() {\r
+ return getRuleContext<TocParser::VarContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::FirstParameterContext::getRuleIndex() const {\r
+ return TocParser::RuleFirstParameter;\r
+}\r
+\r
+void TocParser::FirstParameterContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterFirstParameter(this);\r
+}\r
+\r
+void TocParser::FirstParameterContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitFirstParameter(this);\r
+}\r
+\r
+TocParser::FirstParameterContext* TocParser::firstParameter() {\r
+ FirstParameterContext *_localctx = _tracker.createInstance<FirstParameterContext>(_ctx, getState());\r
+ enterRule(_localctx, 16, TocParser::RuleFirstParameter);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(120);\r
+ var();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- AdditionalParameterContext ------------------------------------------------------------------\r
+\r
+TocParser::AdditionalParameterContext::AdditionalParameterContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarContext* TocParser::AdditionalParameterContext::var() {\r
+ return getRuleContext<TocParser::VarContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::AdditionalParameterContext::getRuleIndex() const {\r
+ return TocParser::RuleAdditionalParameter;\r
+}\r
+\r
+void TocParser::AdditionalParameterContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterAdditionalParameter(this);\r
+}\r
+\r
+void TocParser::AdditionalParameterContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitAdditionalParameter(this);\r
+}\r
+\r
+TocParser::AdditionalParameterContext* TocParser::additionalParameter() {\r
+ AdditionalParameterContext *_localctx = _tracker.createInstance<AdditionalParameterContext>(_ctx, getState());\r
+ enterRule(_localctx, 18, TocParser::RuleAdditionalParameter);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(122);\r
+ match(TocParser::T__6);\r
+ setState(123);\r
+ var();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- BodyContext ------------------------------------------------------------------\r
+\r
+TocParser::BodyContext::BodyContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+std::vector<TocParser::StmtContext *> TocParser::BodyContext::stmt() {\r
+ return getRuleContexts<TocParser::StmtContext>();\r
+}\r
+\r
+TocParser::StmtContext* TocParser::BodyContext::stmt(size_t i) {\r
+ return getRuleContext<TocParser::StmtContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::BodyContext::getRuleIndex() const {\r
+ return TocParser::RuleBody;\r
+}\r
+\r
+void TocParser::BodyContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterBody(this);\r
+}\r
+\r
+void TocParser::BodyContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitBody(this);\r
+}\r
+\r
+TocParser::BodyContext* TocParser::body() {\r
+ BodyContext *_localctx = _tracker.createInstance<BodyContext>(_ctx, getState());\r
+ enterRule(_localctx, 20, TocParser::RuleBody);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(125);\r
+ match(TocParser::T__7);\r
+ setState(129);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ while ((((_la & ~ 0x3fULL) == 0) &&\r
+ ((1ULL << _la) & ((1ULL << TocParser::T__0)\r
+ | (1ULL << TocParser::T__4)\r
+ | (1ULL << TocParser::T__10)\r
+ | (1ULL << TocParser::T__11)\r
+ | (1ULL << TocParser::T__12)\r
+ | (1ULL << TocParser::INTLIT)\r
+ | (1ULL << TocParser::NAME))) != 0)) {\r
+ setState(126);\r
+ stmt();\r
+ setState(131);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ }\r
+ setState(132);\r
+ match(TocParser::T__8);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StructDeclContext ------------------------------------------------------------------\r
+\r
+TocParser::StructDeclContext::StructDeclContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::StructNameContext* TocParser::StructDeclContext::structName() {\r
+ return getRuleContext<TocParser::StructNameContext>(0);\r
+}\r
+\r
+std::vector<TocParser::StructMemberContext *> TocParser::StructDeclContext::structMember() {\r
+ return getRuleContexts<TocParser::StructMemberContext>();\r
+}\r
+\r
+TocParser::StructMemberContext* TocParser::StructDeclContext::structMember(size_t i) {\r
+ return getRuleContext<TocParser::StructMemberContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::StructDeclContext::getRuleIndex() const {\r
+ return TocParser::RuleStructDecl;\r
+}\r
+\r
+void TocParser::StructDeclContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStructDecl(this);\r
+}\r
+\r
+void TocParser::StructDeclContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStructDecl(this);\r
+}\r
+\r
+TocParser::StructDeclContext* TocParser::structDecl() {\r
+ StructDeclContext *_localctx = _tracker.createInstance<StructDeclContext>(_ctx, getState());\r
+ enterRule(_localctx, 22, TocParser::RuleStructDecl);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(134);\r
+ match(TocParser::T__9);\r
+ setState(135);\r
+ structName();\r
+ setState(136);\r
+ match(TocParser::T__7);\r
+ setState(140);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ while (_la == TocParser::NAME) {\r
+ setState(137);\r
+ structMember();\r
+ setState(142);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ }\r
+ setState(143);\r
+ match(TocParser::T__8);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StructMemberContext ------------------------------------------------------------------\r
+\r
+TocParser::StructMemberContext::StructMemberContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::StructVarContext* TocParser::StructMemberContext::structVar() {\r
+ return getRuleContext<TocParser::StructVarContext>(0);\r
+}\r
+\r
+TocParser::StructMethodContext* TocParser::StructMemberContext::structMethod() {\r
+ return getRuleContext<TocParser::StructMethodContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::StructMemberContext::getRuleIndex() const {\r
+ return TocParser::RuleStructMember;\r
+}\r
+\r
+void TocParser::StructMemberContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStructMember(this);\r
+}\r
+\r
+void TocParser::StructMemberContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStructMember(this);\r
+}\r
+\r
+TocParser::StructMemberContext* TocParser::structMember() {\r
+ StructMemberContext *_localctx = _tracker.createInstance<StructMemberContext>(_ctx, getState());\r
+ enterRule(_localctx, 24, TocParser::RuleStructMember);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ setState(147);\r
+ _errHandler->sync(this);\r
+ switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 7, _ctx)) {\r
+ case 1: {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(145);\r
+ structVar();\r
+ break;\r
+ }\r
+\r
+ case 2: {\r
+ enterOuterAlt(_localctx, 2);\r
+ setState(146);\r
+ structMethod();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StructVarContext ------------------------------------------------------------------\r
+\r
+TocParser::StructVarContext::StructVarContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarContext* TocParser::StructVarContext::var() {\r
+ return getRuleContext<TocParser::VarContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::StructVarContext::getRuleIndex() const {\r
+ return TocParser::RuleStructVar;\r
+}\r
+\r
+void TocParser::StructVarContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStructVar(this);\r
+}\r
+\r
+void TocParser::StructVarContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStructVar(this);\r
+}\r
+\r
+TocParser::StructVarContext* TocParser::structVar() {\r
+ StructVarContext *_localctx = _tracker.createInstance<StructVarContext>(_ctx, getState());\r
+ enterRule(_localctx, 26, TocParser::RuleStructVar);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(149);\r
+ var();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StructMethodContext ------------------------------------------------------------------\r
+\r
+TocParser::StructMethodContext::StructMethodContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncContext* TocParser::StructMethodContext::func() {\r
+ return getRuleContext<TocParser::FuncContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::StructMethodContext::getRuleIndex() const {\r
+ return TocParser::RuleStructMethod;\r
+}\r
+\r
+void TocParser::StructMethodContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStructMethod(this);\r
+}\r
+\r
+void TocParser::StructMethodContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStructMethod(this);\r
+}\r
+\r
+TocParser::StructMethodContext* TocParser::structMethod() {\r
+ StructMethodContext *_localctx = _tracker.createInstance<StructMethodContext>(_ctx, getState());\r
+ enterRule(_localctx, 28, TocParser::RuleStructMethod);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(151);\r
+ func();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StmtContext ------------------------------------------------------------------\r
+\r
+TocParser::StmtContext::StmtContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarDeclContext* TocParser::StmtContext::varDecl() {\r
+ return getRuleContext<TocParser::VarDeclContext>(0);\r
+}\r
+\r
+TocParser::ConditionalContext* TocParser::StmtContext::conditional() {\r
+ return getRuleContext<TocParser::ConditionalContext>(0);\r
+}\r
+\r
+TocParser::LoopContext* TocParser::StmtContext::loop() {\r
+ return getRuleContext<TocParser::LoopContext>(0);\r
+}\r
+\r
+TocParser::AssignmentContext* TocParser::StmtContext::assignment() {\r
+ return getRuleContext<TocParser::AssignmentContext>(0);\r
+}\r
+\r
+TocParser::ReturnStmtContext* TocParser::StmtContext::returnStmt() {\r
+ return getRuleContext<TocParser::ReturnStmtContext>(0);\r
+}\r
+\r
+TocParser::ExprContext* TocParser::StmtContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::StmtContext::getRuleIndex() const {\r
+ return TocParser::RuleStmt;\r
+}\r
+\r
+void TocParser::StmtContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStmt(this);\r
+}\r
+\r
+void TocParser::StmtContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStmt(this);\r
+}\r
+\r
+TocParser::StmtContext* TocParser::stmt() {\r
+ StmtContext *_localctx = _tracker.createInstance<StmtContext>(_ctx, getState());\r
+ enterRule(_localctx, 30, TocParser::RuleStmt);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(159);\r
+ _errHandler->sync(this);\r
+ switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 8, _ctx)) {\r
+ case 1: {\r
+ setState(153);\r
+ varDecl();\r
+ break;\r
+ }\r
+\r
+ case 2: {\r
+ setState(154);\r
+ conditional();\r
+ break;\r
+ }\r
+\r
+ case 3: {\r
+ setState(155);\r
+ loop();\r
+ break;\r
+ }\r
+\r
+ case 4: {\r
+ setState(156);\r
+ assignment();\r
+ break;\r
+ }\r
+\r
+ case 5: {\r
+ setState(157);\r
+ returnStmt();\r
+ break;\r
+ }\r
+\r
+ case 6: {\r
+ setState(158);\r
+ expr();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- ConditionalContext ------------------------------------------------------------------\r
+\r
+TocParser::ConditionalContext::ConditionalContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::IfCondContext* TocParser::ConditionalContext::ifCond() {\r
+ return getRuleContext<TocParser::IfCondContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::ConditionalContext::getRuleIndex() const {\r
+ return TocParser::RuleConditional;\r
+}\r
+\r
+void TocParser::ConditionalContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterConditional(this);\r
+}\r
+\r
+void TocParser::ConditionalContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitConditional(this);\r
+}\r
+\r
+TocParser::ConditionalContext* TocParser::conditional() {\r
+ ConditionalContext *_localctx = _tracker.createInstance<ConditionalContext>(_ctx, getState());\r
+ enterRule(_localctx, 32, TocParser::RuleConditional);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(161);\r
+ ifCond();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- IfCondContext ------------------------------------------------------------------\r
+\r
+TocParser::IfCondContext::IfCondContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::ExprContext* TocParser::IfCondContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+TocParser::BodyContext* TocParser::IfCondContext::body() {\r
+ return getRuleContext<TocParser::BodyContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::IfCondContext::getRuleIndex() const {\r
+ return TocParser::RuleIfCond;\r
+}\r
+\r
+void TocParser::IfCondContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterIfCond(this);\r
+}\r
+\r
+void TocParser::IfCondContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitIfCond(this);\r
+}\r
+\r
+TocParser::IfCondContext* TocParser::ifCond() {\r
+ IfCondContext *_localctx = _tracker.createInstance<IfCondContext>(_ctx, getState());\r
+ enterRule(_localctx, 34, TocParser::RuleIfCond);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(163);\r
+ match(TocParser::T__10);\r
+ setState(164);\r
+ expr();\r
+ setState(165);\r
+ body();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- LoopContext ------------------------------------------------------------------\r
+\r
+TocParser::LoopContext::LoopContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::WhileLoopContext* TocParser::LoopContext::whileLoop() {\r
+ return getRuleContext<TocParser::WhileLoopContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::LoopContext::getRuleIndex() const {\r
+ return TocParser::RuleLoop;\r
+}\r
+\r
+void TocParser::LoopContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterLoop(this);\r
+}\r
+\r
+void TocParser::LoopContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitLoop(this);\r
+}\r
+\r
+TocParser::LoopContext* TocParser::loop() {\r
+ LoopContext *_localctx = _tracker.createInstance<LoopContext>(_ctx, getState());\r
+ enterRule(_localctx, 36, TocParser::RuleLoop);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(167);\r
+ whileLoop();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- WhileLoopContext ------------------------------------------------------------------\r
+\r
+TocParser::WhileLoopContext::WhileLoopContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::ExprContext* TocParser::WhileLoopContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+TocParser::BodyContext* TocParser::WhileLoopContext::body() {\r
+ return getRuleContext<TocParser::BodyContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::WhileLoopContext::getRuleIndex() const {\r
+ return TocParser::RuleWhileLoop;\r
+}\r
+\r
+void TocParser::WhileLoopContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterWhileLoop(this);\r
+}\r
+\r
+void TocParser::WhileLoopContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitWhileLoop(this);\r
+}\r
+\r
+TocParser::WhileLoopContext* TocParser::whileLoop() {\r
+ WhileLoopContext *_localctx = _tracker.createInstance<WhileLoopContext>(_ctx, getState());\r
+ enterRule(_localctx, 38, TocParser::RuleWhileLoop);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(169);\r
+ match(TocParser::T__11);\r
+ setState(170);\r
+ expr();\r
+ setState(171);\r
+ body();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- AssignmentContext ------------------------------------------------------------------\r
+\r
+TocParser::AssignmentContext::AssignmentContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::AssignmentContext::identifier() {\r
+ return getRuleContext<TocParser::IdentifierContext>(0);\r
+}\r
+\r
+TocParser::ExprContext* TocParser::AssignmentContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::AssignmentContext::getRuleIndex() const {\r
+ return TocParser::RuleAssignment;\r
+}\r
+\r
+void TocParser::AssignmentContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterAssignment(this);\r
+}\r
+\r
+void TocParser::AssignmentContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitAssignment(this);\r
+}\r
+\r
+TocParser::AssignmentContext* TocParser::assignment() {\r
+ AssignmentContext *_localctx = _tracker.createInstance<AssignmentContext>(_ctx, getState());\r
+ enterRule(_localctx, 40, TocParser::RuleAssignment);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(173);\r
+ identifier();\r
+ setState(174);\r
+ match(TocParser::T__2);\r
+ setState(175);\r
+ expr();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- ReturnStmtContext ------------------------------------------------------------------\r
+\r
+TocParser::ReturnStmtContext::ReturnStmtContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::ExprContext* TocParser::ReturnStmtContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::ReturnStmtContext::getRuleIndex() const {\r
+ return TocParser::RuleReturnStmt;\r
+}\r
+\r
+void TocParser::ReturnStmtContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterReturnStmt(this);\r
+}\r
+\r
+void TocParser::ReturnStmtContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitReturnStmt(this);\r
+}\r
+\r
+TocParser::ReturnStmtContext* TocParser::returnStmt() {\r
+ ReturnStmtContext *_localctx = _tracker.createInstance<ReturnStmtContext>(_ctx, getState());\r
+ enterRule(_localctx, 42, TocParser::RuleReturnStmt);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(177);\r
+ match(TocParser::T__12);\r
+ setState(178);\r
+ expr();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- ExprContext ------------------------------------------------------------------\r
+\r
+TocParser::ExprContext::ExprContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncCallContext* TocParser::ExprContext::funcCall() {\r
+ return getRuleContext<TocParser::FuncCallContext>(0);\r
+}\r
+\r
+TocParser::LiteralContext* TocParser::ExprContext::literal() {\r
+ return getRuleContext<TocParser::LiteralContext>(0);\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::ExprContext::identifier() {\r
+ return getRuleContext<TocParser::IdentifierContext>(0);\r
+}\r
+\r
+TocParser::SubscriptContext* TocParser::ExprContext::subscript() {\r
+ return getRuleContext<TocParser::SubscriptContext>(0);\r
+}\r
+\r
+TocParser::MemberAccessContext* TocParser::ExprContext::memberAccess() {\r
+ return getRuleContext<TocParser::MemberAccessContext>(0);\r
+}\r
+\r
+TocParser::ParenExprContext* TocParser::ExprContext::parenExpr() {\r
+ return getRuleContext<TocParser::ParenExprContext>(0);\r
+}\r
+\r
+TocParser::OperatorExprContext* TocParser::ExprContext::operatorExpr() {\r
+ return getRuleContext<TocParser::OperatorExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::ExprContext::getRuleIndex() const {\r
+ return TocParser::RuleExpr;\r
+}\r
+\r
+void TocParser::ExprContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterExpr(this);\r
+}\r
+\r
+void TocParser::ExprContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitExpr(this);\r
+}\r
+\r
+TocParser::ExprContext* TocParser::expr() {\r
+ ExprContext *_localctx = _tracker.createInstance<ExprContext>(_ctx, getState());\r
+ enterRule(_localctx, 44, TocParser::RuleExpr);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ setState(187);\r
+ _errHandler->sync(this);\r
+ switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 9, _ctx)) {\r
+ case 1: {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(180);\r
+ funcCall();\r
+ break;\r
+ }\r
+\r
+ case 2: {\r
+ enterOuterAlt(_localctx, 2);\r
+ setState(181);\r
+ literal();\r
+ break;\r
+ }\r
+\r
+ case 3: {\r
+ enterOuterAlt(_localctx, 3);\r
+ setState(182);\r
+ identifier();\r
+ break;\r
+ }\r
+\r
+ case 4: {\r
+ enterOuterAlt(_localctx, 4);\r
+ setState(183);\r
+ subscript();\r
+ break;\r
+ }\r
+\r
+ case 5: {\r
+ enterOuterAlt(_localctx, 5);\r
+ setState(184);\r
+ memberAccess();\r
+ break;\r
+ }\r
+\r
+ case 6: {\r
+ enterOuterAlt(_localctx, 6);\r
+ setState(185);\r
+ parenExpr();\r
+ break;\r
+ }\r
+\r
+ case 7: {\r
+ enterOuterAlt(_localctx, 7);\r
+ setState(186);\r
+ operatorExpr();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- NonOpExprContext ------------------------------------------------------------------\r
+\r
+TocParser::NonOpExprContext::NonOpExprContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncCallContext* TocParser::NonOpExprContext::funcCall() {\r
+ return getRuleContext<TocParser::FuncCallContext>(0);\r
+}\r
+\r
+TocParser::LiteralContext* TocParser::NonOpExprContext::literal() {\r
+ return getRuleContext<TocParser::LiteralContext>(0);\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::NonOpExprContext::identifier() {\r
+ return getRuleContext<TocParser::IdentifierContext>(0);\r
+}\r
+\r
+TocParser::SubscriptContext* TocParser::NonOpExprContext::subscript() {\r
+ return getRuleContext<TocParser::SubscriptContext>(0);\r
+}\r
+\r
+TocParser::MemberAccessContext* TocParser::NonOpExprContext::memberAccess() {\r
+ return getRuleContext<TocParser::MemberAccessContext>(0);\r
+}\r
+\r
+TocParser::ParenExprContext* TocParser::NonOpExprContext::parenExpr() {\r
+ return getRuleContext<TocParser::ParenExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::NonOpExprContext::getRuleIndex() const {\r
+ return TocParser::RuleNonOpExpr;\r
+}\r
+\r
+void TocParser::NonOpExprContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterNonOpExpr(this);\r
+}\r
+\r
+void TocParser::NonOpExprContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitNonOpExpr(this);\r
+}\r
+\r
+TocParser::NonOpExprContext* TocParser::nonOpExpr() {\r
+ NonOpExprContext *_localctx = _tracker.createInstance<NonOpExprContext>(_ctx, getState());\r
+ enterRule(_localctx, 46, TocParser::RuleNonOpExpr);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ setState(195);\r
+ _errHandler->sync(this);\r
+ switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 10, _ctx)) {\r
+ case 1: {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(189);\r
+ funcCall();\r
+ break;\r
+ }\r
+\r
+ case 2: {\r
+ enterOuterAlt(_localctx, 2);\r
+ setState(190);\r
+ literal();\r
+ break;\r
+ }\r
+\r
+ case 3: {\r
+ enterOuterAlt(_localctx, 3);\r
+ setState(191);\r
+ identifier();\r
+ break;\r
+ }\r
+\r
+ case 4: {\r
+ enterOuterAlt(_localctx, 4);\r
+ setState(192);\r
+ subscript();\r
+ break;\r
+ }\r
+\r
+ case 5: {\r
+ enterOuterAlt(_localctx, 5);\r
+ setState(193);\r
+ memberAccess();\r
+ break;\r
+ }\r
+\r
+ case 6: {\r
+ enterOuterAlt(_localctx, 6);\r
+ setState(194);\r
+ parenExpr();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- NonSubscriptExprContext ------------------------------------------------------------------\r
+\r
+TocParser::NonSubscriptExprContext::NonSubscriptExprContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncCallContext* TocParser::NonSubscriptExprContext::funcCall() {\r
+ return getRuleContext<TocParser::FuncCallContext>(0);\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::NonSubscriptExprContext::identifier() {\r
+ return getRuleContext<TocParser::IdentifierContext>(0);\r
+}\r
+\r
+TocParser::MemberAccessContext* TocParser::NonSubscriptExprContext::memberAccess() {\r
+ return getRuleContext<TocParser::MemberAccessContext>(0);\r
+}\r
+\r
+TocParser::ParenExprContext* TocParser::NonSubscriptExprContext::parenExpr() {\r
+ return getRuleContext<TocParser::ParenExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::NonSubscriptExprContext::getRuleIndex() const {\r
+ return TocParser::RuleNonSubscriptExpr;\r
+}\r
+\r
+void TocParser::NonSubscriptExprContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterNonSubscriptExpr(this);\r
+}\r
+\r
+void TocParser::NonSubscriptExprContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitNonSubscriptExpr(this);\r
+}\r
+\r
+TocParser::NonSubscriptExprContext* TocParser::nonSubscriptExpr() {\r
+ NonSubscriptExprContext *_localctx = _tracker.createInstance<NonSubscriptExprContext>(_ctx, getState());\r
+ enterRule(_localctx, 48, TocParser::RuleNonSubscriptExpr);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ setState(201);\r
+ _errHandler->sync(this);\r
+ switch (getInterpreter<atn::ParserATNSimulator>()->adaptivePredict(_input, 11, _ctx)) {\r
+ case 1: {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(197);\r
+ funcCall();\r
+ break;\r
+ }\r
+\r
+ case 2: {\r
+ enterOuterAlt(_localctx, 2);\r
+ setState(198);\r
+ identifier();\r
+ break;\r
+ }\r
+\r
+ case 3: {\r
+ enterOuterAlt(_localctx, 3);\r
+ setState(199);\r
+ memberAccess();\r
+ break;\r
+ }\r
+\r
+ case 4: {\r
+ enterOuterAlt(_localctx, 4);\r
+ setState(200);\r
+ parenExpr();\r
+ break;\r
+ }\r
+\r
+ default:\r
+ break;\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- FuncCallContext ------------------------------------------------------------------\r
+\r
+TocParser::FuncCallContext::FuncCallContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::FuncNameContext* TocParser::FuncCallContext::funcName() {\r
+ return getRuleContext<TocParser::FuncNameContext>(0);\r
+}\r
+\r
+std::vector<TocParser::ExprContext *> TocParser::FuncCallContext::expr() {\r
+ return getRuleContexts<TocParser::ExprContext>();\r
+}\r
+\r
+TocParser::ExprContext* TocParser::FuncCallContext::expr(size_t i) {\r
+ return getRuleContext<TocParser::ExprContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::FuncCallContext::getRuleIndex() const {\r
+ return TocParser::RuleFuncCall;\r
+}\r
+\r
+void TocParser::FuncCallContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterFuncCall(this);\r
+}\r
+\r
+void TocParser::FuncCallContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitFuncCall(this);\r
+}\r
+\r
+TocParser::FuncCallContext* TocParser::funcCall() {\r
+ FuncCallContext *_localctx = _tracker.createInstance<FuncCallContext>(_ctx, getState());\r
+ enterRule(_localctx, 50, TocParser::RuleFuncCall);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(203);\r
+ funcName();\r
+ setState(204);\r
+ match(TocParser::T__4);\r
+ setState(213);\r
+ _errHandler->sync(this);\r
+\r
+ _la = _input->LA(1);\r
+ if ((((_la & ~ 0x3fULL) == 0) &&\r
+ ((1ULL << _la) & ((1ULL << TocParser::T__4)\r
+ | (1ULL << TocParser::INTLIT)\r
+ | (1ULL << TocParser::NAME))) != 0)) {\r
+ setState(205);\r
+ expr();\r
+ setState(210);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ while (_la == TocParser::T__6) {\r
+ setState(206);\r
+ match(TocParser::T__6);\r
+ setState(207);\r
+ expr();\r
+ setState(212);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ }\r
+ }\r
+ setState(215);\r
+ match(TocParser::T__5);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- OperatorExprContext ------------------------------------------------------------------\r
+\r
+TocParser::OperatorExprContext::OperatorExprContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::BinaryOperatorContext* TocParser::OperatorExprContext::binaryOperator() {\r
+ return getRuleContext<TocParser::BinaryOperatorContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::OperatorExprContext::getRuleIndex() const {\r
+ return TocParser::RuleOperatorExpr;\r
+}\r
+\r
+void TocParser::OperatorExprContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterOperatorExpr(this);\r
+}\r
+\r
+void TocParser::OperatorExprContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitOperatorExpr(this);\r
+}\r
+\r
+TocParser::OperatorExprContext* TocParser::operatorExpr() {\r
+ OperatorExprContext *_localctx = _tracker.createInstance<OperatorExprContext>(_ctx, getState());\r
+ enterRule(_localctx, 52, TocParser::RuleOperatorExpr);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(217);\r
+ binaryOperator();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- BinaryOperatorContext ------------------------------------------------------------------\r
+\r
+TocParser::BinaryOperatorContext::BinaryOperatorContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+std::vector<TocParser::NonOpExprContext *> TocParser::BinaryOperatorContext::nonOpExpr() {\r
+ return getRuleContexts<TocParser::NonOpExprContext>();\r
+}\r
+\r
+TocParser::NonOpExprContext* TocParser::BinaryOperatorContext::nonOpExpr(size_t i) {\r
+ return getRuleContext<TocParser::NonOpExprContext>(i);\r
+}\r
+\r
+std::vector<tree::TerminalNode *> TocParser::BinaryOperatorContext::BINARY_OPERATOR() {\r
+ return getTokens(TocParser::BINARY_OPERATOR);\r
+}\r
+\r
+tree::TerminalNode* TocParser::BinaryOperatorContext::BINARY_OPERATOR(size_t i) {\r
+ return getToken(TocParser::BINARY_OPERATOR, i);\r
+}\r
+\r
+\r
+size_t TocParser::BinaryOperatorContext::getRuleIndex() const {\r
+ return TocParser::RuleBinaryOperator;\r
+}\r
+\r
+void TocParser::BinaryOperatorContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterBinaryOperator(this);\r
+}\r
+\r
+void TocParser::BinaryOperatorContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitBinaryOperator(this);\r
+}\r
+\r
+TocParser::BinaryOperatorContext* TocParser::binaryOperator() {\r
+ BinaryOperatorContext *_localctx = _tracker.createInstance<BinaryOperatorContext>(_ctx, getState());\r
+ enterRule(_localctx, 54, TocParser::RuleBinaryOperator);\r
+ size_t _la = 0;\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(219);\r
+ nonOpExpr();\r
+ setState(220);\r
+ match(TocParser::BINARY_OPERATOR);\r
+ setState(221);\r
+ nonOpExpr();\r
+ setState(226);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ while (_la == TocParser::BINARY_OPERATOR) {\r
+ setState(222);\r
+ match(TocParser::BINARY_OPERATOR);\r
+ setState(223);\r
+ nonOpExpr();\r
+ setState(228);\r
+ _errHandler->sync(this);\r
+ _la = _input->LA(1);\r
+ }\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- IdentifierContext ------------------------------------------------------------------\r
+\r
+TocParser::IdentifierContext::IdentifierContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::VarNameContext* TocParser::IdentifierContext::varName() {\r
+ return getRuleContext<TocParser::VarNameContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::IdentifierContext::getRuleIndex() const {\r
+ return TocParser::RuleIdentifier;\r
+}\r
+\r
+void TocParser::IdentifierContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterIdentifier(this);\r
+}\r
+\r
+void TocParser::IdentifierContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitIdentifier(this);\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::identifier() {\r
+ IdentifierContext *_localctx = _tracker.createInstance<IdentifierContext>(_ctx, getState());\r
+ enterRule(_localctx, 56, TocParser::RuleIdentifier);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(229);\r
+ varName();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- LiteralContext ------------------------------------------------------------------\r
+\r
+TocParser::LiteralContext::LiteralContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::LiteralContext::INTLIT() {\r
+ return getToken(TocParser::INTLIT, 0);\r
+}\r
+\r
+\r
+size_t TocParser::LiteralContext::getRuleIndex() const {\r
+ return TocParser::RuleLiteral;\r
+}\r
+\r
+void TocParser::LiteralContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterLiteral(this);\r
+}\r
+\r
+void TocParser::LiteralContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitLiteral(this);\r
+}\r
+\r
+TocParser::LiteralContext* TocParser::literal() {\r
+ LiteralContext *_localctx = _tracker.createInstance<LiteralContext>(_ctx, getState());\r
+ enterRule(_localctx, 58, TocParser::RuleLiteral);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(231);\r
+ match(TocParser::INTLIT);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- SubscriptContext ------------------------------------------------------------------\r
+\r
+TocParser::SubscriptContext::SubscriptContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::NonSubscriptExprContext* TocParser::SubscriptContext::nonSubscriptExpr() {\r
+ return getRuleContext<TocParser::NonSubscriptExprContext>(0);\r
+}\r
+\r
+TocParser::ExprContext* TocParser::SubscriptContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::SubscriptContext::getRuleIndex() const {\r
+ return TocParser::RuleSubscript;\r
+}\r
+\r
+void TocParser::SubscriptContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterSubscript(this);\r
+}\r
+\r
+void TocParser::SubscriptContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitSubscript(this);\r
+}\r
+\r
+TocParser::SubscriptContext* TocParser::subscript() {\r
+ SubscriptContext *_localctx = _tracker.createInstance<SubscriptContext>(_ctx, getState());\r
+ enterRule(_localctx, 60, TocParser::RuleSubscript);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(233);\r
+ nonSubscriptExpr();\r
+ setState(234);\r
+ match(TocParser::T__13);\r
+ setState(235);\r
+ expr();\r
+ setState(236);\r
+ match(TocParser::T__14);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- MemberAccessContext ------------------------------------------------------------------\r
+\r
+TocParser::MemberAccessContext::MemberAccessContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+std::vector<TocParser::IdentifierContext *> TocParser::MemberAccessContext::identifier() {\r
+ return getRuleContexts<TocParser::IdentifierContext>();\r
+}\r
+\r
+TocParser::IdentifierContext* TocParser::MemberAccessContext::identifier(size_t i) {\r
+ return getRuleContext<TocParser::IdentifierContext>(i);\r
+}\r
+\r
+\r
+size_t TocParser::MemberAccessContext::getRuleIndex() const {\r
+ return TocParser::RuleMemberAccess;\r
+}\r
+\r
+void TocParser::MemberAccessContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterMemberAccess(this);\r
+}\r
+\r
+void TocParser::MemberAccessContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitMemberAccess(this);\r
+}\r
+\r
+TocParser::MemberAccessContext* TocParser::memberAccess() {\r
+ MemberAccessContext *_localctx = _tracker.createInstance<MemberAccessContext>(_ctx, getState());\r
+ enterRule(_localctx, 62, TocParser::RuleMemberAccess);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(238);\r
+ identifier();\r
+ setState(239);\r
+ match(TocParser::T__15);\r
+ setState(240);\r
+ identifier();\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- ParenExprContext ------------------------------------------------------------------\r
+\r
+TocParser::ParenExprContext::ParenExprContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+TocParser::ExprContext* TocParser::ParenExprContext::expr() {\r
+ return getRuleContext<TocParser::ExprContext>(0);\r
+}\r
+\r
+\r
+size_t TocParser::ParenExprContext::getRuleIndex() const {\r
+ return TocParser::RuleParenExpr;\r
+}\r
+\r
+void TocParser::ParenExprContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterParenExpr(this);\r
+}\r
+\r
+void TocParser::ParenExprContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitParenExpr(this);\r
+}\r
+\r
+TocParser::ParenExprContext* TocParser::parenExpr() {\r
+ ParenExprContext *_localctx = _tracker.createInstance<ParenExprContext>(_ctx, getState());\r
+ enterRule(_localctx, 64, TocParser::RuleParenExpr);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(242);\r
+ match(TocParser::T__4);\r
+ setState(243);\r
+ expr();\r
+ setState(244);\r
+ match(TocParser::T__5);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- FuncNameContext ------------------------------------------------------------------\r
+\r
+TocParser::FuncNameContext::FuncNameContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::FuncNameContext::NAME() {\r
+ return getToken(TocParser::NAME, 0);\r
+}\r
+\r
+\r
+size_t TocParser::FuncNameContext::getRuleIndex() const {\r
+ return TocParser::RuleFuncName;\r
+}\r
+\r
+void TocParser::FuncNameContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterFuncName(this);\r
+}\r
+\r
+void TocParser::FuncNameContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitFuncName(this);\r
+}\r
+\r
+TocParser::FuncNameContext* TocParser::funcName() {\r
+ FuncNameContext *_localctx = _tracker.createInstance<FuncNameContext>(_ctx, getState());\r
+ enterRule(_localctx, 66, TocParser::RuleFuncName);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(246);\r
+ match(TocParser::NAME);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- VarNameContext ------------------------------------------------------------------\r
+\r
+TocParser::VarNameContext::VarNameContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::VarNameContext::NAME() {\r
+ return getToken(TocParser::NAME, 0);\r
+}\r
+\r
+\r
+size_t TocParser::VarNameContext::getRuleIndex() const {\r
+ return TocParser::RuleVarName;\r
+}\r
+\r
+void TocParser::VarNameContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterVarName(this);\r
+}\r
+\r
+void TocParser::VarNameContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitVarName(this);\r
+}\r
+\r
+TocParser::VarNameContext* TocParser::varName() {\r
+ VarNameContext *_localctx = _tracker.createInstance<VarNameContext>(_ctx, getState());\r
+ enterRule(_localctx, 68, TocParser::RuleVarName);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(248);\r
+ match(TocParser::NAME);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- TypeNameContext ------------------------------------------------------------------\r
+\r
+TocParser::TypeNameContext::TypeNameContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::TypeNameContext::NAME() {\r
+ return getToken(TocParser::NAME, 0);\r
+}\r
+\r
+\r
+size_t TocParser::TypeNameContext::getRuleIndex() const {\r
+ return TocParser::RuleTypeName;\r
+}\r
+\r
+void TocParser::TypeNameContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterTypeName(this);\r
+}\r
+\r
+void TocParser::TypeNameContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitTypeName(this);\r
+}\r
+\r
+TocParser::TypeNameContext* TocParser::typeName() {\r
+ TypeNameContext *_localctx = _tracker.createInstance<TypeNameContext>(_ctx, getState());\r
+ enterRule(_localctx, 70, TocParser::RuleTypeName);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(250);\r
+ match(TocParser::NAME);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+//----------------- StructNameContext ------------------------------------------------------------------\r
+\r
+TocParser::StructNameContext::StructNameContext(ParserRuleContext *parent, size_t invokingState)\r
+ : ParserRuleContext(parent, invokingState) {\r
+}\r
+\r
+tree::TerminalNode* TocParser::StructNameContext::NAME() {\r
+ return getToken(TocParser::NAME, 0);\r
+}\r
+\r
+\r
+size_t TocParser::StructNameContext::getRuleIndex() const {\r
+ return TocParser::RuleStructName;\r
+}\r
+\r
+void TocParser::StructNameContext::enterRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->enterStructName(this);\r
+}\r
+\r
+void TocParser::StructNameContext::exitRule(tree::ParseTreeListener *listener) {\r
+ auto parserListener = dynamic_cast<TocListener *>(listener);\r
+ if (parserListener != nullptr)\r
+ parserListener->exitStructName(this);\r
+}\r
+\r
+TocParser::StructNameContext* TocParser::structName() {\r
+ StructNameContext *_localctx = _tracker.createInstance<StructNameContext>(_ctx, getState());\r
+ enterRule(_localctx, 72, TocParser::RuleStructName);\r
+\r
+#if __cplusplus > 201703L\r
+ auto onExit = finally([=, this] {\r
+#else\r
+ auto onExit = finally([=] {\r
+#endif\r
+ exitRule();\r
+ });\r
+ try {\r
+ enterOuterAlt(_localctx, 1);\r
+ setState(252);\r
+ match(TocParser::NAME);\r
+ \r
+ }\r
+ catch (RecognitionException &e) {\r
+ _errHandler->reportError(this, e);\r
+ _localctx->exception = std::current_exception();\r
+ _errHandler->recover(this, _localctx->exception);\r
+ }\r
+\r
+ return _localctx;\r
+}\r
+\r
+// Static vars and initialization.\r
+std::vector<dfa::DFA> TocParser::_decisionToDFA;\r
+atn::PredictionContextCache TocParser::_sharedContextCache;\r
+\r
+// We own the ATN which in turn owns the ATN states.\r
+atn::ATN TocParser::_atn;\r
+std::vector<uint16_t> TocParser::_serializedATN;\r
+\r
+std::vector<std::string> TocParser::_ruleNames = {\r
+ "prog", "decl", "varDecl", "var", "type", "funcDecl", "func", "parameter", \r
+ "firstParameter", "additionalParameter", "body", "structDecl", "structMember", \r
+ "structVar", "structMethod", "stmt", "conditional", "ifCond", "loop", \r
+ "whileLoop", "assignment", "returnStmt", "expr", "nonOpExpr", "nonSubscriptExpr", \r
+ "funcCall", "operatorExpr", "binaryOperator", "identifier", "literal", \r
+ "subscript", "memberAccess", "parenExpr", "funcName", "varName", "typeName", \r
+ "structName"\r
+};\r
+\r
+std::vector<std::string> TocParser::_literalNames = {\r
+ "", "'var'", "':'", "'='", "'func'", "'('", "')'", "','", "'{'", "'}'", \r
+ "'struct'", "'if'", "'while'", "'return'", "'['", "']'", "'.'"\r
+};\r
+\r
+std::vector<std::string> TocParser::_symbolicNames = {\r
+ "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "BINARY_OPERATOR", \r
+ "INTLIT", "NAME", "WS", "NEWLINE"\r
+};\r
+\r
+dfa::Vocabulary TocParser::_vocabulary(_literalNames, _symbolicNames);\r
+\r
+std::vector<std::string> TocParser::_tokenNames;\r
+\r
+TocParser::Initializer::Initializer() {\r
+ for (size_t i = 0; i < _symbolicNames.size(); ++i) {\r
+ std::string name = _vocabulary.getLiteralName(i);\r
+ if (name.empty()) {\r
+ name = _vocabulary.getSymbolicName(i);\r
+ }\r
+\r
+ if (name.empty()) {\r
+ _tokenNames.push_back("<INVALID>");\r
+ } else {\r
+ _tokenNames.push_back(name);\r
+ }\r
+ }\r
+\r
+ static const uint16_t serializedATNSegment0[] = {\r
+ 0x3, 0x608b, 0xa72a, 0x8133, 0xb9ed, 0x417c, 0x3be7, 0x7786, 0x5964, \r
+ 0x3, 0x17, 0x101, 0x4, 0x2, 0x9, 0x2, 0x4, 0x3, 0x9, 0x3, 0x4, 0x4, \r
+ 0x9, 0x4, 0x4, 0x5, 0x9, 0x5, 0x4, 0x6, 0x9, 0x6, 0x4, 0x7, 0x9, \r
+ 0x7, 0x4, 0x8, 0x9, 0x8, 0x4, 0x9, 0x9, 0x9, 0x4, 0xa, 0x9, 0xa, \r
+ 0x4, 0xb, 0x9, 0xb, 0x4, 0xc, 0x9, 0xc, 0x4, 0xd, 0x9, 0xd, 0x4, \r
+ 0xe, 0x9, 0xe, 0x4, 0xf, 0x9, 0xf, 0x4, 0x10, 0x9, 0x10, 0x4, 0x11, \r
+ 0x9, 0x11, 0x4, 0x12, 0x9, 0x12, 0x4, 0x13, 0x9, 0x13, 0x4, 0x14, \r
+ 0x9, 0x14, 0x4, 0x15, 0x9, 0x15, 0x4, 0x16, 0x9, 0x16, 0x4, 0x17, \r
+ 0x9, 0x17, 0x4, 0x18, 0x9, 0x18, 0x4, 0x19, 0x9, 0x19, 0x4, 0x1a, \r
+ 0x9, 0x1a, 0x4, 0x1b, 0x9, 0x1b, 0x4, 0x1c, 0x9, 0x1c, 0x4, 0x1d, \r
+ 0x9, 0x1d, 0x4, 0x1e, 0x9, 0x1e, 0x4, 0x1f, 0x9, 0x1f, 0x4, 0x20, \r
+ 0x9, 0x20, 0x4, 0x21, 0x9, 0x21, 0x4, 0x22, 0x9, 0x22, 0x4, 0x23, \r
+ 0x9, 0x23, 0x4, 0x24, 0x9, 0x24, 0x4, 0x25, 0x9, 0x25, 0x4, 0x26, \r
+ 0x9, 0x26, 0x3, 0x2, 0x6, 0x2, 0x4e, 0xa, 0x2, 0xd, 0x2, 0xe, 0x2, \r
+ 0x4f, 0x3, 0x2, 0x3, 0x2, 0x3, 0x3, 0x3, 0x3, 0x3, 0x3, 0x5, 0x3, \r
+ 0x57, 0xa, 0x3, 0x3, 0x4, 0x3, 0x4, 0x3, 0x4, 0x3, 0x5, 0x3, 0x5, \r
+ 0x3, 0x5, 0x3, 0x5, 0x3, 0x5, 0x3, 0x5, 0x5, 0x5, 0x62, 0xa, 0x5, \r
+ 0x3, 0x6, 0x3, 0x6, 0x3, 0x7, 0x3, 0x7, 0x3, 0x7, 0x3, 0x8, 0x3, \r
+ 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, 0x3, 0x8, \r
+ 0x3, 0x8, 0x3, 0x9, 0x3, 0x9, 0x7, 0x9, 0x74, 0xa, 0x9, 0xc, 0x9, \r
+ 0xe, 0x9, 0x77, 0xb, 0x9, 0x5, 0x9, 0x79, 0xa, 0x9, 0x3, 0xa, 0x3, \r
+ 0xa, 0x3, 0xb, 0x3, 0xb, 0x3, 0xb, 0x3, 0xc, 0x3, 0xc, 0x7, 0xc, \r
+ 0x82, 0xa, 0xc, 0xc, 0xc, 0xe, 0xc, 0x85, 0xb, 0xc, 0x3, 0xc, 0x3, \r
+ 0xc, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x3, 0xd, 0x7, 0xd, 0x8d, 0xa, \r
+ 0xd, 0xc, 0xd, 0xe, 0xd, 0x90, 0xb, 0xd, 0x3, 0xd, 0x3, 0xd, 0x3, \r
+ 0xe, 0x3, 0xe, 0x5, 0xe, 0x96, 0xa, 0xe, 0x3, 0xf, 0x3, 0xf, 0x3, \r
+ 0x10, 0x3, 0x10, 0x3, 0x11, 0x3, 0x11, 0x3, 0x11, 0x3, 0x11, 0x3, \r
+ 0x11, 0x3, 0x11, 0x5, 0x11, 0xa2, 0xa, 0x11, 0x3, 0x12, 0x3, 0x12, \r
+ 0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x13, 0x3, 0x14, 0x3, 0x14, \r
+ 0x3, 0x15, 0x3, 0x15, 0x3, 0x15, 0x3, 0x15, 0x3, 0x16, 0x3, 0x16, \r
+ 0x3, 0x16, 0x3, 0x16, 0x3, 0x17, 0x3, 0x17, 0x3, 0x17, 0x3, 0x18, \r
+ 0x3, 0x18, 0x3, 0x18, 0x3, 0x18, 0x3, 0x18, 0x3, 0x18, 0x3, 0x18, \r
+ 0x5, 0x18, 0xbe, 0xa, 0x18, 0x3, 0x19, 0x3, 0x19, 0x3, 0x19, 0x3, \r
+ 0x19, 0x3, 0x19, 0x3, 0x19, 0x5, 0x19, 0xc6, 0xa, 0x19, 0x3, 0x1a, \r
+ 0x3, 0x1a, 0x3, 0x1a, 0x3, 0x1a, 0x5, 0x1a, 0xcc, 0xa, 0x1a, 0x3, \r
+ 0x1b, 0x3, 0x1b, 0x3, 0x1b, 0x3, 0x1b, 0x3, 0x1b, 0x7, 0x1b, 0xd3, \r
+ 0xa, 0x1b, 0xc, 0x1b, 0xe, 0x1b, 0xd6, 0xb, 0x1b, 0x5, 0x1b, 0xd8, \r
+ 0xa, 0x1b, 0x3, 0x1b, 0x3, 0x1b, 0x3, 0x1c, 0x3, 0x1c, 0x3, 0x1d, \r
+ 0x3, 0x1d, 0x3, 0x1d, 0x3, 0x1d, 0x3, 0x1d, 0x7, 0x1d, 0xe3, 0xa, \r
+ 0x1d, 0xc, 0x1d, 0xe, 0x1d, 0xe6, 0xb, 0x1d, 0x3, 0x1e, 0x3, 0x1e, \r
+ 0x3, 0x1f, 0x3, 0x1f, 0x3, 0x20, 0x3, 0x20, 0x3, 0x20, 0x3, 0x20, \r
+ 0x3, 0x20, 0x3, 0x21, 0x3, 0x21, 0x3, 0x21, 0x3, 0x21, 0x3, 0x22, \r
+ 0x3, 0x22, 0x3, 0x22, 0x3, 0x22, 0x3, 0x23, 0x3, 0x23, 0x3, 0x24, \r
+ 0x3, 0x24, 0x3, 0x25, 0x3, 0x25, 0x3, 0x26, 0x3, 0x26, 0x3, 0x26, \r
+ 0x2, 0x2, 0x27, 0x2, 0x4, 0x6, 0x8, 0xa, 0xc, 0xe, 0x10, 0x12, 0x14, \r
+ 0x16, 0x18, 0x1a, 0x1c, 0x1e, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, \r
+ 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e, 0x40, \r
+ 0x42, 0x44, 0x46, 0x48, 0x4a, 0x2, 0x2, 0x2, 0xfa, 0x2, 0x4d, 0x3, \r
+ 0x2, 0x2, 0x2, 0x4, 0x56, 0x3, 0x2, 0x2, 0x2, 0x6, 0x58, 0x3, 0x2, \r
+ 0x2, 0x2, 0x8, 0x5b, 0x3, 0x2, 0x2, 0x2, 0xa, 0x63, 0x3, 0x2, 0x2, \r
+ 0x2, 0xc, 0x65, 0x3, 0x2, 0x2, 0x2, 0xe, 0x68, 0x3, 0x2, 0x2, 0x2, \r
+ 0x10, 0x78, 0x3, 0x2, 0x2, 0x2, 0x12, 0x7a, 0x3, 0x2, 0x2, 0x2, 0x14, \r
+ 0x7c, 0x3, 0x2, 0x2, 0x2, 0x16, 0x7f, 0x3, 0x2, 0x2, 0x2, 0x18, 0x88, \r
+ 0x3, 0x2, 0x2, 0x2, 0x1a, 0x95, 0x3, 0x2, 0x2, 0x2, 0x1c, 0x97, 0x3, \r
+ 0x2, 0x2, 0x2, 0x1e, 0x99, 0x3, 0x2, 0x2, 0x2, 0x20, 0xa1, 0x3, 0x2, \r
+ 0x2, 0x2, 0x22, 0xa3, 0x3, 0x2, 0x2, 0x2, 0x24, 0xa5, 0x3, 0x2, 0x2, \r
+ 0x2, 0x26, 0xa9, 0x3, 0x2, 0x2, 0x2, 0x28, 0xab, 0x3, 0x2, 0x2, 0x2, \r
+ 0x2a, 0xaf, 0x3, 0x2, 0x2, 0x2, 0x2c, 0xb3, 0x3, 0x2, 0x2, 0x2, 0x2e, \r
+ 0xbd, 0x3, 0x2, 0x2, 0x2, 0x30, 0xc5, 0x3, 0x2, 0x2, 0x2, 0x32, 0xcb, \r
+ 0x3, 0x2, 0x2, 0x2, 0x34, 0xcd, 0x3, 0x2, 0x2, 0x2, 0x36, 0xdb, 0x3, \r
+ 0x2, 0x2, 0x2, 0x38, 0xdd, 0x3, 0x2, 0x2, 0x2, 0x3a, 0xe7, 0x3, 0x2, \r
+ 0x2, 0x2, 0x3c, 0xe9, 0x3, 0x2, 0x2, 0x2, 0x3e, 0xeb, 0x3, 0x2, 0x2, \r
+ 0x2, 0x40, 0xf0, 0x3, 0x2, 0x2, 0x2, 0x42, 0xf4, 0x3, 0x2, 0x2, 0x2, \r
+ 0x44, 0xf8, 0x3, 0x2, 0x2, 0x2, 0x46, 0xfa, 0x3, 0x2, 0x2, 0x2, 0x48, \r
+ 0xfc, 0x3, 0x2, 0x2, 0x2, 0x4a, 0xfe, 0x3, 0x2, 0x2, 0x2, 0x4c, 0x4e, \r
+ 0x5, 0x4, 0x3, 0x2, 0x4d, 0x4c, 0x3, 0x2, 0x2, 0x2, 0x4e, 0x4f, 0x3, \r
+ 0x2, 0x2, 0x2, 0x4f, 0x4d, 0x3, 0x2, 0x2, 0x2, 0x4f, 0x50, 0x3, 0x2, \r
+ 0x2, 0x2, 0x50, 0x51, 0x3, 0x2, 0x2, 0x2, 0x51, 0x52, 0x7, 0x2, 0x2, \r
+ 0x3, 0x52, 0x3, 0x3, 0x2, 0x2, 0x2, 0x53, 0x57, 0x5, 0x6, 0x4, 0x2, \r
+ 0x54, 0x57, 0x5, 0xc, 0x7, 0x2, 0x55, 0x57, 0x5, 0x18, 0xd, 0x2, \r
+ 0x56, 0x53, 0x3, 0x2, 0x2, 0x2, 0x56, 0x54, 0x3, 0x2, 0x2, 0x2, 0x56, \r
+ 0x55, 0x3, 0x2, 0x2, 0x2, 0x57, 0x5, 0x3, 0x2, 0x2, 0x2, 0x58, 0x59, \r
+ 0x7, 0x3, 0x2, 0x2, 0x59, 0x5a, 0x5, 0x8, 0x5, 0x2, 0x5a, 0x7, 0x3, \r
+ 0x2, 0x2, 0x2, 0x5b, 0x5c, 0x5, 0x46, 0x24, 0x2, 0x5c, 0x5d, 0x7, \r
+ 0x4, 0x2, 0x2, 0x5d, 0x5e, 0x5, 0xa, 0x6, 0x2, 0x5e, 0x61, 0x3, 0x2, \r
+ 0x2, 0x2, 0x5f, 0x60, 0x7, 0x5, 0x2, 0x2, 0x60, 0x62, 0x5, 0x2e, \r
+ 0x18, 0x2, 0x61, 0x5f, 0x3, 0x2, 0x2, 0x2, 0x61, 0x62, 0x3, 0x2, \r
+ 0x2, 0x2, 0x62, 0x9, 0x3, 0x2, 0x2, 0x2, 0x63, 0x64, 0x5, 0x48, 0x25, \r
+ 0x2, 0x64, 0xb, 0x3, 0x2, 0x2, 0x2, 0x65, 0x66, 0x7, 0x6, 0x2, 0x2, \r
+ 0x66, 0x67, 0x5, 0xe, 0x8, 0x2, 0x67, 0xd, 0x3, 0x2, 0x2, 0x2, 0x68, \r
+ 0x69, 0x5, 0x44, 0x23, 0x2, 0x69, 0x6a, 0x7, 0x7, 0x2, 0x2, 0x6a, \r
+ 0x6b, 0x5, 0x10, 0x9, 0x2, 0x6b, 0x6c, 0x7, 0x8, 0x2, 0x2, 0x6c, \r
+ 0x6d, 0x7, 0x4, 0x2, 0x2, 0x6d, 0x6e, 0x5, 0xa, 0x6, 0x2, 0x6e, 0x6f, \r
+ 0x3, 0x2, 0x2, 0x2, 0x6f, 0x70, 0x5, 0x16, 0xc, 0x2, 0x70, 0xf, 0x3, \r
+ 0x2, 0x2, 0x2, 0x71, 0x75, 0x5, 0x12, 0xa, 0x2, 0x72, 0x74, 0x5, \r
+ 0x14, 0xb, 0x2, 0x73, 0x72, 0x3, 0x2, 0x2, 0x2, 0x74, 0x77, 0x3, \r
+ 0x2, 0x2, 0x2, 0x75, 0x73, 0x3, 0x2, 0x2, 0x2, 0x75, 0x76, 0x3, 0x2, \r
+ 0x2, 0x2, 0x76, 0x79, 0x3, 0x2, 0x2, 0x2, 0x77, 0x75, 0x3, 0x2, 0x2, \r
+ 0x2, 0x78, 0x71, 0x3, 0x2, 0x2, 0x2, 0x78, 0x79, 0x3, 0x2, 0x2, 0x2, \r
+ 0x79, 0x11, 0x3, 0x2, 0x2, 0x2, 0x7a, 0x7b, 0x5, 0x8, 0x5, 0x2, 0x7b, \r
+ 0x13, 0x3, 0x2, 0x2, 0x2, 0x7c, 0x7d, 0x7, 0x9, 0x2, 0x2, 0x7d, 0x7e, \r
+ 0x5, 0x8, 0x5, 0x2, 0x7e, 0x15, 0x3, 0x2, 0x2, 0x2, 0x7f, 0x83, 0x7, \r
+ 0xa, 0x2, 0x2, 0x80, 0x82, 0x5, 0x20, 0x11, 0x2, 0x81, 0x80, 0x3, \r
+ 0x2, 0x2, 0x2, 0x82, 0x85, 0x3, 0x2, 0x2, 0x2, 0x83, 0x81, 0x3, 0x2, \r
+ 0x2, 0x2, 0x83, 0x84, 0x3, 0x2, 0x2, 0x2, 0x84, 0x86, 0x3, 0x2, 0x2, \r
+ 0x2, 0x85, 0x83, 0x3, 0x2, 0x2, 0x2, 0x86, 0x87, 0x7, 0xb, 0x2, 0x2, \r
+ 0x87, 0x17, 0x3, 0x2, 0x2, 0x2, 0x88, 0x89, 0x7, 0xc, 0x2, 0x2, 0x89, \r
+ 0x8a, 0x5, 0x4a, 0x26, 0x2, 0x8a, 0x8e, 0x7, 0xa, 0x2, 0x2, 0x8b, \r
+ 0x8d, 0x5, 0x1a, 0xe, 0x2, 0x8c, 0x8b, 0x3, 0x2, 0x2, 0x2, 0x8d, \r
+ 0x90, 0x3, 0x2, 0x2, 0x2, 0x8e, 0x8c, 0x3, 0x2, 0x2, 0x2, 0x8e, 0x8f, \r
+ 0x3, 0x2, 0x2, 0x2, 0x8f, 0x91, 0x3, 0x2, 0x2, 0x2, 0x90, 0x8e, 0x3, \r
+ 0x2, 0x2, 0x2, 0x91, 0x92, 0x7, 0xb, 0x2, 0x2, 0x92, 0x19, 0x3, 0x2, \r
+ 0x2, 0x2, 0x93, 0x96, 0x5, 0x1c, 0xf, 0x2, 0x94, 0x96, 0x5, 0x1e, \r
+ 0x10, 0x2, 0x95, 0x93, 0x3, 0x2, 0x2, 0x2, 0x95, 0x94, 0x3, 0x2, \r
+ 0x2, 0x2, 0x96, 0x1b, 0x3, 0x2, 0x2, 0x2, 0x97, 0x98, 0x5, 0x8, 0x5, \r
+ 0x2, 0x98, 0x1d, 0x3, 0x2, 0x2, 0x2, 0x99, 0x9a, 0x5, 0xe, 0x8, 0x2, \r
+ 0x9a, 0x1f, 0x3, 0x2, 0x2, 0x2, 0x9b, 0xa2, 0x5, 0x6, 0x4, 0x2, 0x9c, \r
+ 0xa2, 0x5, 0x22, 0x12, 0x2, 0x9d, 0xa2, 0x5, 0x26, 0x14, 0x2, 0x9e, \r
+ 0xa2, 0x5, 0x2a, 0x16, 0x2, 0x9f, 0xa2, 0x5, 0x2c, 0x17, 0x2, 0xa0, \r
+ 0xa2, 0x5, 0x2e, 0x18, 0x2, 0xa1, 0x9b, 0x3, 0x2, 0x2, 0x2, 0xa1, \r
+ 0x9c, 0x3, 0x2, 0x2, 0x2, 0xa1, 0x9d, 0x3, 0x2, 0x2, 0x2, 0xa1, 0x9e, \r
+ 0x3, 0x2, 0x2, 0x2, 0xa1, 0x9f, 0x3, 0x2, 0x2, 0x2, 0xa1, 0xa0, 0x3, \r
+ 0x2, 0x2, 0x2, 0xa2, 0x21, 0x3, 0x2, 0x2, 0x2, 0xa3, 0xa4, 0x5, 0x24, \r
+ 0x13, 0x2, 0xa4, 0x23, 0x3, 0x2, 0x2, 0x2, 0xa5, 0xa6, 0x7, 0xd, \r
+ 0x2, 0x2, 0xa6, 0xa7, 0x5, 0x2e, 0x18, 0x2, 0xa7, 0xa8, 0x5, 0x16, \r
+ 0xc, 0x2, 0xa8, 0x25, 0x3, 0x2, 0x2, 0x2, 0xa9, 0xaa, 0x5, 0x28, \r
+ 0x15, 0x2, 0xaa, 0x27, 0x3, 0x2, 0x2, 0x2, 0xab, 0xac, 0x7, 0xe, \r
+ 0x2, 0x2, 0xac, 0xad, 0x5, 0x2e, 0x18, 0x2, 0xad, 0xae, 0x5, 0x16, \r
+ 0xc, 0x2, 0xae, 0x29, 0x3, 0x2, 0x2, 0x2, 0xaf, 0xb0, 0x5, 0x3a, \r
+ 0x1e, 0x2, 0xb0, 0xb1, 0x7, 0x5, 0x2, 0x2, 0xb1, 0xb2, 0x5, 0x2e, \r
+ 0x18, 0x2, 0xb2, 0x2b, 0x3, 0x2, 0x2, 0x2, 0xb3, 0xb4, 0x7, 0xf, \r
+ 0x2, 0x2, 0xb4, 0xb5, 0x5, 0x2e, 0x18, 0x2, 0xb5, 0x2d, 0x3, 0x2, \r
+ 0x2, 0x2, 0xb6, 0xbe, 0x5, 0x34, 0x1b, 0x2, 0xb7, 0xbe, 0x5, 0x3c, \r
+ 0x1f, 0x2, 0xb8, 0xbe, 0x5, 0x3a, 0x1e, 0x2, 0xb9, 0xbe, 0x5, 0x3e, \r
+ 0x20, 0x2, 0xba, 0xbe, 0x5, 0x40, 0x21, 0x2, 0xbb, 0xbe, 0x5, 0x42, \r
+ 0x22, 0x2, 0xbc, 0xbe, 0x5, 0x36, 0x1c, 0x2, 0xbd, 0xb6, 0x3, 0x2, \r
+ 0x2, 0x2, 0xbd, 0xb7, 0x3, 0x2, 0x2, 0x2, 0xbd, 0xb8, 0x3, 0x2, 0x2, \r
+ 0x2, 0xbd, 0xb9, 0x3, 0x2, 0x2, 0x2, 0xbd, 0xba, 0x3, 0x2, 0x2, 0x2, \r
+ 0xbd, 0xbb, 0x3, 0x2, 0x2, 0x2, 0xbd, 0xbc, 0x3, 0x2, 0x2, 0x2, 0xbe, \r
+ 0x2f, 0x3, 0x2, 0x2, 0x2, 0xbf, 0xc6, 0x5, 0x34, 0x1b, 0x2, 0xc0, \r
+ 0xc6, 0x5, 0x3c, 0x1f, 0x2, 0xc1, 0xc6, 0x5, 0x3a, 0x1e, 0x2, 0xc2, \r
+ 0xc6, 0x5, 0x3e, 0x20, 0x2, 0xc3, 0xc6, 0x5, 0x40, 0x21, 0x2, 0xc4, \r
+ 0xc6, 0x5, 0x42, 0x22, 0x2, 0xc5, 0xbf, 0x3, 0x2, 0x2, 0x2, 0xc5, \r
+ 0xc0, 0x3, 0x2, 0x2, 0x2, 0xc5, 0xc1, 0x3, 0x2, 0x2, 0x2, 0xc5, 0xc2, \r
+ 0x3, 0x2, 0x2, 0x2, 0xc5, 0xc3, 0x3, 0x2, 0x2, 0x2, 0xc5, 0xc4, 0x3, \r
+ 0x2, 0x2, 0x2, 0xc6, 0x31, 0x3, 0x2, 0x2, 0x2, 0xc7, 0xcc, 0x5, 0x34, \r
+ 0x1b, 0x2, 0xc8, 0xcc, 0x5, 0x3a, 0x1e, 0x2, 0xc9, 0xcc, 0x5, 0x40, \r
+ 0x21, 0x2, 0xca, 0xcc, 0x5, 0x42, 0x22, 0x2, 0xcb, 0xc7, 0x3, 0x2, \r
+ 0x2, 0x2, 0xcb, 0xc8, 0x3, 0x2, 0x2, 0x2, 0xcb, 0xc9, 0x3, 0x2, 0x2, \r
+ 0x2, 0xcb, 0xca, 0x3, 0x2, 0x2, 0x2, 0xcc, 0x33, 0x3, 0x2, 0x2, 0x2, \r
+ 0xcd, 0xce, 0x5, 0x44, 0x23, 0x2, 0xce, 0xd7, 0x7, 0x7, 0x2, 0x2, \r
+ 0xcf, 0xd4, 0x5, 0x2e, 0x18, 0x2, 0xd0, 0xd1, 0x7, 0x9, 0x2, 0x2, \r
+ 0xd1, 0xd3, 0x5, 0x2e, 0x18, 0x2, 0xd2, 0xd0, 0x3, 0x2, 0x2, 0x2, \r
+ 0xd3, 0xd6, 0x3, 0x2, 0x2, 0x2, 0xd4, 0xd2, 0x3, 0x2, 0x2, 0x2, 0xd4, \r
+ 0xd5, 0x3, 0x2, 0x2, 0x2, 0xd5, 0xd8, 0x3, 0x2, 0x2, 0x2, 0xd6, 0xd4, \r
+ 0x3, 0x2, 0x2, 0x2, 0xd7, 0xcf, 0x3, 0x2, 0x2, 0x2, 0xd7, 0xd8, 0x3, \r
+ 0x2, 0x2, 0x2, 0xd8, 0xd9, 0x3, 0x2, 0x2, 0x2, 0xd9, 0xda, 0x7, 0x8, \r
+ 0x2, 0x2, 0xda, 0x35, 0x3, 0x2, 0x2, 0x2, 0xdb, 0xdc, 0x5, 0x38, \r
+ 0x1d, 0x2, 0xdc, 0x37, 0x3, 0x2, 0x2, 0x2, 0xdd, 0xde, 0x5, 0x30, \r
+ 0x19, 0x2, 0xde, 0xdf, 0x7, 0x13, 0x2, 0x2, 0xdf, 0xe4, 0x5, 0x30, \r
+ 0x19, 0x2, 0xe0, 0xe1, 0x7, 0x13, 0x2, 0x2, 0xe1, 0xe3, 0x5, 0x30, \r
+ 0x19, 0x2, 0xe2, 0xe0, 0x3, 0x2, 0x2, 0x2, 0xe3, 0xe6, 0x3, 0x2, \r
+ 0x2, 0x2, 0xe4, 0xe2, 0x3, 0x2, 0x2, 0x2, 0xe4, 0xe5, 0x3, 0x2, 0x2, \r
+ 0x2, 0xe5, 0x39, 0x3, 0x2, 0x2, 0x2, 0xe6, 0xe4, 0x3, 0x2, 0x2, 0x2, \r
+ 0xe7, 0xe8, 0x5, 0x46, 0x24, 0x2, 0xe8, 0x3b, 0x3, 0x2, 0x2, 0x2, \r
+ 0xe9, 0xea, 0x7, 0x14, 0x2, 0x2, 0xea, 0x3d, 0x3, 0x2, 0x2, 0x2, \r
+ 0xeb, 0xec, 0x5, 0x32, 0x1a, 0x2, 0xec, 0xed, 0x7, 0x10, 0x2, 0x2, \r
+ 0xed, 0xee, 0x5, 0x2e, 0x18, 0x2, 0xee, 0xef, 0x7, 0x11, 0x2, 0x2, \r
+ 0xef, 0x3f, 0x3, 0x2, 0x2, 0x2, 0xf0, 0xf1, 0x5, 0x3a, 0x1e, 0x2, \r
+ 0xf1, 0xf2, 0x7, 0x12, 0x2, 0x2, 0xf2, 0xf3, 0x5, 0x3a, 0x1e, 0x2, \r
+ 0xf3, 0x41, 0x3, 0x2, 0x2, 0x2, 0xf4, 0xf5, 0x7, 0x7, 0x2, 0x2, 0xf5, \r
+ 0xf6, 0x5, 0x2e, 0x18, 0x2, 0xf6, 0xf7, 0x7, 0x8, 0x2, 0x2, 0xf7, \r
+ 0x43, 0x3, 0x2, 0x2, 0x2, 0xf8, 0xf9, 0x7, 0x15, 0x2, 0x2, 0xf9, \r
+ 0x45, 0x3, 0x2, 0x2, 0x2, 0xfa, 0xfb, 0x7, 0x15, 0x2, 0x2, 0xfb, \r
+ 0x47, 0x3, 0x2, 0x2, 0x2, 0xfc, 0xfd, 0x7, 0x15, 0x2, 0x2, 0xfd, \r
+ 0x49, 0x3, 0x2, 0x2, 0x2, 0xfe, 0xff, 0x7, 0x15, 0x2, 0x2, 0xff, \r
+ 0x4b, 0x3, 0x2, 0x2, 0x2, 0x11, 0x4f, 0x56, 0x61, 0x75, 0x78, 0x83, \r
+ 0x8e, 0x95, 0xa1, 0xbd, 0xc5, 0xcb, 0xd4, 0xd7, 0xe4, \r
+ };\r
+\r
+ _serializedATN.insert(_serializedATN.end(), serializedATNSegment0,\r
+ serializedATNSegment0 + sizeof(serializedATNSegment0) / sizeof(serializedATNSegment0[0]));\r
+\r
+\r
+ atn::ATNDeserializer deserializer;\r
+ _atn = deserializer.deserialize(_serializedATN);\r
+\r
+ size_t count = _atn.getNumberOfDecisions();\r
+ _decisionToDFA.reserve(count);\r
+ for (size_t i = 0; i < count; i++) { \r
+ _decisionToDFA.emplace_back(_atn.getDecisionState(i), i);\r
+ }\r
+}\r
+\r
+TocParser::Initializer TocParser::_init;\r
--- /dev/null
+\r
+// Generated from Toc.g4 by ANTLR 4.9.2\r
+\r
+#pragma once\r
+\r
+\r
+#include "antlr4-runtime.h"\r
+\r
+\r
+\r
+\r
+class TocParser : public antlr4::Parser {\r
+public:\r
+ enum {\r
+ T__0 = 1, T__1 = 2, T__2 = 3, T__3 = 4, T__4 = 5, T__5 = 6, T__6 = 7, \r
+ T__7 = 8, T__8 = 9, T__9 = 10, T__10 = 11, T__11 = 12, T__12 = 13, T__13 = 14, \r
+ T__14 = 15, T__15 = 16, BINARY_OPERATOR = 17, INTLIT = 18, NAME = 19, \r
+ WS = 20, NEWLINE = 21\r
+ };\r
+\r
+ enum {\r
+ RuleProg = 0, RuleDecl = 1, RuleVarDecl = 2, RuleVar = 3, RuleType = 4, \r
+ RuleFuncDecl = 5, RuleFunc = 6, RuleParameter = 7, RuleFirstParameter = 8, \r
+ RuleAdditionalParameter = 9, RuleBody = 10, RuleStructDecl = 11, RuleStructMember = 12, \r
+ RuleStructVar = 13, RuleStructMethod = 14, RuleStmt = 15, RuleConditional = 16, \r
+ RuleIfCond = 17, RuleLoop = 18, RuleWhileLoop = 19, RuleAssignment = 20, \r
+ RuleReturnStmt = 21, RuleExpr = 22, RuleNonOpExpr = 23, RuleNonSubscriptExpr = 24, \r
+ RuleFuncCall = 25, RuleOperatorExpr = 26, RuleBinaryOperator = 27, RuleIdentifier = 28, \r
+ RuleLiteral = 29, RuleSubscript = 30, RuleMemberAccess = 31, RuleParenExpr = 32, \r
+ RuleFuncName = 33, RuleVarName = 34, RuleTypeName = 35, RuleStructName = 36\r
+ };\r
+\r
+ explicit TocParser(antlr4::TokenStream *input);\r
+ ~TocParser();\r
+\r
+ virtual std::string getGrammarFileName() const override;\r
+ virtual const antlr4::atn::ATN& getATN() const override { return _atn; };\r
+ virtual const std::vector<std::string>& getTokenNames() const override { return _tokenNames; }; // deprecated: use vocabulary instead.\r
+ virtual const std::vector<std::string>& getRuleNames() const override;\r
+ virtual antlr4::dfa::Vocabulary& getVocabulary() const override;\r
+\r
+\r
+ class ProgContext;\r
+ class DeclContext;\r
+ class VarDeclContext;\r
+ class VarContext;\r
+ class TypeContext;\r
+ class FuncDeclContext;\r
+ class FuncContext;\r
+ class ParameterContext;\r
+ class FirstParameterContext;\r
+ class AdditionalParameterContext;\r
+ class BodyContext;\r
+ class StructDeclContext;\r
+ class StructMemberContext;\r
+ class StructVarContext;\r
+ class StructMethodContext;\r
+ class StmtContext;\r
+ class ConditionalContext;\r
+ class IfCondContext;\r
+ class LoopContext;\r
+ class WhileLoopContext;\r
+ class AssignmentContext;\r
+ class ReturnStmtContext;\r
+ class ExprContext;\r
+ class NonOpExprContext;\r
+ class NonSubscriptExprContext;\r
+ class FuncCallContext;\r
+ class OperatorExprContext;\r
+ class BinaryOperatorContext;\r
+ class IdentifierContext;\r
+ class LiteralContext;\r
+ class SubscriptContext;\r
+ class MemberAccessContext;\r
+ class ParenExprContext;\r
+ class FuncNameContext;\r
+ class VarNameContext;\r
+ class TypeNameContext;\r
+ class StructNameContext; \r
+\r
+ class ProgContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ProgContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *EOF();\r
+ std::vector<DeclContext *> decl();\r
+ DeclContext* decl(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ProgContext* prog();\r
+\r
+ class DeclContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ DeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarDeclContext *varDecl();\r
+ FuncDeclContext *funcDecl();\r
+ StructDeclContext *structDecl();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ DeclContext* decl();\r
+\r
+ class VarDeclContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ VarDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarContext *var();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ VarDeclContext* varDecl();\r
+\r
+ class VarContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ VarContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarNameContext *varName();\r
+ TypeContext *type();\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ VarContext* var();\r
+\r
+ class TypeContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ TypeContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ TypeNameContext *typeName();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ TypeContext* type();\r
+\r
+ class FuncDeclContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ FuncDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncContext *func();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ FuncDeclContext* funcDecl();\r
+\r
+ class FuncContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ FuncContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncNameContext *funcName();\r
+ ParameterContext *parameter();\r
+ BodyContext *body();\r
+ TypeContext *type();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ FuncContext* func();\r
+\r
+ class ParameterContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ParameterContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FirstParameterContext *firstParameter();\r
+ std::vector<AdditionalParameterContext *> additionalParameter();\r
+ AdditionalParameterContext* additionalParameter(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ParameterContext* parameter();\r
+\r
+ class FirstParameterContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ FirstParameterContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarContext *var();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ FirstParameterContext* firstParameter();\r
+\r
+ class AdditionalParameterContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ AdditionalParameterContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarContext *var();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ AdditionalParameterContext* additionalParameter();\r
+\r
+ class BodyContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ BodyContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ std::vector<StmtContext *> stmt();\r
+ StmtContext* stmt(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ BodyContext* body();\r
+\r
+ class StructDeclContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StructDeclContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ StructNameContext *structName();\r
+ std::vector<StructMemberContext *> structMember();\r
+ StructMemberContext* structMember(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StructDeclContext* structDecl();\r
+\r
+ class StructMemberContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StructMemberContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ StructVarContext *structVar();\r
+ StructMethodContext *structMethod();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StructMemberContext* structMember();\r
+\r
+ class StructVarContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StructVarContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarContext *var();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StructVarContext* structVar();\r
+\r
+ class StructMethodContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StructMethodContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncContext *func();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StructMethodContext* structMethod();\r
+\r
+ class StmtContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarDeclContext *varDecl();\r
+ ConditionalContext *conditional();\r
+ LoopContext *loop();\r
+ AssignmentContext *assignment();\r
+ ReturnStmtContext *returnStmt();\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StmtContext* stmt();\r
+\r
+ class ConditionalContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ConditionalContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ IfCondContext *ifCond();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ConditionalContext* conditional();\r
+\r
+ class IfCondContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ IfCondContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ ExprContext *expr();\r
+ BodyContext *body();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ IfCondContext* ifCond();\r
+\r
+ class LoopContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ LoopContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ WhileLoopContext *whileLoop();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ LoopContext* loop();\r
+\r
+ class WhileLoopContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ WhileLoopContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ ExprContext *expr();\r
+ BodyContext *body();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ WhileLoopContext* whileLoop();\r
+\r
+ class AssignmentContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ AssignmentContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ IdentifierContext *identifier();\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ AssignmentContext* assignment();\r
+\r
+ class ReturnStmtContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ReturnStmtContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ReturnStmtContext* returnStmt();\r
+\r
+ class ExprContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ExprContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncCallContext *funcCall();\r
+ LiteralContext *literal();\r
+ IdentifierContext *identifier();\r
+ SubscriptContext *subscript();\r
+ MemberAccessContext *memberAccess();\r
+ ParenExprContext *parenExpr();\r
+ OperatorExprContext *operatorExpr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ExprContext* expr();\r
+\r
+ class NonOpExprContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ NonOpExprContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncCallContext *funcCall();\r
+ LiteralContext *literal();\r
+ IdentifierContext *identifier();\r
+ SubscriptContext *subscript();\r
+ MemberAccessContext *memberAccess();\r
+ ParenExprContext *parenExpr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ NonOpExprContext* nonOpExpr();\r
+\r
+ class NonSubscriptExprContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ NonSubscriptExprContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncCallContext *funcCall();\r
+ IdentifierContext *identifier();\r
+ MemberAccessContext *memberAccess();\r
+ ParenExprContext *parenExpr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ NonSubscriptExprContext* nonSubscriptExpr();\r
+\r
+ class FuncCallContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ FuncCallContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ FuncNameContext *funcName();\r
+ std::vector<ExprContext *> expr();\r
+ ExprContext* expr(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ FuncCallContext* funcCall();\r
+\r
+ class OperatorExprContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ OperatorExprContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ BinaryOperatorContext *binaryOperator();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ OperatorExprContext* operatorExpr();\r
+\r
+ class BinaryOperatorContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ BinaryOperatorContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ std::vector<NonOpExprContext *> nonOpExpr();\r
+ NonOpExprContext* nonOpExpr(size_t i);\r
+ std::vector<antlr4::tree::TerminalNode *> BINARY_OPERATOR();\r
+ antlr4::tree::TerminalNode* BINARY_OPERATOR(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ BinaryOperatorContext* binaryOperator();\r
+\r
+ class IdentifierContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ IdentifierContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ VarNameContext *varName();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ IdentifierContext* identifier();\r
+\r
+ class LiteralContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ LiteralContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *INTLIT();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ LiteralContext* literal();\r
+\r
+ class SubscriptContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ SubscriptContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ NonSubscriptExprContext *nonSubscriptExpr();\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ SubscriptContext* subscript();\r
+\r
+ class MemberAccessContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ MemberAccessContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ std::vector<IdentifierContext *> identifier();\r
+ IdentifierContext* identifier(size_t i);\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ MemberAccessContext* memberAccess();\r
+\r
+ class ParenExprContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ ParenExprContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ ExprContext *expr();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ ParenExprContext* parenExpr();\r
+\r
+ class FuncNameContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ FuncNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *NAME();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ FuncNameContext* funcName();\r
+\r
+ class VarNameContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ VarNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *NAME();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ VarNameContext* varName();\r
+\r
+ class TypeNameContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ TypeNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *NAME();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ TypeNameContext* typeName();\r
+\r
+ class StructNameContext : public antlr4::ParserRuleContext {\r
+ public:\r
+ StructNameContext(antlr4::ParserRuleContext *parent, size_t invokingState);\r
+ virtual size_t getRuleIndex() const override;\r
+ antlr4::tree::TerminalNode *NAME();\r
+\r
+ virtual void enterRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ virtual void exitRule(antlr4::tree::ParseTreeListener *listener) override;\r
+ \r
+ };\r
+\r
+ StructNameContext* structName();\r
+\r
+\r
+private:\r
+ static std::vector<antlr4::dfa::DFA> _decisionToDFA;\r
+ static antlr4::atn::PredictionContextCache _sharedContextCache;\r
+ static std::vector<std::string> _ruleNames;\r
+ static std::vector<std::string> _tokenNames;\r
+\r
+ static std::vector<std::string> _literalNames;\r
+ static std::vector<std::string> _symbolicNames;\r
+ static antlr4::dfa::Vocabulary _vocabulary;\r
+ static antlr4::atn::ATN _atn;\r
+ static std::vector<uint16_t> _serializedATN;\r
+\r
+\r
+ struct Initializer {\r
+ Initializer();\r
+ };\r
+ static Initializer _init;\r
+};\r
+\r
--- /dev/null
+#include "TocBaseListener.h"\r
+\r
+#include <iostream>\r
+\r
+using namespace std;\r
+\r
+class MyListener : public TocBaseListener {\r
+ void enterVarDecl(TocParser::VarDeclContext * ctx) {\r
+ cout\r
+ << ctx->var()->type()->getText()\r
+ << " "\r
+ << ctx->var()->varName()->getText();\r
+\r
+ if (ctx->var()->expr() != nullptr) {\r
+ cout << " = ";\r
+ }\r
+ }\r
+ void exitVarDecl(TocParser::VarDeclContext * ctx) {\r
+ cout << ";" << endl;\r
+ }\r
+\r
+ void enterFuncDecl(TocParser::FuncDeclContext * ctx) {\r
+ cout\r
+ << ctx->type()->getText()\r
+ << " "\r
+ << ctx->funcName()->getText()\r
+ << "(";\r
+\r
+ if (ctx->parameter()->firstParameter() != nullptr) {\r
+ cout\r
+ << ctx->parameter()->firstParameter()->var()->type()->getText()\r
+ << " "\r
+ << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
+ }\r
+\r
+ for (auto * p : ctx->parameter()->additionalParameter()) {\r
+ cout\r
+ << ", "\r
+ << p->var()->type()->getText()\r
+ << " "\r
+ << p->var()->varName()->getText();\r
+ }\r
+\r
+ cout\r
+ << ")";\r
+ }\r
+\r
+ void enterBody(TocParser::BodyContext * ctx) {\r
+ cout\r
+ << "{" << endl;\r
+ }\r
+ void exitBody(TocParser::BodyContext * ctx) {\r
+ cout\r
+ << "}" << endl;\r
+ }\r
+\r
+ void enterIfCond(TocParser::IfCondContext * ctx) {\r
+ cout\r
+ << "if (";\r
+ enterExpr(ctx->expr());\r
+ cout\r
+ << ")";\r
+ }\r
+};
\ No newline at end of file
--- /dev/null
+#include <iostream>\r
+#include <fstream>\r
+\r
+#include "TocLexer.h"\r
+#include "TocParser.h"\r
+\r
+#include "toc.h"\r
+#include "repr.h"\r
+#include "repr_get.h"\r
+\r
+using namespace antlr4;\r
+\r
+\r
+int main(int argc, const char * argv[]) {\r
+ std::ifstream ifs("test.toc");\r
+\r
+ ANTLRInputStream input(ifs);\r
+\r
+ TocLexer lexer(&input);\r
+ CommonTokenStream tokens(&lexer);\r
+\r
+ TocParser parser(&tokens);\r
+ TocParser::ProgContext * prog = parser.prog();\r
+ tree::ParseTree * tree = prog;\r
+\r
+ if (parser.getNumberOfSyntaxErrors() > 0) {\r
+ std::cerr << "Parsing error" << std::endl;\r
+ return 1;\r
+ }\r
+\r
+ std::string s = tree->toStringTree(&parser) + "\n";\r
+\r
+ //std::cout << "Parse Tree: " << s << std::endl;\r
+\r
+ //toc(std::cout, prog);\r
+\r
+ //std::ofstream ofs("output.c");\r
+ //toc(ofs, prog);\r
+ //ofs.close();\r
+\r
+ Program prg = getProgram(prog);\r
+ std::cout << "Variables:\n";\r
+ for (auto v : prg.variables)\r
+ std::cout << " " << v.name << endl;\r
+ std::cout << "Functions:\n";\r
+ for (auto f : prg.functions)\r
+ std::cout << " " << f.name << endl;\r
+\r
+ return 0;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <vector>\r
+#include <string>\r
+#include <memory>\r
+\r
+#include "TocParser.h"\r
+\r
+using namespace std;\r
+\r
+struct Type;\r
+struct Variable;\r
+struct Body;\r
+struct Function;\r
+struct Struct;\r
+struct Program;\r
+struct CallExpr;\r
+struct LiteralExpr;\r
+struct VariableExpr;\r
+struct BracketsExpr;\r
+struct OperatorExpr;\r
+struct DotExpr;\r
+struct Expr;\r
+struct IfStmt;\r
+struct WhileStmt;\r
+struct ReturnStmt;\r
+struct AssignStmt;\r
+struct Stmt;\r
+\r
+\r
+struct Type {\r
+ std::string name;\r
+};\r
+\r
+struct Variable {\r
+ std::string name;\r
+ Type type;\r
+};\r
+\r
+struct Body {\r
+ std::vector<Variable> variables;\r
+ std::vector<Stmt> statements;\r
+};\r
+\r
+struct Function {\r
+ std::string name;\r
+ std::vector<Variable> parameters;\r
+ Body body;\r
+};\r
+\r
+struct Struct {\r
+ std::string name;\r
+ std::vector<Variable> members;\r
+ std::vector<Function> methods;\r
+};\r
+\r
+struct Program {\r
+ std::vector<Variable> variables;\r
+ std::vector<Struct> structs;\r
+ std::vector<Function> functions;\r
+};\r
+\r
+enum class ExprType {\r
+ Call, Literal, Variable, Brackets, Operator, Dot\r
+};\r
+\r
+struct CallExpr {\r
+ Function function;\r
+ std::vector<Expr> arguments;\r
+};\r
+\r
+struct LiteralExpr {\r
+ int i;\r
+};\r
+\r
+struct VariableExpr {\r
+ std::string name;\r
+};\r
+\r
+struct BracketsExpr {\r
+ BracketsExpr() {}\r
+ BracketsExpr(const BracketsExpr &) {}\r
+ BracketsExpr & operator=(const BracketsExpr &) {return *this;};\r
+ std::unique_ptr<Expr> lexpr;\r
+ std::unique_ptr<Expr> rexpr;\r
+};\r
+\r
+enum class OperatorType {\r
+ Plus, Minus, Multiply, Divide,\r
+ Equals, NotEquals,\r
+ LessThan, GreaterThan\r
+};\r
+\r
+struct OperatorExpr {\r
+ OperatorExpr() {}\r
+ OperatorExpr(const OperatorExpr &) {}\r
+ OperatorExpr & operator=(const OperatorExpr &) {return *this;};\r
+ std::unique_ptr<Expr> lexpr;\r
+ std::unique_ptr<Expr> rexpr;\r
+ OperatorType type;\r
+};\r
+\r
+struct DotExpr {\r
+ DotExpr() {}\r
+ DotExpr(const DotExpr &) {}\r
+ DotExpr & operator=(const DotExpr &) {return *this;};\r
+ std::unique_ptr<Expr> lexpr;\r
+ std::string name;\r
+};\r
+\r
+struct Expr {\r
+ ExprType type;\r
+\r
+ CallExpr _call;\r
+ LiteralExpr _literal;\r
+ VariableExpr _variable;\r
+ BracketsExpr _brackets;\r
+ OperatorExpr _operator;\r
+ DotExpr _dot;\r
+};\r
+\r
+enum class StmtType {\r
+ If, While, Return, Assign, Expr\r
+};\r
+\r
+struct IfStmt {\r
+ Expr condition;\r
+ Body body;\r
+};\r
+\r
+struct WhileStmt {\r
+ Expr condition;\r
+ Body body;\r
+};\r
+\r
+struct ReturnStmt {\r
+ Expr expr;\r
+};\r
+\r
+struct AssignStmt {\r
+ Expr lexpr;\r
+ Expr rexpr;\r
+};\r
+\r
+struct Stmt {\r
+ StmtType type;\r
+ \r
+ IfStmt _if;\r
+ WhileStmt _while;\r
+ ReturnStmt _return;\r
+ AssignStmt _assign;\r
+ Expr _expr;\r
+};\r
+\r
+\r
--- /dev/null
+#pragma once\r
+\r
+#include "repr.h"\r
+\r
+Type getType(TocParser::TypeContext * ctx);\r
+Variable getVariable(TocParser::VarContext * ctx);\r
+Body getBody(TocParser::BodyContext * ctx);\r
+Function getFunction(TocParser::FuncContext * ctx);\r
+Struct getStruct(TocParser::StructDeclContext * ctx);\r
+Program getProgram(TocParser::ProgContext * ctx);\r
+OperatorExpr getOperatorExpr(TocParser::OperatorExprContext * ctx);\r
+Expr getExpression(TocParser::ExprContext * ctx);\r
+Stmt getStmt(TocParser::StmtContext * ctx);\r
+\r
+Type getType(TocParser::TypeContext * ctx) {\r
+ Type result;\r
+ result.name = ctx->typeName()->NAME()->toString();\r
+ return result;\r
+}\r
+Variable getVariable(TocParser::VarContext * ctx) {\r
+ Variable result;\r
+ result.name = ctx->varName()->NAME()->toString();\r
+ result.type = getType(ctx->type());\r
+ return result;\r
+}\r
+Body getBody(TocParser::BodyContext * ctx) {\r
+ Body result;\r
+ for (auto s : ctx->stmt()) {\r
+ if (s->varDecl() != nullptr) {\r
+ result.variables.push_back(getVariable(s->varDecl()->var()));\r
+ }\r
+ else {\r
+ result.statements.push_back(getStmt(s));\r
+ }\r
+ }\r
+ return result;\r
+}\r
+Function getFunction(TocParser::FuncContext * ctx) {\r
+ Function result;\r
+ result.name = ctx->funcName()->NAME()->toString();\r
+ if (ctx->parameter()->firstParameter() != nullptr) {\r
+ result.parameters.push_back(getVariable(ctx->parameter()->firstParameter()->var()));\r
+ for (auto p : ctx->parameter()->additionalParameter())\r
+ result.parameters.push_back(getVariable(p->var()));\r
+ }\r
+ result.body = getBody(ctx->body());\r
+ return result;\r
+}\r
+Struct getStruct(TocParser::StructDeclContext * ctx) {\r
+ Struct result;\r
+ result.name = ctx->structName()->NAME()->toString();\r
+ for (auto m : ctx->structMember()) {\r
+ if (m->structVar() != nullptr) {\r
+ result.members.push_back(getVariable(m->structVar()->var()));\r
+ }\r
+ if (m->structMethod() != nullptr) {\r
+ result.methods.push_back(getFunction(m->structMethod()->func()));\r
+ }\r
+ }\r
+ return result;\r
+}\r
+Program getProgram(TocParser::ProgContext * ctx) {\r
+ Program result;\r
+ for (auto d : ctx->decl()) {\r
+ if (d->varDecl() != nullptr) {\r
+ result.variables.push_back(getVariable(d->varDecl()->var()));\r
+ }\r
+ if (d->funcDecl() != nullptr) {\r
+ result.functions.push_back(getFunction(d->funcDecl()->func()));\r
+ }\r
+ if (d->structDecl() != nullptr) {\r
+ result.structs.push_back(getStruct(d->structDecl()));\r
+ }\r
+ }\r
+ return result;\r
+}\r
+OperatorExpr getOperatorExpr(TocParser::OperatorExprContext * ctx) {\r
+ OperatorExpr result;\r
+ //result.lexpr = getExpr(ctx->binaryOperator()->nonOpExpr(0));\r
+ //result.rexpr = getExpr(ctx->binaryOperator()->nonOpExpr(1));\r
+ std::string op = ctx->binaryOperator()->BINARY_OPERATOR(0)->toString();\r
+ if (op == "+") result.type = OperatorType::Plus;\r
+ if (op == "-") result.type = OperatorType::Minus;\r
+ if (op == "*") result.type = OperatorType::Multiply;\r
+ if (op == "/") result.type = OperatorType::Divide;\r
+ if (op == "==") result.type = OperatorType::Equals;\r
+ if (op == "!=") result.type = OperatorType::NotEquals;\r
+ if (op == "<") result.type = OperatorType::LessThan;\r
+ if (op == ">") result.type = OperatorType::GreaterThan;\r
+ return result;\r
+}\r
+Expr getExpr(TocParser::ExprContext * ctx) {\r
+ Expr result;\r
+ if (ctx->funcCall() != nullptr) {\r
+ result.type = ExprType::Call;\r
+ for (auto e : ctx->funcCall()->expr())\r
+ result._call.arguments.push_back(getExpr(e));\r
+ //result._call.function = ctx->funcCall()->funcName();\r
+ }\r
+ if (ctx->literal() != nullptr) {\r
+ result.type = ExprType::Literal;\r
+ result._literal.i = atoi(ctx->literal()->INTLIT()->toString().c_str());\r
+ }\r
+ if (ctx->identifier() != nullptr) {\r
+ result.type = ExprType::Variable;\r
+ result._variable.name = ctx->identifier()->varName()->NAME()->toString();\r
+ }\r
+ if (ctx->subscript() != nullptr) {\r
+ result.type = ExprType::Brackets;\r
+ //result._brackets.lexpr = getExpr(ctx->subscript()->nonSubscriptExpr());\r
+ result._brackets.rexpr = std::make_unique<Expr>(getExpr(ctx->subscript()->expr()));\r
+ }\r
+ if (ctx->memberAccess() != nullptr) {\r
+ result.type = ExprType::Dot;\r
+ //result._dot.lexpr = ctx->memberAccess()->identifier(0);\r
+ result._dot.name = ctx->memberAccess()->identifier(1)->varName()->NAME()->toString();\r
+ }\r
+ if (ctx->operatorExpr() != nullptr) {\r
+ result.type = ExprType::Operator;\r
+ result._operator = getOperatorExpr(ctx->operatorExpr());\r
+ }\r
+ return result;\r
+}\r
+Stmt getStmt(TocParser::StmtContext * ctx) {\r
+ Stmt result;\r
+ if (ctx->conditional() != nullptr) {\r
+ result.type = StmtType::If;\r
+ result._if.condition = getExpr(ctx->conditional()->ifCond()->expr());\r
+ result._if.body = getBody(ctx->conditional()->ifCond()->body());\r
+ }\r
+ if (ctx->loop() != nullptr) {\r
+ result.type = StmtType::While;\r
+ result._while.condition = getExpr(ctx->loop()->whileLoop()->expr());\r
+ result._while.body = getBody(ctx->loop()->whileLoop()->body());\r
+ }\r
+ if (ctx->assignment() != nullptr) {\r
+ result.type = StmtType::Assign;\r
+ //result._assign.lexpr = getExpr(ctx->assignment()->);\r
+ result._assign.rexpr = getExpr(ctx->assignment()->expr());\r
+ }\r
+ if (ctx->returnStmt() != nullptr) {\r
+ result.type = StmtType::Return;\r
+ result._return.expr = getExpr(ctx->returnStmt()->expr());\r
+ }\r
+ if (ctx->expr() != nullptr) {\r
+ result.type = StmtType::Expr;\r
+ result._expr = getExpr(ctx->expr());\r
+ }\r
+ if (ctx->varDecl() != nullptr && ctx->varDecl()->var()->expr() != nullptr) {\r
+ result.type = StmtType::Assign;\r
+ result._assign.rexpr = getExpr(ctx->varDecl()->var()->expr());\r
+ }\r
+ return result;\r
+}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <iostream>\r
+\r
+#include "TocParser.h"\r
+\r
+void toc(std::ostream & o, TocParser::ProgContext * ctx);\r
+void toc(std::ostream & o, TocParser::VarDeclContext * ctx);\r
+void toc(std::ostream & o, TocParser::FuncContext * ctx);\r
+void toc(std::ostream & o, TocParser::StructDeclContext * ctx);\r
+void toc(std::ostream & o, TocParser::BodyContext * ctx);\r
+void toc(std::ostream & o, TocParser::StmtContext * ctx);\r
+void toc(std::ostream & o, TocParser::IfCondContext * ctx);\r
+void toc(std::ostream & o, TocParser::WhileLoopContext * ctx);\r
+void toc(std::ostream & o, TocParser::AssignmentContext * ctx);\r
+void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx);\r
+void toc(std::ostream & o, TocParser::ExprContext * ctx);\r
+void toc(std::ostream & o, TocParser::NonOpExprContext * ctx);\r
+void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx);\r
+void toc(std::ostream & o, TocParser::FuncCallContext * ctx);\r
+void toc(std::ostream & o, TocParser::IdentifierContext * ctx);\r
+void toc(std::ostream & o, TocParser::LiteralContext * ctx);\r
+void toc(std::ostream & o, TocParser::SubscriptContext * ctx);\r
+void toc(std::ostream & o, TocParser::MemberAccessContext * ctx);\r
+void toc(std::ostream & o, TocParser::ParenExprContext * ctx);\r
+void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx);\r
+\r
+void toc_stub(std::ostream & o, TocParser::FuncContext * ctx);\r
+void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx);\r
+\r
+\r
+void toc(std::ostream & o, TocParser::ProgContext * ctx) {\r
+ for (auto * decl : ctx->decl()) {\r
+ /**/ if (decl->structDecl() != nullptr) toc_stub(o, decl->structDecl());\r
+ else if (decl->funcDecl() != nullptr) toc_stub(o, decl->funcDecl()->func());\r
+ }\r
+ for (auto * decl : ctx->decl()) {\r
+ if (decl->varDecl() != nullptr) {\r
+ toc(o, decl->varDecl());\r
+ o << ";\n";\r
+ }\r
+ else if (decl->structDecl() != nullptr) toc(o, decl->structDecl());\r
+ else if (decl->funcDecl() != nullptr) toc(o, decl->funcDecl()->func());\r
+ }\r
+}\r
+void toc(std::ostream & o, TocParser::VarDeclContext * ctx) {\r
+ o\r
+ << ctx->var()->type()->getText()\r
+ << " "\r
+ << ctx->var()->varName()->getText();\r
+ \r
+ if (ctx->var()->expr() != nullptr) {\r
+ o << " = ";\r
+ toc(o, ctx->var()->expr());\r
+ }\r
+}\r
+void toc(std::ostream & o, TocParser::FuncContext * ctx) {\r
+ o\r
+ << ctx->type()->getText()\r
+ << " "\r
+ << ctx->funcName()->getText()\r
+ << "(";\r
+\r
+ if (ctx->parameter()->firstParameter() != nullptr) {\r
+ o\r
+ << ctx->parameter()->firstParameter()->var()->type()->getText()\r
+ << " "\r
+ << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
+\r
+ for (auto * par : ctx->parameter()->additionalParameter()) {\r
+ o\r
+ << ", "\r
+ << par->var()->type()->getText()\r
+ << " "\r
+ << par->var()->varName()->getText();\r
+ }\r
+ }\r
+\r
+ o << ")\n{\n";\r
+\r
+ toc(o, ctx->body());\r
+\r
+ o << "}\n";\r
+}\r
+void toc(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
+ o\r
+ << "typedef struct "\r
+ << ctx->structName()->getText()\r
+ << "\n{\n";\r
+\r
+ for (auto * member : ctx->structMember()) {\r
+ if (member->structVar() != nullptr) {\r
+ o\r
+ << member->structVar()->var()->type()->getText()\r
+ << " "\r
+ << member->structVar()->var()->varName()->getText()\r
+ << ";\n";\r
+ }\r
+ }\r
+ o << "} "\r
+ << ctx->structName()->getText()\r
+ << ";\n";\r
+ for (auto * member : ctx->structMember()) {\r
+ if (member->structMethod() != nullptr) {\r
+ o\r
+ << member->structMethod()->func()->type()->getText()\r
+ << " "\r
+ << ctx->structName()->getText()\r
+ << "_"\r
+ << member->structMethod()->func()->funcName()->getText()\r
+ << "("\r
+ << ctx->structName()->getText()\r
+ << " * this";\r
+\r
+ if (member->structMethod()->func()->parameter()->firstParameter() != nullptr) {\r
+ o\r
+ << ", "\r
+ << member->structMethod()->func()->parameter()->firstParameter()->var()->type()->getText()\r
+ << " "\r
+ << member->structMethod()->func()->parameter()->firstParameter()->var()->varName()->getText();\r
+\r
+ for (auto * par : member->structMethod()->func()->parameter()->additionalParameter()) {\r
+ o\r
+ << ", "\r
+ << par->var()->type()->getText()\r
+ << " "\r
+ << par->var()->varName()->getText();\r
+ }\r
+ }\r
+\r
+ o << ")\n{\n";\r
+\r
+ toc(o, member->structMethod()->func()->body());\r
+\r
+ o << "}\n";\r
+ }\r
+ }\r
+}\r
+void toc(std::ostream & o, TocParser::BodyContext * ctx) {\r
+ for (auto * stmt : ctx->stmt()) {\r
+ toc(o, stmt);\r
+ o << "\n";\r
+ }\r
+}\r
+void toc(std::ostream & o, TocParser::StmtContext * ctx) {\r
+ /**/ if (ctx->varDecl() != nullptr) toc(o, ctx->varDecl());\r
+ else if (ctx->conditional() != nullptr) toc(o, ctx->conditional()->ifCond());\r
+ else if (ctx->loop() != nullptr) toc(o, ctx->loop()->whileLoop());\r
+ else if (ctx->assignment() != nullptr) toc(o, ctx->assignment());\r
+ else if (ctx->returnStmt() != nullptr) toc(o, ctx->returnStmt());\r
+ else if (ctx->expr() != nullptr) toc(o, ctx->expr());\r
+\r
+ if (ctx->conditional() == nullptr && ctx->loop() == nullptr)\r
+ o << ";";\r
+}\r
+void toc(std::ostream & o, TocParser::IfCondContext * ctx) {\r
+ o << "if (";\r
+ toc(o, ctx->expr());\r
+ o << ")\n{\n";\r
+ toc(o, ctx->body());\r
+ o << "}\n";\r
+}\r
+void toc(std::ostream & o, TocParser::WhileLoopContext * ctx) {\r
+ o << "while (";\r
+ toc(o, ctx->expr());\r
+ o << ")\n{\n";\r
+ toc(o, ctx->body());\r
+ o << "}\n";\r
+}\r
+void toc(std::ostream & o, TocParser::AssignmentContext * ctx) {\r
+ toc(o, ctx->identifier());\r
+ o << " = ";\r
+ toc(o, ctx->expr());\r
+}\r
+void toc(std::ostream & o, TocParser::ReturnStmtContext * ctx) {\r
+ o << "return ";\r
+ toc(o, ctx->expr());\r
+}\r
+void toc(std::ostream & o, TocParser::ExprContext * ctx) {\r
+ /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall());\r
+ else if (ctx->identifier() != nullptr) toc(o, ctx->identifier());\r
+ else if (ctx->literal() != nullptr) toc(o, ctx->literal());\r
+ else if (ctx->subscript() != nullptr) toc(o, ctx->subscript());\r
+ else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
+ else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr());\r
+ else if (ctx->operatorExpr() != nullptr) toc(o, ctx->operatorExpr()->binaryOperator());\r
+}\r
+void toc(std::ostream & o, TocParser::NonOpExprContext * ctx) {\r
+ /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall());\r
+ else if (ctx->identifier() != nullptr) toc(o, ctx->identifier());\r
+ else if (ctx->literal() != nullptr) toc(o, ctx->literal());\r
+ else if (ctx->subscript() != nullptr) toc(o, ctx->subscript());\r
+ else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
+ else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr());\r
+}\r
+void toc(std::ostream & o, TocParser::NonSubscriptExprContext * ctx) {\r
+ /**/ if (ctx->funcCall() != nullptr) toc(o, ctx->funcCall());\r
+ else if (ctx->identifier() != nullptr) toc(o, ctx->identifier());\r
+ else if (ctx->memberAccess() != nullptr) toc(o, ctx->memberAccess());\r
+ else if (ctx->parenExpr() != nullptr) toc(o, ctx->parenExpr());\r
+}\r
+void toc(std::ostream & o, TocParser::FuncCallContext * ctx) {\r
+ o\r
+ << ctx->funcName()->getText()\r
+ << "(";\r
+ for (int i = 0; i < ctx->expr().size(); i++) {\r
+ if (i != 0) o << ", ";\r
+ toc(o, ctx->expr(i));\r
+ }\r
+ o << ")";\r
+}\r
+void toc(std::ostream & o, TocParser::IdentifierContext * ctx) {\r
+ o << ctx->getText();\r
+}\r
+void toc(std::ostream & o, TocParser::LiteralContext * ctx) {\r
+ if (ctx->INTLIT() != nullptr) o << ctx->INTLIT()->getText();\r
+}\r
+void toc(std::ostream & o, TocParser::SubscriptContext * ctx) {\r
+ toc(o, ctx->nonSubscriptExpr());\r
+ o << "[";\r
+ toc(o, ctx->expr());\r
+ o << "]";\r
+}\r
+void toc(std::ostream & o, TocParser::MemberAccessContext * ctx) {\r
+ toc(o, ctx->identifier(0));\r
+ o << ".";\r
+ toc(o, ctx->identifier(1));\r
+}\r
+void toc(std::ostream & o, TocParser::ParenExprContext * ctx) {\r
+ o << "(";\r
+ toc(o, ctx->expr());\r
+ o << ")";\r
+}\r
+void toc(std::ostream & o, TocParser::BinaryOperatorContext * ctx) {\r
+ for (int i = 0; i < ctx->BINARY_OPERATOR().size(); i++) {\r
+ toc(o, ctx->nonOpExpr(i));\r
+ o\r
+ << " "\r
+ << ctx->BINARY_OPERATOR(i)->getText()\r
+ << " ";\r
+ toc(o, ctx->nonOpExpr(i + 1));\r
+ }\r
+}\r
+\r
+void toc_stub(std::ostream & o, TocParser::FuncContext * ctx) {\r
+ o\r
+ << ctx->type()->getText()\r
+ << " "\r
+ << ctx->funcName()->getText()\r
+ << "(";\r
+\r
+ if (ctx->parameter()->firstParameter() != nullptr) {\r
+ o\r
+ << ctx->parameter()->firstParameter()->var()->type()->getText()\r
+ << " "\r
+ << ctx->parameter()->firstParameter()->var()->varName()->getText();\r
+\r
+ for (auto * par : ctx->parameter()->additionalParameter()) {\r
+ o\r
+ << ", "\r
+ << par->var()->type()->getText()\r
+ << " "\r
+ << par->var()->varName()->getText();\r
+ }\r
+ }\r
+\r
+ o << ");\n";\r
+}\r
+void toc_stub(std::ostream & o, TocParser::StructDeclContext * ctx) {\r
+ o\r
+ << "struct "\r
+ << ctx->structName()->getText()\r
+ << ";\n";\r
+}\r
--- /dev/null
+var abc: int\r
+var def: int\r
+var ghi: int\r
+\r
+func f1 (a : int, b : int) : int {\r
+ var i1 : int\r
+ var s1 : S1\r
+ if a != i1 {\r
+ var i2 : int = 987\r
+ return i2\r
+ }\r
+ print(s1.i1)\r
+ print(s1.a1[0])\r
+ return 133\r
+}\r
+\r
+struct S1 {\r
+ i1 : int\r
+ i2 : int\r
+ a1 : intArray\r
+\r
+ m1() : void {\r
+ while i1 < i2 {\r
+ i1 = m2(i1)\r
+\r
+ i2 = (i1 + i2) * i2\r
+\r
+ print(12345)\r
+ }\r
+ }\r
+\r
+ m2(i: int) : int {\r
+ var j : int = 0\r
+ while j < 10 {\r
+ print(a1[j])\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+define grammar:\r
+- declarations\r
+ - var decl\r
+ - ptr/array\r
+ - fn decl\r
+ - struct/enum/union\r
+- statements\r
+ - if/while/for/switch\r
+ - expr\r
+ - assignment\r
+ - return\r
+- expressions\r
+ - fn call\r
+ - unary/binary/(ternary) operator\r
+ - variable "call"\r
+ - literal\r
+ - parenthesis\r
+ - array access\r
+ - .\r
+ - cast\r
+\r
+- complete grammar\r
+- semantic checks when visiting\r
+- type modifier\r
+- operator precedence\r
+- ...\r
--- /dev/null
+add_rules("mode.debug", "mode.release")\r
+\r
+target("main")\r
+ set_kind("binary")\r
+ add_files("src/main.cpp")\r
+ add_files("gen/*.cpp")\r
+ add_linkdirs(\r
+ "antlr4-cpp-runtime-4.9.2-source/install/lib"\r
+ )\r
+ add_links("antlr4-runtime")\r
+ add_includedirs(\r
+ "gen",\r
+ "antlr4-cpp-runtime-4.9.2-source/install/include/antlr4-runtime/"\r
+ )\r
+\r
+--\r
+-- If you want to known more usage about xmake, please see https://xmake.io\r
+--\r
+-- ## FAQ\r
+--\r
+-- You can enter the project directory firstly before building project.\r
+--\r
+-- $ cd projectdir\r
+--\r
+-- 1. How to build project?\r
+--\r
+-- $ xmake\r
+--\r
+-- 2. How to configure project?\r
+--\r
+-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]\r
+--\r
+-- 3. Where is the build output directory?\r
+--\r
+-- The default output directory is `./build` and you can configure the output directory.\r
+--\r
+-- $ xmake f -o outputdir\r
+-- $ xmake\r
+--\r
+-- 4. How to run and debug target after building project?\r
+--\r
+-- $ xmake run [targetname]\r
+-- $ xmake run -d [targetname]\r
+--\r
+-- 5. How to install target to the system directory or other output directory?\r
+--\r
+-- $ xmake install\r
+-- $ xmake install -o installdir\r
+--\r
+-- 6. Add some frequently-used compilation flags in xmake.lua\r
+--\r
+-- @code\r
+-- -- add debug and release modes\r
+-- add_rules("mode.debug", "mode.release")\r
+--\r
+-- -- add macro defination\r
+-- add_defines("NDEBUG", "_GNU_SOURCE=1")\r
+--\r
+-- -- set warning all as error\r
+-- set_warnings("all", "error")\r
+--\r
+-- -- set language: c99, c++11\r
+-- set_languages("c99", "c++11")\r
+--\r
+-- -- set optimization: none, faster, fastest, smallest\r
+-- set_optimize("fastest")\r
+--\r
+-- -- add include search directories\r
+-- add_includedirs("/usr/include", "/usr/local/include")\r
+--\r
+-- -- add link libraries and search directories\r
+-- add_links("tbox")\r
+-- add_linkdirs("/usr/local/lib", "/usr/lib")\r
+--\r
+-- -- add system link libraries\r
+-- add_syslinks("z", "pthread")\r
+--\r
+-- -- add compilation and link flags\r
+-- add_cxflags("-stdnolib", "-fno-strict-aliasing")\r
+-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})\r
+--\r
+-- @endcode\r
+--\r
+\r