forked from jasder/antlr
More optimizations of the runtime.
- Lesser use of shared_ptr, e.g. in listeners and some loops. - Removed useless access methods for children in ParseRuleContext. The child list is public. Fixed initialization for start and stop nodes. - Simplified parent + child organization in Tree and all derived classes. Instead of using overridable functions in various descendants we have now central parent + child fields in the base tree class (where they belong actually, considering this is about forming a tree). Users have to cast to the appropriate classes if necessary. - Removed obsolete getChildren() function in Trees helper. We can just return the child vector. - Changed edges member to an unordered_map, as this is a sparse container. This speeds up certain grammars by 1000% (e.g. highly recursive expression rules) and avoids wasting a lot of memory. This change also simplifies handling significantly.
This commit is contained in:
parent
ee2510e654
commit
6f62821573
|
@ -60,7 +60,7 @@ 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::utfConverter.from_bytes(input.substr(3, std::string::npos));
|
||||
_data = antlrcpp::utfConverter.from_bytes(input.data() + 3, input.data() + input.size() - 3);
|
||||
else
|
||||
_data = antlrcpp::utfConverter.from_bytes(input);
|
||||
p = 0;
|
||||
|
|
|
@ -39,12 +39,12 @@
|
|||
using namespace antlr4;
|
||||
|
||||
void BailErrorStrategy::recover(Parser *recognizer, std::exception_ptr e) {
|
||||
Ref<ParserRuleContext> context = recognizer->getContext();
|
||||
ParserRuleContext *context = recognizer->getContext().get();
|
||||
do {
|
||||
context->exception = e;
|
||||
if (context->getParent().expired())
|
||||
if (context->parent.expired())
|
||||
break;
|
||||
context = context->getParent().lock();
|
||||
context = (ParserRuleContext *)context->parent.lock().get();
|
||||
} while (true);
|
||||
|
||||
try {
|
||||
|
@ -63,12 +63,12 @@ Token* BailErrorStrategy::recoverInline(Parser *recognizer) {
|
|||
InputMismatchException e(recognizer);
|
||||
std::exception_ptr exception = std::make_exception_ptr(e);
|
||||
|
||||
Ref<ParserRuleContext> context = recognizer->getContext();
|
||||
ParserRuleContext *context = recognizer->getContext().get();
|
||||
do {
|
||||
context->exception = exception;
|
||||
if (context->getParent().expired())
|
||||
if (context->parent.expired())
|
||||
break;
|
||||
context = context->getParent().lock();
|
||||
context = (ParserRuleContext *)context->parent.lock().get();
|
||||
} while (true);
|
||||
|
||||
try {
|
||||
|
|
|
@ -329,7 +329,7 @@ std::string DefaultErrorStrategy::escapeWSAndQuote(const std::string &s) const {
|
|||
|
||||
misc::IntervalSet DefaultErrorStrategy::getErrorRecoverySet(Parser *recognizer) {
|
||||
const atn::ATN &atn = recognizer->getInterpreter<atn::ATNSimulator>()->atn;
|
||||
Ref<RuleContext> ctx = recognizer->getContext();
|
||||
RuleContext *ctx = recognizer->getContext().get();
|
||||
misc::IntervalSet recoverSet;
|
||||
while (ctx->invokingState >= 0) {
|
||||
// compute what follows who invoked us
|
||||
|
@ -340,7 +340,7 @@ misc::IntervalSet DefaultErrorStrategy::getErrorRecoverySet(Parser *recognizer)
|
|||
|
||||
if (ctx->parent.expired())
|
||||
break;
|
||||
ctx = ctx->parent.lock();
|
||||
ctx = (RuleContext *)ctx->parent.lock().get();
|
||||
}
|
||||
recoverSet.remove(Token::EPSILON);
|
||||
|
||||
|
|
|
@ -66,6 +66,7 @@ void Lexer::reset() {
|
|||
tokenStartCharIndex = -1;
|
||||
tokenStartCharPositionInLine = 0;
|
||||
tokenStartLine = 0;
|
||||
type = 0;
|
||||
_text = "";
|
||||
|
||||
hitEOF = false;
|
||||
|
|
|
@ -64,12 +64,12 @@ void Parser::TraceListener::enterEveryRule(ParserRuleContext *ctx) {
|
|||
<< ", LT(1)=" << outerInstance->_input->LT(1)->getText() << std::endl;
|
||||
}
|
||||
|
||||
void Parser::TraceListener::visitTerminal(Ref<tree::TerminalNode> const& node) {
|
||||
void Parser::TraceListener::visitTerminal(tree::TerminalNode *node) {
|
||||
std::cout << "consume " << node->getSymbol() << " rule "
|
||||
<< outerInstance->getRuleNames()[(size_t)outerInstance->getContext()->getRuleIndex()] << std::endl;
|
||||
}
|
||||
|
||||
void Parser::TraceListener::visitErrorNode(Ref<tree::ErrorNode> const& /*node*/) {
|
||||
void Parser::TraceListener::visitErrorNode(tree::ErrorNode * /*node*/) {
|
||||
}
|
||||
|
||||
void Parser::TraceListener::exitEveryRule(ParserRuleContext *ctx) {
|
||||
|
@ -82,10 +82,10 @@ Parser::TrimToSizeListener Parser::TrimToSizeListener::INSTANCE;
|
|||
void Parser::TrimToSizeListener::enterEveryRule(ParserRuleContext * /*ctx*/) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::visitTerminal(Ref<tree::TerminalNode> const& /*node*/) {
|
||||
void Parser::TrimToSizeListener::visitTerminal(tree::TerminalNode * /*node*/) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::visitErrorNode(Ref<tree::ErrorNode> const& /*node*/) {
|
||||
void Parser::TrimToSizeListener::visitErrorNode(tree::ErrorNode * /*node*/) {
|
||||
}
|
||||
|
||||
void Parser::TrimToSizeListener::exitEveryRule(ParserRuleContext * ctx) {
|
||||
|
@ -107,6 +107,7 @@ void Parser::reset() {
|
|||
}
|
||||
_errHandler->reset(this); // Watch out, this is not shared_ptr.reset().
|
||||
|
||||
_matchedEOF = false;
|
||||
_syntaxErrors = 0;
|
||||
setTrace(false);
|
||||
_precedenceStack.clear();
|
||||
|
@ -320,14 +321,14 @@ Token* Parser::consume() {
|
|||
Ref<tree::ErrorNode> node = _ctx->addErrorNode(o);
|
||||
if (_parseListeners.size() > 0) {
|
||||
for (auto listener : _parseListeners) {
|
||||
listener->visitErrorNode(node);
|
||||
listener->visitErrorNode(node.get());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ref<tree::TerminalNode> node = _ctx->addChild(o);
|
||||
if (_parseListeners.size() > 0) {
|
||||
for (auto listener : _parseListeners) {
|
||||
listener->visitTerminal(node);
|
||||
listener->visitTerminal(node.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -517,7 +518,7 @@ bool Parser::isMatchedEOF() const {
|
|||
}
|
||||
|
||||
misc::IntervalSet Parser::getExpectedTokens() {
|
||||
return getATN().getExpectedTokens(getState(), getContext());
|
||||
return getATN().getExpectedTokens(getState(), getContext().get());
|
||||
}
|
||||
|
||||
misc::IntervalSet Parser::getExpectedTokensWithinCurrentRule() {
|
||||
|
@ -557,7 +558,7 @@ std::vector<std::string> Parser::getRuleInvocationStack(Ref<RuleContext> const&
|
|||
}
|
||||
if (p->parent.expired())
|
||||
break;
|
||||
run = run->parent.lock().get();
|
||||
run = (RuleContext *)run->parent.lock().get();
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
|
|
@ -49,8 +49,8 @@ namespace antlr4 {
|
|||
virtual ~TraceListener() {};
|
||||
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void visitTerminal(Ref<tree::TerminalNode> const& node) override;
|
||||
virtual void visitErrorNode(Ref<tree::ErrorNode> const& node) override;
|
||||
virtual void visitTerminal(tree::TerminalNode *node) override;
|
||||
virtual void visitErrorNode(tree::ErrorNode *node) override;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) override;
|
||||
|
||||
private:
|
||||
|
@ -64,8 +64,8 @@ namespace antlr4 {
|
|||
virtual ~TrimToSizeListener() {};
|
||||
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) override;
|
||||
virtual void visitTerminal(Ref<tree::TerminalNode> const& node) override;
|
||||
virtual void visitErrorNode(Ref<tree::ErrorNode> const& node) override;
|
||||
virtual void visitTerminal(tree::TerminalNode *node) override;
|
||||
virtual void visitErrorNode(tree::ErrorNode *node) override;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) override;
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ using namespace antlrcpp;
|
|||
|
||||
const Ref<ParserRuleContext> ParserRuleContext::EMPTY = std::make_shared<ParserRuleContext>();
|
||||
|
||||
ParserRuleContext::ParserRuleContext() {
|
||||
ParserRuleContext::ParserRuleContext() : start(nullptr), stop(nullptr) {
|
||||
}
|
||||
|
||||
void ParserRuleContext::copyFrom(Ref<ParserRuleContext> const& ctx) {
|
||||
|
@ -94,10 +94,6 @@ Ref<tree::ErrorNode> ParserRuleContext::addErrorNode(Token *badToken) {
|
|||
return t;
|
||||
}
|
||||
|
||||
Ref<tree::Tree> ParserRuleContext::getChildReference(std::size_t i) {
|
||||
return children[i];
|
||||
}
|
||||
|
||||
Ref<tree::TerminalNode> ParserRuleContext::getToken(int ttype, std::size_t i) {
|
||||
if (i >= children.size()) {
|
||||
return nullptr;
|
||||
|
@ -134,10 +130,6 @@ std::vector<Ref<tree::TerminalNode>> ParserRuleContext::getTokens(int ttype) {
|
|||
return tokens;
|
||||
}
|
||||
|
||||
std::size_t ParserRuleContext::getChildCount() {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
misc::Interval ParserRuleContext::getSourceInterval() {
|
||||
if (start == nullptr) {
|
||||
return misc::Interval::INVALID;
|
||||
|
|
|
@ -63,13 +63,6 @@ namespace antlr4 {
|
|||
public:
|
||||
static const Ref<ParserRuleContext> EMPTY;
|
||||
|
||||
/// If we are debugging or building a parse tree for a visitor,
|
||||
/// we need to track all of the tokens and rule invocations associated
|
||||
/// with this rule's context. This is empty for parsing w/o tree constr.
|
||||
/// operation because we don't the need to track the details about
|
||||
/// how we parse this rule.
|
||||
std::vector<Ref<ParseTree>> children;
|
||||
|
||||
/// <summary>
|
||||
/// For debugging/tracing purposes, we want to track all of the nodes in
|
||||
/// the ATN traversed by the parser for a particular rule.
|
||||
|
@ -125,10 +118,6 @@ namespace antlr4 {
|
|||
virtual Ref<tree::TerminalNode> addChild(Token *matchedToken);
|
||||
virtual Ref<tree::ErrorNode> addErrorNode(Token *badToken);
|
||||
|
||||
std::weak_ptr<ParserRuleContext> getParent() {
|
||||
return std::dynamic_pointer_cast<ParserRuleContext>(getParentReference().lock());
|
||||
};
|
||||
|
||||
virtual Ref<tree::TerminalNode> getToken(int ttype, std::size_t i);
|
||||
|
||||
virtual std::vector<Ref<tree::TerminalNode>> getTokens(int ttype);
|
||||
|
@ -162,7 +151,6 @@ namespace antlr4 {
|
|||
return contexts;
|
||||
}
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
virtual misc::Interval getSourceInterval() override;
|
||||
|
||||
/**
|
||||
|
@ -182,9 +170,6 @@ namespace antlr4 {
|
|||
/// <summary>
|
||||
/// Used for rule context info debugging during parse-time, not so much for ATN debugging </summary>
|
||||
virtual std::string toInfoString(Parser *recognizer);
|
||||
|
||||
protected:
|
||||
virtual Ref<Tree> getChildReference(size_t i) override;
|
||||
};
|
||||
|
||||
} // namespace antlr4
|
||||
|
|
|
@ -63,7 +63,7 @@ void RecognitionException::setOffendingState(int offendingState) {
|
|||
|
||||
misc::IntervalSet RecognitionException::getExpectedTokens() const {
|
||||
if (_recognizer) {
|
||||
return _recognizer->getATN().getExpectedTokens(_offendingState, _ctx);
|
||||
return _recognizer->getATN().getExpectedTokens(_offendingState, _ctx.get());
|
||||
}
|
||||
return misc::IntervalSet::EMPTY_SET;
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ RuleContext::RuleContext(std::weak_ptr<RuleContext> parent, int invokingState) {
|
|||
|
||||
int RuleContext::depth() {
|
||||
int n = 1;
|
||||
Ref<RuleContext> p = shared_from_this();
|
||||
RuleContext *p = this;
|
||||
while (true) {
|
||||
if (p->parent.expired())
|
||||
break;
|
||||
p = p->parent.lock();
|
||||
p = (RuleContext *)p->parent.lock().get();
|
||||
n++;
|
||||
}
|
||||
return n;
|
||||
|
@ -73,21 +73,19 @@ Ref<RuleContext> RuleContext::getRuleContext() {
|
|||
return shared_from_this();
|
||||
}
|
||||
|
||||
std::weak_ptr<tree::Tree> RuleContext::getParentReference()
|
||||
{
|
||||
return std::dynamic_pointer_cast<tree::Tree>(parent.lock());
|
||||
}
|
||||
|
||||
std::string RuleContext::getText() {
|
||||
if (getChildCount() == 0) {
|
||||
if (children.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
for (size_t i = 0; i < getChildCount(); i++) {
|
||||
for (size_t i = 0; i < children.size(); i++) {
|
||||
if (i > 0)
|
||||
ss << ", ";
|
||||
ss << getChild(i)->getText();
|
||||
|
||||
Ref<ParseTree> tree = std::dynamic_pointer_cast<ParseTree>(children[i]);
|
||||
if (tree != nullptr)
|
||||
ss << tree->getText();
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
|
@ -97,11 +95,6 @@ ssize_t RuleContext::getRuleIndex() const {
|
|||
return -1;
|
||||
}
|
||||
|
||||
Ref<tree::Tree> RuleContext::getChildReference(size_t /*i*/) {
|
||||
return Ref<tree::Tree>();
|
||||
}
|
||||
|
||||
|
||||
int RuleContext::getAltNumber() const {
|
||||
return atn::ATN::INVALID_ALT_NUMBER;
|
||||
}
|
||||
|
@ -109,10 +102,6 @@ int RuleContext::getAltNumber() const {
|
|||
void RuleContext::setAltNumber(int /*altNumber*/) {
|
||||
}
|
||||
|
||||
std::size_t RuleContext::getChildCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
antlrcpp::Any RuleContext::accept(tree::ParseTreeVisitor *visitor) {
|
||||
return visitor->visitChildren(this);
|
||||
}
|
||||
|
@ -138,9 +127,9 @@ std::string RuleContext::toString(const std::vector<std::string> &ruleNames) {
|
|||
std::string RuleContext::toString(const std::vector<std::string> &ruleNames, Ref<RuleContext> const& stop) {
|
||||
std::stringstream ss;
|
||||
|
||||
Ref<RuleContext> currentParent = shared_from_this();
|
||||
RuleContext *currentParent = this;
|
||||
ss << "[";
|
||||
while (currentParent != stop) {
|
||||
while (currentParent != stop.get()) {
|
||||
if (ruleNames.empty()) {
|
||||
if (!currentParent->isEmpty()) {
|
||||
ss << currentParent->invokingState;
|
||||
|
@ -154,7 +143,7 @@ std::string RuleContext::toString(const std::vector<std::string> &ruleNames, Ref
|
|||
|
||||
if (currentParent->parent.expired()) // No parent anymore.
|
||||
break;
|
||||
currentParent = currentParent->parent.lock();
|
||||
currentParent = (RuleContext *)currentParent->parent.lock().get();
|
||||
if (!ruleNames.empty() || !currentParent->isEmpty()) {
|
||||
ss << " ";
|
||||
}
|
||||
|
|
|
@ -87,9 +87,6 @@ namespace antlr4 {
|
|||
*/
|
||||
class ANTLR4CPP_PUBLIC RuleContext : public tree::RuleNode, public std::enable_shared_from_this<RuleContext> {
|
||||
public:
|
||||
/// What context invoked this rule?
|
||||
std::weak_ptr<RuleContext> parent;
|
||||
|
||||
/// What state invoked the rule associated with this context?
|
||||
/// The "return address" is the followState of invokingState
|
||||
/// If parent is null, this should be -1 and this context object represents the start rule.
|
||||
|
@ -134,8 +131,6 @@ namespace antlr4 {
|
|||
*/
|
||||
virtual void setAltNumber(int altNumber);
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
|
||||
virtual antlrcpp::Any accept(tree::ParseTreeVisitor *visitor) override;
|
||||
|
||||
/// <summary>
|
||||
|
@ -163,10 +158,6 @@ namespace antlr4 {
|
|||
|
||||
bool operator == (const RuleContext &other) { return this == &other; } // Simple address comparison.
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() override;
|
||||
virtual Ref<Tree> getChildReference(size_t i) override;
|
||||
|
||||
private:
|
||||
void InitializeInstanceFields();
|
||||
};
|
||||
|
|
|
@ -150,12 +150,12 @@ int ATN::getNumberOfDecisions() const {
|
|||
return (int)decisionToState.size();
|
||||
}
|
||||
|
||||
misc::IntervalSet ATN::getExpectedTokens(int stateNumber, Ref<RuleContext> const& context) const {
|
||||
misc::IntervalSet ATN::getExpectedTokens(int stateNumber, RuleContext *context) const {
|
||||
if (stateNumber < 0 || stateNumber >= (int)states.size()) {
|
||||
throw IllegalArgumentException("Invalid state number.");
|
||||
}
|
||||
|
||||
Ref<RuleContext> ctx = context;
|
||||
RuleContext *ctx = context;
|
||||
ATNState *s = states.at((size_t)stateNumber);
|
||||
misc::IntervalSet following = nextTokens(s);
|
||||
if (!following.contains(Token::EPSILON)) {
|
||||
|
@ -175,7 +175,7 @@ misc::IntervalSet ATN::getExpectedTokens(int stateNumber, Ref<RuleContext> const
|
|||
if (ctx->parent.expired()) {
|
||||
break;
|
||||
}
|
||||
ctx = ctx->parent.lock();
|
||||
ctx = (RuleContext *)ctx->parent.lock().get();
|
||||
}
|
||||
|
||||
if (following.contains(Token::EPSILON)) {
|
||||
|
|
|
@ -126,7 +126,7 @@ namespace atn {
|
|||
/// specified state in the specified context. </returns>
|
||||
/// <exception cref="IllegalArgumentException"> if the ATN does not contain a state with
|
||||
/// number {@code stateNumber} </exception>
|
||||
virtual misc::IntervalSet getExpectedTokens(int stateNumber, Ref<RuleContext> const& context) const;
|
||||
virtual misc::IntervalSet getExpectedTokens(int stateNumber, RuleContext *context) const;
|
||||
|
||||
std::string toString() const;
|
||||
};
|
||||
|
|
|
@ -52,7 +52,6 @@
|
|||
#define DEBUG_ATN 0
|
||||
#define DEBUG_DFA 0
|
||||
|
||||
|
||||
using namespace antlr4;
|
||||
using namespace antlr4::atn;
|
||||
using namespace antlrcpp;
|
||||
|
@ -114,8 +113,7 @@ int LexerATNSimulator::match(CharStream *input, size_t mode) {
|
|||
|
||||
void LexerATNSimulator::reset() {
|
||||
_prevAccept.reset();
|
||||
_startIndex = 0; // Originally -1, but that would require a signed type with many casts.
|
||||
// The initial value is never tested, so it doesn't matter which value is set here.
|
||||
_startIndex = -1;
|
||||
_line = 1;
|
||||
_charPositionInLine = 0;
|
||||
_mode = Lexer::DEFAULT_MODE;
|
||||
|
@ -551,11 +549,7 @@ void LexerATNSimulator::addDFAEdge(dfa::DFAState *p, ssize_t t, dfa::DFAState *q
|
|||
}
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
if (p->edges.empty()) {
|
||||
// make room for tokens 1..n and -1 masquerading as index 0
|
||||
p->edges.resize(MAX_DFA_EDGE - MIN_DFA_EDGE + 1);
|
||||
}
|
||||
p->edges[(size_t)(t - MIN_DFA_EDGE)] = q; // connect
|
||||
p->edges[t - MIN_DFA_EDGE] = q; // connect
|
||||
}
|
||||
|
||||
dfa::DFAState *LexerATNSimulator::addDFAState(ATNConfigSet *configs) {
|
||||
|
|
|
@ -270,12 +270,12 @@ int ParserATNSimulator::execATN(dfa::DFA &dfa, dfa::DFAState *s0, TokenStream *i
|
|||
}
|
||||
|
||||
dfa::DFAState *ParserATNSimulator::getExistingTargetState(dfa::DFAState *previousD, ssize_t t) {
|
||||
std::vector<dfa::DFAState *> edges = previousD->edges;
|
||||
if (edges.size() == 0 || t + 1 < 0 || t + 1 >= (ssize_t)edges.size()) {
|
||||
auto iterator = previousD->edges.find(t);
|
||||
if (iterator == previousD->edges.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return edges[(size_t)t + 1];
|
||||
return iterator->second;
|
||||
}
|
||||
|
||||
dfa::DFAState *ParserATNSimulator::computeTargetState(dfa::DFA &dfa, dfa::DFAState *previousD, ssize_t t) {
|
||||
|
@ -1181,9 +1181,7 @@ dfa::DFAState *ParserATNSimulator::addDFAEdge(dfa::DFA &dfa, dfa::DFAState *from
|
|||
|
||||
{
|
||||
std::lock_guard<std::recursive_mutex> lck(mtx);
|
||||
if (from->edges.empty())
|
||||
from->edges.resize(atn.maxTokenType + 1 + 1);
|
||||
from->edges[(size_t)(t + 1)] = to; // connect
|
||||
from->edges[t] = to; // connect
|
||||
}
|
||||
|
||||
#if DEBUG_DFA == 1
|
||||
|
|
|
@ -67,7 +67,7 @@ Ref<PredictionContext> PredictionContext::fromRuleContext(const ATN &atn, const
|
|||
}
|
||||
|
||||
// If we have a parent, convert it to a PredictionContext graph
|
||||
Ref<PredictionContext> parent = PredictionContext::fromRuleContext(atn, outerContext->parent.lock());
|
||||
Ref<PredictionContext> parent = PredictionContext::fromRuleContext(atn, std::dynamic_pointer_cast<RuleContext>(outerContext->parent.lock()));
|
||||
|
||||
ATNState *state = atn.states.at((size_t)outerContext->invokingState);
|
||||
RuleTransition *transition = (RuleTransition *)state->transition(0);
|
||||
|
|
|
@ -83,16 +83,13 @@ bool DFA::isPrecedenceDfa() const {
|
|||
}
|
||||
|
||||
DFAState* DFA::getPrecedenceStartState(int precedence) const {
|
||||
if (!isPrecedenceDfa()) {
|
||||
throw IllegalStateException("Only precedence DFAs may contain a precedence start state.");
|
||||
}
|
||||
assert(_precedenceDfa); // Only precedence DFAs may contain a precedence start state.
|
||||
|
||||
// s0.edges is never null for a precedence DFA
|
||||
if (precedence < 0 || precedence >= (int)s0->edges.size()) {
|
||||
auto iterator = s0->edges.find(precedence);
|
||||
if (iterator == s0->edges.end())
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return s0->edges[precedence];
|
||||
return iterator->second;
|
||||
}
|
||||
|
||||
void DFA::setPrecedenceStartState(int precedence, DFAState *startState) {
|
||||
|
@ -104,13 +101,8 @@ void DFA::setPrecedenceStartState(int precedence, DFAState *startState) {
|
|||
return;
|
||||
}
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(_lock);
|
||||
{
|
||||
// s0.edges is never null for a precedence DFA
|
||||
if (precedence >= (int)s0->edges.size()) {
|
||||
s0->edges.resize(precedence + 1);
|
||||
}
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(_lock);
|
||||
s0->edges[precedence] = startState;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,11 +81,10 @@ namespace dfa {
|
|||
|
||||
std::unique_ptr<atn::ATNConfigSet> configs;
|
||||
|
||||
/// <summary>
|
||||
/// {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1)
|
||||
/// <seealso cref="Token#EOF"/> maps to {@code edges[0]}.
|
||||
/// </summary>
|
||||
std::vector<DFAState *> edges;
|
||||
// ml: this is a sparse list, so we use a map instead of a vector.
|
||||
std::unordered_map<ssize_t, DFAState *> edges;
|
||||
|
||||
bool isAcceptState;
|
||||
|
||||
|
|
|
@ -60,13 +60,13 @@ namespace tree {
|
|||
*/
|
||||
virtual antlrcpp::Any visitChildren(RuleNode *node) override {
|
||||
antlrcpp::Any result = defaultResult();
|
||||
size_t n = node->getChildCount();
|
||||
size_t n = node->children.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (!shouldVisitNextChild(node, result)) {
|
||||
break;
|
||||
}
|
||||
|
||||
Ref<ParseTree> c = node->getChild(i);
|
||||
Ref<ParseTree> c = std::dynamic_pointer_cast<ParseTree>(node->children[i]);
|
||||
antlrcpp::Any childResult = c->accept(this);
|
||||
result = aggregateResult(result, childResult);
|
||||
}
|
||||
|
|
|
@ -37,20 +37,14 @@
|
|||
namespace antlr4 {
|
||||
namespace tree {
|
||||
|
||||
/// <summary>
|
||||
/// An interface to access the tree of <seealso cref="RuleContext"/> objects created
|
||||
/// during a parse that makes the data structure look like a simple parse tree.
|
||||
/// This node represents both internal nodes, rule invocations,
|
||||
/// and leaf nodes, token matches.
|
||||
/// <p/>
|
||||
/// The payload is either a <seealso cref="Token"/> or a <seealso cref="RuleContext"/> object.
|
||||
/// </summary>
|
||||
/// during a parse that makes the data structure look like a simple parse tree.
|
||||
/// This node represents both internal nodes, rule invocations,
|
||||
/// and leaf nodes, token matches.
|
||||
///
|
||||
/// The payload is either a <seealso cref="Token"/> or a <seealso cref="RuleContext"/> object.
|
||||
class ANTLR4CPP_PUBLIC ParseTree : public SyntaxTree {
|
||||
public:
|
||||
// the following methods narrow the return type; they are not additional methods
|
||||
std::weak_ptr<ParseTree> getParent() { return std::dynamic_pointer_cast<ParseTree>(getParentReference().lock()); };
|
||||
virtual Ref<ParseTree> getChild(size_t i) { return std::dynamic_pointer_cast<ParseTree>(getChildReference(i)); };
|
||||
|
||||
/// The <seealso cref="ParseTreeVisitor"/> needs a double dispatch method.
|
||||
// ml: This has been changed to use Any instead of a template parameter, to avoid the need of a virtual template function.
|
||||
virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) = 0;
|
||||
|
|
|
@ -51,8 +51,8 @@ namespace tree {
|
|||
public:
|
||||
virtual ~ParseTreeListener() {};
|
||||
|
||||
virtual void visitTerminal(Ref<TerminalNode> const& node) = 0;
|
||||
virtual void visitErrorNode(Ref<ErrorNode> const& node) = 0;
|
||||
virtual void visitTerminal(TerminalNode *node) = 0;
|
||||
virtual void visitErrorNode(ErrorNode *node) = 0;
|
||||
virtual void enterEveryRule(ParserRuleContext *ctx) = 0;
|
||||
virtual void exitEveryRule(ParserRuleContext *ctx) = 0;
|
||||
|
||||
|
|
|
@ -41,30 +41,30 @@ using namespace antlrcpp;
|
|||
|
||||
ParseTreeWalker ParseTreeWalker::DEFAULT;
|
||||
|
||||
void ParseTreeWalker::walk(ParseTreeListener *listener, Ref<ParseTree> const& t) {
|
||||
if (is<ErrorNode>(t)) {
|
||||
listener->visitErrorNode(std::dynamic_pointer_cast<ErrorNode>(t));
|
||||
void ParseTreeWalker::walk(ParseTreeListener *listener, ParseTree *t) const {
|
||||
if (is<ErrorNode *>(t)) {
|
||||
listener->visitErrorNode(dynamic_cast<ErrorNode *>(t));
|
||||
return;
|
||||
} else if (is<TerminalNode>(t)) {
|
||||
listener->visitTerminal(std::dynamic_pointer_cast<TerminalNode>(t));
|
||||
} else if (is<TerminalNode *>(t)) {
|
||||
listener->visitTerminal(dynamic_cast<TerminalNode *>(t));
|
||||
return;
|
||||
}
|
||||
Ref<RuleNode> r = std::dynamic_pointer_cast<RuleNode>(t);
|
||||
|
||||
RuleNode *r = dynamic_cast<RuleNode *>(t);
|
||||
enterRule(listener, r);
|
||||
std::size_t n = r->getChildCount();
|
||||
for (std::size_t i = 0; i < n; i++) {
|
||||
walk(listener, r->getChild(i));
|
||||
for (auto &child : r->children) {
|
||||
walk(listener, dynamic_cast<ParseTree *>(child.get()));
|
||||
}
|
||||
exitRule(listener, r);
|
||||
}
|
||||
|
||||
void ParseTreeWalker::enterRule(ParseTreeListener *listener, Ref<RuleNode> const& r) {
|
||||
void ParseTreeWalker::enterRule(ParseTreeListener *listener, RuleNode *r) const {
|
||||
Ref<ParserRuleContext> ctx = std::dynamic_pointer_cast<ParserRuleContext>(r->getRuleContext());
|
||||
listener->enterEveryRule(ctx.get());
|
||||
ctx->enterRule(listener);
|
||||
}
|
||||
|
||||
void ParseTreeWalker::exitRule(ParseTreeListener *listener, Ref<RuleNode> const& r) {
|
||||
void ParseTreeWalker::exitRule(ParseTreeListener *listener, RuleNode *r) const {
|
||||
Ref<ParserRuleContext> ctx = std::dynamic_pointer_cast<ParserRuleContext>(r->getRuleContext());
|
||||
ctx->exitRule(listener);
|
||||
listener->exitEveryRule(ctx.get());
|
||||
|
|
|
@ -40,16 +40,15 @@ namespace tree {
|
|||
|
||||
virtual ~ParseTreeWalker() {};
|
||||
|
||||
virtual void walk(ParseTreeListener *listener, Ref<ParseTree> const& t);
|
||||
virtual void walk(ParseTreeListener *listener, ParseTree *t) const;
|
||||
|
||||
protected:
|
||||
/// The discovery of a rule node, involves sending two events: the generic
|
||||
/// <seealso cref="ParseTreeListener#enterEveryRule"/> and a
|
||||
/// <seealso cref="RuleContext"/>-specific event. First we trigger the generic and then
|
||||
/// the rule specific. We do them in reverse order upon finishing the node.
|
||||
protected:
|
||||
virtual void enterRule(ParseTreeListener *listener, Ref<RuleNode> const& r);
|
||||
|
||||
virtual void exitRule(ParseTreeListener *listener, Ref<RuleNode> const& r);
|
||||
virtual void enterRule(ParseTreeListener *listener, RuleNode *r) const;
|
||||
virtual void exitRule(ParseTreeListener *listener, RuleNode *r) const;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -54,10 +54,6 @@ misc::Interval TerminalNodeImpl::getSourceInterval() {
|
|||
return misc::Interval(tokenIndex, tokenIndex);
|
||||
}
|
||||
|
||||
std::size_t TerminalNodeImpl::getChildCount() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
antlrcpp::Any TerminalNodeImpl::accept(ParseTreeVisitor *visitor) {
|
||||
return visitor->visitTerminal(this);
|
||||
}
|
||||
|
@ -80,11 +76,3 @@ std::string TerminalNodeImpl::toString() {
|
|||
std::string TerminalNodeImpl::toStringTree() {
|
||||
return toString();
|
||||
}
|
||||
|
||||
std::weak_ptr<Tree> TerminalNodeImpl::getParentReference() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
Ref<Tree> TerminalNodeImpl::getChildReference(size_t /*i*/) {
|
||||
return Ref<Tree>();
|
||||
}
|
||||
|
|
|
@ -39,15 +39,12 @@ namespace tree {
|
|||
class ANTLR4CPP_PUBLIC TerminalNodeImpl : public virtual TerminalNode {
|
||||
public:
|
||||
Token *symbol;
|
||||
std::weak_ptr<ParseTree> parent;
|
||||
|
||||
TerminalNodeImpl(Token *symbol);
|
||||
|
||||
virtual Token* getSymbol() override;
|
||||
virtual misc::Interval getSourceInterval() override;
|
||||
|
||||
virtual std::size_t getChildCount() override;
|
||||
|
||||
virtual antlrcpp::Any accept(ParseTreeVisitor *visitor) override;
|
||||
|
||||
virtual std::string getText() override;
|
||||
|
@ -55,9 +52,6 @@ namespace tree {
|
|||
virtual std::string toString() override;
|
||||
virtual std::string toStringTree() override;
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() override;
|
||||
virtual Ref<Tree> getChildReference(size_t i) override;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -36,52 +36,30 @@
|
|||
namespace antlr4 {
|
||||
namespace tree {
|
||||
|
||||
/// <summary>
|
||||
/// The basic notion of a tree has a parent, a payload, and a list of children.
|
||||
/// It is the most abstract interface for all the trees used by ANTLR.
|
||||
/// </summary>
|
||||
/// It is the most abstract interface for all the trees used by ANTLR.
|
||||
// ml: deviating from Java here. This class forms a tree? Then it should also manage parent + children.
|
||||
class ANTLR4CPP_PUBLIC Tree {
|
||||
public:
|
||||
virtual ~Tree() {};
|
||||
|
||||
/// The parent of this node. If the return value is null, then this
|
||||
/// node is the root of the tree.
|
||||
std::weak_ptr<Tree> getParent() { return getParentReference(); };
|
||||
/// node is the root of the tree.
|
||||
std::weak_ptr<Tree> parent;
|
||||
|
||||
/// <summary>
|
||||
/// This method returns whatever object represents the data at this note. For
|
||||
/// example, for parse trees, the payload can be a <seealso cref="Token"/> representing
|
||||
/// a leaf node or a <seealso cref="RuleContext"/> object representing a rule
|
||||
/// invocation. For abstract syntax trees (ASTs), this is a <seealso cref="Token"/>
|
||||
/// object.
|
||||
/// </summary>
|
||||
/// If we are debugging or building a parse tree for a visitor,
|
||||
/// we need to track all of the tokens and rule invocations associated
|
||||
/// with this rule's context. This is empty for parsing w/o tree constr.
|
||||
/// operation because we don't the need to track the details about
|
||||
/// how we parse this rule.
|
||||
std::vector<Ref<Tree>> children;
|
||||
|
||||
// ml: there are actually only 2 occurences where this method was implemented. We use direct access instead.
|
||||
//virtual void *getPayload() = 0;
|
||||
|
||||
/// <summary>
|
||||
/// If there are children, get the {@code i}th value indexed from 0. </summary>
|
||||
Ref<Tree> getChild(size_t i) { return getChildReference(i); };
|
||||
|
||||
/// <summary>
|
||||
/// How many children are there? If there is none, then this
|
||||
/// node represents a leaf node.
|
||||
/// </summary>
|
||||
virtual std::size_t getChildCount() = 0;
|
||||
|
||||
/// <summary>
|
||||
/// Print out a whole tree, not just a node, in LISP format
|
||||
/// {@code (root child1 .. childN)}. Print just a node if this is a leaf.
|
||||
/// </summary>
|
||||
/// {@code (root child1 .. childN)}. Print just a node if this is a leaf.
|
||||
virtual std::string toStringTree() = 0;
|
||||
|
||||
virtual std::string toString() = 0;
|
||||
|
||||
virtual bool operator == (const Tree &other) const;
|
||||
|
||||
protected:
|
||||
virtual std::weak_ptr<Tree> getParentReference() = 0;
|
||||
virtual Ref<Tree> getChildReference(size_t i) = 0;
|
||||
};
|
||||
|
||||
} // namespace tree
|
||||
|
|
|
@ -63,32 +63,25 @@ std::string Trees::toStringTree(Ref<Tree> const& t, Parser *recog) {
|
|||
|
||||
std::string Trees::toStringTree(Ref<Tree> const& t, const std::vector<std::string> &ruleNames) {
|
||||
std::string temp = antlrcpp::escapeWhitespace(Trees::getNodeText(t, ruleNames), false);
|
||||
if (t->getChildCount() == 0) {
|
||||
if (t->children.empty()) {
|
||||
return temp;
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "(" << temp << ' ';
|
||||
/*
|
||||
for (size_t i = 0; i < t->getChildCount(); i++) {
|
||||
if (i > 0) {
|
||||
ss << ' ';
|
||||
}
|
||||
ss << toStringTree(t->getChild(i), ruleNames);
|
||||
}
|
||||
*/
|
||||
|
||||
// Implement the recursive walk as iteration to avoid trouble we deep nesting.
|
||||
// Implement the recursive walk as iteration to avoid trouble with deep nesting.
|
||||
std::stack<size_t> stack;
|
||||
size_t childIndex = 0;
|
||||
Ref<Tree> run = t;
|
||||
while (childIndex < run->getChildCount()) {
|
||||
while (childIndex < run->children.size()) {
|
||||
if (childIndex > 0) {
|
||||
ss << ' ';
|
||||
}
|
||||
Ref<Tree> child = run->getChild(childIndex);
|
||||
Ref<Tree> child = run->children[childIndex];
|
||||
std::weak_ptr<Tree> parent = child->parent;
|
||||
temp = antlrcpp::escapeWhitespace(Trees::getNodeText(child, ruleNames), false);
|
||||
if (child->getChildCount() > 0) {
|
||||
if (!child->children.empty()) {
|
||||
// Go deeper one level.
|
||||
stack.push(childIndex);
|
||||
run = child;
|
||||
|
@ -96,12 +89,12 @@ std::string Trees::toStringTree(Ref<Tree> const& t, const std::vector<std::strin
|
|||
ss << "(" << temp << " ";
|
||||
} else {
|
||||
ss << temp;
|
||||
while (++childIndex == run->getChildCount()) {
|
||||
while (++childIndex == run->children.size()) {
|
||||
if (stack.size() > 0) {
|
||||
// Reached the end of the current level. See if we can step up from here.
|
||||
childIndex = stack.top();
|
||||
stack.pop();
|
||||
run = run->getParent().lock();
|
||||
run = run->parent.lock();
|
||||
ss << ")";
|
||||
} else {
|
||||
break;
|
||||
|
@ -152,20 +145,12 @@ std::string Trees::getNodeText(Ref<Tree> const& t, const std::vector<std::string
|
|||
return "";
|
||||
}
|
||||
|
||||
std::vector<Ref<Tree>> Trees::getChildren(Ref<Tree> const& t) {
|
||||
std::vector<Ref<Tree>> kids;
|
||||
for (size_t i = 0; i < t->getChildCount(); i++) {
|
||||
kids.push_back(t->getChild(i));
|
||||
}
|
||||
return kids;
|
||||
}
|
||||
|
||||
std::vector<std::weak_ptr<Tree>> Trees::getAncestors(Ref<Tree> const& t) {
|
||||
std::vector<std::weak_ptr<Tree>> ancestors;
|
||||
std::weak_ptr<Tree> parent = t->getParent();
|
||||
std::weak_ptr<Tree> parent = t->parent;
|
||||
while (!parent.expired()) {
|
||||
ancestors.insert(ancestors.begin(), parent); // insert at start
|
||||
parent = parent.lock()->getParent();
|
||||
parent = parent.lock()->parent;
|
||||
}
|
||||
return ancestors;
|
||||
}
|
||||
|
@ -185,22 +170,22 @@ static void _findAllNodes(Ref<ParseTree> const& t, int index, bool findTokens, s
|
|||
}
|
||||
}
|
||||
// check children
|
||||
for (size_t i = 0; i < t->getChildCount(); i++) {
|
||||
_findAllNodes(t->getChild(i), index, findTokens, nodes);
|
||||
for (size_t i = 0; i < t->children.size(); i++) {
|
||||
_findAllNodes(std::dynamic_pointer_cast<ParseTree>(t->children[i]), index, findTokens, nodes);
|
||||
}
|
||||
}
|
||||
|
||||
bool Trees::isAncestorOf(Ref<Tree> const& t, Ref<Tree> const& u) {
|
||||
if (t == nullptr || u == nullptr || t->getParent().expired()) {
|
||||
if (t == nullptr || u == nullptr || t->parent.expired()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Ref<Tree> p = u->getParent().lock();
|
||||
Ref<Tree> p = u->parent.lock();
|
||||
while (p != nullptr) {
|
||||
if (t == p) {
|
||||
return true;
|
||||
}
|
||||
p = p->getParent().lock();
|
||||
p = p->parent.lock();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -222,9 +207,9 @@ std::vector<Ref<ParseTree>> Trees::findAllNodes(Ref<ParseTree> const& t, int ind
|
|||
std::vector<Ref<ParseTree>> Trees::getDescendants(Ref<ParseTree> const& t) {
|
||||
std::vector<Ref<ParseTree>> nodes;
|
||||
nodes.push_back(t);
|
||||
std::size_t n = t->getChildCount();
|
||||
std::size_t n = t->children.size();
|
||||
for (size_t i = 0 ; i < n ; i++) {
|
||||
auto descentants = getDescendants(t->getChild(i));
|
||||
auto descentants = getDescendants(std::dynamic_pointer_cast<ParseTree>(t->children[i]));
|
||||
for (auto entry: descentants) {
|
||||
nodes.push_back(entry);
|
||||
}
|
||||
|
@ -238,9 +223,9 @@ std::vector<Ref<ParseTree>> Trees::descendants(Ref<ParseTree> const& t) {
|
|||
|
||||
Ref<ParserRuleContext> Trees::getRootOfSubtreeEnclosingRegion(Ref<ParseTree> const& t, size_t startTokenIndex,
|
||||
size_t stopTokenIndex) {
|
||||
size_t n = t->getChildCount();
|
||||
for (size_t i = 0; i<n; i++) {
|
||||
Ref<ParseTree> child = t->getChild(i);
|
||||
size_t n = t->children.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
Ref<ParseTree> child = std::dynamic_pointer_cast<ParseTree>(t->children[i]);
|
||||
Ref<ParserRuleContext> r = getRootOfSubtreeEnclosingRegion(child, startTokenIndex, stopTokenIndex);
|
||||
if (r != nullptr) {
|
||||
return r;
|
||||
|
@ -263,9 +248,9 @@ Ref<Tree> Trees::findNodeSuchThat(Ref<Tree> const& t, Ref<Predicate<Tree>> const
|
|||
return t;
|
||||
}
|
||||
|
||||
size_t n = t->getChildCount();
|
||||
size_t n = t->children.size();
|
||||
for (size_t i = 0 ; i < n ; ++i) {
|
||||
Ref<Tree> u = findNodeSuchThat(t->getChild(i), pred);
|
||||
Ref<Tree> u = findNodeSuchThat(t->children[i], pred);
|
||||
if (u != nullptr) {
|
||||
return u;
|
||||
}
|
||||
|
|
|
@ -58,9 +58,6 @@ namespace tree {
|
|||
static std::string getNodeText(Ref<Tree> const& t, Parser *recog);
|
||||
static std::string getNodeText(Ref<Tree> const& t, const std::vector<std::string> &ruleNames);
|
||||
|
||||
/// Return ordered list of all children of this node.
|
||||
static std::vector<Ref<Tree>> getChildren(Ref<Tree> const& t);
|
||||
|
||||
/// Return a list of all ancestors of this node. The first node of
|
||||
/// list is the root and the last is the parent of this node.
|
||||
static std::vector<std::weak_ptr<Tree>> getAncestors(Ref<Tree> const& t);
|
||||
|
|
|
@ -214,7 +214,7 @@ Ref<ParseTree> ParseTreePatternMatcher::matchImpl(Ref<ParseTree> const& tree,
|
|||
}
|
||||
|
||||
// (expr ...) and (expr ...)
|
||||
if (r1->getChildCount() != r2->getChildCount()) {
|
||||
if (r1->children.size() != r2->children.size()) {
|
||||
if (mismatchedNode == nullptr) {
|
||||
mismatchedNode = r1;
|
||||
}
|
||||
|
@ -222,9 +222,10 @@ Ref<ParseTree> ParseTreePatternMatcher::matchImpl(Ref<ParseTree> const& tree,
|
|||
return mismatchedNode;
|
||||
}
|
||||
|
||||
std::size_t n = r1->getChildCount();
|
||||
std::size_t n = r1->children.size();
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
Ref<ParseTree> childMatch = matchImpl(r1->getChild(i), patternTree->getChild(i), labels);
|
||||
Ref<ParseTree> childMatch = matchImpl(std::dynamic_pointer_cast<ParseTree>(r1->children[i]),
|
||||
std::dynamic_pointer_cast<ParseTree>(patternTree->children[i]), labels);
|
||||
if (childMatch) {
|
||||
return childMatch;
|
||||
}
|
||||
|
@ -240,8 +241,8 @@ Ref<ParseTree> ParseTreePatternMatcher::matchImpl(Ref<ParseTree> const& tree,
|
|||
RuleTagToken* ParseTreePatternMatcher::getRuleTagToken(Ref<ParseTree> const& t) {
|
||||
if (is<RuleNode>(t)) {
|
||||
Ref<RuleNode> r = std::dynamic_pointer_cast<RuleNode>(t);
|
||||
if (r->getChildCount() == 1 && is<TerminalNode>(r->getChild(0))) {
|
||||
Ref<TerminalNode> c = std::dynamic_pointer_cast<TerminalNode>(r->getChild(0));
|
||||
if (r->children.size() == 1 && is<TerminalNode>(r->children[0])) {
|
||||
Ref<TerminalNode> c = std::dynamic_pointer_cast<TerminalNode>(r->children[0]);
|
||||
if (is<RuleTagToken *>(c->getSymbol())) {
|
||||
return dynamic_cast<RuleTagToken *>(c->getSymbol());
|
||||
}
|
||||
|
|
|
@ -163,7 +163,7 @@ std::vector<Ref<ParseTree>> XPath::evaluate(const Ref<ParseTree> &t) {
|
|||
while (i < _elements.size()) {
|
||||
std::vector<Ref<ParseTree>> next;
|
||||
for (auto node : work) {
|
||||
if (node->getChildCount() > 0) {
|
||||
if (!node->children.empty()) {
|
||||
// only try to match next element if it has children
|
||||
// e.g., //func/*/stat might have a token node for which
|
||||
// we can't go looking for stat nodes.
|
||||
|
|
|
@ -44,7 +44,7 @@ XPathRuleElement::XPathRuleElement(const std::string &ruleName, int ruleIndex) :
|
|||
std::vector<Ref<ParseTree>> XPathRuleElement::evaluate(const Ref<ParseTree> &t) {
|
||||
// return all children of t that match nodeName
|
||||
std::vector<Ref<ParseTree>> nodes;
|
||||
for (auto c : Trees::getChildren(t)) {
|
||||
for (auto c : t->children) {
|
||||
if (antlrcpp::is<ParserRuleContext>(c)) {
|
||||
Ref<ParserRuleContext> ctx = std::static_pointer_cast<ParserRuleContext>(c);
|
||||
if ((ctx->getRuleIndex() == _ruleIndex && !_invert) || (ctx->getRuleIndex() != _ruleIndex && _invert)) {
|
||||
|
|
|
@ -47,7 +47,7 @@ XPathTokenElement::XPathTokenElement(const std::string &tokenName, int tokenType
|
|||
std::vector<Ref<ParseTree>> XPathTokenElement::evaluate(const std::shared_ptr<ParseTree> &t) {
|
||||
// return all children of t that match nodeName
|
||||
std::vector<Ref<ParseTree>> nodes;
|
||||
for (auto c : Trees::getChildren(t)) {
|
||||
for (auto c : t->children) {
|
||||
if (antlrcpp::is<TerminalNode>(c)) {
|
||||
Ref<TerminalNode> tnode = std::static_pointer_cast<TerminalNode>(c);
|
||||
if ((tnode->getSymbol()->getType() == _tokenType && !_invert) || (tnode->getSymbol()->getType() != _tokenType && _invert)) {
|
||||
|
|
|
@ -46,7 +46,7 @@ std::vector<Ref<ParseTree>> XPathWildcardElement::evaluate(const Ref<ParseTree>
|
|||
return {}; // !* is weird but valid (empty)
|
||||
}
|
||||
std::vector<Ref<ParseTree>> kids;
|
||||
for (auto c : Trees::getChildren(t)) {
|
||||
for (auto c : t->children) {
|
||||
kids.push_back(std::static_pointer_cast<ParseTree>(c));
|
||||
}
|
||||
return kids;
|
||||
|
|
|
@ -147,8 +147,8 @@ public:
|
|||
|
||||
virtual void enterEveryRule(ParserRuleContext * /*ctx*/) override { }
|
||||
virtual void exitEveryRule(ParserRuleContext * /*ctx*/) override { }
|
||||
virtual void visitTerminal(Ref\<tree::TerminalNode> const& /*node*/) override { }
|
||||
virtual void visitErrorNode(Ref\<tree::ErrorNode> const& /*node*/) override { }
|
||||
virtual void visitTerminal(tree::TerminalNode * /*node*/) override { }
|
||||
virtual void visitErrorNode(tree::ErrorNode * /*node*/) override { }
|
||||
|
||||
<if (namedActions.baselistenermembers)>
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue