From fb6fee881cc17087aa49408543edfda0f3420dae Mon Sep 17 00:00:00 2001 From: Ivan Kochurkin Date: Tue, 21 Jun 2022 23:18:16 +0300 Subject: [PATCH] Unify C++, Dart, Go runtimes Signed-off-by: Ivan Kochurkin --- runtime/Cpp/runtime/src/atn/ATNConfig.cpp | 6 ++-- runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp | 6 ++-- .../runtime/src/atn/ParserATNSimulator.cpp | 10 +++--- .../Cpp/runtime/src/atn/PredictionMode.cpp | 4 +-- .../Cpp/runtime/src/atn/SemanticContext.cpp | 22 ++++++------- runtime/Cpp/runtime/src/atn/SemanticContext.h | 14 ++++---- runtime/Dart/lib/src/atn/src/atn_config.dart | 6 ++-- .../Dart/lib/src/atn/src/atn_config_set.dart | 4 +-- .../Dart/lib/src/atn/src/atn_simulator.dart | 2 +- .../lib/src/atn/src/lexer_atn_simulator.dart | 4 +-- .../lib/src/atn/src/parser_atn_simulator.dart | 14 ++++---- .../lib/src/atn/src/semantic_context.dart | 24 +++++++------- runtime/Dart/lib/src/ll1_analyzer.dart | 4 +-- runtime/Dart/lib/src/prediction_context.dart | 32 +++++++++---------- runtime/Go/antlr/parser_atn_simulator.go | 4 +-- runtime/Go/antlr/parser_rule_context.go | 2 +- runtime/Go/antlr/prediction_context.go | 4 +-- runtime/Go/antlr/semantic_context.go | 2 +- 18 files changed, 82 insertions(+), 82 deletions(-) diff --git a/runtime/Cpp/runtime/src/atn/ATNConfig.cpp b/runtime/Cpp/runtime/src/atn/ATNConfig.cpp index a9f83a61cd3..90af1453cd8 100755 --- a/runtime/Cpp/runtime/src/atn/ATNConfig.cpp +++ b/runtime/Cpp/runtime/src/atn/ATNConfig.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ @@ -23,7 +23,7 @@ inline constexpr size_t SUPPRESS_PRECEDENCE_FILTER = 0x40000000; } ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref context) - : ATNConfig(state, alt, std::move(context), 0, SemanticContext::NONE) {} + : ATNConfig(state, alt, std::move(context), 0, SemanticContext::Predicate::NONE) {} ATNConfig::ATNConfig(ATNState *state, size_t alt, Ref context, Ref semanticContext) : ATNConfig(state, alt, std::move(context), 0, std::move(semanticContext)) {} @@ -94,7 +94,7 @@ std::string ATNConfig::toString(bool showAlt) const { if (context) { ss << ",[" << context->toString() << "]"; } - if (semanticContext != nullptr && semanticContext != SemanticContext::NONE) { + if (semanticContext != nullptr && semanticContext != SemanticContext::Predicate::NONE) { ss << ",[" << semanticContext->toString() << "]"; } if (getOuterContextDepth() > 0) { diff --git a/runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp b/runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp index d44e46d5ee1..d49a55dc4b2 100755 --- a/runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp +++ b/runtime/Cpp/runtime/src/atn/ATNConfigSet.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ @@ -43,7 +43,7 @@ bool ATNConfigSet::add(const Ref &config, PredictionContextMergeCache if (_readonly) { throw IllegalStateException("This set is readonly"); } - if (config->semanticContext != SemanticContext::NONE) { + if (config->semanticContext != SemanticContext::Predicate::NONE) { hasSemanticContext = true; } if (config->getOuterContextDepth() > 0) { @@ -114,7 +114,7 @@ std::vector> ATNConfigSet::getPredicates() const { std::vector> preds; preds.reserve(configs.size()); for (const auto &c : configs) { - if (c->semanticContext != SemanticContext::NONE) { + if (c->semanticContext != SemanticContext::Predicate::NONE) { preds.push_back(c->semanticContext); } } diff --git a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp index ed9ca78c513..d0966093af9 100755 --- a/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp +++ b/runtime/Cpp/runtime/src/atn/ParserATNSimulator.cpp @@ -692,8 +692,8 @@ std::vector> ParserATNSimulator::getPredsForAmbigAlts size_t nPredAlts = 0; for (size_t i = 1; i <= nalts; i++) { if (altToPred[i] == nullptr) { - altToPred[i] = SemanticContext::NONE; - } else if (altToPred[i] != SemanticContext::NONE) { + altToPred[i] = SemanticContext::Predicate::NONE; + } else if (altToPred[i] != SemanticContext::Predicate::NONE) { nPredAlts++; } } @@ -712,7 +712,7 @@ std::vector> ParserATNSimulator::getPredsForAmbigAlts std::vector ParserATNSimulator::getPredicatePredictions(const antlrcpp::BitSet &ambigAlts, const std::vector> &altToPred) { bool containsPredicate = std::find_if(altToPred.begin(), altToPred.end(), [](const Ref &context) { - return context != SemanticContext::NONE; + return context != SemanticContext::Predicate::NONE; }) != altToPred.end(); std::vector pairs; if (containsPredicate) { @@ -767,7 +767,7 @@ std::pair ParserATNSimulator::splitAccordingToSe ATNConfigSet *succeeded(new ATNConfigSet(configs->fullCtx)); ATNConfigSet *failed(new ATNConfigSet(configs->fullCtx)); for (const auto &c : configs->configs) { - if (c->semanticContext != SemanticContext::NONE) { + if (c->semanticContext != SemanticContext::Predicate::NONE) { bool predicateEvaluationResult = evalSemanticContext(c->semanticContext, outerContext, c->alt, configs->fullCtx); if (predicateEvaluationResult) { succeeded->add(c); @@ -785,7 +785,7 @@ BitSet ParserATNSimulator::evalSemanticContext(const std::vectorconfigs) { - Ref c = std::make_shared(*config, SemanticContext::NONE); + Ref c = std::make_shared(*config, SemanticContext::Predicate::NONE); dup.add(c); } std::vector altsets = getConflictingAltSubsets(&dup); diff --git a/runtime/Cpp/runtime/src/atn/SemanticContext.cpp b/runtime/Cpp/runtime/src/atn/SemanticContext.cpp index 7ac88cceeb1..c7da74cf7c5 100755 --- a/runtime/Cpp/runtime/src/atn/SemanticContext.cpp +++ b/runtime/Cpp/runtime/src/atn/SemanticContext.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ @@ -137,7 +137,7 @@ bool SemanticContext::PrecedencePredicate::eval(Recognizer *parser, RuleContext Ref SemanticContext::PrecedencePredicate::evalPrecedence(Recognizer *parser, RuleContext *parserCallStack) const { if (parser->precpred(parserCallStack, precedence)) { - return SemanticContext::NONE; + return SemanticContext::Predicate::NONE; } return nullptr; } @@ -237,7 +237,7 @@ Ref SemanticContext::AND::evalPrecedence(Recognizer *pars // The AND context is false if any element is false. return nullptr; } - if (evaluated != NONE) { + if (evaluated != Predicate::NONE) { // Reduce the result by skipping true elements. operands.push_back(std::move(evaluated)); } @@ -249,7 +249,7 @@ Ref SemanticContext::AND::evalPrecedence(Recognizer *pars if (operands.empty()) { // All elements were true, so the AND context is true. - return NONE; + return Predicate::NONE; } Ref result = std::move(operands[0]); @@ -337,9 +337,9 @@ Ref SemanticContext::OR::evalPrecedence(Recognizer *parse for (const auto &context : getOperands()) { auto evaluated = context->evalPrecedence(parser, parserCallStack); differs |= (evaluated != context); - if (evaluated == NONE) { + if (evaluated == Predicate::NONE) { // The OR context is true if any element is true. - return NONE; + return Predicate::NONE; } if (evaluated != nullptr) { // Reduce the result by skipping false elements. @@ -374,18 +374,18 @@ std::string SemanticContext::OR::toString() const { //------------------ SemanticContext ----------------------------------------------------------------------------------- -const Ref SemanticContext::NONE = std::make_shared(INVALID_INDEX, INVALID_INDEX, false); +const Ref SemanticContext::Predicate::NONE = std::make_shared(INVALID_INDEX, INVALID_INDEX, false); Ref SemanticContext::evalPrecedence(Recognizer * /*parser*/, RuleContext * /*parserCallStack*/) const { return shared_from_this(); } Ref SemanticContext::And(Ref a, Ref b) { - if (!a || a == NONE) { + if (!a || a == Predicate::NONE) { return b; } - if (!b || b == NONE) { + if (!b || b == Predicate::NONE) { return a; } @@ -405,8 +405,8 @@ Ref SemanticContext::Or(Ref a, Ref return a; } - if (a == NONE || b == NONE) { - return NONE; + if (a == Predicate::NONE || b == Predicate::NONE) { + return Predicate::NONE; } Ref result = std::make_shared(std::move(a), std::move(b)); diff --git a/runtime/Cpp/runtime/src/atn/SemanticContext.h b/runtime/Cpp/runtime/src/atn/SemanticContext.h index 367b726a4a1..6cdd83f85d6 100755 --- a/runtime/Cpp/runtime/src/atn/SemanticContext.h +++ b/runtime/Cpp/runtime/src/atn/SemanticContext.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. +/* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. * Use of this file is governed by the BSD 3-clause license that * can be found in the LICENSE.txt file in the project root. */ @@ -20,12 +20,6 @@ namespace atn { /// SemanticContext within the scope of this outer class. class ANTLR4CPP_PUBLIC SemanticContext : public std::enable_shared_from_this { public: - /** - * The default {@link SemanticContext}, which is semantically equivalent to - * a predicate of the form {@code {true}?}. - */ - static const Ref NONE; - virtual ~SemanticContext() = default; SemanticContextType getContextType() const { return _contextType; } @@ -99,6 +93,12 @@ namespace atn { class ANTLR4CPP_PUBLIC SemanticContext::Predicate final : public SemanticContext { public: + /** + * The default {@link SemanticContext}, which is semantically equivalent to + * a predicate of the form {@code {true}?}. + */ + static const Ref NONE; + static bool is(const SemanticContext &semanticContext) { return semanticContext.getContextType() == SemanticContextType::PREDICATE; } static bool is(const SemanticContext *semanticContext) { return semanticContext != nullptr && is(*semanticContext); } diff --git a/runtime/Dart/lib/src/atn/src/atn_config.dart b/runtime/Dart/lib/src/atn/src/atn_config.dart index 2b414fa9a1c..1fc79579f5e 100644 --- a/runtime/Dart/lib/src/atn/src/atn_config.dart +++ b/runtime/Dart/lib/src/atn/src/atn_config.dart @@ -89,7 +89,7 @@ class ATNConfig { this.state, this.alt, this.context, [ - this.semanticContext = SemanticContext.NONE, + this.semanticContext = Predicate.NONE, ]) : reachesIntoOuterContext = 0; ATNConfig.dup( @@ -169,7 +169,7 @@ class ATNConfig { buf.write(context.toString()); buf.write(']'); } - if (semanticContext != SemanticContext.NONE) { + if (semanticContext != Predicate.NONE) { buf.write(','); buf.write(semanticContext); } @@ -194,7 +194,7 @@ class LexerATNConfig extends ATNConfig { int alt, PredictionContext context, [ this.lexerActionExecutor, - ]) : super(state, alt, context, SemanticContext.NONE) { + ]) : super(state, alt, context, Predicate.NONE) { passedThroughNonGreedyDecision = false; } diff --git a/runtime/Dart/lib/src/atn/src/atn_config_set.dart b/runtime/Dart/lib/src/atn/src/atn_config_set.dart index 78f3d1593d1..aece7f955cb 100644 --- a/runtime/Dart/lib/src/atn/src/atn_config_set.dart +++ b/runtime/Dart/lib/src/atn/src/atn_config_set.dart @@ -109,7 +109,7 @@ class ATNConfigSet extends Iterable { mergeCache, ]) { if (readOnly) throw StateError('This set is readonly'); - if (config.semanticContext != SemanticContext.NONE) { + if (config.semanticContext != Predicate.NONE) { hasSemanticContext = true; } if (config.outerContextDepth > 0) { @@ -176,7 +176,7 @@ class ATNConfigSet extends Iterable { List get predicates { final preds = []; for (var c in configs) { - if (c.semanticContext != SemanticContext.NONE) { + if (c.semanticContext != Predicate.NONE) { preds.add(c.semanticContext); } } diff --git a/runtime/Dart/lib/src/atn/src/atn_simulator.dart b/runtime/Dart/lib/src/atn/src/atn_simulator.dart index 4c3eb3e607a..be598c49733 100644 --- a/runtime/Dart/lib/src/atn/src/atn_simulator.dart +++ b/runtime/Dart/lib/src/atn/src/atn_simulator.dart @@ -77,7 +77,7 @@ class PredictionContextCache { /// return that one instead and do not add a new context to the cache. /// Protect shared cache from unsafe thread access. PredictionContext add(PredictionContext ctx) { - if (ctx == PredictionContext.EMPTY) return PredictionContext.EMPTY; + if (ctx == EmptyPredictionContext.Instance) return EmptyPredictionContext.Instance; final existing = cache[ctx]; if (existing != null) { // System.out.println(name+" reuses "+existing); diff --git a/runtime/Dart/lib/src/atn/src/lexer_atn_simulator.dart b/runtime/Dart/lib/src/atn/src/lexer_atn_simulator.dart index 0f983c02ef3..3801f727f31 100644 --- a/runtime/Dart/lib/src/atn/src/lexer_atn_simulator.dart +++ b/runtime/Dart/lib/src/atn/src/lexer_atn_simulator.dart @@ -401,7 +401,7 @@ class LexerATNSimulator extends ATNSimulator { } ATNConfigSet computeStartState(CharStream input, ATNState p) { - PredictionContext initialContext = PredictionContext.EMPTY; + PredictionContext initialContext = EmptyPredictionContext.Instance; ATNConfigSet configs = OrderedATNConfigSet(); for (var i = 0; i < p.numberOfTransitions; i++) { final target = p.transition(i).target; @@ -445,7 +445,7 @@ class LexerATNSimulator extends ATNSimulator { configs.add(LexerATNConfig.dup( config, config.state, - context: PredictionContext.EMPTY, + context: EmptyPredictionContext.Instance, )); currentAltReachedAcceptState = true; } diff --git a/runtime/Dart/lib/src/atn/src/parser_atn_simulator.dart b/runtime/Dart/lib/src/atn/src/parser_atn_simulator.dart index 6f14f1cb36b..e671181640c 100644 --- a/runtime/Dart/lib/src/atn/src/parser_atn_simulator.dart +++ b/runtime/Dart/lib/src/atn/src/parser_atn_simulator.dart @@ -1234,8 +1234,8 @@ class ParserATNSimulator extends ATNSimulator { var nPredAlts = 0; for (var i = 1; i <= nalts; i++) { if (altToPred[i] == null) { - altToPred[i] = SemanticContext.NONE; - } else if (altToPred[i] != SemanticContext.NONE) { + altToPred[i] = Predicate.NONE; + } else if (altToPred[i] != Predicate.NONE) { nPredAlts++; } } @@ -1266,7 +1266,7 @@ class ParserATNSimulator extends ATNSimulator { if (ambigAlts != null && ambigAlts[i]) { pairs.add(PredPrediction(pred!, i)); } - if (pred != SemanticContext.NONE) containsPredicate = true; + if (pred != Predicate.NONE) containsPredicate = true; } if (!containsPredicate) { @@ -1370,7 +1370,7 @@ class ParserATNSimulator extends ATNSimulator { final succeeded = ATNConfigSet(configs.fullCtx); final failed = ATNConfigSet(configs.fullCtx); for (var c in configs) { - if (c.semanticContext != SemanticContext.NONE) { + if (c.semanticContext != Predicate.NONE) { final predicateEvaluationResult = evalSemanticContextOne( c.semanticContext, outerContext, @@ -1401,7 +1401,7 @@ class ParserATNSimulator extends ATNSimulator { ) { final predictions = BitSet(); for (var pair in predPredictions) { - if (pair.pred == SemanticContext.NONE) { + if (pair.pred == Predicate.NONE) { predictions.set(pair.alt); if (!complete) { break; @@ -1511,7 +1511,7 @@ class ParserATNSimulator extends ATNSimulator { ATNConfig.dup( config, state: config.state, - context: PredictionContext.EMPTY, + context: EmptyPredictionContext.Instance, ), mergeCache); continue; @@ -2431,7 +2431,7 @@ extension PredictionModeExtension on PredictionMode { // dup configs, tossing out semantic predicates final dup = ATNConfigSet(); for (var c in configs) { - c = ATNConfig.dup(c, semanticContext: SemanticContext.NONE); + c = ATNConfig.dup(c, semanticContext: Predicate.NONE); dup.add(c); } configs = dup; diff --git a/runtime/Dart/lib/src/atn/src/semantic_context.dart b/runtime/Dart/lib/src/atn/src/semantic_context.dart index a78e1f6573f..5b6cc2b159e 100644 --- a/runtime/Dart/lib/src/atn/src/semantic_context.dart +++ b/runtime/Dart/lib/src/atn/src/semantic_context.dart @@ -17,10 +17,6 @@ import '../../util/murmur_hash.dart'; ///

I have scoped the [AND], [OR], and [Predicate] subclasses of /// [SemanticContext] within the scope of this outer class.

abstract class SemanticContext { - /// The default [SemanticContext], which is semantically equivalent to - /// a predicate of the form {@code {true}?}. - static const SemanticContext NONE = Predicate(); - const SemanticContext(); /// For context independent predicates, we evaluate them without a local @@ -60,8 +56,8 @@ abstract class SemanticContext { } static SemanticContext? and(SemanticContext? a, SemanticContext? b) { - if (a == null || a == NONE) return b; - if (b == null || b == NONE) return a; + if (a == null || a == Predicate.NONE) return b; + if (b == null || b == Predicate.NONE) return a; final result = AND(a, b); if (result.opnds.length == 1) { return result.opnds[0]; @@ -75,7 +71,7 @@ abstract class SemanticContext { static SemanticContext? or(SemanticContext? a, SemanticContext? b) { if (a == null) return b; if (b == null) return a; - if (a == NONE || b == NONE) return NONE; + if (a == Predicate.NONE || b == Predicate.NONE) return Predicate.NONE; final result = OR(a, b); if (result.opnds.length == 1) { return result.opnds[0]; @@ -96,6 +92,10 @@ abstract class SemanticContext { } class Predicate extends SemanticContext { + /// The default [SemanticContext], which is semantically equivalent to + /// a predicate of the form {@code {true}?}. + static const SemanticContext NONE = Predicate(); + final int ruleIndex; final int predIndex; final bool isCtxDependent; // e.g., $i ref in pred @@ -150,7 +150,7 @@ class PrecedencePredicate extends SemanticContext RuleContext? parserCallStack, ) { if (parser.precpred(parserCallStack, precedence)) { - return SemanticContext.NONE; + return Predicate.NONE; } else { return null; } @@ -273,7 +273,7 @@ class AND extends Operator { if (evaluated == null) { // The AND context is false if any element is false return null; - } else if (evaluated != SemanticContext.NONE) { + } else if (evaluated != Predicate.NONE) { // Reduce the result by skipping true elements operands.add(evaluated); } @@ -285,7 +285,7 @@ class AND extends Operator { if (operands.isEmpty) { // all elements were true, so the AND context is true - return SemanticContext.NONE; + return Predicate.NONE; } SemanticContext? result = operands[0]; @@ -374,9 +374,9 @@ class OR extends Operator { for (var context in opnds) { final evaluated = context.evalPrecedence(parser, parserCallStack); differs |= (evaluated != context); - if (evaluated == SemanticContext.NONE) { + if (evaluated == Predicate.NONE) { // The OR context is true if any element is true - return SemanticContext.NONE; + return Predicate.NONE; } else if (evaluated != null) { // Reduce the result by skipping false elements operands.add(evaluated); diff --git a/runtime/Dart/lib/src/ll1_analyzer.dart b/runtime/Dart/lib/src/ll1_analyzer.dart index 5ae5d2673b5..b2821a7be65 100644 --- a/runtime/Dart/lib/src/ll1_analyzer.dart +++ b/runtime/Dart/lib/src/ll1_analyzer.dart @@ -38,7 +38,7 @@ class LL1Analyzer { _LOOK( s.transition(n).target, null, - PredictionContext.EMPTY, + EmptyPredictionContext.Instance, lookAlt, lookBusy, BitSet(), @@ -154,7 +154,7 @@ class LL1Analyzer { return; } - if (ctx != PredictionContext.EMPTY) { + if (ctx != EmptyPredictionContext.Instance) { // run thru all possible stack tops in ctx final removed = calledRuleStack[s.ruleIndex]; try { diff --git a/runtime/Dart/lib/src/prediction_context.dart b/runtime/Dart/lib/src/prediction_context.dart index 2e0843a91ca..c069200ac6e 100644 --- a/runtime/Dart/lib/src/prediction_context.dart +++ b/runtime/Dart/lib/src/prediction_context.dart @@ -13,10 +13,6 @@ import 'rule_context.dart'; import 'util/murmur_hash.dart'; abstract class PredictionContext { - /// Represents {@code $} in local context prediction, which means wildcard. - /// {@code *+x = *}. - static final EmptyPredictionContext EMPTY = EmptyPredictionContext(); - /// Represents {@code $} in an array in full context mode, when {@code $} /// doesn't mean wildcard: {@code $ + x = [$,x]}. Here, /// {@code $} = {@link #EMPTY_RETURN_STATE}. @@ -58,11 +54,11 @@ abstract class PredictionContext { // if we are in RuleContext of start rule, s, then PredictionContext // is EMPTY. Nobody called us. (if we are empty, return empty) if (outerContext.parent == null || outerContext == RuleContext.EMPTY) { - return PredictionContext.EMPTY; + return EmptyPredictionContext.Instance; } // If we have a parent, convert it to a PredictionContext graph - PredictionContext parent = EMPTY; + PredictionContext parent = EmptyPredictionContext.Instance; parent = PredictionContext.fromRuleContext(atn, outerContext.parent); final state = atn.states[outerContext.invokingState]!; @@ -81,7 +77,7 @@ abstract class PredictionContext { /// This means only the {@link #EMPTY} (wildcard? not sure) context is in set. */ bool get isEmpty { - return this == EMPTY; + return this == EmptyPredictionContext.Instance; } bool hasEmptyPath() { @@ -298,18 +294,18 @@ abstract class PredictionContext { bool rootIsWildcard, ) { if (rootIsWildcard) { - if (a == EMPTY) return EMPTY; // * + b = * - if (b == EMPTY) return EMPTY; // a + * = * + if (a == EmptyPredictionContext.Instance) return EmptyPredictionContext.Instance; // * + b = * + if (b == EmptyPredictionContext.Instance) return EmptyPredictionContext.Instance; // a + * = * } else { - if (a == EMPTY && b == EMPTY) return EMPTY; // $ + $ = $ - if (a == EMPTY) { + if (a == EmptyPredictionContext.Instance && b == EmptyPredictionContext.Instance) return EmptyPredictionContext.Instance; // $ + $ = $ + if (a == EmptyPredictionContext.Instance) { // $ + x = [x,$] final payloads = [b.returnState, EMPTY_RETURN_STATE]; final parents = [b.parent, null]; PredictionContext joined = ArrayPredictionContext(parents, payloads); return joined; } - if (b == EMPTY) { + if (b == EmptyPredictionContext.Instance) { // x + $ = [x,$] ($ is always last if present) final payloads = [a.returnState, EMPTY_RETURN_STATE]; final parents = [a.parent, null]; @@ -518,7 +514,7 @@ abstract class PredictionContext { } for (var current in nodes) { - if (current == EMPTY) continue; + if (current == EmptyPredictionContext.Instance) continue; for (var i = 0; i < current.length; i++) { if (current.getParent(i) == null) continue; final s = current.id.toString(); @@ -590,7 +586,7 @@ abstract class PredictionContext { PredictionContext updated; if (parents.isEmpty) { - updated = EMPTY; + updated = EmptyPredictionContext.Instance; } else if (parents.length == 1) { updated = SingletonPredictionContext.create( parents[0], context.getReturnState(0)); @@ -706,7 +702,7 @@ abstract class PredictionContext { } } stateNumber = p.getReturnState(index); - p = p.getParent(index) ?? EMPTY; + p = p.getParent(index) ?? EmptyPredictionContext.Instance; } localBuffer.write(']'); result.add(localBuffer.toString()); @@ -737,7 +733,7 @@ class SingletonPredictionContext extends PredictionContext { ) { if (returnState == PredictionContext.EMPTY_RETURN_STATE && parent == null) { // someone can pass in the bits of an array ctx that mean $ - return PredictionContext.EMPTY; + return EmptyPredictionContext.Instance; } return SingletonPredictionContext(parent, returnState); } @@ -789,6 +785,10 @@ class SingletonPredictionContext extends PredictionContext { } class EmptyPredictionContext extends SingletonPredictionContext { + /// Represents {@code $} in local context prediction, which means wildcard. + /// {@code *+x = *}. + static final EmptyPredictionContext Instance = EmptyPredictionContext(); + EmptyPredictionContext() : super(null, PredictionContext.EMPTY_RETURN_STATE); @override diff --git a/runtime/Go/antlr/parser_atn_simulator.go b/runtime/Go/antlr/parser_atn_simulator.go index 888d512975a..01d50e14166 100644 --- a/runtime/Go/antlr/parser_atn_simulator.go +++ b/runtime/Go/antlr/parser_atn_simulator.go @@ -111,7 +111,7 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou if s0 == nil { if outerContext == nil { - outerContext = RuleContextEmpty + outerContext = ParserRuleContextEmpty } if ParserATNSimulatorDebug || ParserATNSimulatorListATNDecisions { fmt.Println("predictATN decision " + strconv.Itoa(dfa.decision) + @@ -119,7 +119,7 @@ func (p *ParserATNSimulator) AdaptivePredict(input TokenStream, decision int, ou ", outerContext=" + outerContext.String(p.parser.GetRuleNames(), nil)) } fullCtx := false - s0Closure := p.computeStartState(dfa.atnStartState, RuleContextEmpty, fullCtx) + s0Closure := p.computeStartState(dfa.atnStartState, ParserRuleContextEmpty, fullCtx) p.atn.stateMu.Lock() if dfa.getPrecedenceDfa() { diff --git a/runtime/Go/antlr/parser_rule_context.go b/runtime/Go/antlr/parser_rule_context.go index 49cd10c5ffc..780cb4dbb38 100644 --- a/runtime/Go/antlr/parser_rule_context.go +++ b/runtime/Go/antlr/parser_rule_context.go @@ -340,7 +340,7 @@ func (prc *BaseParserRuleContext) String(ruleNames []string, stop RuleContext) s return s } -var RuleContextEmpty = NewBaseParserRuleContext(nil, -1) +var ParserRuleContextEmpty = NewBaseParserRuleContext(nil, -1) type InterpreterRuleContext interface { ParserRuleContext diff --git a/runtime/Go/antlr/prediction_context.go b/runtime/Go/antlr/prediction_context.go index 9fdfd52b26c..f85d202a4a3 100644 --- a/runtime/Go/antlr/prediction_context.go +++ b/runtime/Go/antlr/prediction_context.go @@ -343,11 +343,11 @@ func (a *ArrayPredictionContext) String() string { // / func predictionContextFromRuleContext(a *ATN, outerContext RuleContext) PredictionContext { if outerContext == nil { - outerContext = RuleContextEmpty + outerContext = ParserRuleContextEmpty } // if we are in RuleContext of start rule, s, then BasePredictionContext // is EMPTY. Nobody called us. (if we are empty, return empty) - if outerContext.GetParent() == nil || outerContext == RuleContextEmpty { + if outerContext.GetParent() == nil || outerContext == ParserRuleContextEmpty { return BasePredictionContextEMPTY } // If we have a parent, convert it to a BasePredictionContext graph diff --git a/runtime/Go/antlr/semantic_context.go b/runtime/Go/antlr/semantic_context.go index 9ada430779c..4c54429fd61 100644 --- a/runtime/Go/antlr/semantic_context.go +++ b/runtime/Go/antlr/semantic_context.go @@ -78,7 +78,7 @@ func NewPredicate(ruleIndex, predIndex int, isCtxDependent bool) *Predicate { //The default {@link SemanticContext}, which is semantically equivalent to //a predicate of the form {@code {true}?}. -var SemanticContextNone SemanticContext = NewPredicate(-1, -1, false) +var SemanticContextNone = NewPredicate(-1, -1, false) func (p *Predicate) evalPrecedence(parser Recognizer, outerContext RuleContext) SemanticContext { return p