Merge branch 'sharpen'

This commit is contained in:
Sam Harwell 2014-06-30 22:44:37 -05:00
commit c860ff779f
19 changed files with 2119 additions and 280 deletions

@ -1 +1 @@
Subproject commit cd9d2e248a9754a601e4a27f32fd889cc9459935 Subproject commit 8506131d96c239c9df0465575e42d6676d0d6cff

View File

@ -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)
{ {

View File

@ -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)
{
}
}
}

View File

@ -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)
{
}
}
}

View File

@ -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;
}
}
}

View File

@ -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 + '}';
}
}
}

View File

@ -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&lt;Symbol&gt;.SyntaxError&lt;T&gt;(Antlr4.Runtime.Recognizer&lt;Symbol, ATNInterpreter&gt;, 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)
{
}
}
}

View File

@ -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)
{
}
}
}

View File

@ -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;
}
}
}

View File

@ -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;
}
} }
} }

View File

@ -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&lt;Symbol, ATNInterpreter&gt;, 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;
}
}
}

View File

@ -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;
}
}
}

View File

@ -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)
{ {

View File

@ -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)
{ {

View File

@ -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>

View File

@ -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();
} }
} }

View File

@ -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&amp;~other.</summary> public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet a)
/// <remarks>
/// Compute this-other via this&amp;~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 &gt;= 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;
} }

View File

@ -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

View File

@ -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)