forked from jasder/antlr
Merge branch 'sharpen'
This commit is contained in:
commit
c860ff779f
|
@ -1 +1 @@
|
||||||
Subproject commit cd9d2e248a9754a601e4a27f32fd889cc9459935
|
Subproject commit 8506131d96c239c9df0465575e42d6676d0d6cff
|
|
@ -70,6 +70,23 @@ namespace Antlr4.Runtime.Atn
|
||||||
|
|
||||||
public abstract void Reset();
|
public abstract void Reset();
|
||||||
|
|
||||||
|
/// <summary>Clear the DFA cache used by the current instance.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Clear the DFA cache used by the current instance. Since the DFA cache may
|
||||||
|
/// be shared by multiple ATN simulators, this method may affect the
|
||||||
|
/// performance (but not accuracy) of other parsers which are being used
|
||||||
|
/// concurrently.
|
||||||
|
/// </remarks>
|
||||||
|
/// <exception cref="System.NotSupportedException">
|
||||||
|
/// if the current instance does not
|
||||||
|
/// support clearing the DFA.
|
||||||
|
/// </exception>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public virtual void ClearDFA()
|
||||||
|
{
|
||||||
|
atn.ClearDFA();
|
||||||
|
}
|
||||||
|
|
||||||
[Obsolete(@"Use ATNDeserializer.Deserialize(char[]) instead.")]
|
[Obsolete(@"Use ATNDeserializer.Deserialize(char[]) instead.")]
|
||||||
public static ATN Deserialize(char[] data)
|
public static ATN Deserialize(char[] data)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>This class represents profiling event information for an ambiguity.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class represents profiling event information for an ambiguity.
|
||||||
|
/// Ambiguities are decisions where a particular input resulted in an SLL
|
||||||
|
/// conflict, followed by LL prediction also reaching a conflict state
|
||||||
|
/// (indicating a true ambiguity in the grammar).
|
||||||
|
/// <p>
|
||||||
|
/// This event may be reported during SLL prediction in cases where the
|
||||||
|
/// conflicting SLL configuration set provides sufficient information to
|
||||||
|
/// determine that the SLL conflict is truly an ambiguity. For example, if none
|
||||||
|
/// of the ATN configurations in the conflicting SLL configuration set have
|
||||||
|
/// traversed a global follow transition (i.e.
|
||||||
|
/// <see cref="ATNConfig.ReachesIntoOuterContext()">ATNConfig.ReachesIntoOuterContext()</see>
|
||||||
|
/// is
|
||||||
|
/// <code>false</code>
|
||||||
|
/// for all
|
||||||
|
/// configurations), then the result of SLL prediction for that input is known to
|
||||||
|
/// be equivalent to the result of LL prediction for that input.</p>
|
||||||
|
/// <p>
|
||||||
|
/// In some cases, the minimum represented alternative in the conflicting LL
|
||||||
|
/// configuration set is not equal to the minimum represented alternative in the
|
||||||
|
/// conflicting SLL configuration set. Grammars and inputs which result in this
|
||||||
|
/// scenario are unable to use
|
||||||
|
/// <see cref="PredictionMode.Sll">PredictionMode.Sll</see>
|
||||||
|
/// , which in turn means
|
||||||
|
/// they cannot use the two-stage parsing strategy to improve parsing performance
|
||||||
|
/// for that input.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ParserATNSimulator.ReportAmbiguity(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, int, int, bool, Sharpen.BitSet, ATNConfigSet)">ParserATNSimulator.ReportAmbiguity(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, int, int, bool, Sharpen.BitSet, ATNConfigSet)</seealso>
|
||||||
|
/// <seealso cref="Antlr4.Runtime.IParserErrorListener.ReportAmbiguity(Antlr4.Runtime.Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, ATNConfigSet)">Antlr4.Runtime.IParserErrorListener.ReportAmbiguity(Antlr4.Runtime.Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, ATNConfigSet)</seealso>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class AmbiguityInfo : DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="AmbiguityInfo">AmbiguityInfo</see>
|
||||||
|
/// class with the
|
||||||
|
/// specified detailed ambiguity information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
/// <param name="state">
|
||||||
|
/// The final simulator state identifying the ambiguous
|
||||||
|
/// alternatives for the current input
|
||||||
|
/// </param>
|
||||||
|
/// <param name="input">The input token stream</param>
|
||||||
|
/// <param name="startIndex">The start index for the current prediction</param>
|
||||||
|
/// <param name="stopIndex">
|
||||||
|
/// The index at which the ambiguity was identified during
|
||||||
|
/// prediction
|
||||||
|
/// </param>
|
||||||
|
public AmbiguityInfo(int decision, SimulatorState state, ITokenStream input, int startIndex, int stopIndex)
|
||||||
|
: base(decision, state, input, startIndex, stopIndex, state.useContext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>This class represents profiling event information for a context sensitivity.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class represents profiling event information for a context sensitivity.
|
||||||
|
/// Context sensitivities are decisions where a particular input resulted in an
|
||||||
|
/// SLL conflict, but LL prediction produced a single unique alternative.
|
||||||
|
/// <p>
|
||||||
|
/// In some cases, the unique alternative identified by LL prediction is not
|
||||||
|
/// equal to the minimum represented alternative in the conflicting SLL
|
||||||
|
/// configuration set. Grammars and inputs which result in this scenario are
|
||||||
|
/// unable to use
|
||||||
|
/// <see cref="PredictionMode.Sll">PredictionMode.Sll</see>
|
||||||
|
/// , which in turn means they cannot use
|
||||||
|
/// the two-stage parsing strategy to improve parsing performance for that
|
||||||
|
/// input.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ParserATNSimulator.ReportContextSensitivity(Antlr4.Runtime.Dfa.DFA, int, SimulatorState, int, int)">ParserATNSimulator.ReportContextSensitivity(Antlr4.Runtime.Dfa.DFA, int, SimulatorState, int, int)</seealso>
|
||||||
|
/// <seealso cref="Antlr4.Runtime.IParserErrorListener.ReportContextSensitivity(Antlr4.Runtime.Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, SimulatorState)">Antlr4.Runtime.IParserErrorListener.ReportContextSensitivity(Antlr4.Runtime.Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, SimulatorState)</seealso>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class ContextSensitivityInfo : DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="ContextSensitivityInfo">ContextSensitivityInfo</see>
|
||||||
|
/// class
|
||||||
|
/// with the specified detailed context sensitivity information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
/// <param name="state">
|
||||||
|
/// The final simulator state containing the unique
|
||||||
|
/// alternative identified by full-context prediction
|
||||||
|
/// </param>
|
||||||
|
/// <param name="input">The input token stream</param>
|
||||||
|
/// <param name="startIndex">The start index for the current prediction</param>
|
||||||
|
/// <param name="stopIndex">
|
||||||
|
/// The index at which the context sensitivity was
|
||||||
|
/// identified during full-context prediction
|
||||||
|
/// </param>
|
||||||
|
public ContextSensitivityInfo(int decision, SimulatorState state, ITokenStream input, int startIndex, int stopIndex)
|
||||||
|
: base(decision, state, input, startIndex, stopIndex, true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Antlr4.Runtime.Misc;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This is the base class for gathering detailed information about prediction
|
||||||
|
/// events which occur during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the base class for gathering detailed information about prediction
|
||||||
|
/// events which occur during parsing.
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>The invoked decision number which this event is related to.</summary>
|
||||||
|
/// <remarks>The invoked decision number which this event is related to.</remarks>
|
||||||
|
/// <seealso cref="ATN.decisionToState">ATN.decisionToState</seealso>
|
||||||
|
public readonly int decision;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The simulator state containing additional information relevant to the
|
||||||
|
/// prediction state when the current event occurred, or
|
||||||
|
/// <code>null</code>
|
||||||
|
/// if no
|
||||||
|
/// additional information is relevant or available.
|
||||||
|
/// </summary>
|
||||||
|
[Nullable]
|
||||||
|
public readonly SimulatorState state;
|
||||||
|
|
||||||
|
/// <summary>The input token stream which is being parsed.</summary>
|
||||||
|
/// <remarks>The input token stream which is being parsed.</remarks>
|
||||||
|
[NotNull]
|
||||||
|
public readonly ITokenStream input;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The token index in the input stream at which the current prediction was
|
||||||
|
/// originally invoked.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The token index in the input stream at which the current prediction was
|
||||||
|
/// originally invoked.
|
||||||
|
/// </remarks>
|
||||||
|
public readonly int startIndex;
|
||||||
|
|
||||||
|
/// <summary>The token index in the input stream at which the current event occurred.</summary>
|
||||||
|
/// <remarks>The token index in the input stream at which the current event occurred.</remarks>
|
||||||
|
public readonly int stopIndex;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if the current event occurred during LL prediction;
|
||||||
|
/// otherwise,
|
||||||
|
/// <code>false</code>
|
||||||
|
/// if the input occurred during SLL prediction.
|
||||||
|
/// </summary>
|
||||||
|
public readonly bool fullCtx;
|
||||||
|
|
||||||
|
public DecisionEventInfo(int decision, SimulatorState state, ITokenStream input, int startIndex, int stopIndex, bool fullCtx)
|
||||||
|
{
|
||||||
|
this.decision = decision;
|
||||||
|
this.fullCtx = fullCtx;
|
||||||
|
this.stopIndex = stopIndex;
|
||||||
|
this.input = input;
|
||||||
|
this.startIndex = startIndex;
|
||||||
|
this.state = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,325 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>This class contains profiling gathered for a particular decision.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class contains profiling gathered for a particular decision.
|
||||||
|
/// <p>
|
||||||
|
/// Parsing performance in ANTLR 4 is heavily influenced by both static factors
|
||||||
|
/// (e.g. the form of the rules in the grammar) and dynamic factors (e.g. the
|
||||||
|
/// choice of input and the state of the DFA cache at the time profiling
|
||||||
|
/// operations are started). For best results, gather and use aggregate
|
||||||
|
/// statistics from a large sample of inputs representing the inputs expected in
|
||||||
|
/// production before using the results to make changes in the grammar.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class DecisionInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The decision number, which is an index into
|
||||||
|
/// <see cref="ATN.decisionToState">ATN.decisionToState</see>
|
||||||
|
/// .
|
||||||
|
/// </summary>
|
||||||
|
public readonly int decision;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of times
|
||||||
|
/// <see cref="ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)">ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)</see>
|
||||||
|
/// was
|
||||||
|
/// invoked for this decision.
|
||||||
|
/// </summary>
|
||||||
|
public long invocations;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total time spent in
|
||||||
|
/// <see cref="ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)">ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)</see>
|
||||||
|
/// for
|
||||||
|
/// this decision, in nanoseconds.
|
||||||
|
/// <p>
|
||||||
|
/// The value of this field contains the sum of differential results obtained
|
||||||
|
/// by
|
||||||
|
/// <see cref="Sharpen.Runtime.NanoTime()">Sharpen.Runtime.NanoTime()</see>
|
||||||
|
/// , and is not adjusted to compensate for JIT
|
||||||
|
/// and/or garbage collection overhead. For best accuracy, use a modern JVM
|
||||||
|
/// implementation that provides precise results from
|
||||||
|
/// <see cref="Sharpen.Runtime.NanoTime()">Sharpen.Runtime.NanoTime()</see>
|
||||||
|
/// , and perform profiling in a separate process
|
||||||
|
/// which is warmed up by parsing the input prior to profiling. If desired,
|
||||||
|
/// call
|
||||||
|
/// <see cref="ATNSimulator.ClearDFA()">ATNSimulator.ClearDFA()</see>
|
||||||
|
/// to reset the DFA cache to its initial
|
||||||
|
/// state before starting the profiling measurement pass.</p>
|
||||||
|
/// </summary>
|
||||||
|
public long timeInPrediction;
|
||||||
|
|
||||||
|
/// <summary>The sum of the lookahead required for SLL prediction for this decision.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The sum of the lookahead required for SLL prediction for this decision.
|
||||||
|
/// Note that SLL prediction is used before LL prediction for performance
|
||||||
|
/// reasons even when
|
||||||
|
/// <see cref="PredictionMode.Ll">PredictionMode.Ll</see>
|
||||||
|
/// or
|
||||||
|
/// <see cref="PredictionMode.LlExactAmbigDetection">PredictionMode.LlExactAmbigDetection</see>
|
||||||
|
/// is used.
|
||||||
|
/// </remarks>
|
||||||
|
public long SLL_TotalLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the minimum lookahead required for any single SLL prediction to
|
||||||
|
/// complete for this decision, by reaching a unique prediction, reaching an
|
||||||
|
/// SLL conflict state, or encountering a syntax error.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the minimum lookahead required for any single SLL prediction to
|
||||||
|
/// complete for this decision, by reaching a unique prediction, reaching an
|
||||||
|
/// SLL conflict state, or encountering a syntax error.
|
||||||
|
/// </remarks>
|
||||||
|
public long SLL_MinLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum lookahead required for any single SLL prediction to
|
||||||
|
/// complete for this decision, by reaching a unique prediction, reaching an
|
||||||
|
/// SLL conflict state, or encountering a syntax error.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the maximum lookahead required for any single SLL prediction to
|
||||||
|
/// complete for this decision, by reaching a unique prediction, reaching an
|
||||||
|
/// SLL conflict state, or encountering a syntax error.
|
||||||
|
/// </remarks>
|
||||||
|
public long SLL_MaxLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the
|
||||||
|
/// <see cref="LookaheadEventInfo">LookaheadEventInfo</see>
|
||||||
|
/// associated with the event where the
|
||||||
|
/// <see cref="SLL_MaxLook">SLL_MaxLook</see>
|
||||||
|
/// value was set.
|
||||||
|
/// </summary>
|
||||||
|
public LookaheadEventInfo SLL_MaxLookEvent;
|
||||||
|
|
||||||
|
/// <summary>The sum of the lookahead required for LL prediction for this decision.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The sum of the lookahead required for LL prediction for this decision.
|
||||||
|
/// Note that LL prediction is only used when SLL prediction reaches a
|
||||||
|
/// conflict state.
|
||||||
|
/// </remarks>
|
||||||
|
public long LL_TotalLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the minimum lookahead required for any single LL prediction to
|
||||||
|
/// complete for this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the minimum lookahead required for any single LL prediction to
|
||||||
|
/// complete for this decision. An LL prediction completes when the algorithm
|
||||||
|
/// reaches a unique prediction, a conflict state (for
|
||||||
|
/// <see cref="PredictionMode.Ll">PredictionMode.Ll</see>
|
||||||
|
/// , an ambiguity state (for
|
||||||
|
/// <see cref="PredictionMode.LlExactAmbigDetection">PredictionMode.LlExactAmbigDetection</see>
|
||||||
|
/// , or a syntax error.
|
||||||
|
/// </remarks>
|
||||||
|
public long LL_MinLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the maximum lookahead required for any single LL prediction to
|
||||||
|
/// complete for this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the maximum lookahead required for any single LL prediction to
|
||||||
|
/// complete for this decision. An LL prediction completes when the algorithm
|
||||||
|
/// reaches a unique prediction, a conflict state (for
|
||||||
|
/// <see cref="PredictionMode.Ll">PredictionMode.Ll</see>
|
||||||
|
/// , an ambiguity state (for
|
||||||
|
/// <see cref="PredictionMode.LlExactAmbigDetection">PredictionMode.LlExactAmbigDetection</see>
|
||||||
|
/// , or a syntax error.
|
||||||
|
/// </remarks>
|
||||||
|
public long LL_MaxLook;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the
|
||||||
|
/// <see cref="LookaheadEventInfo">LookaheadEventInfo</see>
|
||||||
|
/// associated with the event where the
|
||||||
|
/// <see cref="LL_MaxLook">LL_MaxLook</see>
|
||||||
|
/// value was set.
|
||||||
|
/// </summary>
|
||||||
|
public LookaheadEventInfo LL_MaxLookEvent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of
|
||||||
|
/// <see cref="ContextSensitivityInfo">ContextSensitivityInfo</see>
|
||||||
|
/// instances describing the
|
||||||
|
/// context sensitivities encountered during LL prediction for this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ContextSensitivityInfo">ContextSensitivityInfo</seealso>
|
||||||
|
public readonly IList<ContextSensitivityInfo> contextSensitivities = new List<ContextSensitivityInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of
|
||||||
|
/// <see cref="ErrorInfo">ErrorInfo</see>
|
||||||
|
/// instances describing the parse errors
|
||||||
|
/// identified during calls to
|
||||||
|
/// <see cref="ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)">ParserATNSimulator.AdaptivePredict(Antlr4.Runtime.ITokenStream, int, Antlr4.Runtime.ParserRuleContext)</see>
|
||||||
|
/// for
|
||||||
|
/// this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="ErrorInfo">ErrorInfo</seealso>
|
||||||
|
public readonly IList<ErrorInfo> errors = new List<ErrorInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of
|
||||||
|
/// <see cref="AmbiguityInfo">AmbiguityInfo</see>
|
||||||
|
/// instances describing the
|
||||||
|
/// ambiguities encountered during LL prediction for this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="AmbiguityInfo">AmbiguityInfo</seealso>
|
||||||
|
public readonly IList<AmbiguityInfo> ambiguities = new List<AmbiguityInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A collection of
|
||||||
|
/// <see cref="PredicateEvalInfo">PredicateEvalInfo</see>
|
||||||
|
/// instances describing the
|
||||||
|
/// results of evaluating individual predicates during prediction for this
|
||||||
|
/// decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <seealso cref="PredicateEvalInfo">PredicateEvalInfo</seealso>
|
||||||
|
public readonly IList<PredicateEvalInfo> predicateEvals = new List<PredicateEvalInfo>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of ATN transitions required during SLL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The total number of ATN transitions required during SLL prediction for
|
||||||
|
/// this decision. An ATN transition is determined by the number of times the
|
||||||
|
/// DFA does not contain an edge that is required for prediction, resulting
|
||||||
|
/// in on-the-fly computation of that edge.
|
||||||
|
/// <p>
|
||||||
|
/// If DFA caching of SLL transitions is employed by the implementation, ATN
|
||||||
|
/// computation may cache the computed edge for efficient lookup during
|
||||||
|
/// future parsing of this decision. Otherwise, the SLL parsing algorithm
|
||||||
|
/// will use ATN transitions exclusively.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="SLL_ATNTransitions">SLL_ATNTransitions</seealso>
|
||||||
|
/// <seealso cref="ParserATNSimulator.ComputeTargetState(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, Antlr4.Runtime.ParserRuleContext, int, bool, PredictionContextCache)">ParserATNSimulator.ComputeTargetState(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, Antlr4.Runtime.ParserRuleContext, int, bool, PredictionContextCache)</seealso>
|
||||||
|
/// <seealso cref="LexerATNSimulator.ComputeTargetState(Antlr4.Runtime.ICharStream, Antlr4.Runtime.Dfa.DFAState, int)">LexerATNSimulator.ComputeTargetState(Antlr4.Runtime.ICharStream, Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
public long SLL_ATNTransitions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of DFA transitions required during SLL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The total number of DFA transitions required during SLL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// <p>If the ATN simulator implementation does not use DFA caching for SLL
|
||||||
|
/// transitions, this value will be 0.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ParserATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)">ParserATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
/// <seealso cref="LexerATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)">LexerATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
public long SLL_DFATransitions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of times SLL prediction completed in a conflict
|
||||||
|
/// state, resulting in fallback to LL prediction.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of times SLL prediction completed in a conflict
|
||||||
|
/// state, resulting in fallback to LL prediction.
|
||||||
|
/// <p>Note that this value is not related to whether or not
|
||||||
|
/// <see cref="PredictionMode.Sll">PredictionMode.Sll</see>
|
||||||
|
/// may be used successfully with a particular
|
||||||
|
/// grammar. If the ambiguity resolution algorithm applied to the SLL
|
||||||
|
/// conflicts for this decision produce the same result as LL prediction for
|
||||||
|
/// this decision,
|
||||||
|
/// <see cref="PredictionMode.Sll">PredictionMode.Sll</see>
|
||||||
|
/// would produce the same overall
|
||||||
|
/// parsing result as
|
||||||
|
/// <see cref="PredictionMode.Ll">PredictionMode.Ll</see>
|
||||||
|
/// .</p>
|
||||||
|
/// </remarks>
|
||||||
|
public long LL_Fallback;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of ATN transitions required during LL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The total number of ATN transitions required during LL prediction for
|
||||||
|
/// this decision. An ATN transition is determined by the number of times the
|
||||||
|
/// DFA does not contain an edge that is required for prediction, resulting
|
||||||
|
/// in on-the-fly computation of that edge.
|
||||||
|
/// <p>
|
||||||
|
/// If DFA caching of LL transitions is employed by the implementation, ATN
|
||||||
|
/// computation may cache the computed edge for efficient lookup during
|
||||||
|
/// future parsing of this decision. Otherwise, the LL parsing algorithm will
|
||||||
|
/// use ATN transitions exclusively.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="LL_DFATransitions">LL_DFATransitions</seealso>
|
||||||
|
/// <seealso cref="ParserATNSimulator.ComputeTargetState(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, Antlr4.Runtime.ParserRuleContext, int, bool, PredictionContextCache)">ParserATNSimulator.ComputeTargetState(Antlr4.Runtime.Dfa.DFA, Antlr4.Runtime.Dfa.DFAState, Antlr4.Runtime.ParserRuleContext, int, bool, PredictionContextCache)</seealso>
|
||||||
|
/// <seealso cref="LexerATNSimulator.ComputeTargetState(Antlr4.Runtime.ICharStream, Antlr4.Runtime.Dfa.DFAState, int)">LexerATNSimulator.ComputeTargetState(Antlr4.Runtime.ICharStream, Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
public long LL_ATNTransitions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The total number of DFA transitions required during LL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The total number of DFA transitions required during LL prediction for
|
||||||
|
/// this decision.
|
||||||
|
/// <p>If the ATN simulator implementation does not use DFA caching for LL
|
||||||
|
/// transitions, this value will be 0.</p>
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ParserATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)">ParserATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
/// <seealso cref="LexerATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)">LexerATNSimulator.GetExistingTargetState(Antlr4.Runtime.Dfa.DFAState, int)</seealso>
|
||||||
|
public long LL_DFATransitions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="DecisionInfo">DecisionInfo</see>
|
||||||
|
/// class to contain
|
||||||
|
/// statistics for a particular decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
public DecisionInfo(int decision)
|
||||||
|
{
|
||||||
|
this.decision = decision;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return "{" + "decision=" + decision + ", contextSensitivities=" + contextSensitivities.Count + ", errors=" + errors.Count + ", ambiguities=" + ambiguities.Count + ", SLL_lookahead=" + SLL_TotalLook + ", SLL_ATNTransitions=" + SLL_ATNTransitions + ", SLL_DFATransitions=" + SLL_DFATransitions + ", LL_Fallback=" + LL_Fallback + ", LL_lookahead=" + LL_TotalLook + ", LL_ATNTransitions=" + LL_ATNTransitions + '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents profiling event information for a syntax error
|
||||||
|
/// identified during prediction.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class represents profiling event information for a syntax error
|
||||||
|
/// identified during prediction. Syntax errors occur when the prediction
|
||||||
|
/// algorithm is unable to identify an alternative which would lead to a
|
||||||
|
/// successful parse.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="Antlr4.Runtime.Parser.NotifyErrorListeners(Antlr4.Runtime.IToken, string, Antlr4.Runtime.RecognitionException)">Antlr4.Runtime.Parser.NotifyErrorListeners(Antlr4.Runtime.IToken, string, Antlr4.Runtime.RecognitionException)</seealso>
|
||||||
|
/// <seealso cref="Antlr4.Runtime.IANTLRErrorListener{Symbol}.SyntaxError{T}(Antlr4.Runtime.Recognizer{Symbol, ATNInterpreter}, object, int, int, string, Antlr4.Runtime.RecognitionException)">Antlr4.Runtime.IANTLRErrorListener<Symbol>.SyntaxError<T>(Antlr4.Runtime.Recognizer<Symbol, ATNInterpreter>, object, int, int, string, Antlr4.Runtime.RecognitionException)</seealso>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class ErrorInfo : DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="ErrorInfo">ErrorInfo</see>
|
||||||
|
/// class with the
|
||||||
|
/// specified detailed syntax error information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
/// <param name="state">
|
||||||
|
/// The final simulator state reached during prediction
|
||||||
|
/// prior to reaching the
|
||||||
|
/// <see cref="ATNSimulator.Error">ATNSimulator.Error</see>
|
||||||
|
/// state
|
||||||
|
/// </param>
|
||||||
|
/// <param name="input">The input token stream</param>
|
||||||
|
/// <param name="startIndex">The start index for the current prediction</param>
|
||||||
|
/// <param name="stopIndex">The index at which the syntax error was identified</param>
|
||||||
|
public ErrorInfo(int decision, SimulatorState state, ITokenStream input, int startIndex, int stopIndex)
|
||||||
|
: base(decision, state, input, startIndex, stopIndex, state.useContext)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents profiling event information for tracking the lookahead
|
||||||
|
/// depth required in order to make a prediction.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class represents profiling event information for tracking the lookahead
|
||||||
|
/// depth required in order to make a prediction.
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class LookaheadEventInfo : DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="LookaheadEventInfo">LookaheadEventInfo</see>
|
||||||
|
/// class with
|
||||||
|
/// the specified detailed lookahead information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
/// <param name="state">
|
||||||
|
/// The final simulator state containing the necessary
|
||||||
|
/// information to determine the result of a prediction, or
|
||||||
|
/// <code>null</code>
|
||||||
|
/// if
|
||||||
|
/// the final state is not available
|
||||||
|
/// </param>
|
||||||
|
/// <param name="input">The input token stream</param>
|
||||||
|
/// <param name="startIndex">The start index for the current prediction</param>
|
||||||
|
/// <param name="stopIndex">The index at which the prediction was finally made</param>
|
||||||
|
/// <param name="fullCtx">
|
||||||
|
///
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if the current lookahead is part of an LL
|
||||||
|
/// prediction; otherwise,
|
||||||
|
/// <code>false</code>
|
||||||
|
/// if the current lookahead is part of
|
||||||
|
/// an SLL prediction
|
||||||
|
/// </param>
|
||||||
|
public LookaheadEventInfo(int decision, SimulatorState state, ITokenStream input, int startIndex, int stopIndex, bool fullCtx)
|
||||||
|
: base(decision, state, input, startIndex, stopIndex, fullCtx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,264 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Antlr4.Runtime.Dfa;
|
||||||
|
using Antlr4.Runtime.Misc;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class provides access to specific and aggregate statistics gathered
|
||||||
|
/// during profiling of a parser.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class provides access to specific and aggregate statistics gathered
|
||||||
|
/// during profiling of a parser.
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class ParseInfo
|
||||||
|
{
|
||||||
|
protected internal readonly ProfilingATNSimulator atnSimulator;
|
||||||
|
|
||||||
|
public ParseInfo(ProfilingATNSimulator atnSimulator)
|
||||||
|
{
|
||||||
|
this.atnSimulator = atnSimulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets an array of
|
||||||
|
/// <see cref="DecisionInfo">DecisionInfo</see>
|
||||||
|
/// instances containing the profiling
|
||||||
|
/// information gathered for each decision in the ATN.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// An array of
|
||||||
|
/// <see cref="DecisionInfo">DecisionInfo</see>
|
||||||
|
/// instances, indexed by decision
|
||||||
|
/// number.
|
||||||
|
/// </returns>
|
||||||
|
[NotNull]
|
||||||
|
public virtual DecisionInfo[] GetDecisionInfo()
|
||||||
|
{
|
||||||
|
return atnSimulator.GetDecisionInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the decision numbers for decisions that required one or more
|
||||||
|
/// full-context predictions during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the decision numbers for decisions that required one or more
|
||||||
|
/// full-context predictions during parsing. These are decisions for which
|
||||||
|
/// <see cref="DecisionInfo.LL_Fallback">DecisionInfo.LL_Fallback</see>
|
||||||
|
/// is non-zero.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// A list of decision numbers which required one or more
|
||||||
|
/// full-context predictions during parsing.
|
||||||
|
/// </returns>
|
||||||
|
[NotNull]
|
||||||
|
public virtual IList<int> GetLLDecisions()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
IList<int> Ll = new List<int>();
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
long fallBack = decisions[i].LL_Fallback;
|
||||||
|
if (fallBack > 0)
|
||||||
|
{
|
||||||
|
Ll.AddItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Ll;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total time spent during prediction across all decisions made
|
||||||
|
/// during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total time spent during prediction across all decisions made
|
||||||
|
/// during parsing. This value is the sum of
|
||||||
|
/// <see cref="DecisionInfo.timeInPrediction">DecisionInfo.timeInPrediction</see>
|
||||||
|
/// for all decisions.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalTimeInPrediction()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long t = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
t += decisions[i].timeInPrediction;
|
||||||
|
}
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of SLL lookahead operations across all decisions
|
||||||
|
/// made during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of SLL lookahead operations across all decisions
|
||||||
|
/// made during parsing. This value is the sum of
|
||||||
|
/// <see cref="DecisionInfo.SLL_TotalLook">DecisionInfo.SLL_TotalLook</see>
|
||||||
|
/// for all decisions.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalSLLLookaheadOps()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long k = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
k += decisions[i].SLL_TotalLook;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of LL lookahead operations across all decisions
|
||||||
|
/// made during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of LL lookahead operations across all decisions
|
||||||
|
/// made during parsing. This value is the sum of
|
||||||
|
/// <see cref="DecisionInfo.LL_TotalLook">DecisionInfo.LL_TotalLook</see>
|
||||||
|
/// for all decisions.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalLLLookaheadOps()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long k = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
k += decisions[i].LL_TotalLook;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of ATN lookahead operations for SLL prediction
|
||||||
|
/// across all decisions made during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of ATN lookahead operations for SLL prediction
|
||||||
|
/// across all decisions made during parsing.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalSLLATNLookaheadOps()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long k = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
k += decisions[i].SLL_ATNTransitions;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of ATN lookahead operations for LL prediction
|
||||||
|
/// across all decisions made during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of ATN lookahead operations for LL prediction
|
||||||
|
/// across all decisions made during parsing.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalLLATNLookaheadOps()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long k = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
k += decisions[i].LL_ATNTransitions;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of ATN lookahead operations for SLL and LL
|
||||||
|
/// prediction across all decisions made during parsing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of ATN lookahead operations for SLL and LL
|
||||||
|
/// prediction across all decisions made during parsing.
|
||||||
|
/// <p>
|
||||||
|
/// This value is the sum of
|
||||||
|
/// <see cref="GetTotalSLLATNLookaheadOps()">GetTotalSLLATNLookaheadOps()</see>
|
||||||
|
/// and
|
||||||
|
/// <see cref="GetTotalLLATNLookaheadOps()">GetTotalLLATNLookaheadOps()</see>
|
||||||
|
/// .</p>
|
||||||
|
/// </remarks>
|
||||||
|
public virtual long GetTotalATNLookaheadOps()
|
||||||
|
{
|
||||||
|
DecisionInfo[] decisions = atnSimulator.GetDecisionInfo();
|
||||||
|
long k = 0;
|
||||||
|
for (int i = 0; i < decisions.Length; i++)
|
||||||
|
{
|
||||||
|
k += decisions[i].SLL_ATNTransitions;
|
||||||
|
k += decisions[i].LL_ATNTransitions;
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of DFA states stored in the DFA cache for all
|
||||||
|
/// decisions in the ATN.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of DFA states stored in the DFA cache for all
|
||||||
|
/// decisions in the ATN.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual int GetDFASize()
|
||||||
|
{
|
||||||
|
int n = 0;
|
||||||
|
DFA[] decisionToDFA = atnSimulator.atn.decisionToDFA;
|
||||||
|
for (int i = 0; i < decisionToDFA.Length; i++)
|
||||||
|
{
|
||||||
|
n += GetDFASize(i);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the total number of DFA states stored in the DFA cache for a
|
||||||
|
/// particular decision.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Gets the total number of DFA states stored in the DFA cache for a
|
||||||
|
/// particular decision.
|
||||||
|
/// </remarks>
|
||||||
|
public virtual int GetDFASize(int decision)
|
||||||
|
{
|
||||||
|
DFA decisionToDFA = atnSimulator.atn.decisionToDFA[decision];
|
||||||
|
return decisionToDFA.states.Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -545,7 +545,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
protected internal virtual int ExecDFA(DFA dfa, ITokenStream input, int startIndex, SimulatorState state)
|
protected internal virtual int ExecDFA(DFA dfa, ITokenStream input, int startIndex, SimulatorState state)
|
||||||
{
|
{
|
||||||
ParserRuleContext outerContext = state.outerContext;
|
ParserRuleContext outerContext = state.outerContext;
|
||||||
DFAState acceptState = null;
|
|
||||||
DFAState s = state.s0;
|
DFAState s = state.s0;
|
||||||
int t = input.La(1);
|
int t = input.La(1);
|
||||||
ParserRuleContext remainingOuterContext = state.remainingOuterContext;
|
ParserRuleContext remainingOuterContext = state.remainingOuterContext;
|
||||||
|
@ -567,6 +566,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
SimulatorState initialState = new SimulatorState(state.outerContext, s, state.useContext, remainingOuterContext);
|
SimulatorState initialState = new SimulatorState(state.outerContext, s, state.useContext, remainingOuterContext);
|
||||||
return ExecATN(dfa, input, startIndex, initialState);
|
return ExecATN(dfa, input, startIndex, initialState);
|
||||||
}
|
}
|
||||||
|
System.Diagnostics.Debug.Assert(remainingOuterContext != null);
|
||||||
remainingOuterContext = ((ParserRuleContext)remainingOuterContext.Parent);
|
remainingOuterContext = ((ParserRuleContext)remainingOuterContext.Parent);
|
||||||
s = next;
|
s = next;
|
||||||
}
|
}
|
||||||
|
@ -576,7 +576,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
if (s.predicates != null)
|
if (s.predicates != null)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
acceptState = s;
|
|
||||||
// keep going unless we're at EOF or state only has one alt number
|
// keep going unless we're at EOF or state only has one alt number
|
||||||
// mentioned in configs; check if something else could match
|
// mentioned in configs; check if something else could match
|
||||||
// TODO: don't we always stop? only lexer would keep going
|
// TODO: don't we always stop? only lexer would keep going
|
||||||
|
@ -586,7 +585,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
// t is not updated if one of these states is reached
|
// t is not updated if one of these states is reached
|
||||||
System.Diagnostics.Debug.Assert(!s.isAcceptState);
|
System.Diagnostics.Debug.Assert(!s.isAcceptState);
|
||||||
// if no edge, pop over to ATN interpreter, update DFA and return
|
// if no edge, pop over to ATN interpreter, update DFA and return
|
||||||
DFAState target = s.GetTarget(t);
|
DFAState target = GetExistingTargetState(s, t);
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
#if !PORTABLE
|
#if !PORTABLE
|
||||||
|
@ -598,19 +597,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
int alt;
|
int alt;
|
||||||
SimulatorState initialState = new SimulatorState(outerContext, s, state.useContext, remainingOuterContext);
|
SimulatorState initialState = new SimulatorState(outerContext, s, state.useContext, remainingOuterContext);
|
||||||
alt = ExecATN(dfa, input, startIndex, initialState);
|
alt = ExecATN(dfa, input, startIndex, initialState);
|
||||||
// this adds edge even if next state is accept for
|
|
||||||
// same alt; e.g., s0-A->:s1=>2-B->:s2=>2
|
|
||||||
// TODO: This next stuff kills edge, but extra states remain. :(
|
|
||||||
if (s.isAcceptState && alt != -1)
|
|
||||||
{
|
|
||||||
DFAState d = s.GetTarget(input.La(1));
|
|
||||||
if (d.isAcceptState && d.prediction == s.prediction)
|
|
||||||
{
|
|
||||||
// we can carve it out.
|
|
||||||
s.SetTarget(input.La(1), Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// IGNORE really not error
|
|
||||||
//dump(dfa);
|
//dump(dfa);
|
||||||
// action already executed
|
// action already executed
|
||||||
return alt;
|
return alt;
|
||||||
|
@ -635,11 +621,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
// if ( debug ) System.out.println("!!! no viable alt in dfa");
|
// if ( debug ) System.out.println("!!! no viable alt in dfa");
|
||||||
// return -1;
|
// return -1;
|
||||||
// }
|
// }
|
||||||
if (acceptState.configs.ConflictingAlts != null)
|
if (s.configs.ConflictingAlts != null)
|
||||||
{
|
{
|
||||||
if (dfa.atnStartState is DecisionState)
|
if (dfa.atnStartState is DecisionState)
|
||||||
{
|
{
|
||||||
if (!userWantsCtxSensitive || !acceptState.configs.DipsIntoOuterContext || (treat_sllk1_conflict_as_ambiguity && input.Index == startIndex))
|
if (!userWantsCtxSensitive || !s.configs.DipsIntoOuterContext || (treat_sllk1_conflict_as_ambiguity && input.Index == startIndex))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -653,14 +639,15 @@ namespace Antlr4.Runtime.Atn
|
||||||
// disambiguating or validating predicates to evaluate which allow an
|
// disambiguating or validating predicates to evaluate which allow an
|
||||||
// immediate decision
|
// immediate decision
|
||||||
BitSet conflictingAlts = null;
|
BitSet conflictingAlts = null;
|
||||||
if (acceptState.predicates != null)
|
DFAState.PredPrediction[] predicates = s.predicates;
|
||||||
|
if (predicates != null)
|
||||||
{
|
{
|
||||||
int conflictIndex = input.Index;
|
int conflictIndex = input.Index;
|
||||||
if (conflictIndex != startIndex)
|
if (conflictIndex != startIndex)
|
||||||
{
|
{
|
||||||
input.Seek(startIndex);
|
input.Seek(startIndex);
|
||||||
}
|
}
|
||||||
conflictingAlts = EvalSemanticContext(s.predicates, outerContext, true);
|
conflictingAlts = EvalSemanticContext(predicates, outerContext, true);
|
||||||
if (conflictingAlts.Cardinality() == 1)
|
if (conflictingAlts.Cardinality() == 1)
|
||||||
{
|
{
|
||||||
return conflictingAlts.NextSetBit(0);
|
return conflictingAlts.NextSetBit(0);
|
||||||
|
@ -674,7 +661,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
if (reportAmbiguities)
|
if (reportAmbiguities)
|
||||||
{
|
{
|
||||||
SimulatorState conflictState = new SimulatorState(outerContext, acceptState, state.useContext, remainingOuterContext);
|
SimulatorState conflictState = new SimulatorState(outerContext, s, state.useContext, remainingOuterContext);
|
||||||
ReportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, input.Index);
|
ReportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, input.Index);
|
||||||
}
|
}
|
||||||
input.Seek(startIndex);
|
input.Seek(startIndex);
|
||||||
|
@ -684,14 +671,15 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
// Before jumping to prediction, check to see if there are
|
// Before jumping to prediction, check to see if there are
|
||||||
// disambiguating or validating predicates to evaluate
|
// disambiguating or validating predicates to evaluate
|
||||||
if (s.predicates != null)
|
DFAState.PredPrediction[] predicates_1 = s.predicates;
|
||||||
|
if (predicates_1 != null)
|
||||||
{
|
{
|
||||||
int stopIndex = input.Index;
|
int stopIndex = input.Index;
|
||||||
if (startIndex != stopIndex)
|
if (startIndex != stopIndex)
|
||||||
{
|
{
|
||||||
input.Seek(startIndex);
|
input.Seek(startIndex);
|
||||||
}
|
}
|
||||||
BitSet alts = EvalSemanticContext(s.predicates, outerContext, reportAmbiguities && predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection);
|
BitSet alts = EvalSemanticContext(predicates_1, outerContext, reportAmbiguities && predictionMode == Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection);
|
||||||
switch (alts.Cardinality())
|
switch (alts.Cardinality())
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -717,7 +705,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return acceptState.prediction;
|
return s.prediction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -1067,6 +1055,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
System.Diagnostics.Debug.Assert(remainingGlobalContext != null);
|
||||||
remainingGlobalContext = ((ParserRuleContext)remainingGlobalContext.Parent);
|
remainingGlobalContext = ((ParserRuleContext)remainingGlobalContext.Parent);
|
||||||
s = next;
|
s = next;
|
||||||
}
|
}
|
||||||
|
@ -1642,7 +1631,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
// if no (null, i), then no default prediction.
|
// if no (null, i), then no default prediction.
|
||||||
if (ambigAlts != null && ambigAlts.Get(i) && pred == SemanticContext.None)
|
if (ambigAlts != null && ambigAlts.Get(i) && pred == SemanticContext.None)
|
||||||
{
|
{
|
||||||
pairs.Add(new DFAState.PredPrediction(null, i));
|
pairs.Add(new DFAState.PredPrediction(pred, i));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1677,7 +1666,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
BitSet predictions = new BitSet();
|
BitSet predictions = new BitSet();
|
||||||
foreach (DFAState.PredPrediction pair in predPredictions)
|
foreach (DFAState.PredPrediction pair in predPredictions)
|
||||||
{
|
{
|
||||||
if (pair.pred == null)
|
if (pair.pred == SemanticContext.None)
|
||||||
{
|
{
|
||||||
predictions.Set(pair.alt);
|
predictions.Set(pair.alt);
|
||||||
if (!complete)
|
if (!complete)
|
||||||
|
@ -1686,7 +1675,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool evaluatedResult = pair.pred.Eval(parser, outerContext);
|
bool evaluatedResult = EvalSemanticContext(pair.pred, outerContext, pair.alt);
|
||||||
#if !PORTABLE
|
#if !PORTABLE
|
||||||
if (debug || dfa_debug)
|
if (debug || dfa_debug)
|
||||||
{
|
{
|
||||||
|
@ -1711,6 +1700,44 @@ namespace Antlr4.Runtime.Atn
|
||||||
return predictions;
|
return predictions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Evaluate a semantic context within a specific parser context.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Evaluate a semantic context within a specific parser context.
|
||||||
|
/// <p>
|
||||||
|
/// This method might not be called for every semantic context evaluated
|
||||||
|
/// during the prediction process. In particular, we currently do not
|
||||||
|
/// evaluate the following but it may change in the future:</p>
|
||||||
|
/// <ul>
|
||||||
|
/// <li>Precedence predicates (represented by
|
||||||
|
/// <see cref="PrecedencePredicate">PrecedencePredicate</see>
|
||||||
|
/// ) are not currently evaluated
|
||||||
|
/// through this method.</li>
|
||||||
|
/// <li>Operator predicates (represented by
|
||||||
|
/// <see cref="AND">AND</see>
|
||||||
|
/// and
|
||||||
|
/// <see cref="OR">OR</see>
|
||||||
|
/// ) are evaluated as a single semantic
|
||||||
|
/// context, rather than evaluating the operands individually.
|
||||||
|
/// Implementations which require evaluation results from individual
|
||||||
|
/// predicates should override this method to explicitly handle evaluation of
|
||||||
|
/// the operands within operator predicates.</li>
|
||||||
|
/// </ul>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="pred">The semantic context to evaluate</param>
|
||||||
|
/// <param name="parserCallStack">
|
||||||
|
/// The parser context in which to evaluate the
|
||||||
|
/// semantic context
|
||||||
|
/// </param>
|
||||||
|
/// <param name="alt">
|
||||||
|
/// The alternative which is guarded by
|
||||||
|
/// <code>pred</code>
|
||||||
|
/// </param>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
protected internal virtual bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt)
|
||||||
|
{
|
||||||
|
return pred.Eval(parser, parserCallStack);
|
||||||
|
}
|
||||||
|
|
||||||
protected internal virtual void Closure(ATNConfigSet sourceConfigs, ATNConfigSet configs, bool collectPredicates, bool hasMoreContext, PredictionContextCache contextCache, bool treatEofAsEpsilon)
|
protected internal virtual void Closure(ATNConfigSet sourceConfigs, ATNConfigSet configs, bool collectPredicates, bool hasMoreContext, PredictionContextCache contextCache, bool treatEofAsEpsilon)
|
||||||
{
|
{
|
||||||
if (contextCache == null)
|
if (contextCache == null)
|
||||||
|
@ -1927,7 +1954,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
[return: Nullable]
|
[return: Nullable]
|
||||||
protected internal virtual ATNConfig PrecedenceTransition(ATNConfig config, PrecedencePredicateTransition pt, bool collectPredicates, bool inContext)
|
protected internal virtual ATNConfig PrecedenceTransition(ATNConfig config, PrecedencePredicateTransition pt, bool collectPredicates, bool inContext)
|
||||||
{
|
{
|
||||||
ATNConfig c = null;
|
ATNConfig c;
|
||||||
if (collectPredicates && inContext)
|
if (collectPredicates && inContext)
|
||||||
{
|
{
|
||||||
SemanticContext newSemCtx = SemanticContext.And(config.SemanticContext, pt.GetPredicate());
|
SemanticContext newSemCtx = SemanticContext.And(config.SemanticContext, pt.GetPredicate());
|
||||||
|
@ -1979,9 +2006,9 @@ namespace Antlr4.Runtime.Atn
|
||||||
return config.Transform(t.target, newContext, false);
|
return config.Transform(t.target, newContext, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private sealed class _IComparer_1905 : IComparer<ATNConfig>
|
private sealed class _IComparer_1928 : IComparer<ATNConfig>
|
||||||
{
|
{
|
||||||
public _IComparer_1905()
|
public _IComparer_1928()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2001,7 +2028,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1905();
|
private static readonly IComparer<ATNConfig> StateAltSortComparator = new _IComparer_1928();
|
||||||
|
|
||||||
private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache)
|
private BitSet IsConflicted(ATNConfigSet configset, PredictionContextCache contextCache)
|
||||||
{
|
{
|
||||||
|
@ -2019,9 +2046,8 @@ namespace Antlr4.Runtime.Atn
|
||||||
// minAlt from the first state, #2 will fail if the assumption was
|
// minAlt from the first state, #2 will fail if the assumption was
|
||||||
// incorrect
|
// incorrect
|
||||||
int currentState = configs[0].State.NonStopStateNumber;
|
int currentState = configs[0].State.NonStopStateNumber;
|
||||||
for (int i = 0; i < configs.Count; i++)
|
foreach (ATNConfig config in configs)
|
||||||
{
|
{
|
||||||
ATNConfig config = configs[i];
|
|
||||||
int stateNumber = config.State.NonStopStateNumber;
|
int stateNumber = config.State.NonStopStateNumber;
|
||||||
if (stateNumber != currentState)
|
if (stateNumber != currentState)
|
||||||
{
|
{
|
||||||
|
@ -2032,32 +2058,30 @@ namespace Antlr4.Runtime.Atn
|
||||||
currentState = stateNumber;
|
currentState = stateNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BitSet representedAlts = null;
|
BitSet representedAlts;
|
||||||
if (exact)
|
if (exact)
|
||||||
{
|
{
|
||||||
currentState = configs[0].State.NonStopStateNumber;
|
currentState = configs[0].State.NonStopStateNumber;
|
||||||
// get the represented alternatives of the first state
|
// get the represented alternatives of the first state
|
||||||
representedAlts = new BitSet();
|
representedAlts = new BitSet();
|
||||||
int maxAlt = minAlt;
|
int maxAlt = minAlt;
|
||||||
for (int i_1 = 0; i_1 < configs.Count; i_1++)
|
foreach (ATNConfig config_1 in configs)
|
||||||
{
|
{
|
||||||
ATNConfig config = configs[i_1];
|
if (config_1.State.NonStopStateNumber != currentState)
|
||||||
if (config.State.NonStopStateNumber != currentState)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int alt = config.Alt;
|
int alt = config_1.Alt;
|
||||||
representedAlts.Set(alt);
|
representedAlts.Set(alt);
|
||||||
maxAlt = alt;
|
maxAlt = alt;
|
||||||
}
|
}
|
||||||
// quick check #3:
|
// quick check #3:
|
||||||
currentState = configs[0].State.NonStopStateNumber;
|
currentState = configs[0].State.NonStopStateNumber;
|
||||||
int currentAlt = minAlt;
|
int currentAlt = minAlt;
|
||||||
for (int i_2 = 0; i_2 < configs.Count; i_2++)
|
foreach (ATNConfig config_2 in configs)
|
||||||
{
|
{
|
||||||
ATNConfig config = configs[i_2];
|
int stateNumber = config_2.State.NonStopStateNumber;
|
||||||
int stateNumber = config.State.NonStopStateNumber;
|
int alt = config_2.Alt;
|
||||||
int alt = config.Alt;
|
|
||||||
if (stateNumber != currentState)
|
if (stateNumber != currentState)
|
||||||
{
|
{
|
||||||
if (currentAlt != maxAlt)
|
if (currentAlt != maxAlt)
|
||||||
|
@ -2084,31 +2108,31 @@ namespace Antlr4.Runtime.Atn
|
||||||
int firstIndexCurrentState = 0;
|
int firstIndexCurrentState = 0;
|
||||||
int lastIndexCurrentStateMinAlt = 0;
|
int lastIndexCurrentStateMinAlt = 0;
|
||||||
PredictionContext joinedCheckContext = configs[0].Context;
|
PredictionContext joinedCheckContext = configs[0].Context;
|
||||||
for (int i_3 = 1; i_3 < configs.Count; i_3++)
|
for (int i = 1; i < configs.Count; i++)
|
||||||
{
|
{
|
||||||
ATNConfig config = configs[i_3];
|
ATNConfig config_1 = configs[i];
|
||||||
if (config.Alt != minAlt)
|
if (config_1.Alt != minAlt)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (config.State.NonStopStateNumber != currentState)
|
if (config_1.State.NonStopStateNumber != currentState)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
lastIndexCurrentStateMinAlt = i_3;
|
lastIndexCurrentStateMinAlt = i;
|
||||||
joinedCheckContext = contextCache.Join(joinedCheckContext, configs[i_3].Context);
|
joinedCheckContext = contextCache.Join(joinedCheckContext, configs[i].Context);
|
||||||
}
|
}
|
||||||
for (int i_4 = lastIndexCurrentStateMinAlt + 1; i_4 < configs.Count; i_4++)
|
for (int i_1 = lastIndexCurrentStateMinAlt + 1; i_1 < configs.Count; i_1++)
|
||||||
{
|
{
|
||||||
ATNConfig config = configs[i_4];
|
ATNConfig config_1 = configs[i_1];
|
||||||
ATNState state = config.State;
|
ATNState state = config_1.State;
|
||||||
alts.Set(config.Alt);
|
alts.Set(config_1.Alt);
|
||||||
if (state.NonStopStateNumber != currentState)
|
if (state.NonStopStateNumber != currentState)
|
||||||
{
|
{
|
||||||
currentState = state.NonStopStateNumber;
|
currentState = state.NonStopStateNumber;
|
||||||
firstIndexCurrentState = i_4;
|
firstIndexCurrentState = i_1;
|
||||||
lastIndexCurrentStateMinAlt = i_4;
|
lastIndexCurrentStateMinAlt = i_1;
|
||||||
joinedCheckContext = config.Context;
|
joinedCheckContext = config_1.Context;
|
||||||
for (int j = firstIndexCurrentState + 1; j < configs.Count; j++)
|
for (int j = firstIndexCurrentState + 1; j < configs.Count; j++)
|
||||||
{
|
{
|
||||||
ATNConfig config2 = configs[j];
|
ATNConfig config2 = configs[j];
|
||||||
|
@ -2123,12 +2147,12 @@ namespace Antlr4.Runtime.Atn
|
||||||
lastIndexCurrentStateMinAlt = j;
|
lastIndexCurrentStateMinAlt = j;
|
||||||
joinedCheckContext = contextCache.Join(joinedCheckContext, config2.Context);
|
joinedCheckContext = contextCache.Join(joinedCheckContext, config2.Context);
|
||||||
}
|
}
|
||||||
i_4 = lastIndexCurrentStateMinAlt;
|
i_1 = lastIndexCurrentStateMinAlt;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
PredictionContext joinedCheckContext2 = config.Context;
|
PredictionContext joinedCheckContext2 = config_1.Context;
|
||||||
int currentAlt = config.Alt;
|
int currentAlt = config_1.Alt;
|
||||||
int lastIndexCurrentStateCurrentAlt = i_4;
|
int lastIndexCurrentStateCurrentAlt = i_1;
|
||||||
for (int j_1 = lastIndexCurrentStateCurrentAlt + 1; j_1 < configs.Count; j_1++)
|
for (int j_1 = lastIndexCurrentStateCurrentAlt + 1; j_1 < configs.Count; j_1++)
|
||||||
{
|
{
|
||||||
ATNConfig config2 = configs[j_1];
|
ATNConfig config2 = configs[j_1];
|
||||||
|
@ -2143,7 +2167,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
lastIndexCurrentStateCurrentAlt = j_1;
|
lastIndexCurrentStateCurrentAlt = j_1;
|
||||||
joinedCheckContext2 = contextCache.Join(joinedCheckContext2, config2.Context);
|
joinedCheckContext2 = contextCache.Join(joinedCheckContext2, config2.Context);
|
||||||
}
|
}
|
||||||
i_4 = lastIndexCurrentStateCurrentAlt;
|
i_1 = lastIndexCurrentStateCurrentAlt;
|
||||||
if (exact)
|
if (exact)
|
||||||
{
|
{
|
||||||
if (!joinedCheckContext.Equals(joinedCheckContext2))
|
if (!joinedCheckContext.Equals(joinedCheckContext2))
|
||||||
|
@ -2164,19 +2188,19 @@ namespace Antlr4.Runtime.Atn
|
||||||
for (int j = firstIndexCurrentState; j <= lastIndexCurrentStateMinAlt; j++)
|
for (int j = firstIndexCurrentState; j <= lastIndexCurrentStateMinAlt; j++)
|
||||||
{
|
{
|
||||||
ATNConfig checkConfig = configs[j];
|
ATNConfig checkConfig = configs[j];
|
||||||
if (checkConfig.SemanticContext != SemanticContext.None && !checkConfig.SemanticContext.Equals(config.SemanticContext))
|
if (checkConfig.SemanticContext != SemanticContext.None && !checkConfig.SemanticContext.Equals(config_1.SemanticContext))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (joinedCheckContext != checkConfig.Context)
|
if (joinedCheckContext != checkConfig.Context)
|
||||||
{
|
{
|
||||||
PredictionContext check = contextCache.Join(checkConfig.Context, config.Context);
|
PredictionContext check = contextCache.Join(checkConfig.Context, config_1.Context);
|
||||||
if (!checkConfig.Context.Equals(check))
|
if (!checkConfig.Context.Equals(check))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.IsHidden = true;
|
config_1.IsHidden = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2486,22 +2510,6 @@ namespace Antlr4.Runtime.Atn
|
||||||
#if !PORTABLE
|
#if !PORTABLE
|
||||||
if (debug || retry_debug)
|
if (debug || retry_debug)
|
||||||
{
|
{
|
||||||
// ParserATNPathFinder finder = new ParserATNPathFinder(parser, atn);
|
|
||||||
// int i = 1;
|
|
||||||
// for (Transition t : dfa.atnStartState.transitions) {
|
|
||||||
// System.out.println("ALT "+i+"=");
|
|
||||||
// System.out.println(startIndex+".."+stopIndex+", len(input)="+parser.getInputStream().size());
|
|
||||||
// TraceTree path = finder.trace(t.target, parser.getContext(), (TokenStream)parser.getInputStream(),
|
|
||||||
// startIndex, stopIndex);
|
|
||||||
// if ( path!=null ) {
|
|
||||||
// System.out.println("path = "+path.toStringTree());
|
|
||||||
// for (TraceTree leaf : path.leaves) {
|
|
||||||
// List<ATNState> states = path.getPathToNode(leaf);
|
|
||||||
// System.out.println("states="+states);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// i++;
|
|
||||||
// }
|
|
||||||
Interval interval = Interval.Of(startIndex, stopIndex);
|
Interval interval = Interval.Of(startIndex, stopIndex);
|
||||||
System.Console.Out.WriteLine("reportAmbiguity " + ambigAlts + ":" + configs + ", input=" + ((ITokenStream)parser.InputStream).GetText(interval));
|
System.Console.Out.WriteLine("reportAmbiguity " + ambigAlts + ":" + configs + ", input=" + ((ITokenStream)parser.InputStream).GetText(interval));
|
||||||
}
|
}
|
||||||
|
@ -2542,5 +2550,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
}
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public virtual Parser GetParser()
|
||||||
|
{
|
||||||
|
return parser;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents profiling event information for semantic predicate
|
||||||
|
/// evaluations which occur during prediction.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class represents profiling event information for semantic predicate
|
||||||
|
/// evaluations which occur during prediction.
|
||||||
|
/// </remarks>
|
||||||
|
/// <seealso cref="ParserATNSimulator.EvalSemanticContext(Antlr4.Runtime.Dfa.DFAState.PredPrediction[], Antlr4.Runtime.ParserRuleContext, bool)">ParserATNSimulator.EvalSemanticContext(Antlr4.Runtime.Dfa.DFAState.PredPrediction[], Antlr4.Runtime.ParserRuleContext, bool)</seealso>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class PredicateEvalInfo : DecisionEventInfo
|
||||||
|
{
|
||||||
|
/// <summary>The semantic context which was evaluated.</summary>
|
||||||
|
/// <remarks>The semantic context which was evaluated.</remarks>
|
||||||
|
public readonly SemanticContext semctx;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The alternative number for the decision which is guarded by the semantic
|
||||||
|
/// context
|
||||||
|
/// <see cref="semctx">semctx</see>
|
||||||
|
/// . Note that other ATN
|
||||||
|
/// configurations may predict the same alternative which are guarded by
|
||||||
|
/// other semantic contexts and/or
|
||||||
|
/// <see cref="SemanticContext.None">SemanticContext.None</see>
|
||||||
|
/// .
|
||||||
|
/// </summary>
|
||||||
|
public readonly int predictedAlt;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The result of evaluating the semantic context
|
||||||
|
/// <see cref="semctx">semctx</see>
|
||||||
|
/// .
|
||||||
|
/// </summary>
|
||||||
|
public readonly bool evalResult;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructs a new instance of the
|
||||||
|
/// <see cref="PredicateEvalInfo">PredicateEvalInfo</see>
|
||||||
|
/// class with the
|
||||||
|
/// specified detailed predicate evaluation information.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="state">The simulator state</param>
|
||||||
|
/// <param name="decision">The decision number</param>
|
||||||
|
/// <param name="input">The input token stream</param>
|
||||||
|
/// <param name="startIndex">The start index for the current prediction</param>
|
||||||
|
/// <param name="stopIndex">
|
||||||
|
/// The index at which the predicate evaluation was
|
||||||
|
/// triggered. Note that the input stream may be reset to other positions for
|
||||||
|
/// the actual evaluation of individual predicates.
|
||||||
|
/// </param>
|
||||||
|
/// <param name="semctx">The semantic context which was evaluated</param>
|
||||||
|
/// <param name="evalResult">The results of evaluating the semantic context</param>
|
||||||
|
/// <param name="predictedAlt">
|
||||||
|
/// The alternative number for the decision which is
|
||||||
|
/// guarded by the semantic context
|
||||||
|
/// <code>semctx</code>
|
||||||
|
/// . See
|
||||||
|
/// <see cref="predictedAlt">predictedAlt</see>
|
||||||
|
/// for more information.
|
||||||
|
/// </param>
|
||||||
|
/// <seealso cref="ParserATNSimulator.EvalSemanticContext(SemanticContext, Antlr4.Runtime.ParserRuleContext, int)">ParserATNSimulator.EvalSemanticContext(SemanticContext, Antlr4.Runtime.ParserRuleContext, int)</seealso>
|
||||||
|
/// <seealso cref="SemanticContext.Eval(Antlr4.Runtime.Recognizer{Symbol, ATNInterpreter}, Antlr4.Runtime.RuleContext)">SemanticContext.Eval(Antlr4.Runtime.Recognizer<Symbol, ATNInterpreter>, Antlr4.Runtime.RuleContext)</seealso>
|
||||||
|
public PredicateEvalInfo(SimulatorState state, int decision, ITokenStream input, int startIndex, int stopIndex, SemanticContext semctx, bool evalResult, int predictedAlt)
|
||||||
|
: base(decision, state, input, startIndex, stopIndex, state.useContext)
|
||||||
|
{
|
||||||
|
this.semctx = semctx;
|
||||||
|
this.evalResult = evalResult;
|
||||||
|
this.predictedAlt = predictedAlt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,273 @@
|
||||||
|
/*
|
||||||
|
* [The "BSD license"]
|
||||||
|
* Copyright (c) 2013 Terence Parr
|
||||||
|
* Copyright (c) 2013 Sam Harwell
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||||
|
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using Antlr4.Runtime;
|
||||||
|
using Antlr4.Runtime.Atn;
|
||||||
|
using Antlr4.Runtime.Dfa;
|
||||||
|
using Sharpen;
|
||||||
|
|
||||||
|
namespace Antlr4.Runtime.Atn
|
||||||
|
{
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public class ProfilingATNSimulator : ParserATNSimulator
|
||||||
|
{
|
||||||
|
protected internal readonly DecisionInfo[] decisions;
|
||||||
|
|
||||||
|
protected internal int numDecisions;
|
||||||
|
|
||||||
|
protected internal ITokenStream _input;
|
||||||
|
|
||||||
|
protected internal int _startIndex;
|
||||||
|
|
||||||
|
protected internal int _sllStopIndex;
|
||||||
|
|
||||||
|
protected internal int _llStopIndex;
|
||||||
|
|
||||||
|
protected internal int currentDecision;
|
||||||
|
|
||||||
|
protected internal SimulatorState currentState;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// At the point of LL failover, we record how SLL would resolve the conflict so that
|
||||||
|
/// we can determine whether or not a decision / input pair is context-sensitive.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// At the point of LL failover, we record how SLL would resolve the conflict so that
|
||||||
|
/// we can determine whether or not a decision / input pair is context-sensitive.
|
||||||
|
/// If LL gives a different result than SLL's predicted alternative, we have a
|
||||||
|
/// context sensitivity for sure. The converse is not necessarily true, however.
|
||||||
|
/// It's possible that after conflict resolution chooses minimum alternatives,
|
||||||
|
/// SLL could get the same answer as LL. Regardless of whether or not the result indicates
|
||||||
|
/// an ambiguity, it is not treated as a context sensitivity because LL prediction
|
||||||
|
/// was not required in order to produce a correct prediction for this decision and input sequence.
|
||||||
|
/// It may in fact still be a context sensitivity but we don't know by looking at the
|
||||||
|
/// minimum alternatives for the current input.
|
||||||
|
/// </remarks>
|
||||||
|
protected internal int conflictingAltResolvedBySLL;
|
||||||
|
|
||||||
|
public ProfilingATNSimulator(Parser parser)
|
||||||
|
: base(parser, parser.Interpreter.atn)
|
||||||
|
{
|
||||||
|
optimize_ll1 = false;
|
||||||
|
reportAmbiguities = true;
|
||||||
|
numDecisions = atn.decisionToState.Count;
|
||||||
|
decisions = new DecisionInfo[numDecisions];
|
||||||
|
for (int i = 0; i < numDecisions; i++)
|
||||||
|
{
|
||||||
|
decisions[i] = new DecisionInfo(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int AdaptivePredict(ITokenStream input, int decision, ParserRuleContext outerContext)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
this._input = input;
|
||||||
|
this._startIndex = input.Index;
|
||||||
|
this._sllStopIndex = -1;
|
||||||
|
this._llStopIndex = -1;
|
||||||
|
this.currentDecision = decision;
|
||||||
|
this.currentState = null;
|
||||||
|
this.conflictingAltResolvedBySLL = ATN.InvalidAltNumber;
|
||||||
|
long start = Sharpen.Runtime.NanoTime();
|
||||||
|
// expensive but useful info
|
||||||
|
int alt = base.AdaptivePredict(input, decision, outerContext);
|
||||||
|
long stop = Sharpen.Runtime.NanoTime();
|
||||||
|
decisions[decision].timeInPrediction += (stop - start);
|
||||||
|
decisions[decision].invocations++;
|
||||||
|
int SLL_k = _sllStopIndex - _startIndex + 1;
|
||||||
|
decisions[decision].SLL_TotalLook += SLL_k;
|
||||||
|
decisions[decision].SLL_MinLook = decisions[decision].SLL_MinLook == 0 ? SLL_k : Math.Min(decisions[decision].SLL_MinLook, SLL_k);
|
||||||
|
if (SLL_k > decisions[decision].SLL_MaxLook)
|
||||||
|
{
|
||||||
|
decisions[decision].SLL_MaxLook = SLL_k;
|
||||||
|
decisions[decision].SLL_MaxLookEvent = new LookaheadEventInfo(decision, null, input, _startIndex, _sllStopIndex, false);
|
||||||
|
}
|
||||||
|
if (_llStopIndex >= 0)
|
||||||
|
{
|
||||||
|
int LL_k = _llStopIndex - _startIndex + 1;
|
||||||
|
decisions[decision].LL_TotalLook += LL_k;
|
||||||
|
decisions[decision].LL_MinLook = decisions[decision].LL_MinLook == 0 ? LL_k : Math.Min(decisions[decision].LL_MinLook, LL_k);
|
||||||
|
if (LL_k > decisions[decision].LL_MaxLook)
|
||||||
|
{
|
||||||
|
decisions[decision].LL_MaxLook = LL_k;
|
||||||
|
decisions[decision].LL_MaxLookEvent = new LookaheadEventInfo(decision, null, input, _startIndex, _llStopIndex, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return alt;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
this._input = null;
|
||||||
|
this.currentDecision = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override SimulatorState GetStartState(DFA dfa, ITokenStream input, ParserRuleContext outerContext, bool useContext)
|
||||||
|
{
|
||||||
|
SimulatorState state = base.GetStartState(dfa, input, outerContext, useContext);
|
||||||
|
currentState = state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override SimulatorState ComputeStartState(DFA dfa, ParserRuleContext globalContext, bool useContext)
|
||||||
|
{
|
||||||
|
SimulatorState state = base.ComputeStartState(dfa, globalContext, useContext);
|
||||||
|
currentState = state;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override SimulatorState ComputeReachSet(DFA dfa, SimulatorState previous, int t, PredictionContextCache contextCache)
|
||||||
|
{
|
||||||
|
SimulatorState reachState = base.ComputeReachSet(dfa, previous, t, contextCache);
|
||||||
|
if (reachState == null)
|
||||||
|
{
|
||||||
|
// no reach on current lookahead symbol. ERROR.
|
||||||
|
decisions[currentDecision].errors.AddItem(new ErrorInfo(currentDecision, previous, _input, _startIndex, _input.Index));
|
||||||
|
}
|
||||||
|
currentState = reachState;
|
||||||
|
return reachState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override DFAState GetExistingTargetState(DFAState previousD, int t)
|
||||||
|
{
|
||||||
|
// this method is called after each time the input position advances
|
||||||
|
if (currentState.useContext)
|
||||||
|
{
|
||||||
|
_llStopIndex = _input.Index;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_sllStopIndex = _input.Index;
|
||||||
|
}
|
||||||
|
DFAState existingTargetState = base.GetExistingTargetState(previousD, t);
|
||||||
|
if (existingTargetState != null)
|
||||||
|
{
|
||||||
|
// this method is directly called by execDFA; must construct a SimulatorState
|
||||||
|
// to represent the current state for this case
|
||||||
|
currentState = new SimulatorState(currentState.outerContext, existingTargetState, currentState.useContext, currentState.remainingOuterContext);
|
||||||
|
if (currentState.useContext)
|
||||||
|
{
|
||||||
|
decisions[currentDecision].LL_DFATransitions++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decisions[currentDecision].SLL_DFATransitions++;
|
||||||
|
}
|
||||||
|
// count only if we transition over a DFA state
|
||||||
|
if (existingTargetState == Error)
|
||||||
|
{
|
||||||
|
SimulatorState state = new SimulatorState(currentState.outerContext, previousD, currentState.useContext, currentState.remainingOuterContext);
|
||||||
|
decisions[currentDecision].errors.AddItem(new ErrorInfo(currentDecision, state, _input, _startIndex, _input.Index));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return existingTargetState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override Tuple<DFAState, ParserRuleContext> ComputeTargetState(DFA dfa, DFAState s, ParserRuleContext remainingGlobalContext, int t, bool useContext, PredictionContextCache contextCache)
|
||||||
|
{
|
||||||
|
Tuple<DFAState, ParserRuleContext> targetState = base.ComputeTargetState(dfa, s, remainingGlobalContext, t, useContext, contextCache);
|
||||||
|
if (useContext)
|
||||||
|
{
|
||||||
|
decisions[currentDecision].LL_ATNTransitions++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decisions[currentDecision].SLL_ATNTransitions++;
|
||||||
|
}
|
||||||
|
return targetState;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt)
|
||||||
|
{
|
||||||
|
bool result = base.EvalSemanticContext(pred, parserCallStack, alt);
|
||||||
|
if (!(pred is SemanticContext.PrecedencePredicate))
|
||||||
|
{
|
||||||
|
bool fullContext = _llStopIndex >= 0;
|
||||||
|
int stopIndex = fullContext ? _llStopIndex : _sllStopIndex;
|
||||||
|
decisions[currentDecision].predicateEvals.AddItem(new PredicateEvalInfo(currentState, currentDecision, _input, _startIndex, stopIndex, pred, result, alt));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override void ReportContextSensitivity(DFA dfa, int prediction, SimulatorState acceptState, int startIndex, int stopIndex)
|
||||||
|
{
|
||||||
|
if (prediction != conflictingAltResolvedBySLL)
|
||||||
|
{
|
||||||
|
decisions[currentDecision].contextSensitivities.AddItem(new ContextSensitivityInfo(currentDecision, acceptState, _input, startIndex, stopIndex));
|
||||||
|
}
|
||||||
|
base.ReportContextSensitivity(dfa, prediction, acceptState, startIndex, stopIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, SimulatorState conflictState, int startIndex, int stopIndex)
|
||||||
|
{
|
||||||
|
if (conflictingAlts != null)
|
||||||
|
{
|
||||||
|
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
conflictingAltResolvedBySLL = conflictState.s0.configs.GetRepresentedAlternatives().NextSetBit(0);
|
||||||
|
}
|
||||||
|
decisions[currentDecision].LL_Fallback++;
|
||||||
|
base.ReportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected internal override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs)
|
||||||
|
{
|
||||||
|
int prediction;
|
||||||
|
if (ambigAlts != null)
|
||||||
|
{
|
||||||
|
prediction = ambigAlts.NextSetBit(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prediction = configs.GetRepresentedAlternatives().NextSetBit(0);
|
||||||
|
}
|
||||||
|
if (conflictingAltResolvedBySLL != ATN.InvalidAltNumber && prediction != conflictingAltResolvedBySLL)
|
||||||
|
{
|
||||||
|
// Even though this is an ambiguity we are reporting, we can
|
||||||
|
// still detect some context sensitivities. Both SLL and LL
|
||||||
|
// are showing a conflict, hence an ambiguity, but if they resolve
|
||||||
|
// to different minimum alternatives we have also identified a
|
||||||
|
// context sensitivity.
|
||||||
|
decisions[currentDecision].contextSensitivities.AddItem(new ContextSensitivityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
|
||||||
|
}
|
||||||
|
decisions[currentDecision].ambiguities.AddItem(new AmbiguityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
|
||||||
|
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------
|
||||||
|
public virtual DecisionInfo[] GetDecisionInfo()
|
||||||
|
{
|
||||||
|
return decisions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -88,12 +88,12 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// prediction, so we passed in the outer context here in case of context
|
/// prediction, so we passed in the outer context here in case of context
|
||||||
/// dependent predicate evaluation.</p>
|
/// dependent predicate evaluation.</p>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public abstract bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public abstract bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
where ATNInterpreter : ATNSimulator;
|
where ATNInterpreter : ATNSimulator;
|
||||||
/// <summary>Evaluate the precedence predicates for the context and reduce the result.</summary>
|
/// <summary>Evaluate the precedence predicates for the context and reduce the result.</summary>
|
||||||
/// <remarks>Evaluate the precedence predicates for the context and reduce the result.</remarks>
|
/// <remarks>Evaluate the precedence predicates for the context and reduce the result.</remarks>
|
||||||
/// <param name="parser">The parser instance.</param>
|
/// <param name="parser">The parser instance.</param>
|
||||||
/// <param name="outerContext">The current parser context object.</param>
|
/// <param name="parserCallStack"></param>
|
||||||
/// <returns>
|
/// <returns>
|
||||||
/// The simplified semantic context after precedence predicates are
|
/// The simplified semantic context after precedence predicates are
|
||||||
/// evaluated, which will be one of the following values.
|
/// evaluated, which will be one of the following values.
|
||||||
|
@ -122,7 +122,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// semantic context after precedence predicates are evaluated.</li>
|
/// semantic context after precedence predicates are evaluated.</li>
|
||||||
/// </ul>
|
/// </ul>
|
||||||
/// </returns>
|
/// </returns>
|
||||||
public virtual SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public virtual SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
where ATNInterpreter : ATNSimulator
|
where ATNInterpreter : ATNSimulator
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
|
@ -151,9 +151,9 @@ namespace Antlr4.Runtime.Atn
|
||||||
this.isCtxDependent = isCtxDependent;
|
this.isCtxDependent = isCtxDependent;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
RuleContext localctx = isCtxDependent ? outerContext : null;
|
RuleContext localctx = isCtxDependent ? parserCallStack : null;
|
||||||
return parser.Sempred(localctx, ruleIndex, predIndex);
|
return parser.Sempred(localctx, ruleIndex, predIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,14 +201,14 @@ namespace Antlr4.Runtime.Atn
|
||||||
this.precedence = precedence;
|
this.precedence = precedence;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
return parser.Precpred(outerContext, precedence);
|
return parser.Precpred(parserCallStack, precedence);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
if (parser.Precpred(outerContext, precedence))
|
if (parser.Precpred(parserCallStack, precedence))
|
||||||
{
|
{
|
||||||
return SemanticContext.None;
|
return SemanticContext.None;
|
||||||
}
|
}
|
||||||
|
@ -246,10 +246,35 @@ namespace Antlr4.Runtime.Atn
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return base.ToString();
|
// precedence >= _precedenceStack.peek()
|
||||||
|
return "{" + precedence + ">=prec}?";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This is the base class for semantic context "operators", which operate on
|
||||||
|
/// a collection of semantic context "operands".
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is the base class for semantic context "operators", which operate on
|
||||||
|
/// a collection of semantic context "operands".
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public abstract class Operator : SemanticContext
|
||||||
|
{
|
||||||
|
/// <summary>Gets the operands for the semantic context operator.</summary>
|
||||||
|
/// <remarks>Gets the operands for the semantic context operator.</remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// a collection of
|
||||||
|
/// <see cref="SemanticContext">SemanticContext</see>
|
||||||
|
/// operands for the
|
||||||
|
/// operator.
|
||||||
|
/// </returns>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
[NotNull]
|
||||||
|
public abstract ICollection<SemanticContext> GetOperands();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A semantic context which is true whenever none of the contained contexts
|
/// A semantic context which is true whenever none of the contained contexts
|
||||||
/// is false.
|
/// is false.
|
||||||
|
@ -258,7 +283,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// A semantic context which is true whenever none of the contained contexts
|
/// A semantic context which is true whenever none of the contained contexts
|
||||||
/// is false.
|
/// is false.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class AND : SemanticContext
|
public class AND : SemanticContext.Operator
|
||||||
{
|
{
|
||||||
[NotNull]
|
[NotNull]
|
||||||
public readonly SemanticContext[] opnds;
|
public readonly SemanticContext[] opnds;
|
||||||
|
@ -292,6 +317,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
opnds = operands.ToArray();
|
opnds = operands.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ICollection<SemanticContext> GetOperands()
|
||||||
|
{
|
||||||
|
return Arrays.AsList(opnds);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
@ -317,11 +347,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// The evaluation of predicates by this context is short-circuiting, but
|
/// The evaluation of predicates by this context is short-circuiting, but
|
||||||
/// unordered.</p>
|
/// unordered.</p>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
foreach (SemanticContext opnd in opnds)
|
foreach (SemanticContext opnd in opnds)
|
||||||
{
|
{
|
||||||
if (!opnd.Eval(parser, outerContext))
|
if (!opnd.Eval(parser, parserCallStack))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -329,13 +359,13 @@ namespace Antlr4.Runtime.Atn
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
bool differs = false;
|
bool differs = false;
|
||||||
IList<SemanticContext> operands = new List<SemanticContext>();
|
IList<SemanticContext> operands = new List<SemanticContext>();
|
||||||
foreach (SemanticContext context in opnds)
|
foreach (SemanticContext context in opnds)
|
||||||
{
|
{
|
||||||
SemanticContext evaluated = context.EvalPrecedence(parser, outerContext);
|
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
|
||||||
differs |= (evaluated != context);
|
differs |= (evaluated != context);
|
||||||
if (evaluated == null)
|
if (evaluated == null)
|
||||||
{
|
{
|
||||||
|
@ -382,7 +412,7 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// A semantic context which is true whenever at least one of the contained
|
/// A semantic context which is true whenever at least one of the contained
|
||||||
/// contexts is true.
|
/// contexts is true.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class OR : SemanticContext
|
public class OR : SemanticContext.Operator
|
||||||
{
|
{
|
||||||
[NotNull]
|
[NotNull]
|
||||||
public readonly SemanticContext[] opnds;
|
public readonly SemanticContext[] opnds;
|
||||||
|
@ -416,6 +446,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
this.opnds = operands.ToArray();
|
this.opnds = operands.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ICollection<SemanticContext> GetOperands()
|
||||||
|
{
|
||||||
|
return Arrays.AsList(opnds);
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
if (this == obj)
|
if (this == obj)
|
||||||
|
@ -441,11 +476,11 @@ namespace Antlr4.Runtime.Atn
|
||||||
/// The evaluation of predicates by this context is short-circuiting, but
|
/// The evaluation of predicates by this context is short-circuiting, but
|
||||||
/// unordered.</p>
|
/// unordered.</p>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override bool Eval<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
foreach (SemanticContext opnd in opnds)
|
foreach (SemanticContext opnd in opnds)
|
||||||
{
|
{
|
||||||
if (opnd.Eval(parser, outerContext))
|
if (opnd.Eval(parser, parserCallStack))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -453,13 +488,13 @@ namespace Antlr4.Runtime.Atn
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext outerContext)
|
public override SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
|
||||||
{
|
{
|
||||||
bool differs = false;
|
bool differs = false;
|
||||||
IList<SemanticContext> operands = new List<SemanticContext>();
|
IList<SemanticContext> operands = new List<SemanticContext>();
|
||||||
foreach (SemanticContext context in opnds)
|
foreach (SemanticContext context in opnds)
|
||||||
{
|
{
|
||||||
SemanticContext evaluated = context.EvalPrecedence(parser, outerContext);
|
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
|
||||||
differs |= (evaluated != context);
|
differs |= (evaluated != context);
|
||||||
if (evaluated == None)
|
if (evaluated == None)
|
||||||
{
|
{
|
||||||
|
|
|
@ -461,26 +461,25 @@ namespace Antlr4.Runtime
|
||||||
/// <code>i</code>
|
/// <code>i</code>
|
||||||
/// if
|
/// if
|
||||||
/// <code>tokens[i]</code>
|
/// <code>tokens[i]</code>
|
||||||
/// is on channel. Return
|
/// is on channel. Return the index of
|
||||||
/// <code>-1</code>
|
/// the EOF token if there are no tokens on channel between
|
||||||
/// if there are no tokens
|
|
||||||
/// on channel between
|
|
||||||
/// <code>i</code>
|
/// <code>i</code>
|
||||||
/// and EOF.
|
/// and
|
||||||
|
/// EOF.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected internal virtual int NextTokenOnChannel(int i, int channel)
|
protected internal virtual int NextTokenOnChannel(int i, int channel)
|
||||||
{
|
{
|
||||||
Sync(i);
|
Sync(i);
|
||||||
IToken token = tokens[i];
|
|
||||||
if (i >= Size)
|
if (i >= Size)
|
||||||
{
|
{
|
||||||
return -1;
|
return Size - 1;
|
||||||
}
|
}
|
||||||
|
IToken token = tokens[i];
|
||||||
while (token.Channel != channel)
|
while (token.Channel != channel)
|
||||||
{
|
{
|
||||||
if (token.Type == TokenConstants.Eof)
|
if (token.Type == TokenConstants.Eof)
|
||||||
{
|
{
|
||||||
return -1;
|
return i;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
Sync(i);
|
Sync(i);
|
||||||
|
@ -489,26 +488,42 @@ namespace Antlr4.Runtime
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Given a starting index, return the index of the previous token on channel.</summary>
|
/// <summary>
|
||||||
|
/// Given a starting index, return the index of the previous token on
|
||||||
|
/// channel.
|
||||||
|
/// </summary>
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// Given a starting index, return the index of the previous token on channel.
|
/// Given a starting index, return the index of the previous token on
|
||||||
/// Return
|
/// channel. Return
|
||||||
/// <code>i</code>
|
/// <code>i</code>
|
||||||
/// if
|
/// if
|
||||||
/// <code>tokens[i]</code>
|
/// <code>tokens[i]</code>
|
||||||
/// is on channel. Return
|
/// is on channel. Return -1
|
||||||
/// <code>-1</code>
|
/// if there are no tokens on channel between
|
||||||
/// if there are no tokens
|
|
||||||
/// on channel between
|
|
||||||
/// <code>i</code>
|
/// <code>i</code>
|
||||||
/// and
|
/// and 0.
|
||||||
/// <code>0</code>
|
/// <p>
|
||||||
/// .
|
/// If
|
||||||
|
/// <code>i</code>
|
||||||
|
/// 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>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
protected internal virtual int PreviousTokenOnChannel(int i, int channel)
|
protected internal virtual int PreviousTokenOnChannel(int i, int channel)
|
||||||
{
|
{
|
||||||
while (i >= 0 && tokens[i].Channel != channel)
|
Sync(i);
|
||||||
|
if (i >= Size)
|
||||||
{
|
{
|
||||||
|
// the EOF token is on every channel
|
||||||
|
return Size - 1;
|
||||||
|
}
|
||||||
|
while (i >= 0)
|
||||||
|
{
|
||||||
|
IToken token = tokens[i];
|
||||||
|
if (token.Type == TokenConstants.Eof || token.Channel == channel)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
i--;
|
i--;
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
|
@ -576,6 +591,11 @@ namespace Antlr4.Runtime
|
||||||
{
|
{
|
||||||
throw new ArgumentOutOfRangeException(tokenIndex + " not in 0.." + (tokens.Count - 1));
|
throw new ArgumentOutOfRangeException(tokenIndex + " not in 0.." + (tokens.Count - 1));
|
||||||
}
|
}
|
||||||
|
if (tokenIndex == 0)
|
||||||
|
{
|
||||||
|
// obviously no tokens can appear before the first token
|
||||||
|
return null;
|
||||||
|
}
|
||||||
int prevOnChannel = PreviousTokenOnChannel(tokenIndex - 1, Lexer.DefaultTokenChannel);
|
int prevOnChannel = PreviousTokenOnChannel(tokenIndex - 1, Lexer.DefaultTokenChannel);
|
||||||
if (prevOnChannel == tokenIndex - 1)
|
if (prevOnChannel == tokenIndex - 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,40 +45,52 @@ namespace Antlr4.Runtime
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method is called by the parser when a full-context prediction
|
/// This method is called by the parser when a full-context prediction
|
||||||
/// results in an ambiguity.
|
/// results in an ambiguity.
|
||||||
/// <p/>
|
/// <p>Each full-context prediction which does not result in a syntax error
|
||||||
|
/// will call either
|
||||||
|
/// <see cref="ReportContextSensitivity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, Antlr4.Runtime.Atn.SimulatorState)">ReportContextSensitivity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, Antlr4.Runtime.Atn.SimulatorState)</see>
|
||||||
|
/// or
|
||||||
|
/// <see cref="ReportAmbiguity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, Antlr4.Runtime.Atn.ATNConfigSet)">ReportAmbiguity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, Antlr4.Runtime.Atn.ATNConfigSet)</see>
|
||||||
|
/// .</p>
|
||||||
|
/// <p>
|
||||||
/// When
|
/// When
|
||||||
|
/// <code>ambigAlts</code>
|
||||||
|
/// is not null, it contains the set of potentially
|
||||||
|
/// viable alternatives identified by the prediction algorithm. When
|
||||||
|
/// <code>ambigAlts</code>
|
||||||
|
/// is null, use
|
||||||
|
/// <see cref="Antlr4.Runtime.Atn.ATNConfigSet.GetRepresentedAlternatives()">Antlr4.Runtime.Atn.ATNConfigSet.GetRepresentedAlternatives()</see>
|
||||||
|
/// to obtain the represented
|
||||||
|
/// alternatives from the
|
||||||
|
/// <code>configs</code>
|
||||||
|
/// argument.</p>
|
||||||
|
/// <p>When
|
||||||
/// <code>exact</code>
|
/// <code>exact</code>
|
||||||
/// is
|
/// is
|
||||||
/// <code>true</code>
|
/// <code>true</code>
|
||||||
/// , <em>all</em> of the alternatives in
|
/// , <em>all</em> of the potentially
|
||||||
/// <code>ambigAlts</code>
|
/// viable alternatives are truly viable, i.e. this is reporting an exact
|
||||||
/// are viable, i.e. this is reporting an exact ambiguity.
|
/// ambiguity. When
|
||||||
/// When
|
|
||||||
/// <code>exact</code>
|
/// <code>exact</code>
|
||||||
/// is
|
/// is
|
||||||
/// <code>false</code>
|
/// <code>false</code>
|
||||||
/// , <em>at least two</em> of the
|
/// , <em>at least two</em> of
|
||||||
/// alternatives in
|
/// the potentially viable alternatives are viable for the current input, but
|
||||||
/// <code>ambigAlts</code>
|
|
||||||
/// are viable for the current input, but
|
|
||||||
/// the prediction algorithm terminated as soon as it determined that at
|
/// the prediction algorithm terminated as soon as it determined that at
|
||||||
/// least the <em>minimum</em> alternative in
|
/// least the <em>minimum</em> potentially viable alternative is truly
|
||||||
/// <code>ambigAlts</code>
|
/// viable.</p>
|
||||||
/// is viable.
|
/// <p>When the
|
||||||
/// <p/>
|
|
||||||
/// When the
|
|
||||||
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
|
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
|
||||||
/// prediction mode
|
/// prediction
|
||||||
/// is used, the parser is required to identify exact ambiguities so
|
/// mode is used, the parser is required to identify exact ambiguities so
|
||||||
/// <code>exact</code>
|
/// <code>exact</code>
|
||||||
/// will always be
|
/// will always be
|
||||||
/// <code>true</code>
|
/// <code>true</code>
|
||||||
/// .
|
/// .</p>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="recognizer">the parser instance</param>
|
/// <param name="recognizer">the parser instance</param>
|
||||||
/// <param name="dfa">the DFA for the current decision</param>
|
/// <param name="dfa">the DFA for the current decision</param>
|
||||||
/// <param name="startIndex">the input index where the decision started</param>
|
/// <param name="startIndex">the input index where the decision started</param>
|
||||||
/// <param name="stopIndex">the input input where the ambiguity is reported</param>
|
/// <param name="stopIndex">the input input where the ambiguity was identified</param>
|
||||||
/// <param name="exact">
|
/// <param name="exact">
|
||||||
///
|
///
|
||||||
/// <code>true</code>
|
/// <code>true</code>
|
||||||
|
@ -90,10 +102,16 @@ namespace Antlr4.Runtime
|
||||||
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
|
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
|
||||||
/// is used.
|
/// is used.
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <param name="ambigAlts">the potentially ambiguous alternatives</param>
|
/// <param name="ambigAlts">
|
||||||
|
/// the potentially ambiguous alternatives, or
|
||||||
|
/// <code>null</code>
|
||||||
|
/// to indicate that the potentially ambiguous alternatives are the complete
|
||||||
|
/// set of represented alternatives in
|
||||||
|
/// <code>configs</code>
|
||||||
|
/// </param>
|
||||||
/// <param name="configs">
|
/// <param name="configs">
|
||||||
/// the ATN configuration set where the ambiguity was
|
/// the ATN configuration set where the ambiguity was
|
||||||
/// determined
|
/// identified
|
||||||
/// </param>
|
/// </param>
|
||||||
void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs);
|
void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs);
|
||||||
|
|
||||||
|
@ -104,15 +122,14 @@ namespace Antlr4.Runtime
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method is called when an SLL conflict occurs and the parser is about
|
/// 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.
|
/// to use the full context information to make an LL decision.
|
||||||
/// <p/>
|
/// <p>If one or more configurations in
|
||||||
/// If one or more configurations in
|
|
||||||
/// <code>configs</code>
|
/// <code>configs</code>
|
||||||
/// contains a semantic
|
/// contains a semantic
|
||||||
/// predicate, the predicates are evaluated before this method is called. The
|
/// predicate, the predicates are evaluated before this method is called. The
|
||||||
/// subset of alternatives which are still viable after predicates are
|
/// subset of alternatives which are still viable after predicates are
|
||||||
/// evaluated is reported in
|
/// evaluated is reported in
|
||||||
/// <code>conflictingAlts</code>
|
/// <code>conflictingAlts</code>
|
||||||
/// .
|
/// .</p>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="recognizer">the parser instance</param>
|
/// <param name="recognizer">the parser instance</param>
|
||||||
/// <param name="dfa">the DFA for the current decision</param>
|
/// <param name="dfa">the DFA for the current decision</param>
|
||||||
|
@ -139,23 +156,35 @@ namespace Antlr4.Runtime
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// This method is called by the parser when a full-context prediction has a
|
/// This method is called by the parser when a full-context prediction has a
|
||||||
/// unique result.
|
/// unique result.
|
||||||
/// <p/>
|
/// <p>Each full-context prediction which does not result in a syntax error
|
||||||
/// For prediction implementations that only evaluate full-context
|
/// will call either
|
||||||
|
/// <see cref="ReportContextSensitivity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, Antlr4.Runtime.Atn.SimulatorState)">ReportContextSensitivity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, int, Antlr4.Runtime.Atn.SimulatorState)</see>
|
||||||
|
/// or
|
||||||
|
/// <see cref="ReportAmbiguity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, Antlr4.Runtime.Atn.ATNConfigSet)">ReportAmbiguity(Parser, Antlr4.Runtime.Dfa.DFA, int, int, bool, Sharpen.BitSet, Antlr4.Runtime.Atn.ATNConfigSet)</see>
|
||||||
|
/// .</p>
|
||||||
|
/// <p>For prediction implementations that only evaluate full-context
|
||||||
/// predictions when an SLL conflict is found (including the default
|
/// predictions when an SLL conflict is found (including the default
|
||||||
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator">Antlr4.Runtime.Atn.ParserATNSimulator</see>
|
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator">Antlr4.Runtime.Atn.ParserATNSimulator</see>
|
||||||
/// implementation), this method reports cases
|
/// implementation), this method reports cases
|
||||||
/// where SLL conflicts were resolved to unique full-context predictions,
|
/// where SLL conflicts were resolved to unique full-context predictions,
|
||||||
/// i.e. the decision was context-sensitive. This report does not necessarily
|
/// i.e. the decision was context-sensitive. This report does not necessarily
|
||||||
/// indicate a problem, and it may appear even in completely unambiguous
|
/// indicate a problem, and it may appear even in completely unambiguous
|
||||||
/// grammars.
|
/// grammars.</p>
|
||||||
/// <p/>
|
/// <p>
|
||||||
/// <code>configs</code>
|
/// <code>configs</code>
|
||||||
/// may have more than one represented alternative if the
|
/// may have more than one represented alternative if the
|
||||||
/// full-context prediction algorithm does not evaluate predicates before
|
/// full-context prediction algorithm does not evaluate predicates before
|
||||||
/// beginning the full-context prediction. In all cases, the final prediction
|
/// beginning the full-context prediction. In all cases, the final prediction
|
||||||
/// is passed as the
|
/// is passed as the
|
||||||
/// <code>prediction</code>
|
/// <code>prediction</code>
|
||||||
/// argument.
|
/// argument.</p>
|
||||||
|
/// <p>Note that the definition of "context sensitivity" in this method
|
||||||
|
/// differs from the concept in
|
||||||
|
/// <see cref="Antlr4.Runtime.Atn.DecisionInfo.contextSensitivities">Antlr4.Runtime.Atn.DecisionInfo.contextSensitivities</see>
|
||||||
|
/// .
|
||||||
|
/// 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>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="recognizer">the parser instance</param>
|
/// <param name="recognizer">the parser instance</param>
|
||||||
/// <param name="dfa">the DFA for the current decision</param>
|
/// <param name="dfa">the DFA for the current decision</param>
|
||||||
|
|
|
@ -33,60 +33,272 @@ using Sharpen;
|
||||||
|
|
||||||
namespace Antlr4.Runtime.Misc
|
namespace Antlr4.Runtime.Misc
|
||||||
{
|
{
|
||||||
/// <summary>A generic set of ints.</summary>
|
/// <summary>A generic set of integers.</summary>
|
||||||
/// <remarks>A generic set of ints.</remarks>
|
/// <remarks>A generic set of integers.</remarks>
|
||||||
/// <seealso cref="IntervalSet">IntervalSet</seealso>
|
/// <seealso cref="IntervalSet">IntervalSet</seealso>
|
||||||
public interface IIntSet
|
public interface IIntSet
|
||||||
{
|
{
|
||||||
/// <summary>Add an element to the set</summary>
|
/// <summary>Adds the specified value to the current set.</summary>
|
||||||
|
/// <remarks>Adds the specified value to the current set.</remarks>
|
||||||
|
/// <param name="el">the value to add</param>
|
||||||
|
/// <exception>
|
||||||
|
/// IllegalStateException
|
||||||
|
/// if the current set is read-only
|
||||||
|
/// </exception>
|
||||||
void Add(int el);
|
void Add(int el);
|
||||||
|
|
||||||
/// <summary>Add all elements from incoming set to this set.</summary>
|
/// <summary>
|
||||||
/// <remarks>
|
/// Modify the current
|
||||||
/// Add all elements from incoming set to this set. Can limit
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
/// to set of its own type. Return "this" so we can chain calls.
|
/// object to contain all elements that are
|
||||||
/// </remarks>
|
/// present in itself, the specified
|
||||||
|
/// <code>set</code>
|
||||||
|
/// , or both.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="set">
|
||||||
|
/// The set to add to the current set. A
|
||||||
|
/// <code>null</code>
|
||||||
|
/// argument is
|
||||||
|
/// treated as though it were an empty set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
///
|
||||||
|
/// <code>this</code>
|
||||||
|
/// (to support chained calls)
|
||||||
|
/// </returns>
|
||||||
|
/// <exception>
|
||||||
|
/// IllegalStateException
|
||||||
|
/// if the current set is read-only
|
||||||
|
/// </exception>
|
||||||
|
[NotNull]
|
||||||
IIntSet AddAll(IIntSet set);
|
IIntSet AddAll(IIntSet set);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Return the intersection of this set with the argument, creating
|
/// Return a new
|
||||||
/// a new set.
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// object containing all elements that are
|
||||||
|
/// present in both the current set and the specified set
|
||||||
|
/// <code>a</code>
|
||||||
|
/// .
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
/// <param name="a">
|
||||||
/// Return the intersection of this set with the argument, creating
|
/// The set to intersect with the current set. A
|
||||||
/// a new set.
|
/// <code>null</code>
|
||||||
/// </remarks>
|
/// argument is treated as though it were an empty set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instance containing the intersection of the
|
||||||
|
/// current set and
|
||||||
|
/// <code>a</code>
|
||||||
|
/// . The value
|
||||||
|
/// <code>null</code>
|
||||||
|
/// may be returned in
|
||||||
|
/// place of an empty result set.
|
||||||
|
/// </returns>
|
||||||
|
[Nullable]
|
||||||
IIntSet And(IIntSet a);
|
IIntSet And(IIntSet a);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// object containing all elements that are
|
||||||
|
/// present in
|
||||||
|
/// <code>elements</code>
|
||||||
|
/// but not present in the current set. The
|
||||||
|
/// following expressions are equivalent for input non-null
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instances
|
||||||
|
/// <code>x</code>
|
||||||
|
/// and
|
||||||
|
/// <code>y</code>
|
||||||
|
/// .
|
||||||
|
/// <ul>
|
||||||
|
/// <li>
|
||||||
|
/// <code>x.complement(y)</code>
|
||||||
|
/// </li>
|
||||||
|
/// <li>
|
||||||
|
/// <code>y.subtract(x)</code>
|
||||||
|
/// </li>
|
||||||
|
/// </ul>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="elements">
|
||||||
|
/// The set to compare with the current set. A
|
||||||
|
/// <code>null</code>
|
||||||
|
/// argument is treated as though it were an empty set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instance containing the elements present in
|
||||||
|
/// <code>elements</code>
|
||||||
|
/// but not present in the current set. The value
|
||||||
|
/// <code>null</code>
|
||||||
|
/// may be returned in place of an empty result set.
|
||||||
|
/// </returns>
|
||||||
|
[Nullable]
|
||||||
IIntSet Complement(IIntSet elements);
|
IIntSet Complement(IIntSet elements);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// object containing all elements that are
|
||||||
|
/// present in the current set, the specified set
|
||||||
|
/// <code>a</code>
|
||||||
|
/// , or both.
|
||||||
|
/// <p>
|
||||||
|
/// This method is similar to
|
||||||
|
/// <see cref="AddAll(IIntSet)">AddAll(IIntSet)</see>
|
||||||
|
/// , but returns a new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instance instead of modifying the current set.</p>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">
|
||||||
|
/// The set to union with the current set. A
|
||||||
|
/// <code>null</code>
|
||||||
|
/// argument
|
||||||
|
/// is treated as though it were an empty set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instance containing the union of the current
|
||||||
|
/// set and
|
||||||
|
/// <code>a</code>
|
||||||
|
/// . The value
|
||||||
|
/// <code>null</code>
|
||||||
|
/// may be returned in place of an
|
||||||
|
/// empty result set.
|
||||||
|
/// </returns>
|
||||||
|
[Nullable]
|
||||||
IIntSet Or(IIntSet a);
|
IIntSet Or(IIntSet a);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return a new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// object containing all elements that are
|
||||||
|
/// present in the current set but not present in the input set
|
||||||
|
/// <code>a</code>
|
||||||
|
/// .
|
||||||
|
/// The following expressions are equivalent for input non-null
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instances
|
||||||
|
/// <code>x</code>
|
||||||
|
/// and
|
||||||
|
/// <code>y</code>
|
||||||
|
/// .
|
||||||
|
/// <ul>
|
||||||
|
/// <li>
|
||||||
|
/// <code>y.subtract(x)</code>
|
||||||
|
/// </li>
|
||||||
|
/// <li>
|
||||||
|
/// <code>x.complement(y)</code>
|
||||||
|
/// </li>
|
||||||
|
/// </ul>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">
|
||||||
|
/// The set to compare with the current set. A
|
||||||
|
/// <code>null</code>
|
||||||
|
/// argument is treated as though it were an empty set.
|
||||||
|
/// </param>
|
||||||
|
/// <returns>
|
||||||
|
/// A new
|
||||||
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
|
/// instance containing the elements present in
|
||||||
|
/// <code>elements</code>
|
||||||
|
/// but not present in the current set. The value
|
||||||
|
/// <code>null</code>
|
||||||
|
/// may be returned in place of an empty result set.
|
||||||
|
/// </returns>
|
||||||
|
[Nullable]
|
||||||
IIntSet Subtract(IIntSet a);
|
IIntSet Subtract(IIntSet a);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>Return the total number of elements represented by the current set.</summary>
|
||||||
/// Return the size of this set (not the underlying implementation's
|
/// <remarks>Return the total number of elements represented by the current set.</remarks>
|
||||||
/// allocated memory size, for example).
|
/// <returns>
|
||||||
/// </summary>
|
/// the total number of elements represented by the current set,
|
||||||
/// <remarks>
|
/// regardless of the manner in which the elements are stored.
|
||||||
/// Return the size of this set (not the underlying implementation's
|
/// </returns>
|
||||||
/// allocated memory size, for example).
|
|
||||||
/// </remarks>
|
|
||||||
int Size();
|
int Size();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if this set contains no elements.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
///
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if the current set contains no elements; otherwise,
|
||||||
|
/// <code>false</code>
|
||||||
|
/// .
|
||||||
|
/// </returns>
|
||||||
bool IsNil();
|
bool IsNil();
|
||||||
|
|
||||||
|
/// <summary><inheritDoc></inheritDoc></summary>
|
||||||
bool Equals(object obj);
|
bool Equals(object obj);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the single value contained in the set, if
|
||||||
|
/// <see cref="Size()">Size()</see>
|
||||||
|
/// is 1;
|
||||||
|
/// otherwise, returns
|
||||||
|
/// <see cref="Antlr4.Runtime.IToken.InvalidType">Antlr4.Runtime.IToken.InvalidType</see>
|
||||||
|
/// .
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>
|
||||||
|
/// the single value contained in the set, if
|
||||||
|
/// <see cref="Size()">Size()</see>
|
||||||
|
/// is 1;
|
||||||
|
/// otherwise, returns
|
||||||
|
/// <see cref="Antlr4.Runtime.IToken.InvalidType">Antlr4.Runtime.IToken.InvalidType</see>
|
||||||
|
/// .
|
||||||
|
/// </returns>
|
||||||
int GetSingleElement();
|
int GetSingleElement();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if the set contains the specified element.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="el">The element to check for.</param>
|
||||||
|
/// <returns>
|
||||||
|
///
|
||||||
|
/// <code>true</code>
|
||||||
|
/// if the set contains
|
||||||
|
/// <code>el</code>
|
||||||
|
/// ; otherwise
|
||||||
|
/// <code>false</code>
|
||||||
|
/// .
|
||||||
|
/// </returns>
|
||||||
bool Contains(int el);
|
bool Contains(int el);
|
||||||
|
|
||||||
/// <summary>remove this element from this set</summary>
|
/// <summary>Removes the specified value from the current set.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Removes the specified value from the current set. If the current set does
|
||||||
|
/// not contain the element, no changes are made.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="el">the value to remove</param>
|
||||||
|
/// <exception>
|
||||||
|
/// IllegalStateException
|
||||||
|
/// if the current set is read-only
|
||||||
|
/// </exception>
|
||||||
void Remove(int el);
|
void Remove(int el);
|
||||||
|
|
||||||
|
/// <summary>Return a list containing the elements represented by the current set.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Return a list containing the elements represented by the current set. The
|
||||||
|
/// list is returned in ascending numerical order.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// A list containing all element present in the current set, sorted
|
||||||
|
/// in ascending numerical order.
|
||||||
|
/// </returns>
|
||||||
|
[NotNull]
|
||||||
IList<int> ToList();
|
IList<int> ToList();
|
||||||
|
|
||||||
|
/// <summary><inheritDoc></inheritDoc></summary>
|
||||||
string ToString();
|
string ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,28 +38,37 @@ using Sharpen;
|
||||||
namespace Antlr4.Runtime.Misc
|
namespace Antlr4.Runtime.Misc
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A set of integers that relies on ranges being common to do
|
/// This class implements the
|
||||||
/// "run-length-encoded" like compression (if you view an IntSet like
|
/// <see cref="IIntSet">IIntSet</see>
|
||||||
/// a BitSet with runs of 0s and 1s).
|
/// backed by a sorted array of
|
||||||
|
/// non-overlapping intervals. It is particularly efficient for representing
|
||||||
|
/// large collections of numbers, where the majority of elements appear as part
|
||||||
|
/// of a sequential range of numbers that are all part of the set. For example,
|
||||||
|
/// the set { 1, 2, 3, 4, 7, 8 } may be represented as { [1, 4], [7, 8] }.
|
||||||
|
/// <p>
|
||||||
|
/// This class is able to represent sets containing any combination of values in
|
||||||
|
/// the range
|
||||||
|
/// <see cref="int.MinValue">int.MinValue</see>
|
||||||
|
/// to
|
||||||
|
/// <see cref="int.MaxValue">int.MaxValue</see>
|
||||||
|
/// (inclusive).</p>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// A set of integers that relies on ranges being common to do
|
|
||||||
/// "run-length-encoded" like compression (if you view an IntSet like
|
|
||||||
/// a BitSet with runs of 0s and 1s). Only ranges are recorded so that
|
|
||||||
/// a few ints up near value 1000 don't cause massive bitsets, just two
|
|
||||||
/// integer intervals.
|
|
||||||
/// element values may be negative. Useful for sets of EPSILON and EOF.
|
|
||||||
/// 0..9 char range is index pair ['\u0030','\u0039'].
|
|
||||||
/// Multiple ranges are encoded with multiple index pairs. Isolated
|
|
||||||
/// elements are encoded with an index pair where both intervals are the same.
|
|
||||||
/// The ranges are ordered and disjoint so that 2..6 appears before 101..103.
|
|
||||||
/// </remarks>
|
|
||||||
public class IntervalSet : IIntSet
|
public class IntervalSet : IIntSet
|
||||||
{
|
{
|
||||||
public static readonly Antlr4.Runtime.Misc.IntervalSet CompleteCharSet = Antlr4.Runtime.Misc.IntervalSet.Of(0, Lexer.MaxCharValue);
|
public static readonly Antlr4.Runtime.Misc.IntervalSet CompleteCharSet = Antlr4.Runtime.Misc.IntervalSet.Of(Lexer.MinCharValue, Lexer.MaxCharValue);
|
||||||
|
|
||||||
|
static IntervalSet()
|
||||||
|
{
|
||||||
|
CompleteCharSet.SetReadonly(true);
|
||||||
|
}
|
||||||
|
|
||||||
public static readonly Antlr4.Runtime.Misc.IntervalSet EmptySet = new Antlr4.Runtime.Misc.IntervalSet();
|
public static readonly Antlr4.Runtime.Misc.IntervalSet EmptySet = new Antlr4.Runtime.Misc.IntervalSet();
|
||||||
|
|
||||||
|
static IntervalSet()
|
||||||
|
{
|
||||||
|
EmptySet.SetReadonly(true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>The list of sorted, disjoint intervals.</summary>
|
/// <summary>The list of sorted, disjoint intervals.</summary>
|
||||||
/// <remarks>The list of sorted, disjoint intervals.</remarks>
|
/// <remarks>The list of sorted, disjoint intervals.</remarks>
|
||||||
protected internal IList<Interval> intervals;
|
protected internal IList<Interval> intervals;
|
||||||
|
@ -226,10 +235,8 @@ namespace Antlr4.Runtime.Misc
|
||||||
{
|
{
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
if (!(set is Antlr4.Runtime.Misc.IntervalSet))
|
if (set is Antlr4.Runtime.Misc.IntervalSet)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("can't add non IntSet (" + set.GetType().FullName + ") to IntervalSet");
|
|
||||||
}
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set;
|
Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set;
|
||||||
// walk set and add each interval
|
// walk set and add each interval
|
||||||
int n = other.intervals.Count;
|
int n = other.intervals.Count;
|
||||||
|
@ -238,6 +245,14 @@ namespace Antlr4.Runtime.Misc
|
||||||
Interval I = other.intervals[i];
|
Interval I = other.intervals[i];
|
||||||
this.Add(I.a, I.b);
|
this.Add(I.a, I.b);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (int value in set.ToList())
|
||||||
|
{
|
||||||
|
Add(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,79 +262,133 @@ namespace Antlr4.Runtime.Misc
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Given the set of possible values (rather than, say UNICODE or MAXINT),
|
/// <inheritDoc></inheritDoc>
|
||||||
/// return a new set containing all elements in vocabulary, but not in
|
///
|
||||||
/// this.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <remarks>
|
|
||||||
/// Given the set of possible values (rather than, say UNICODE or MAXINT),
|
|
||||||
/// return a new set containing all elements in vocabulary, but not in
|
|
||||||
/// this. The computation is (vocabulary - this).
|
|
||||||
/// 'this' is assumed to be either a subset or equal to vocabulary.
|
|
||||||
/// </remarks>
|
|
||||||
public virtual Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary)
|
public virtual Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary)
|
||||||
{
|
{
|
||||||
if (vocabulary == null)
|
if (vocabulary == null || vocabulary.IsNil())
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// nothing in common with null set
|
// nothing in common with null set
|
||||||
if (!(vocabulary is Antlr4.Runtime.Misc.IntervalSet))
|
Antlr4.Runtime.Misc.IntervalSet vocabularyIS;
|
||||||
|
if (vocabulary is Antlr4.Runtime.Misc.IntervalSet)
|
||||||
{
|
{
|
||||||
throw new ArgumentException("can't complement with non IntervalSet (" + vocabulary.GetType().FullName + ")");
|
vocabularyIS = (Antlr4.Runtime.Misc.IntervalSet)vocabulary;
|
||||||
}
|
}
|
||||||
Antlr4.Runtime.Misc.IntervalSet vocabularyIS = ((Antlr4.Runtime.Misc.IntervalSet)vocabulary);
|
else
|
||||||
int maxElement = vocabularyIS.GetMaxElement();
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet compl = new Antlr4.Runtime.Misc.IntervalSet();
|
|
||||||
int n = intervals.Count;
|
|
||||||
if (n == 0)
|
|
||||||
{
|
{
|
||||||
return compl;
|
vocabularyIS = new Antlr4.Runtime.Misc.IntervalSet();
|
||||||
|
vocabularyIS.AddAll(vocabulary);
|
||||||
}
|
}
|
||||||
Interval first = intervals[0];
|
return vocabularyIS.Subtract(this);
|
||||||
// add a range from 0 to first.a constrained to vocab
|
|
||||||
if (first.a > 0)
|
|
||||||
{
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(0, first.a - 1);
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
|
|
||||||
compl.AddAll(a);
|
|
||||||
}
|
|
||||||
for (int i = 1; i < n; i++)
|
|
||||||
{
|
|
||||||
// from 2nd interval .. nth
|
|
||||||
Interval previous = intervals[i - 1];
|
|
||||||
Interval current = intervals[i];
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(previous.b + 1, current.a - 1);
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
|
|
||||||
compl.AddAll(a);
|
|
||||||
}
|
|
||||||
Interval last = intervals[n - 1];
|
|
||||||
// add a range from last.b to maxElement constrained to vocab
|
|
||||||
if (last.b < maxElement)
|
|
||||||
{
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(last.b + 1, maxElement);
|
|
||||||
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
|
|
||||||
compl.AddAll(a);
|
|
||||||
}
|
|
||||||
return compl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Compute this-other via this&~other.</summary>
|
public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet a)
|
||||||
/// <remarks>
|
|
||||||
/// Compute this-other via this&~other.
|
|
||||||
/// Return a new set containing all elements in this but not in other.
|
|
||||||
/// other is assumed to be a subset of this;
|
|
||||||
/// anything that is in other but not in this will be ignored.
|
|
||||||
/// </remarks>
|
|
||||||
public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet other)
|
|
||||||
{
|
{
|
||||||
// assume the whole unicode range here for the complement
|
if (a == null || a.IsNil())
|
||||||
// because it doesn't matter. Anything beyond the max of this' set
|
{
|
||||||
// will be ignored since we are doing this & ~other. The intersection
|
return new Antlr4.Runtime.Misc.IntervalSet(this);
|
||||||
// will be empty. The only problem would be when this' set max value
|
}
|
||||||
// goes beyond MAX_CHAR_VALUE, but hopefully the constant MAX_CHAR_VALUE
|
if (a is Antlr4.Runtime.Misc.IntervalSet)
|
||||||
// will prevent this.
|
{
|
||||||
return this.And(((Antlr4.Runtime.Misc.IntervalSet)other).Complement(CompleteCharSet));
|
return Subtract(this, (Antlr4.Runtime.Misc.IntervalSet)a);
|
||||||
|
}
|
||||||
|
Antlr4.Runtime.Misc.IntervalSet other = new Antlr4.Runtime.Misc.IntervalSet();
|
||||||
|
other.AddAll(a);
|
||||||
|
return Subtract(this, other);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Compute the set difference between two interval sets.</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Compute the set difference between two interval sets. The specific
|
||||||
|
/// operation is
|
||||||
|
/// <code>left - right</code>
|
||||||
|
/// . If either of the input sets is
|
||||||
|
/// <code>null</code>
|
||||||
|
/// , it is treated as though it was an empty set.
|
||||||
|
/// </remarks>
|
||||||
|
[NotNull]
|
||||||
|
public static Antlr4.Runtime.Misc.IntervalSet Subtract(Antlr4.Runtime.Misc.IntervalSet left, Antlr4.Runtime.Misc.IntervalSet right)
|
||||||
|
{
|
||||||
|
if (left == null || left.IsNil())
|
||||||
|
{
|
||||||
|
return new Antlr4.Runtime.Misc.IntervalSet();
|
||||||
|
}
|
||||||
|
Antlr4.Runtime.Misc.IntervalSet result = new Antlr4.Runtime.Misc.IntervalSet(left);
|
||||||
|
if (right == null || right.IsNil())
|
||||||
|
{
|
||||||
|
// right set has no elements; just return the copy of the current set
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
int resultI = 0;
|
||||||
|
int rightI = 0;
|
||||||
|
while (resultI < result.intervals.Count && rightI < right.intervals.Count)
|
||||||
|
{
|
||||||
|
Interval resultInterval = result.intervals[resultI];
|
||||||
|
Interval rightInterval = right.intervals[rightI];
|
||||||
|
// operation: (resultInterval - rightInterval) and update indexes
|
||||||
|
if (rightInterval.b < resultInterval.a)
|
||||||
|
{
|
||||||
|
rightI++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rightInterval.a > resultInterval.b)
|
||||||
|
{
|
||||||
|
resultI++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Interval beforeCurrent = null;
|
||||||
|
Interval afterCurrent = null;
|
||||||
|
if (rightInterval.a > resultInterval.a)
|
||||||
|
{
|
||||||
|
beforeCurrent = new Interval(resultInterval.a, rightInterval.a - 1);
|
||||||
|
}
|
||||||
|
if (rightInterval.b < resultInterval.b)
|
||||||
|
{
|
||||||
|
afterCurrent = new Interval(rightInterval.b + 1, resultInterval.b);
|
||||||
|
}
|
||||||
|
if (beforeCurrent != null)
|
||||||
|
{
|
||||||
|
if (afterCurrent != null)
|
||||||
|
{
|
||||||
|
// split the current interval into two
|
||||||
|
result.intervals.Set(resultI, beforeCurrent);
|
||||||
|
result.intervals.Add(resultI + 1, afterCurrent);
|
||||||
|
resultI++;
|
||||||
|
rightI++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// replace the current interval
|
||||||
|
result.intervals.Set(resultI, beforeCurrent);
|
||||||
|
resultI++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (afterCurrent != null)
|
||||||
|
{
|
||||||
|
// replace the current interval
|
||||||
|
result.intervals.Set(resultI, afterCurrent);
|
||||||
|
rightI++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// remove the current interval (thus no need to increment resultI)
|
||||||
|
result.intervals.RemoveAt(resultI);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If rightI reached right.intervals.size(), no more intervals to subtract from result.
|
||||||
|
// If resultI reached result.intervals.size(), we would be subtracting from an empty set.
|
||||||
|
// Either way, we are done.
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual Antlr4.Runtime.Misc.IntervalSet Or(IIntSet a)
|
public virtual Antlr4.Runtime.Misc.IntervalSet Or(IIntSet a)
|
||||||
|
@ -330,13 +399,10 @@ namespace Antlr4.Runtime.Misc
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Return a new set with the intersection of this set with other.</summary>
|
/// <summary>
|
||||||
/// <remarks>
|
/// <inheritDoc></inheritDoc>
|
||||||
/// Return a new set with the intersection of this set with other. Because
|
///
|
||||||
/// the intervals are sorted, we can use an iterator for each list and
|
/// </summary>
|
||||||
/// just walk them together. This is roughly O(min(n,m)) for interval
|
|
||||||
/// list lengths n and m.
|
|
||||||
/// </remarks>
|
|
||||||
public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other)
|
public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other)
|
||||||
{
|
{
|
||||||
if (other == null)
|
if (other == null)
|
||||||
|
@ -435,7 +501,10 @@ namespace Antlr4.Runtime.Misc
|
||||||
return intersection;
|
return intersection;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is el in any range of this set?</summary>
|
/// <summary>
|
||||||
|
/// <inheritDoc></inheritDoc>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public virtual bool Contains(int el)
|
public virtual bool Contains(int el)
|
||||||
{
|
{
|
||||||
int n = intervals.Count;
|
int n = intervals.Count;
|
||||||
|
@ -458,13 +527,19 @@ namespace Antlr4.Runtime.Misc
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>return true if this set has no members</summary>
|
/// <summary>
|
||||||
|
/// <inheritDoc></inheritDoc>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public virtual bool IsNil()
|
public virtual bool IsNil()
|
||||||
{
|
{
|
||||||
return intervals == null || intervals.Count == 0;
|
return intervals == null || intervals.Count == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>If this set is a single integer, return it otherwise Token.INVALID_TYPE</summary>
|
/// <summary>
|
||||||
|
/// <inheritDoc></inheritDoc>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public virtual int GetSingleElement()
|
public virtual int GetSingleElement()
|
||||||
{
|
{
|
||||||
if (intervals != null && intervals.Count == 1)
|
if (intervals != null && intervals.Count == 1)
|
||||||
|
@ -478,6 +553,14 @@ namespace Antlr4.Runtime.Misc
|
||||||
return TokenConstants.InvalidType;
|
return TokenConstants.InvalidType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>Returns the maximum value contained in the set.</summary>
|
||||||
|
/// <remarks>Returns the maximum value contained in the set.</remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// the maximum value contained in the set. If the set is empty, this
|
||||||
|
/// method returns
|
||||||
|
/// <see cref="Antlr4.Runtime.IToken.InvalidType">Antlr4.Runtime.IToken.InvalidType</see>
|
||||||
|
/// .
|
||||||
|
/// </returns>
|
||||||
public virtual int GetMaxElement()
|
public virtual int GetMaxElement()
|
||||||
{
|
{
|
||||||
if (IsNil())
|
if (IsNil())
|
||||||
|
@ -488,28 +571,21 @@ namespace Antlr4.Runtime.Misc
|
||||||
return last.b;
|
return last.b;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Return minimum element >= 0</summary>
|
/// <summary>Returns the minimum value contained in the set.</summary>
|
||||||
|
/// <remarks>Returns the minimum value contained in the set.</remarks>
|
||||||
|
/// <returns>
|
||||||
|
/// the minimum value contained in the set. If the set is empty, this
|
||||||
|
/// method returns
|
||||||
|
/// <see cref="Antlr4.Runtime.IToken.InvalidType">Antlr4.Runtime.IToken.InvalidType</see>
|
||||||
|
/// .
|
||||||
|
/// </returns>
|
||||||
public virtual int GetMinElement()
|
public virtual int GetMinElement()
|
||||||
{
|
{
|
||||||
if (IsNil())
|
if (IsNil())
|
||||||
{
|
{
|
||||||
return TokenConstants.InvalidType;
|
return TokenConstants.InvalidType;
|
||||||
}
|
}
|
||||||
int n = intervals.Count;
|
return intervals[0].a;
|
||||||
for (int i = 0; i < n; i++)
|
|
||||||
{
|
|
||||||
Interval I = intervals[i];
|
|
||||||
int a = I.a;
|
|
||||||
int b = I.b;
|
|
||||||
for (int v = a; v <= b; v++)
|
|
||||||
{
|
|
||||||
if (v >= 0)
|
|
||||||
{
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return TokenConstants.InvalidType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Return a list of Interval objects.</summary>
|
/// <summary>Return a list of Interval objects.</summary>
|
||||||
|
@ -580,7 +656,7 @@ namespace Antlr4.Runtime.Misc
|
||||||
int b = I.b;
|
int b = I.b;
|
||||||
if (a == b)
|
if (a == b)
|
||||||
{
|
{
|
||||||
if (a == -1)
|
if (a == TokenConstants.Eof)
|
||||||
{
|
{
|
||||||
buf.Append("<EOF>");
|
buf.Append("<EOF>");
|
||||||
}
|
}
|
||||||
|
@ -804,6 +880,10 @@ namespace Antlr4.Runtime.Misc
|
||||||
|
|
||||||
public virtual void SetReadonly(bool @readonly)
|
public virtual void SetReadonly(bool @readonly)
|
||||||
{
|
{
|
||||||
|
if (this.@readonly && !@readonly)
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("can't alter readonly IntervalSet");
|
||||||
|
}
|
||||||
this.@readonly = @readonly;
|
this.@readonly = @readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1161,6 +1161,36 @@ namespace Antlr4.Runtime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override ParseInfo GetParseInfo()
|
||||||
|
{
|
||||||
|
ParserATNSimulator interp = Interpreter;
|
||||||
|
if (interp is ProfilingATNSimulator)
|
||||||
|
{
|
||||||
|
return new ParseInfo((ProfilingATNSimulator)interp);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public virtual void SetProfile(bool profile)
|
||||||
|
{
|
||||||
|
ParserATNSimulator interp = Interpreter;
|
||||||
|
if (profile)
|
||||||
|
{
|
||||||
|
if (!(interp is ProfilingATNSimulator))
|
||||||
|
{
|
||||||
|
Interpreter = new ProfilingATNSimulator(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (interp is ProfilingATNSimulator)
|
||||||
|
{
|
||||||
|
Interpreter = new ParserATNSimulator(this, Atn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if !PORTABLE
|
#if !PORTABLE
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// During a parse is sometimes useful to listen in on the rule entry and exit
|
/// During a parse is sometimes useful to listen in on the rule entry and exit
|
||||||
|
|
|
@ -206,6 +206,20 @@ namespace Antlr4.Runtime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// If profiling during the parse/lex, this will return DecisionInfo records
|
||||||
|
/// for each decision in recognizer in a ParseInfo object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If profiling during the parse/lex, this will return DecisionInfo records
|
||||||
|
/// for each decision in recognizer in a ParseInfo object.
|
||||||
|
/// </remarks>
|
||||||
|
/// <since>4.3</since>
|
||||||
|
public virtual ParseInfo GetParseInfo()
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>What is the error header, normally line/character position information?</summary>
|
/// <summary>What is the error header, normally line/character position information?</summary>
|
||||||
[return: NotNull]
|
[return: NotNull]
|
||||||
public virtual string GetErrorHeader(RecognitionException e)
|
public virtual string GetErrorHeader(RecognitionException e)
|
||||||
|
|
Loading…
Reference in New Issue