add antlr
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,3 +1,6 @@
|
|||||||
|
.antlr/
|
||||||
|
build/
|
||||||
|
|
||||||
# Prerequisites
|
# Prerequisites
|
||||||
*.d
|
*.d
|
||||||
|
|
||||||
@@ -31,8 +34,6 @@
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
build/
|
|
||||||
|
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeCache.txt
|
CMakeCache.txt
|
||||||
CMakeFiles
|
CMakeFiles
|
||||||
|
18
.vscode/c_cpp_properties.json
vendored
Normal file
18
.vscode/c_cpp_properties.json
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/include",
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/lib64/ccache/clang",
|
||||||
|
"cStandard": "c11",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"intelliSenseMode": "clang-x64",
|
||||||
|
"configurationProvider": "ms-vscode.cmake-tools"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@@ -1,3 +1,10 @@
|
|||||||
{
|
{
|
||||||
"cmake.configureOnOpen": true
|
"cmake.configureOnOpen": true,
|
||||||
|
"antlr4.generation": {
|
||||||
|
"mode": "external",
|
||||||
|
"language": "Cpp",
|
||||||
|
"listeners": true,
|
||||||
|
"visitors": true,
|
||||||
|
"outputDir": "../lib/generated"
|
||||||
|
}
|
||||||
}
|
}
|
@@ -9,11 +9,21 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
src/main.cpp
|
src/main.cpp
|
||||||
|
lib/generated/bfLexer.cpp
|
||||||
|
lib/generated/bfParser.cpp
|
||||||
|
lib/generated/bfBaseVisitor.cpp
|
||||||
|
lib/generated/bfVisitor.cpp
|
||||||
|
lib/generated/bfBaseListener.cpp
|
||||||
|
lib/generated/bfListener.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(main.out ${SOURCES})
|
add_executable(main.out ${SOURCES})
|
||||||
|
|
||||||
|
target_link_libraries(main.out ${PROJECT_SOURCE_DIR}/lib/antlr4/lib/libantlr4-runtime.a)
|
||||||
|
|
||||||
target_include_directories(main.out
|
target_include_directories(main.out
|
||||||
PRIVATE
|
PRIVATE
|
||||||
${PROJECT_SOURCE_DIR}/include
|
${PROJECT_SOURCE_DIR}/include
|
||||||
|
${PROJECT_SOURCE_DIR}/lib/antlr4/include
|
||||||
|
${PROJECT_SOURCE_DIR}/lib/generated
|
||||||
|
|
||||||
)
|
)
|
||||||
|
13
grammar/bf.g4
Normal file
13
grammar/bf.g4
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
grammar bf;
|
||||||
|
|
||||||
|
program: statements;
|
||||||
|
|
||||||
|
statements: INC | DEC | INPUT|OUTPUT;
|
||||||
|
|
||||||
|
COMMENT: '\\\\.*?\\\\' -> skip;
|
||||||
|
INPUT: '?';
|
||||||
|
OUTPUT: '.';
|
||||||
|
DEC: '-';
|
||||||
|
INC: '+';
|
||||||
|
LEFT: '>';
|
||||||
|
RIGHT: '<';
|
3
include/main.hpp
Normal file
3
include/main.hpp
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#ifndef __MAIN_HPP
|
||||||
|
#define FIVE 5
|
||||||
|
#endif
|
167
lib/antlr4/include/ANTLRErrorListener.h
Normal file
167
lib/antlr4/include/ANTLRErrorListener.h
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/* 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
|
121
lib/antlr4/include/ANTLRErrorStrategy.h
Normal file
121
lib/antlr4/include/ANTLRErrorStrategy.h
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
/* 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
|
27
lib/antlr4/include/ANTLRFileStream.h
Normal file
27
lib/antlr4/include/ANTLRFileStream.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* 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 {
|
||||||
|
protected:
|
||||||
|
std::string _fileName; // UTF-8 encoded file name.
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Assumes a file name encoded in UTF-8 and file content in the same encoding (with or w/o BOM).
|
||||||
|
ANTLRFileStream(const std::string &fileName);
|
||||||
|
|
||||||
|
virtual void loadFromFile(const std::string &fileName);
|
||||||
|
virtual std::string getSourceName() const override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace antlr4
|
69
lib/antlr4/include/ANTLRInputStream.h
Normal file
69
lib/antlr4/include/ANTLRInputStream.h
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/* 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(const std::string &input = "");
|
||||||
|
ANTLRInputStream(const char data_[], size_t numberOfActualCharsInArray);
|
||||||
|
ANTLRInputStream(std::istream &stream);
|
||||||
|
|
||||||
|
virtual void load(const std::string &input);
|
||||||
|
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
|
59
lib/antlr4/include/BailErrorStrategy.h
Normal file
59
lib/antlr4/include/BailErrorStrategy.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/* 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
|
36
lib/antlr4/include/BaseErrorListener.h
Normal file
36
lib/antlr4/include/BaseErrorListener.h
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/* 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
|
200
lib/antlr4/include/BufferedTokenStream.h
Normal file
200
lib/antlr4/include/BufferedTokenStream.h
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
/* 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
|
37
lib/antlr4/include/CharStream.h
Normal file
37
lib/antlr4/include/CharStream.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/* 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
|
158
lib/antlr4/include/CommonToken.h
Normal file
158
lib/antlr4/include/CommonToken.h
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
/* 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
|
74
lib/antlr4/include/CommonTokenFactory.h
Normal file
74
lib/antlr4/include/CommonTokenFactory.h
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
/* 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 Ref<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
|
79
lib/antlr4/include/CommonTokenStream.h
Normal file
79
lib/antlr4/include/CommonTokenStream.h
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
/* 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
|
35
lib/antlr4/include/ConsoleErrorListener.h
Normal file
35
lib/antlr4/include/ConsoleErrorListener.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* 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
|
466
lib/antlr4/include/DefaultErrorStrategy.h
Normal file
466
lib/antlr4/include/DefaultErrorStrategy.h
Normal file
@@ -0,0 +1,466 @@
|
|||||||
|
/* 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
|
80
lib/antlr4/include/DiagnosticErrorListener.h
Normal file
80
lib/antlr4/include/DiagnosticErrorListener.h
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
/* 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
|
99
lib/antlr4/include/Exceptions.h
Normal file
99
lib/antlr4/include/Exceptions.h
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
/* 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
|
32
lib/antlr4/include/FailedPredicateException.h
Normal file
32
lib/antlr4/include/FailedPredicateException.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* 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
|
24
lib/antlr4/include/InputMismatchException.h
Normal file
24
lib/antlr4/include/InputMismatchException.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* 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
|
218
lib/antlr4/include/IntStream.h
Normal file
218
lib/antlr4/include/IntStream.h
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t EOF = static_cast<size_t>(-1); // std::numeric_limits<size_t>::max(); doesn't work in VS 2013
|
||||||
|
|
||||||
|
/// 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
|
45
lib/antlr4/include/InterpreterRuleContext.h
Normal file
45
lib/antlr4/include/InterpreterRuleContext.h
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* 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
|
196
lib/antlr4/include/Lexer.h
Normal file
196
lib/antlr4/include/Lexer.h
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t DEFAULT_MODE = 0;
|
||||||
|
static const size_t MORE = static_cast<size_t>(-2);
|
||||||
|
static const size_t SKIP = static_cast<size_t>(-3);
|
||||||
|
|
||||||
|
static const size_t DEFAULT_TOKEN_CHANNEL = Token::DEFAULT_CHANNEL;
|
||||||
|
static const size_t HIDDEN = Token::HIDDEN_CHANNEL;
|
||||||
|
static const size_t MIN_CHAR_VALUE = 0;
|
||||||
|
static const size_t MAX_CHAR_VALUE = 0x10FFFF;
|
||||||
|
|
||||||
|
CharStream *_input; // Pure reference, usually from statically allocated instance.
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// How to create token objects.
|
||||||
|
Ref<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 Ref<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
|
52
lib/antlr4/include/LexerInterpreter.h
Normal file
52
lib/antlr4/include/LexerInterpreter.h
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/* 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
|
31
lib/antlr4/include/LexerNoViableAltException.h
Normal file
31
lib/antlr4/include/LexerNoViableAltException.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* 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
|
88
lib/antlr4/include/ListTokenSource.h
Normal file
88
lib/antlr4/include/ListTokenSource.h
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
/* 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"/>.
|
||||||
|
Ref<TokenFactory<CommonToken>> _factory = CommonTokenFactory::DEFAULT;
|
||||||
|
|
||||||
|
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 Ref<TokenFactory<CommonToken>> getTokenFactory() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitializeInstanceFields();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace antlr4
|
42
lib/antlr4/include/NoViableAltException.h
Normal file
42
lib/antlr4/include/NoViableAltException.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* 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
|
467
lib/antlr4/include/Parser.h
Normal file
467
lib/antlr4/include/Parser.h
Normal file
@@ -0,0 +1,467 @@
|
|||||||
|
/* 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 Ref<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
|
179
lib/antlr4/include/ParserInterpreter.h
Normal file
179
lib/antlr4/include/ParserInterpreter.h
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
/* 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
|
147
lib/antlr4/include/ParserRuleContext.h
Normal file
147
lib/antlr4/include/ParserRuleContext.h
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/* 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
|
38
lib/antlr4/include/ProxyErrorListener.h
Normal file
38
lib/antlr4/include/ProxyErrorListener.h
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/* 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
|
98
lib/antlr4/include/RecognitionException.h
Normal file
98
lib/antlr4/include/RecognitionException.h
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
/* 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
|
164
lib/antlr4/include/Recognizer.h
Normal file
164
lib/antlr4/include/Recognizer.h
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t EOF = static_cast<size_t>(-1); // std::numeric_limits<size_t>::max(); doesn't work in VS 2013.
|
||||||
|
|
||||||
|
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 Ref<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
|
137
lib/antlr4/include/RuleContext.h
Normal file
137
lib/antlr4/include/RuleContext.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/* 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
|
32
lib/antlr4/include/RuleContextWithAltNum.h
Normal file
32
lib/antlr4/include/RuleContextWithAltNum.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
/* 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
|
155
lib/antlr4/include/RuntimeMetaData.h
Normal file
155
lib/antlr4/include/RuntimeMetaData.h
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/* 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
|
92
lib/antlr4/include/Token.h
Normal file
92
lib/antlr4/include/Token.h
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t INVALID_TYPE = 0;
|
||||||
|
|
||||||
|
/// During lookahead operations, this "token" signifies we hit rule end ATN state
|
||||||
|
/// and did not follow it despite needing to.
|
||||||
|
static const size_t EPSILON = static_cast<size_t>(-2);
|
||||||
|
static const size_t MIN_USER_TOKEN_TYPE = 1;
|
||||||
|
static const size_t EOF = IntStream::EOF;
|
||||||
|
|
||||||
|
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.
|
||||||
|
static const size_t DEFAULT_CHANNEL = 0;
|
||||||
|
|
||||||
|
/// Anything on different channel than DEFAULT_CHANNEL is not parsed
|
||||||
|
/// by parser.
|
||||||
|
static const size_t HIDDEN_CHANNEL = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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()
|
||||||
|
*/
|
||||||
|
static const size_t MIN_USER_CHANNEL_VALUE = 2;
|
||||||
|
|
||||||
|
/// 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
|
30
lib/antlr4/include/TokenFactory.h
Normal file
30
lib/antlr4/include/TokenFactory.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* 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
|
85
lib/antlr4/include/TokenSource.h
Normal file
85
lib/antlr4/include/TokenSource.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* 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 Ref<TokenFactory<CommonToken>> getTokenFactory() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace antlr4
|
137
lib/antlr4/include/TokenStream.h
Normal file
137
lib/antlr4/include/TokenStream.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/* 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
|
293
lib/antlr4/include/TokenStreamRewriter.h
Normal file
293
lib/antlr4/include/TokenStreamRewriter.h
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
/* 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;
|
||||||
|
static const size_t PROGRAM_INIT_SIZE = 100;
|
||||||
|
static const size_t MIN_TOKEN_INDEX = 0;
|
||||||
|
|
||||||
|
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
|
123
lib/antlr4/include/UnbufferedCharStream.h
Normal file
123
lib/antlr4/include/UnbufferedCharStream.h
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
/* 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
|
115
lib/antlr4/include/UnbufferedTokenStream.h
Normal file
115
lib/antlr4/include/UnbufferedTokenStream.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/* 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
|
193
lib/antlr4/include/Vocabulary.h
Normal file
193
lib/antlr4/include/Vocabulary.h
Normal file
@@ -0,0 +1,193 @@
|
|||||||
|
/* 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:
|
||||||
|
Vocabulary(Vocabulary const&) = default;
|
||||||
|
virtual ~Vocabulary();
|
||||||
|
|
||||||
|
/// 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() {}
|
||||||
|
|
||||||
|
/// <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
|
23
lib/antlr4/include/WritableToken.h
Normal file
23
lib/antlr4/include/WritableToken.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/* 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
|
137
lib/antlr4/include/antlr4-common.h
Normal file
137
lib/antlr4/include/antlr4-common.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/* 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 <codecvt>
|
||||||
|
#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>
|
||||||
|
|
||||||
|
// 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>;
|
167
lib/antlr4/include/antlr4-runtime.h
Normal file
167
lib/antlr4/include/antlr4-runtime.h
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
/* 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"
|
||||||
|
|
||||||
|
|
112
lib/antlr4/include/atn/ATN.h
Normal file
112
lib/antlr4/include/atn/ATN.h
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t INVALID_ALT_NUMBER = 0;
|
||||||
|
|
||||||
|
/// 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
|
148
lib/antlr4/include/atn/ATNConfig.h
Normal file
148
lib/antlr4/include/atn/ATNConfig.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
/* 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.
|
||||||
|
*/
|
||||||
|
static const size_t SUPPRESS_PRECEDENCE_FILTER;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // 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 (auto &config : vector) {
|
||||||
|
seed ^= config->hashCode() + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||||
|
}
|
||||||
|
return seed;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
110
lib/antlr4/include/atn/ATNConfigSet.h
Normal file
110
lib/antlr4/include/atn/ATNConfigSet.h
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
/* 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
|
50
lib/antlr4/include/atn/ATNDeserializationOptions.h
Normal file
50
lib/antlr4/include/atn/ATNDeserializationOptions.h
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
/* 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
|
85
lib/antlr4/include/atn/ATNDeserializer.h
Normal file
85
lib/antlr4/include/atn/ATNDeserializer.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t SERIALIZED_VERSION;
|
||||||
|
|
||||||
|
/// 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
|
61
lib/antlr4/include/atn/ATNSerializer.h
Normal file
61
lib/antlr4/include/atn/ATNSerializer.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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
|
87
lib/antlr4/include/atn/ATNSimulator.h
Normal file
87
lib/antlr4/include/atn/ATNSimulator.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* 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
|
133
lib/antlr4/include/atn/ATNState.h
Normal file
133
lib/antlr4/include/atn/ATNState.h
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
/* 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;
|
||||||
|
|
||||||
|
static const size_t INITIAL_NUM_TRANSITIONS = 4;
|
||||||
|
static const size_t INVALID_STATE_NUMBER = static_cast<size_t>(-1); // std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
|
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
|
20
lib/antlr4/include/atn/ATNType.h
Normal file
20
lib/antlr4/include/atn/ATNType.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* 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
|
24
lib/antlr4/include/atn/AbstractPredicateTransition.h
Normal file
24
lib/antlr4/include/atn/AbstractPredicateTransition.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* 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
|
33
lib/antlr4/include/atn/ActionTransition.h
Normal file
33
lib/antlr4/include/atn/ActionTransition.h
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/* 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
|
68
lib/antlr4/include/atn/AmbiguityInfo.h
Normal file
68
lib/antlr4/include/atn/AmbiguityInfo.h
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
/* 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
|
43
lib/antlr4/include/atn/ArrayPredictionContext.h
Normal file
43
lib/antlr4/include/atn/ArrayPredictionContext.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
|
||||||
|
/* 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
|
||||||
|
|
30
lib/antlr4/include/atn/AtomTransition.h
Normal file
30
lib/antlr4/include/atn/AtomTransition.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* 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
|
22
lib/antlr4/include/atn/BasicBlockStartState.h
Normal file
22
lib/antlr4/include/atn/BasicBlockStartState.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/* 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
|
21
lib/antlr4/include/atn/BasicState.h
Normal file
21
lib/antlr4/include/atn/BasicState.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* 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
|
24
lib/antlr4/include/atn/BlockEndState.h
Normal file
24
lib/antlr4/include/atn/BlockEndState.h
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
/* 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
|
21
lib/antlr4/include/atn/BlockStartState.h
Normal file
21
lib/antlr4/include/atn/BlockStartState.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/* 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
|
47
lib/antlr4/include/atn/ContextSensitivityInfo.h
Normal file
47
lib/antlr4/include/atn/ContextSensitivityInfo.h
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/* 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
|
70
lib/antlr4/include/atn/DecisionEventInfo.h
Normal file
70
lib/antlr4/include/atn/DecisionEventInfo.h
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
/* 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
|
227
lib/antlr4/include/atn/DecisionInfo.h
Normal file
227
lib/antlr4/include/atn/DecisionInfo.h
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
/* 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
|
30
lib/antlr4/include/atn/DecisionState.h
Normal file
30
lib/antlr4/include/atn/DecisionState.h
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
/* 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
|
27
lib/antlr4/include/atn/EmptyPredictionContext.h
Normal file
27
lib/antlr4/include/atn/EmptyPredictionContext.h
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
/* 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
|
39
lib/antlr4/include/atn/EpsilonTransition.h
Normal file
39
lib/antlr4/include/atn/EpsilonTransition.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/* 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
|
43
lib/antlr4/include/atn/ErrorInfo.h
Normal file
43
lib/antlr4/include/atn/ErrorInfo.h
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
/* 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
|
109
lib/antlr4/include/atn/LL1Analyzer.h
Normal file
109
lib/antlr4/include/atn/LL1Analyzer.h
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
/* 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}.
|
||||||
|
static const size_t HIT_PRED = Token::INVALID_TYPE;
|
||||||
|
|
||||||
|
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
|
44
lib/antlr4/include/atn/LexerATNConfig.h
Normal file
44
lib/antlr4/include/atn/LexerATNConfig.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/* 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
|
210
lib/antlr4/include/atn/LexerATNSimulator.h
Normal file
210
lib/antlr4/include/atn/LexerATNSimulator.h
Normal file
@@ -0,0 +1,210 @@
|
|||||||
|
/* 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:
|
||||||
|
static const size_t MIN_DFA_EDGE = 0;
|
||||||
|
static const size_t MAX_DFA_EDGE = 127; // forces unicode to stay in ATN
|
||||||
|
|
||||||
|
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
|
66
lib/antlr4/include/atn/LexerAction.h
Normal file
66
lib/antlr4/include/atn/LexerAction.h
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
/* 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
|
115
lib/antlr4/include/atn/LexerActionExecutor.h
Normal file
115
lib/antlr4/include/atn/LexerActionExecutor.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/* 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
|
55
lib/antlr4/include/atn/LexerActionType.h
Normal file
55
lib/antlr4/include/atn/LexerActionType.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* 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
|
63
lib/antlr4/include/atn/LexerChannelAction.h
Normal file
63
lib/antlr4/include/atn/LexerChannelAction.h
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
/* 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
|
87
lib/antlr4/include/atn/LexerCustomAction.h
Normal file
87
lib/antlr4/include/atn/LexerCustomAction.h
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* 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
|
82
lib/antlr4/include/atn/LexerIndexedCustomAction.h
Normal file
82
lib/antlr4/include/atn/LexerIndexedCustomAction.h
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
/* 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
|
||||||
|
|
61
lib/antlr4/include/atn/LexerModeAction.h
Normal file
61
lib/antlr4/include/atn/LexerModeAction.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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
|
57
lib/antlr4/include/atn/LexerMoreAction.h
Normal file
57
lib/antlr4/include/atn/LexerMoreAction.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* 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
|
57
lib/antlr4/include/atn/LexerPopModeAction.h
Normal file
57
lib/antlr4/include/atn/LexerPopModeAction.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/* 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
|
61
lib/antlr4/include/atn/LexerPushModeAction.h
Normal file
61
lib/antlr4/include/atn/LexerPushModeAction.h
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
/* 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
|
55
lib/antlr4/include/atn/LexerSkipAction.h
Normal file
55
lib/antlr4/include/atn/LexerSkipAction.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* 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
|
55
lib/antlr4/include/atn/LexerTypeAction.h
Normal file
55
lib/antlr4/include/atn/LexerTypeAction.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/* 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
|
42
lib/antlr4/include/atn/LookaheadEventInfo.h
Normal file
42
lib/antlr4/include/atn/LookaheadEventInfo.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/* 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
|
22
lib/antlr4/include/atn/LoopEndState.h
Normal file
22
lib/antlr4/include/atn/LoopEndState.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/* 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
|
25
lib/antlr4/include/atn/NotSetTransition.h
Normal file
25
lib/antlr4/include/atn/NotSetTransition.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* 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
|
20
lib/antlr4/include/atn/OrderedATNConfigSet.h
Normal file
20
lib/antlr4/include/atn/OrderedATNConfigSet.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/* 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
|
102
lib/antlr4/include/atn/ParseInfo.h
Normal file
102
lib/antlr4/include/atn/ParseInfo.h
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
/* 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
|
904
lib/antlr4/include/atn/ParserATNSimulator.h
Normal file
904
lib/antlr4/include/atn/ParserATNSimulator.h
Normal file
@@ -0,0 +1,904 @@
|
|||||||
|
/* 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
|
||||||
|
|
25
lib/antlr4/include/atn/PlusBlockStartState.h
Normal file
25
lib/antlr4/include/atn/PlusBlockStartState.h
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
/* 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
|
22
lib/antlr4/include/atn/PlusLoopbackState.h
Normal file
22
lib/antlr4/include/atn/PlusLoopbackState.h
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
/* 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
|
29
lib/antlr4/include/atn/PrecedencePredicateTransition.h
Normal file
29
lib/antlr4/include/atn/PrecedencePredicateTransition.h
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
/* 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
|
62
lib/antlr4/include/atn/PredicateEvalInfo.h
Normal file
62
lib/antlr4/include/atn/PredicateEvalInfo.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/* 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
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user