Commit 29d08f1c authored by Tobias Tebbi's avatar Tobias Tebbi Committed by Commit Bot

[third_party] remove antlr

Bug: v8:7754
Change-Id: Iffd3a2f665258032e2284e5cd700f9a3286618d1
Reviewed-on: https://chromium-review.googlesource.com/1145064Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54581}
parent 7221681b
This diff is collapsed.
[The "BSD 3-clause license"]
Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=====
MIT License for codepointat.js from https://git.io/codepointat
MIT License for fromcodepoint.js from https://git.io/vDW1m
Copyright Mathias Bynens <https://mathiasbynens.be/>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# C++ target for ANTLR 4
This folder contains the C++ runtime support for ANTLR. See [the canonical antlr4 repository](https://github.com/antlr/antlr4) for in depth detail about how to use ANTLR 4.
## Authors and major contributors
ANTLR 4 is the result of substantial effort of the following people:
* [Terence Parr](http://www.cs.usfca.edu/~parrt/), parrt@cs.usfca.edu
ANTLR project lead and supreme dictator for life
[University of San Francisco](http://www.usfca.edu/)
* [Sam Harwell](http://tunnelvisionlabs.com/)
Tool co-author, Java and C# target)
The C++ target has been the work of the following people:
* Dan McLaughlin, dan.mclaughlin@gmail.com (initial port, got code to compile)
* David Sisson, dsisson@google.com (initial port, made the runtime C++ tests runnable)
* [Mike Lischke](www.soft-gems.net), mike@lischke-online.de (brought the initial port to a working library, made most runtime tests passing)
## Other contributors
* Marcin Szalowicz, mszalowicz@mailplus.pl (cmake build setup)
* Tim O'Callaghan, timo@linux.com (additional superbuild cmake pattern script)
## Project Status
* Building on OS X, Windows, and Linux
* No errors and warnings
* Library linking
* Some unit tests in the OSX project, for important base classes with almost 100% code coverage.
* All memory allocations checked
* Simple command line demo application working on all supported platforms.
* All runtime tests pass.
### Build + Usage Notes
The minimum C++ version to compile the ANTLR C++ runtime with is C++11. The supplied projects can built the runtime either as static or dynamic library, as both 32bit and 64bit arch. The OSX project contains a target for iOS and can also be built using cmake (instead of XCode).
Include the antlr4-runtime.h umbrella header in your target application to get everything needed to use the library.
If you are compiling with cmake, the minimum version required is cmake 2.8.
#### Compiling on Windows
Simply open the VS solution (VS 2013+) and build it.
#### Compiling on OSX
Either open the included XCode project and build that or use the cmake compilation as described for linux.
#### Compiling on Linux
- cd <antlr4-dir>/runtime/Cpp (this is where this readme is located)
- mkdir build && mkdir run && cd build
- cmake .. -DANTLR_JAR_LOCATION=full/path/to/antlr4-4.5.4-SNAPSHOT.jar -DWITH_DEMO=True
- make
- DESTDIR=<antlr4-dir>/runtime/Cpp/run make install
If you don't want to build the demo then simply run cmake without parameters.
There is another cmake script available in the subfolder cmake/ for those who prefer the superbuild cmake pattern.
/* 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.
*/
#include "ANTLRErrorListener.h"
antlr4::ANTLRErrorListener::~ANTLRErrorListener() {}
/* 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
/* 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.
*/
#include "ANTLRErrorStrategy.h"
antlr4::ANTLRErrorStrategy::~ANTLRErrorStrategy() {}
/* 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/>
/// TO_DO: 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
/* 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.
*/
#include "support/StringUtils.h"
#include "ANTLRFileStream.h"
using namespace antlr4;
ANTLRFileStream::ANTLRFileStream(const std::string& fileName) {
_fileName = fileName;
loadFromFile(fileName);
}
void ANTLRFileStream::loadFromFile(const std::string& fileName) {
_fileName = fileName;
if (_fileName.empty()) {
return;
}
#ifdef _MSC_VER
std::ifstream stream(antlrcpp::s2ws(fileName), std::ios::binary);
#else
std::ifstream stream(fileName, std::ios::binary);
#endif
ANTLRInputStream::load(stream);
}
std::string ANTLRFileStream::getSourceName() const { return _fileName; }
/* 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
/* 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.
*/
#include "Exceptions.h"
#include "IntStream.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "support/StringUtils.h"
#include "ANTLRInputStream.h"
using namespace antlr4;
using namespace antlrcpp;
using misc::Interval;
ANTLRInputStream::ANTLRInputStream(const std::string& input) {
InitializeInstanceFields();
load(input);
}
ANTLRInputStream::ANTLRInputStream(const char data_[],
size_t numberOfActualCharsInArray)
: ANTLRInputStream(std::string(data_, numberOfActualCharsInArray)) {}
ANTLRInputStream::ANTLRInputStream(std::istream& stream) {
InitializeInstanceFields();
load(stream);
}
void ANTLRInputStream::load(const std::string& input) {
// Remove the UTF-8 BOM if present.
const char bom[4] = "\xef\xbb\xbf";
if (input.compare(0, 3, bom, 3) == 0)
_data =
antlrcpp::utf8_to_utf32(input.data() + 3, input.data() + input.size());
else
_data = antlrcpp::utf8_to_utf32(input.data(), input.data() + input.size());
p = 0;
}
void ANTLRInputStream::load(std::istream& stream) {
if (!stream.good() || stream.eof()) // No fail, bad or EOF.
return;
_data.clear();
std::string s((std::istreambuf_iterator<char>(stream)),
std::istreambuf_iterator<char>());
load(s);
}
void ANTLRInputStream::reset() { p = 0; }
void ANTLRInputStream::consume() {
if (p >= _data.size()) {
assert(LA(1) == IntStream::EOF);
throw IllegalStateException("cannot consume EOF");
}
if (p < _data.size()) {
p++;
}
}
size_t ANTLRInputStream::LA(ssize_t i) {
if (i == 0) {
return 0; // undefined
}
ssize_t position = static_cast<ssize_t>(p);
if (i < 0) {
i++; // e.g., translate LA(-1) to use offset i=0; then _data[p+0-1]
if ((position + i - 1) < 0) {
return IntStream::EOF; // invalid; no char before first char
}
}
if ((position + i - 1) >= static_cast<ssize_t>(_data.size())) {
return IntStream::EOF;
}
return _data[static_cast<size_t>((position + i - 1))];
}
size_t ANTLRInputStream::LT(ssize_t i) { return LA(i); }
size_t ANTLRInputStream::index() { return p; }
size_t ANTLRInputStream::size() { return _data.size(); }
// Mark/release do nothing. We have entire buffer.
ssize_t ANTLRInputStream::mark() { return -1; }
void ANTLRInputStream::release(ssize_t /* marker */) {}
void ANTLRInputStream::seek(size_t index) {
if (index <= p) {
p = index; // just jump; don't update stream state (line, ...)
return;
}
// seek forward, consume until p hits index or n (whichever comes first)
index = std::min(index, _data.size());
while (p < index) {
consume();
}
}
std::string ANTLRInputStream::getText(const Interval& interval) {
if (interval.a < 0 || interval.b < 0) {
return "";
}
size_t start = static_cast<size_t>(interval.a);
size_t stop = static_cast<size_t>(interval.b);
if (stop >= _data.size()) {
stop = _data.size() - 1;
}
size_t count = stop - start + 1;
if (start >= _data.size()) {
return "";
}
return antlrcpp::utf32_to_utf8(_data.substr(start, count));
}
std::string ANTLRInputStream::getSourceName() const {
if (name.empty()) {
return IntStream::UNKNOWN_SOURCE_NAME;
}
return name;
}
std::string ANTLRInputStream::toString() const {
return antlrcpp::utf32_to_utf8(_data);
}
void ANTLRInputStream::InitializeInstanceFields() { p = 0; }
/* 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
/* 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.
*/
#include "Exceptions.h"
#include "InputMismatchException.h"
#include "Parser.h"
#include "ParserRuleContext.h"
#include "BailErrorStrategy.h"
using namespace antlr4;
void BailErrorStrategy::recover(Parser* recognizer, std::exception_ptr e) {
ParserRuleContext* context = recognizer->getContext();
do {
context->exception = e;
if (context->parent == nullptr) break;
context = static_cast<ParserRuleContext*>(context->parent);
} while (true);
try {
std::rethrow_exception(
e); // Throw the exception to be able to catch and rethrow nested.
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
} catch (RecognitionException& inner) {
throw ParseCancellationException(inner.what());
#else
} catch (RecognitionException& /*inner*/) {
std::throw_with_nested(ParseCancellationException());
#endif
}
}
Token* BailErrorStrategy::recoverInline(Parser* recognizer) {
InputMismatchException e(recognizer);
std::exception_ptr exception = std::make_exception_ptr(e);
ParserRuleContext* context = recognizer->getContext();
do {
context->exception = exception;
if (context->parent == nullptr) break;
context = static_cast<ParserRuleContext*>(context->parent);
} while (true);
try {
throw e;
#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023026
} catch (InputMismatchException& inner) {
throw ParseCancellationException(inner.what());
#else
} catch (InputMismatchException& /*inner*/) {
std::throw_with_nested(ParseCancellationException());
#endif
}
}
void BailErrorStrategy::sync(Parser* /*recognizer*/) {}
/* 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
/* 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.
*/
#include "BaseErrorListener.h"
#include "RecognitionException.h"
using namespace antlr4;
void BaseErrorListener::syntaxError(Recognizer* /*recognizer*/,
Token* /*offendingSymbol*/, size_t /*line*/,
size_t /*charPositionInLine*/,
const std::string& /*msg*/,
std::exception_ptr /*e*/) {}
void BaseErrorListener::reportAmbiguity(Parser* /*recognizer*/,
const dfa::DFA& /*dfa*/,
size_t /*startIndex*/,
size_t /*stopIndex*/, bool /*exact*/,
const antlrcpp::BitSet& /*ambigAlts*/,
atn::ATNConfigSet* /*configs*/) {}
void BaseErrorListener::reportAttemptingFullContext(
Parser* /*recognizer*/, const dfa::DFA& /*dfa*/, size_t /*startIndex*/,
size_t /*stopIndex*/, const antlrcpp::BitSet& /*conflictingAlts*/,
atn::ATNConfigSet* /*configs*/) {}
void BaseErrorListener::reportContextSensitivity(
Parser* /*recognizer*/, const dfa::DFA& /*dfa*/, size_t /*startIndex*/,
size_t /*stopIndex*/, size_t /*prediction*/,
atn::ATNConfigSet* /*configs*/) {}
/* 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
/* 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
/* 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.
*/
#include "CharStream.h"
using namespace antlr4;
CharStream::~CharStream() {}
/* 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
/* 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.
*/
#include "CharStream.h"
#include "Recognizer.h"
#include "TokenSource.h"
#include "Vocabulary.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "support/StringUtils.h"
#include "CommonToken.h"
using namespace antlr4;
using namespace antlr4::misc;
using namespace antlrcpp;
const std::pair<TokenSource*, CharStream*> CommonToken::EMPTY_SOURCE(nullptr,
nullptr);
CommonToken::CommonToken(size_t type) {
InitializeInstanceFields();
_type = type;
}
CommonToken::CommonToken(std::pair<TokenSource*, CharStream*> source,
size_t type, size_t channel, size_t start,
size_t stop) {
InitializeInstanceFields();
_source = source;
_type = type;
_channel = channel;
_start = start;
_stop = stop;
if (_source.first != nullptr) {
_line = static_cast<int>(source.first->getLine());
_charPositionInLine = source.first->getCharPositionInLine();
}
}
CommonToken::CommonToken(size_t type, const std::string& text) {
InitializeInstanceFields();
_type = type;
_channel = DEFAULT_CHANNEL;
_text = text;
_source = EMPTY_SOURCE;
}
CommonToken::CommonToken(Token* oldToken) {
InitializeInstanceFields();
_type = oldToken->getType();
_line = oldToken->getLine();
_index = oldToken->getTokenIndex();
_charPositionInLine = oldToken->getCharPositionInLine();
_channel = oldToken->getChannel();
_start = oldToken->getStartIndex();
_stop = oldToken->getStopIndex();
if (is<CommonToken*>(oldToken)) {
_text = (static_cast<CommonToken*>(oldToken))->_text;
_source = (static_cast<CommonToken*>(oldToken))->_source;
} else {
_text = oldToken->getText();
_source = {oldToken->getTokenSource(), oldToken->getInputStream()};
}
}
size_t CommonToken::getType() const { return _type; }
void CommonToken::setLine(size_t line) { _line = line; }
std::string CommonToken::getText() const {
if (!_text.empty()) {
return _text;
}
CharStream* input = getInputStream();
if (input == nullptr) {
return "";
}
size_t n = input->size();
if (_start < n && _stop < n) {
return input->getText(misc::Interval(_start, _stop));
} else {
return "<EOF>";
}
}
void CommonToken::setText(const std::string& text) { _text = text; }
size_t CommonToken::getLine() const { return _line; }
size_t CommonToken::getCharPositionInLine() const {
return _charPositionInLine;
}
void CommonToken::setCharPositionInLine(size_t charPositionInLine) {
_charPositionInLine = charPositionInLine;
}
size_t CommonToken::getChannel() const { return _channel; }
void CommonToken::setChannel(size_t channel) { _channel = channel; }
void CommonToken::setType(size_t type) { _type = type; }
size_t CommonToken::getStartIndex() const { return _start; }
void CommonToken::setStartIndex(size_t start) { _start = start; }
size_t CommonToken::getStopIndex() const { return _stop; }
void CommonToken::setStopIndex(size_t stop) { _stop = stop; }
size_t CommonToken::getTokenIndex() const { return _index; }
void CommonToken::setTokenIndex(size_t index) { _index = index; }
antlr4::TokenSource* CommonToken::getTokenSource() const {
return _source.first;
}
antlr4::CharStream* CommonToken::getInputStream() const {
return _source.second;
}
std::string CommonToken::toString() const { return toString(nullptr); }
std::string CommonToken::toString(Recognizer* r) const {
std::stringstream ss;
std::string channelStr;
if (_channel > 0) {
channelStr = ",channel=" + std::to_string(_channel);
}
std::string txt = getText();
if (!txt.empty()) {
antlrcpp::replaceAll(txt, "\n", "\\n");
antlrcpp::replaceAll(txt, "\r", "\\r");
antlrcpp::replaceAll(txt, "\t", "\\t");
} else {
txt = "<no text>";
}
std::string typeString = std::to_string(symbolToNumeric(_type));
if (r != nullptr) typeString = r->getVocabulary().getDisplayName(_type);
ss << "[@" << symbolToNumeric(getTokenIndex()) << ","
<< symbolToNumeric(_start) << ":" << symbolToNumeric(_stop) << "='" << txt
<< "',<" << typeString << ">" << channelStr << "," << _line << ":"
<< getCharPositionInLine() << "]";
return ss.str();
}
void CommonToken::InitializeInstanceFields() {
_type = 0;
_line = 0;
_charPositionInLine = INVALID_INDEX;
_channel = DEFAULT_CHANNEL;
_index = INVALID_INDEX;
_start = 0;
_stop = 0;
_source = EMPTY_SOURCE;
}
/* 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
/* 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.
*/
#include "CharStream.h"
#include "CommonToken.h"
#include "misc/Interval.h"
#include "CommonTokenFactory.h"
using namespace antlr4;
const Ref<TokenFactory<CommonToken>> CommonTokenFactory::DEFAULT =
std::make_shared<CommonTokenFactory>();
CommonTokenFactory::CommonTokenFactory(bool copyText_) : copyText(copyText_) {}
CommonTokenFactory::CommonTokenFactory() : CommonTokenFactory(false) {}
std::unique_ptr<CommonToken> CommonTokenFactory::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) {
std::unique_ptr<CommonToken> t(
new CommonToken(source, type, channel, start, stop));
t->setLine(line);
t->setCharPositionInLine(charPositionInLine);
if (text != "") {
t->setText(text);
} else if (copyText && source.second != nullptr) {
t->setText(source.second->getText(misc::Interval(start, stop)));
}
return t;
}
std::unique_ptr<CommonToken> CommonTokenFactory::create(
size_t type, const std::string& text) {
return std::unique_ptr<CommonToken>(new CommonToken(type, text));
}
/* 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
/* 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.
*/
#include "Token.h"
#include "CommonTokenStream.h"
using namespace antlr4;
CommonTokenStream::CommonTokenStream(TokenSource* tokenSource)
: CommonTokenStream(tokenSource, Token::DEFAULT_CHANNEL) {}
CommonTokenStream::CommonTokenStream(TokenSource* tokenSource, size_t channel_)
: BufferedTokenStream(tokenSource), channel(channel_) {}
ssize_t CommonTokenStream::adjustSeekIndex(size_t i) {
return nextTokenOnChannel(i, channel);
}
Token* CommonTokenStream::LB(size_t k) {
if (k == 0 || k > _p) {
return nullptr;
}
ssize_t i = static_cast<ssize_t>(_p);
size_t n = 1;
// find k good tokens looking backwards
while (n <= k) {
// skip off-channel tokens
i = previousTokenOnChannel(i - 1, channel);
n++;
}
if (i < 0) {
return nullptr;
}
return _tokens[i].get();
}
Token* CommonTokenStream::LT(ssize_t k) {
lazyInit();
if (k == 0) {
return nullptr;
}
if (k < 0) {
return LB(static_cast<size_t>(-k));
}
size_t i = _p;
ssize_t n = 1; // we know tokens[p] is a good one
// find k good tokens
while (n < k) {
// skip off-channel tokens, but make sure to not look past EOF
if (sync(i + 1)) {
i = nextTokenOnChannel(i + 1, channel);
}
n++;
}
return _tokens[i].get();
}
int CommonTokenStream::getNumberOfOnChannelTokens() {
int n = 0;
fill();
for (size_t i = 0; i < _tokens.size(); i++) {
Token* t = _tokens[i].get();
if (t->getChannel() == channel) {
n++;
}
if (t->getType() == Token::EOF) {
break;
}
}
return n;
}
/* 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
/* 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.
*/
#include "ConsoleErrorListener.h"
using namespace antlr4;
ConsoleErrorListener ConsoleErrorListener::INSTANCE;
void ConsoleErrorListener::syntaxError(Recognizer* /*recognizer*/,
Token* /*offendingSymbol*/, size_t line,
size_t charPositionInLine,
const std::string& msg,
std::exception_ptr /*e*/) {
std::cerr << "line " << line << ":" << charPositionInLine << " " << msg
<< std::endl;
}
/* 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
/* 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.
*/
#include "Parser.h"
#include "atn/ATNConfig.h"
#include "atn/ATNConfigSet.h"
#include "atn/PredictionContext.h"
#include "dfa/DFA.h"
#include "misc/Interval.h"
#include "DiagnosticErrorListener.h"
using namespace antlr4;
DiagnosticErrorListener::DiagnosticErrorListener()
: DiagnosticErrorListener(true) {}
DiagnosticErrorListener::DiagnosticErrorListener(bool exactOnly_)
: exactOnly(exactOnly_) {}
void DiagnosticErrorListener::reportAmbiguity(Parser* recognizer,
const dfa::DFA& dfa,
size_t startIndex,
size_t stopIndex, bool exact,
const antlrcpp::BitSet& ambigAlts,
atn::ATNConfigSet* configs) {
if (exactOnly && !exact) {
return;
}
std::string decision = getDecisionDescription(recognizer, dfa);
antlrcpp::BitSet conflictingAlts = getConflictingAlts(ambigAlts, configs);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message = "reportAmbiguity d=" + decision +
": ambigAlts=" + conflictingAlts.toString() +
", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
void DiagnosticErrorListener::reportAttemptingFullContext(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, const antlrcpp::BitSet& /*conflictingAlts*/,
atn::ATNConfigSet* /*configs*/) {
std::string decision = getDecisionDescription(recognizer, dfa);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message =
"reportAttemptingFullContext d=" + decision + ", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
void DiagnosticErrorListener::reportContextSensitivity(
Parser* recognizer, const dfa::DFA& dfa, size_t startIndex,
size_t stopIndex, size_t /*prediction*/, atn::ATNConfigSet* /*configs*/) {
std::string decision = getDecisionDescription(recognizer, dfa);
std::string text = recognizer->getTokenStream()->getText(
misc::Interval(startIndex, stopIndex));
std::string message =
"reportContextSensitivity d=" + decision + ", input='" + text + "'";
recognizer->notifyErrorListeners(message);
}
std::string DiagnosticErrorListener::getDecisionDescription(
Parser* recognizer, const dfa::DFA& dfa) {
size_t decision = dfa.decision;
size_t ruleIndex =
(reinterpret_cast<atn::ATNState*>(dfa.atnStartState))->ruleIndex;
const std::vector<std::string>& ruleNames = recognizer->getRuleNames();
if (ruleIndex == INVALID_INDEX || ruleIndex >= ruleNames.size()) {
return std::to_string(decision);
}
std::string ruleName = ruleNames[ruleIndex];
if (ruleName == "" || ruleName.empty()) {
return std::to_string(decision);
}
return std::to_string(decision) + " (" + ruleName + ")";
}
antlrcpp::BitSet DiagnosticErrorListener::getConflictingAlts(
const antlrcpp::BitSet& reportedAlts, atn::ATNConfigSet* configs) {
if (reportedAlts.count() > 0) { // Not exactly like the original Java code,
// but this listener is only used in the
// TestRig (where it never provides a good
// alt set), so it's probably ok so.
return reportedAlts;
}
antlrcpp::BitSet result;
for (auto& config : configs->configs) {
result.set(config->alt);
}
return result;
}
/* 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
/* 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.
*/
#include "Exceptions.h"
using namespace antlr4;
RuntimeException::RuntimeException(const std::string& msg)
: std::exception(), _message(msg) {}
const char* RuntimeException::what() const NOEXCEPT { return _message.c_str(); }
//------------------ IOException
//---------------------------------------------------------------------------------------
IOException::IOException(const std::string& msg)
: std::exception(), _message(msg) {}
const char* IOException::what() const NOEXCEPT { return _message.c_str(); }
//------------------ IllegalStateException
//-----------------------------------------------------------------------------
IllegalStateException::~IllegalStateException() {}
//------------------ IllegalArgumentException
//--------------------------------------------------------------------------
IllegalArgumentException::~IllegalArgumentException() {}
//------------------ NullPointerException
//------------------------------------------------------------------------------
NullPointerException::~NullPointerException() {}
//------------------ IndexOutOfBoundsException
//-------------------------------------------------------------------------
IndexOutOfBoundsException::~IndexOutOfBoundsException() {}
//------------------ UnsupportedOperationException
//---------------------------------------------------------------------
UnsupportedOperationException::~UnsupportedOperationException() {}
//------------------ EmptyStackException
//-------------------------------------------------------------------------------
EmptyStackException::~EmptyStackException() {}
//------------------ CancellationException
//-----------------------------------------------------------------------------
CancellationException::~CancellationException() {}
//------------------ ParseCancellationException
//------------------------------------------------------------------------
ParseCancellationException::~ParseCancellationException() {}
/* 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
/* 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.
*/
#include "Parser.h"
#include "atn/ATN.h"
#include "atn/ATNState.h"
#include "atn/ParserATNSimulator.h"
#include "atn/PredicateTransition.h"
#include "support/CPPUtils.h"
#include "FailedPredicateException.h"
using namespace antlr4;
using namespace antlrcpp;
FailedPredicateException::FailedPredicateException(Parser* recognizer)
: FailedPredicateException(recognizer, "", "") {}
FailedPredicateException::FailedPredicateException(Parser* recognizer,
const std::string& predicate)
: FailedPredicateException(recognizer, predicate, "") {}
FailedPredicateException::FailedPredicateException(Parser* recognizer,
const std::string& predicate,
const std::string& message)
: RecognitionException(
!message.empty() ? message : "failed predicate: " + predicate + "?",
recognizer, recognizer->getInputStream(), recognizer->getContext(),
recognizer->getCurrentToken()) {
atn::ATNState* s = recognizer->getInterpreter<atn::ATNSimulator>()
->atn.states[recognizer->getState()];
atn::Transition* transition = s->transitions[0];
if (is<atn::PredicateTransition*>(transition)) {
_ruleIndex = static_cast<atn::PredicateTransition*>(transition)->ruleIndex;
_predicateIndex =
static_cast<atn::PredicateTransition*>(transition)->predIndex;
} else {
_ruleIndex = 0;
_predicateIndex = 0;
}
_predicate = predicate;
}
size_t FailedPredicateException::getRuleIndex() { return _ruleIndex; }
size_t FailedPredicateException::getPredIndex() { return _predicateIndex; }
std::string FailedPredicateException::getPredicate() { return _predicate; }
/* 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
/* 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.
*/
#include "Parser.h"
#include "InputMismatchException.h"
using namespace antlr4;
InputMismatchException::InputMismatchException(Parser* recognizer)
: RecognitionException(recognizer, recognizer->getInputStream(),
recognizer->getContext(),
recognizer->getCurrentToken()) {}
InputMismatchException::~InputMismatchException() {}
/* 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
/* 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.
*/
#include "IntStream.h"
using namespace antlr4;
const std::string IntStream::UNKNOWN_SOURCE_NAME = "<unknown>";
IntStream::~IntStream() = default;
/* 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
/* 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.
*/
#include "InterpreterRuleContext.h"
using namespace antlr4;
InterpreterRuleContext::InterpreterRuleContext() : ParserRuleContext() {}
InterpreterRuleContext::InterpreterRuleContext(ParserRuleContext* parent,
size_t invokingStateNumber,
size_t ruleIndex)
: ParserRuleContext(parent, invokingStateNumber), _ruleIndex(ruleIndex) {}
size_t InterpreterRuleContext::getRuleIndex() const { return _ruleIndex; }
/* 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
/* 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.
*/
#include "ANTLRErrorListener.h"
#include "CommonToken.h"
#include "CommonTokenFactory.h"
#include "Exceptions.h"
#include "LexerNoViableAltException.h"
#include "atn/LexerATNSimulator.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "support/StringUtils.h"
#include "Lexer.h"
#define DEBUG_LEXER 0
using namespace antlrcpp;
using namespace antlr4;
Lexer::Lexer() : Recognizer() {
InitializeInstanceFields();
_input = nullptr;
}
Lexer::Lexer(CharStream* input) : Recognizer(), _input(input) {
InitializeInstanceFields();
}
void Lexer::reset() {
// wack Lexer state variables
_input->seek(0); // rewind the input
_syntaxErrors = 0;
token.reset();
type = Token::INVALID_TYPE;
channel = Token::DEFAULT_CHANNEL;
tokenStartCharIndex = INVALID_INDEX;
tokenStartCharPositionInLine = 0;
tokenStartLine = 0;
type = 0;
_text = "";
hitEOF = false;
mode = Lexer::DEFAULT_MODE;
modeStack.clear();
getInterpreter<atn::LexerATNSimulator>()->reset();
}
std::unique_ptr<Token> Lexer::nextToken() {
// Mark start location in char stream so unbuffered streams are
// guaranteed at least have text of current token
ssize_t tokenStartMarker = _input->mark();
auto onExit = finally([this, tokenStartMarker] {
// make sure we release marker after match or
// unbuffered char stream will keep buffering
_input->release(tokenStartMarker);
});
while (true) {
outerContinue:
if (hitEOF) {
emitEOF();
return std::move(token);
}
token.reset();
channel = Token::DEFAULT_CHANNEL;
tokenStartCharIndex = _input->index();
tokenStartCharPositionInLine =
getInterpreter<atn::LexerATNSimulator>()->getCharPositionInLine();
tokenStartLine = getInterpreter<atn::LexerATNSimulator>()->getLine();
_text = "";
do {
type = Token::INVALID_TYPE;
size_t ttype;
try {
ttype = getInterpreter<atn::LexerATNSimulator>()->match(_input, mode);
} catch (LexerNoViableAltException& e) {
notifyListeners(e); // report error
recover(e);
ttype = SKIP;
}
if (_input->LA(1) == EOF) {
hitEOF = true;
}
if (type == Token::INVALID_TYPE) {
type = ttype;
}
if (type == SKIP) {
goto outerContinue;
}
} while (type == MORE);
if (token == nullptr) {
emit();
}
return std::move(token);
}
}
void Lexer::skip() { type = SKIP; }
void Lexer::more() { type = MORE; }
void Lexer::setMode(size_t m) { mode = m; }
void Lexer::pushMode(size_t m) {
#if DEBUG_LEXER == 1
std::cout << "pushMode " << m << std::endl;
#endif
modeStack.push_back(mode);
setMode(m);
}
size_t Lexer::popMode() {
if (modeStack.empty()) {
throw EmptyStackException();
}
#if DEBUG_LEXER == 1
std::cout << std::string("popMode back to ") << modeStack.back() << std::endl;
#endif
setMode(modeStack.back());
modeStack.pop_back();
return mode;
}
Ref<TokenFactory<CommonToken>> Lexer::getTokenFactory() { return _factory; }
void Lexer::setInputStream(IntStream* input) {
reset();
_input = dynamic_cast<CharStream*>(input);
}
std::string Lexer::getSourceName() { return _input->getSourceName(); }
CharStream* Lexer::getInputStream() { return _input; }
void Lexer::emit(std::unique_ptr<Token> newToken) {
token = std::move(newToken);
}
Token* Lexer::emit() {
emit(_factory->create({this, _input}, type, _text, channel,
tokenStartCharIndex, getCharIndex() - 1, tokenStartLine,
tokenStartCharPositionInLine));
return token.get();
}
Token* Lexer::emitEOF() {
size_t cpos = getCharPositionInLine();
size_t line = getLine();
emit(_factory->create({this, _input}, EOF, "", Token::DEFAULT_CHANNEL,
_input->index(), _input->index() - 1, line, cpos));
return token.get();
}
size_t Lexer::getLine() const {
return getInterpreter<atn::LexerATNSimulator>()->getLine();
}
size_t Lexer::getCharPositionInLine() {
return getInterpreter<atn::LexerATNSimulator>()->getCharPositionInLine();
}
void Lexer::setLine(size_t line) {
getInterpreter<atn::LexerATNSimulator>()->setLine(line);
}
void Lexer::setCharPositionInLine(size_t charPositionInLine) {
getInterpreter<atn::LexerATNSimulator>()->setCharPositionInLine(
charPositionInLine);
}
size_t Lexer::getCharIndex() { return _input->index(); }
std::string Lexer::getText() {
if (!_text.empty()) {
return _text;
}
return getInterpreter<atn::LexerATNSimulator>()->getText(_input);
}
void Lexer::setText(const std::string& text) { _text = text; }
std::unique_ptr<Token> Lexer::getToken() { return std::move(token); }
void Lexer::setToken(std::unique_ptr<Token> newToken) {
token = std::move(newToken);
}
void Lexer::setType(size_t ttype) { type = ttype; }
size_t Lexer::getType() { return type; }
void Lexer::setChannel(size_t newChannel) { channel = newChannel; }
size_t Lexer::getChannel() { return channel; }
std::vector<std::unique_ptr<Token>> Lexer::getAllTokens() {
std::vector<std::unique_ptr<Token>> tokens;
std::unique_ptr<Token> t = nextToken();
while (t->getType() != EOF) {
tokens.push_back(std::move(t));
t = nextToken();
}
return tokens;
}
void Lexer::recover(const LexerNoViableAltException& /*e*/) {
if (_input->LA(1) != EOF) {
// skip a char and try again
getInterpreter<atn::LexerATNSimulator>()->consume(_input);
}
}
void Lexer::notifyListeners(const LexerNoViableAltException& /*e*/) {
++_syntaxErrors;
std::string text =
_input->getText(misc::Interval(tokenStartCharIndex, _input->index()));
std::string msg = std::string("token recognition error at: '") +
getErrorDisplay(text) + std::string("'");
ProxyErrorListener& listener = getErrorListenerDispatch();
listener.syntaxError(this, nullptr, tokenStartLine,
tokenStartCharPositionInLine, msg,
std::current_exception());
}
std::string Lexer::getErrorDisplay(const std::string& s) {
std::stringstream ss;
for (auto c : s) {
switch (c) {
case '\n':
ss << "\\n";
break;
case '\t':
ss << "\\t";
break;
case '\r':
ss << "\\r";
break;
default:
ss << c;
break;
}
}
return ss.str();
}
void Lexer::recover(RecognitionException* /*re*/) {
// TO_DO: Do we lose character or line position information?
_input->consume();
}
size_t Lexer::getNumberOfSyntaxErrors() { return _syntaxErrors; }
void Lexer::InitializeInstanceFields() {
_syntaxErrors = 0;
token = nullptr;
_factory = CommonTokenFactory::DEFAULT;
tokenStartCharIndex = INVALID_INDEX;
tokenStartLine = 0;
tokenStartCharPositionInLine = 0;
hitEOF = false;
channel = 0;
type = 0;
mode = Lexer::DEFAULT_MODE;
}
/* 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 "Recognizer.h"
#include "Token.h"
#include "TokenSource.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
/* 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.
*/
#include "Exceptions.h"
#include "Vocabulary.h"
#include "atn/ATNType.h"
#include "atn/EmptyPredictionContext.h"
#include "atn/LexerATNSimulator.h"
#include "dfa/DFA.h"
#include "LexerInterpreter.h"
using namespace antlr4;
LexerInterpreter::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(grammarFileName,
dfa::Vocabulary::fromTokenNames(tokenNames), ruleNames,
channelNames, modeNames, atn, input) {}
LexerInterpreter::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)
: Lexer(input),
_grammarFileName(grammarFileName),
_atn(atn),
_ruleNames(ruleNames),
_channelNames(channelNames),
_modeNames(modeNames),
_vocabulary(vocabulary) {
if (_atn.grammarType != atn::ATNType::LEXER) {
throw IllegalArgumentException("The ATN must be a lexer ATN.");
}
for (size_t i = 0; i < atn.maxTokenType; i++) {
_tokenNames.push_back(vocabulary.getDisplayName(i));
}
for (size_t i = 0; i < atn.getNumberOfDecisions(); ++i) {
_decisionToDFA.push_back(dfa::DFA(_atn.getDecisionState(i), i));
}
_interpreter = new atn::LexerATNSimulator(
this, _atn, _decisionToDFA,
_sharedContextCache); /* mem-check: deleted in d-tor */
}
LexerInterpreter::~LexerInterpreter() { delete _interpreter; }
const atn::ATN& LexerInterpreter::getATN() const { return _atn; }
std::string LexerInterpreter::getGrammarFileName() const {
return _grammarFileName;
}
const std::vector<std::string>& LexerInterpreter::getTokenNames() const {
return _tokenNames;
}
const std::vector<std::string>& LexerInterpreter::getRuleNames() const {
return _ruleNames;
}
const std::vector<std::string>& LexerInterpreter::getChannelNames() const {
return _channelNames;
}
const std::vector<std::string>& LexerInterpreter::getModeNames() const {
return _modeNames;
}
const dfa::Vocabulary& LexerInterpreter::getVocabulary() const {
return _vocabulary;
}
/* 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 "Vocabulary.h"
#include "atn/PredictionContext.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
/* 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.
*/
#include "CharStream.h"
#include "Lexer.h"
#include "misc/Interval.h"
#include "support/CPPUtils.h"
#include "LexerNoViableAltException.h"
using namespace antlr4;
LexerNoViableAltException::LexerNoViableAltException(
Lexer* lexer, CharStream* input, size_t startIndex,
atn::ATNConfigSet* deadEndConfigs)
: RecognitionException(lexer, input, nullptr, nullptr),
_startIndex(startIndex),
_deadEndConfigs(deadEndConfigs) {}
size_t LexerNoViableAltException::getStartIndex() { return _startIndex; }
atn::ATNConfigSet* LexerNoViableAltException::getDeadEndConfigs() {
return _deadEndConfigs;
}
std::string LexerNoViableAltException::toString() {
std::string symbol;
if (_startIndex < getInputStream()->size()) {
symbol = static_cast<CharStream*>(getInputStream())
->getText(misc::Interval(_startIndex, _startIndex));
symbol = antlrcpp::escapeWhitespace(symbol, false);
}
std::string format = "LexerNoViableAltException('" + symbol + "')";
return format;
}
/* 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
/* 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.
*/
#include "CharStream.h"
#include "CommonToken.h"
#include "Token.h"
#include "ListTokenSource.h"
using namespace antlr4;
ListTokenSource::ListTokenSource(std::vector<std::unique_ptr<Token>> tokens_)
: ListTokenSource(std::move(tokens_), "") {}
ListTokenSource::ListTokenSource(std::vector<std::unique_ptr<Token>> tokens_,
const std::string& sourceName_)
: tokens(std::move(tokens_)), sourceName(sourceName_) {
InitializeInstanceFields();
if (tokens.empty()) {
throw "tokens cannot be null";
}
// Check if there is an eof token and create one if not.
if (tokens.back()->getType() != Token::EOF) {
Token* lastToken = tokens.back().get();
size_t start = INVALID_INDEX;
size_t previousStop = lastToken->getStopIndex();
if (previousStop != INVALID_INDEX) {
start = previousStop + 1;
}
size_t stop = std::max(INVALID_INDEX, start - 1);
tokens.emplace_back((_factory->create(
{this, getInputStream()}, Token::EOF, "EOF", Token::DEFAULT_CHANNEL,
start, stop, static_cast<int>(lastToken->getLine()),
lastToken->getCharPositionInLine())));
}
}
size_t ListTokenSource::getCharPositionInLine() {
if (i < tokens.size()) {
return tokens[i]->getCharPositionInLine();
}
return 0;
}
std::unique_ptr<Token> ListTokenSource::nextToken() {
if (i < tokens.size()) {
return std::move(tokens[i++]);
}
return nullptr;
}
size_t ListTokenSource::getLine() const {
if (i < tokens.size()) {
return tokens[i]->getLine();
}
return 1;
}
CharStream* ListTokenSource::getInputStream() {
if (i < tokens.size()) {
return tokens[i]->getInputStream();
} else if (!tokens.empty()) {
return tokens.back()->getInputStream();
}
// no input stream information is available
return nullptr;
}
std::string ListTokenSource::getSourceName() {
if (sourceName != "") {
return sourceName;
}
CharStream* inputStream = getInputStream();
if (inputStream != nullptr) {
return inputStream->getSourceName();
}
return "List";
}
Ref<TokenFactory<CommonToken>> ListTokenSource::getTokenFactory() {
return _factory;
}
void ListTokenSource::InitializeInstanceFields() {
i = 0;
_factory = CommonTokenFactory::DEFAULT;
}
/* 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.
*/
#include "Parser.h"
#include "NoViableAltException.h"
using namespace antlr4;
NoViableAltException::NoViableAltException(Parser* recognizer)
: NoViableAltException(recognizer, recognizer->getTokenStream(),
recognizer->getCurrentToken(),
recognizer->getCurrentToken(), nullptr,
recognizer->getContext()) {}
NoViableAltException::NoViableAltException(Parser* recognizer,
TokenStream* input,
Token* startToken,
Token* offendingToken,
atn::ATNConfigSet* deadEndConfigs,
ParserRuleContext* ctx)
: RecognitionException("No viable alternative", recognizer, input, ctx,
offendingToken),
_deadEndConfigs(deadEndConfigs),
_startToken(startToken) {}
Token* NoViableAltException::getStartToken() const { return _startToken; }
atn::ATNConfigSet* NoViableAltException::getDeadEndConfigs() const {
return _deadEndConfigs;
}
This diff is collapsed.
This diff is collapsed.
/* 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.
*/
#include "atn/ATN.h"
#include "RuleContextWithAltNum.h"
using namespace antlr4;
using namespace antlr4::atn;
RuleContextWithAltNum::RuleContextWithAltNum() : ParserRuleContext() {
altNum = ATN::INVALID_ALT_NUMBER;
}
RuleContextWithAltNum::RuleContextWithAltNum(ParserRuleContext* parent,
int invokingStateNumber)
: ParserRuleContext(parent, invokingStateNumber) {}
size_t RuleContextWithAltNum::getAltNumber() const { return altNum; }
void RuleContextWithAltNum::setAltNumber(size_t number) { altNum = number; }
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment