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();
/// <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.")]
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)
{
ParserRuleContext outerContext = state.outerContext;
DFAState acceptState = null;
DFAState s = state.s0;
int t = input.La(1);
ParserRuleContext remainingOuterContext = state.remainingOuterContext;
@ -567,6 +566,7 @@ namespace Antlr4.Runtime.Atn
SimulatorState initialState = new SimulatorState(state.outerContext, s, state.useContext, remainingOuterContext);
return ExecATN(dfa, input, startIndex, initialState);
}
System.Diagnostics.Debug.Assert(remainingOuterContext != null);
remainingOuterContext = ((ParserRuleContext)remainingOuterContext.Parent);
s = next;
}
@ -576,7 +576,6 @@ namespace Antlr4.Runtime.Atn
if (s.predicates != null)
{
}
acceptState = s;
// keep going unless we're at EOF or state only has one alt number
// mentioned in configs; check if something else could match
// 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
System.Diagnostics.Debug.Assert(!s.isAcceptState);
// 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 !PORTABLE
@ -598,19 +597,6 @@ namespace Antlr4.Runtime.Atn
int alt;
SimulatorState initialState = new SimulatorState(outerContext, s, state.useContext, remainingOuterContext);
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);
// action already executed
return alt;
@ -635,11 +621,11 @@ namespace Antlr4.Runtime.Atn
// if ( debug ) System.out.println("!!! no viable alt in dfa");
// return -1;
// }
if (acceptState.configs.ConflictingAlts != null)
if (s.configs.ConflictingAlts != null)
{
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
@ -653,14 +639,15 @@ namespace Antlr4.Runtime.Atn
// disambiguating or validating predicates to evaluate which allow an
// immediate decision
BitSet conflictingAlts = null;
if (acceptState.predicates != null)
DFAState.PredPrediction[] predicates = s.predicates;
if (predicates != null)
{
int conflictIndex = input.Index;
if (conflictIndex != startIndex)
{
input.Seek(startIndex);
}
conflictingAlts = EvalSemanticContext(s.predicates, outerContext, true);
conflictingAlts = EvalSemanticContext(predicates, outerContext, true);
if (conflictingAlts.Cardinality() == 1)
{
return conflictingAlts.NextSetBit(0);
@ -674,7 +661,7 @@ namespace Antlr4.Runtime.Atn
}
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);
}
input.Seek(startIndex);
@ -684,14 +671,15 @@ namespace Antlr4.Runtime.Atn
}
// Before jumping to prediction, check to see if there are
// disambiguating or validating predicates to evaluate
if (s.predicates != null)
DFAState.PredPrediction[] predicates_1 = s.predicates;
if (predicates_1 != null)
{
int stopIndex = input.Index;
if (startIndex != stopIndex)
{
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())
{
case 0:
@ -717,7 +705,7 @@ namespace Antlr4.Runtime.Atn
}
}
}
return acceptState.prediction;
return s.prediction;
}
/// <summary>
@ -1067,6 +1055,7 @@ namespace Antlr4.Runtime.Atn
{
break;
}
System.Diagnostics.Debug.Assert(remainingGlobalContext != null);
remainingGlobalContext = ((ParserRuleContext)remainingGlobalContext.Parent);
s = next;
}
@ -1642,7 +1631,7 @@ namespace Antlr4.Runtime.Atn
// if no (null, i), then no default prediction.
if (ambigAlts != null && ambigAlts.Get(i) && pred == SemanticContext.None)
{
pairs.Add(new DFAState.PredPrediction(null, i));
pairs.Add(new DFAState.PredPrediction(pred, i));
}
else
{
@ -1677,7 +1666,7 @@ namespace Antlr4.Runtime.Atn
BitSet predictions = new BitSet();
foreach (DFAState.PredPrediction pair in predPredictions)
{
if (pair.pred == null)
if (pair.pred == SemanticContext.None)
{
predictions.Set(pair.alt);
if (!complete)
@ -1686,7 +1675,7 @@ namespace Antlr4.Runtime.Atn
}
continue;
}
bool evaluatedResult = pair.pred.Eval(parser, outerContext);
bool evaluatedResult = EvalSemanticContext(pair.pred, outerContext, pair.alt);
#if !PORTABLE
if (debug || dfa_debug)
{
@ -1711,6 +1700,44 @@ namespace Antlr4.Runtime.Atn
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)
{
if (contextCache == null)
@ -1927,7 +1954,7 @@ namespace Antlr4.Runtime.Atn
[return: Nullable]
protected internal virtual ATNConfig PrecedenceTransition(ATNConfig config, PrecedencePredicateTransition pt, bool collectPredicates, bool inContext)
{
ATNConfig c = null;
ATNConfig c;
if (collectPredicates && inContext)
{
SemanticContext newSemCtx = SemanticContext.And(config.SemanticContext, pt.GetPredicate());
@ -1979,9 +2006,9 @@ namespace Antlr4.Runtime.Atn
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)
{
@ -2019,9 +2046,8 @@ namespace Antlr4.Runtime.Atn
// minAlt from the first state, #2 will fail if the assumption was
// incorrect
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;
if (stateNumber != currentState)
{
@ -2032,32 +2058,30 @@ namespace Antlr4.Runtime.Atn
currentState = stateNumber;
}
}
BitSet representedAlts = null;
BitSet representedAlts;
if (exact)
{
currentState = configs[0].State.NonStopStateNumber;
// get the represented alternatives of the first state
representedAlts = new BitSet();
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.State.NonStopStateNumber != currentState)
if (config_1.State.NonStopStateNumber != currentState)
{
break;
}
int alt = config.Alt;
int alt = config_1.Alt;
representedAlts.Set(alt);
maxAlt = alt;
}
// quick check #3:
currentState = configs[0].State.NonStopStateNumber;
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.State.NonStopStateNumber;
int alt = config.Alt;
int stateNumber = config_2.State.NonStopStateNumber;
int alt = config_2.Alt;
if (stateNumber != currentState)
{
if (currentAlt != maxAlt)
@ -2084,31 +2108,31 @@ namespace Antlr4.Runtime.Atn
int firstIndexCurrentState = 0;
int lastIndexCurrentStateMinAlt = 0;
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];
if (config.Alt != minAlt)
ATNConfig config_1 = configs[i];
if (config_1.Alt != minAlt)
{
break;
}
if (config.State.NonStopStateNumber != currentState)
if (config_1.State.NonStopStateNumber != currentState)
{
break;
}
lastIndexCurrentStateMinAlt = i_3;
joinedCheckContext = contextCache.Join(joinedCheckContext, configs[i_3].Context);
lastIndexCurrentStateMinAlt = i;
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];
ATNState state = config.State;
alts.Set(config.Alt);
ATNConfig config_1 = configs[i_1];
ATNState state = config_1.State;
alts.Set(config_1.Alt);
if (state.NonStopStateNumber != currentState)
{
currentState = state.NonStopStateNumber;
firstIndexCurrentState = i_4;
lastIndexCurrentStateMinAlt = i_4;
joinedCheckContext = config.Context;
firstIndexCurrentState = i_1;
lastIndexCurrentStateMinAlt = i_1;
joinedCheckContext = config_1.Context;
for (int j = firstIndexCurrentState + 1; j < configs.Count; j++)
{
ATNConfig config2 = configs[j];
@ -2123,12 +2147,12 @@ namespace Antlr4.Runtime.Atn
lastIndexCurrentStateMinAlt = j;
joinedCheckContext = contextCache.Join(joinedCheckContext, config2.Context);
}
i_4 = lastIndexCurrentStateMinAlt;
i_1 = lastIndexCurrentStateMinAlt;
continue;
}
PredictionContext joinedCheckContext2 = config.Context;
int currentAlt = config.Alt;
int lastIndexCurrentStateCurrentAlt = i_4;
PredictionContext joinedCheckContext2 = config_1.Context;
int currentAlt = config_1.Alt;
int lastIndexCurrentStateCurrentAlt = i_1;
for (int j_1 = lastIndexCurrentStateCurrentAlt + 1; j_1 < configs.Count; j_1++)
{
ATNConfig config2 = configs[j_1];
@ -2143,7 +2167,7 @@ namespace Antlr4.Runtime.Atn
lastIndexCurrentStateCurrentAlt = j_1;
joinedCheckContext2 = contextCache.Join(joinedCheckContext2, config2.Context);
}
i_4 = lastIndexCurrentStateCurrentAlt;
i_1 = lastIndexCurrentStateCurrentAlt;
if (exact)
{
if (!joinedCheckContext.Equals(joinedCheckContext2))
@ -2164,19 +2188,19 @@ namespace Antlr4.Runtime.Atn
for (int j = firstIndexCurrentState; j <= lastIndexCurrentStateMinAlt; 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;
}
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))
{
continue;
}
}
config.IsHidden = true;
config_1.IsHidden = true;
}
}
}
@ -2486,22 +2510,6 @@ namespace Antlr4.Runtime.Atn
#if !PORTABLE
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);
System.Console.Out.WriteLine("reportAmbiguity " + ambigAlts + ":" + configs + ", input=" + ((ITokenStream)parser.InputStream).GetText(interval));
}
@ -2542,5 +2550,11 @@ namespace Antlr4.Runtime.Atn
}
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
/// dependent predicate evaluation.</p>
/// </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;
/// <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>
/// <param name="parser">The parser instance.</param>
/// <param name="outerContext">The current parser context object.</param>
/// <param name="parserCallStack"></param>
/// <returns>
/// The simplified semantic context after precedence predicates are
/// 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>
/// </ul>
/// </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
{
return this;
@ -151,9 +151,9 @@ namespace Antlr4.Runtime.Atn
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);
}
@ -201,14 +201,14 @@ namespace Antlr4.Runtime.Atn
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;
}
@ -246,10 +246,35 @@ namespace Antlr4.Runtime.Atn
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>
/// A semantic context which is true whenever none of the contained contexts
/// is false.
@ -258,7 +283,7 @@ namespace Antlr4.Runtime.Atn
/// A semantic context which is true whenever none of the contained contexts
/// is false.
/// </remarks>
public class AND : SemanticContext
public class AND : SemanticContext.Operator
{
[NotNull]
public readonly SemanticContext[] opnds;
@ -292,6 +317,11 @@ namespace Antlr4.Runtime.Atn
opnds = operands.ToArray();
}
public override ICollection<SemanticContext> GetOperands()
{
return Arrays.AsList(opnds);
}
public override bool Equals(object obj)
{
if (this == obj)
@ -317,11 +347,11 @@ namespace Antlr4.Runtime.Atn
/// The evaluation of predicates by this context is short-circuiting, but
/// unordered.</p>
/// </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)
{
if (!opnd.Eval(parser, outerContext))
if (!opnd.Eval(parser, parserCallStack))
{
return false;
}
@ -329,13 +359,13 @@ namespace Antlr4.Runtime.Atn
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;
IList<SemanticContext> operands = new List<SemanticContext>();
foreach (SemanticContext context in opnds)
{
SemanticContext evaluated = context.EvalPrecedence(parser, outerContext);
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
differs |= (evaluated != context);
if (evaluated == null)
{
@ -382,7 +412,7 @@ namespace Antlr4.Runtime.Atn
/// A semantic context which is true whenever at least one of the contained
/// contexts is true.
/// </remarks>
public class OR : SemanticContext
public class OR : SemanticContext.Operator
{
[NotNull]
public readonly SemanticContext[] opnds;
@ -416,6 +446,11 @@ namespace Antlr4.Runtime.Atn
this.opnds = operands.ToArray();
}
public override ICollection<SemanticContext> GetOperands()
{
return Arrays.AsList(opnds);
}
public override bool Equals(object obj)
{
if (this == obj)
@ -441,11 +476,11 @@ namespace Antlr4.Runtime.Atn
/// The evaluation of predicates by this context is short-circuiting, but
/// unordered.</p>
/// </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)
{
if (opnd.Eval(parser, outerContext))
if (opnd.Eval(parser, parserCallStack))
{
return true;
}
@ -453,13 +488,13 @@ namespace Antlr4.Runtime.Atn
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;
IList<SemanticContext> operands = new List<SemanticContext>();
foreach (SemanticContext context in opnds)
{
SemanticContext evaluated = context.EvalPrecedence(parser, outerContext);
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
differs |= (evaluated != context);
if (evaluated == None)
{

View File

@ -461,26 +461,25 @@ namespace Antlr4.Runtime
/// <code>i</code>
/// if
/// <code>tokens[i]</code>
/// is on channel. Return
/// <code>-1</code>
/// if there are no tokens
/// on channel between
/// is on channel. Return the index of
/// the EOF token if there are no tokens on channel between
/// <code>i</code>
/// and EOF.
/// and
/// EOF.
/// </remarks>
protected internal virtual int NextTokenOnChannel(int i, int channel)
{
Sync(i);
IToken token = tokens[i];
if (i >= Size)
{
return -1;
return Size - 1;
}
IToken token = tokens[i];
while (token.Channel != channel)
{
if (token.Type == TokenConstants.Eof)
{
return -1;
return i;
}
i++;
Sync(i);
@ -489,26 +488,42 @@ namespace Antlr4.Runtime
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>
/// Given a starting index, return the index of the previous token on channel.
/// Return
/// Given a starting index, return the index of the previous token on
/// channel. Return
/// <code>i</code>
/// if
/// <code>tokens[i]</code>
/// is on channel. Return
/// <code>-1</code>
/// if there are no tokens
/// on channel between
/// is on channel. Return -1
/// if there are no tokens on channel between
/// <code>i</code>
/// and
/// <code>0</code>
/// .
/// and 0.
/// <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>
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--;
}
return i;
@ -576,6 +591,11 @@ namespace Antlr4.Runtime
{
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);
if (prevOnChannel == tokenIndex - 1)
{

View File

@ -45,40 +45,52 @@ namespace Antlr4.Runtime
/// <remarks>
/// This method is called by the parser when a full-context prediction
/// 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
/// <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>
/// is
/// <code>true</code>
/// , <em>all</em> of the alternatives in
/// <code>ambigAlts</code>
/// are viable, i.e. this is reporting an exact ambiguity.
/// When
/// , <em>all</em> of the potentially
/// viable alternatives are truly viable, i.e. this is reporting an exact
/// ambiguity. When
/// <code>exact</code>
/// is
/// <code>false</code>
/// , <em>at least two</em> of the
/// alternatives in
/// <code>ambigAlts</code>
/// are viable for the current input, but
/// , <em>at least two</em> of
/// the potentially viable alternatives are viable for the current input, but
/// the prediction algorithm terminated as soon as it determined that at
/// least the <em>minimum</em> alternative in
/// <code>ambigAlts</code>
/// is viable.
/// <p/>
/// When the
/// least the <em>minimum</em> potentially viable alternative is truly
/// viable.</p>
/// <p>When the
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
/// prediction mode
/// is used, the parser is required to identify exact ambiguities so
/// prediction
/// mode is used, the parser is required to identify exact ambiguities so
/// <code>exact</code>
/// will always be
/// <code>true</code>
/// .
/// .</p>
/// </remarks>
/// <param name="recognizer">the parser instance</param>
/// <param name="dfa">the DFA for the current decision</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">
///
/// <code>true</code>
@ -90,10 +102,16 @@ namespace Antlr4.Runtime
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection">Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection</see>
/// is used.
/// </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">
/// the ATN configuration set where the ambiguity was
/// determined
/// identified
/// </param>
void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs);
@ -104,15 +122,14 @@ namespace Antlr4.Runtime
/// <remarks>
/// This method is called when an SLL conflict occurs and the parser is about
/// to use the full context information to make an LL decision.
/// <p/>
/// If one or more configurations in
/// <p>If one or more configurations in
/// <code>configs</code>
/// contains a semantic
/// predicate, the predicates are evaluated before this method is called. The
/// subset of alternatives which are still viable after predicates are
/// evaluated is reported in
/// <code>conflictingAlts</code>
/// .
/// .</p>
/// </remarks>
/// <param name="recognizer">the parser instance</param>
/// <param name="dfa">the DFA for the current decision</param>
@ -139,23 +156,35 @@ namespace Antlr4.Runtime
/// <remarks>
/// This method is called by the parser when a full-context prediction has a
/// unique result.
/// <p/>
/// For prediction implementations that only evaluate full-context
/// <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>For prediction implementations that only evaluate full-context
/// predictions when an SLL conflict is found (including the default
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator">Antlr4.Runtime.Atn.ParserATNSimulator</see>
/// implementation), this method reports cases
/// where SLL conflicts were resolved to unique full-context predictions,
/// i.e. the decision was context-sensitive. This report does not necessarily
/// indicate a problem, and it may appear even in completely unambiguous
/// grammars.
/// <p/>
/// grammars.</p>
/// <p>
/// <code>configs</code>
/// may have more than one represented alternative if the
/// full-context prediction algorithm does not evaluate predicates before
/// beginning the full-context prediction. In all cases, the final prediction
/// is passed as the
/// <code>prediction</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>
/// <param name="recognizer">the parser instance</param>
/// <param name="dfa">the DFA for the current decision</param>

View File

@ -33,60 +33,272 @@ using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>A generic set of ints.</summary>
/// <remarks>A generic set of ints.</remarks>
/// <summary>A generic set of integers.</summary>
/// <remarks>A generic set of integers.</remarks>
/// <seealso cref="IntervalSet">IntervalSet</seealso>
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);
/// <summary>Add all elements from incoming set to this set.</summary>
/// <remarks>
/// Add all elements from incoming set to this set. Can limit
/// to set of its own type. Return "this" so we can chain calls.
/// </remarks>
/// <summary>
/// Modify the current
/// <see cref="IIntSet">IIntSet</see>
/// object to contain all elements that are
/// 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);
/// <summary>
/// Return the intersection of this set with the argument, creating
/// a new set.
/// Return a new
/// <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>
/// <remarks>
/// Return the intersection of this set with the argument, creating
/// a new set.
/// </remarks>
/// <param name="a">
/// The set to intersect 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 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);
/// <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);
/// <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);
/// <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);
/// <summary>
/// Return the size of this set (not the underlying implementation's
/// allocated memory size, for example).
/// </summary>
/// <remarks>
/// Return the size of this set (not the underlying implementation's
/// allocated memory size, for example).
/// </remarks>
/// <summary>Return the total number of elements represented by the current set.</summary>
/// <remarks>Return the total number of elements represented by the current set.</remarks>
/// <returns>
/// the total number of elements represented by the current set,
/// regardless of the manner in which the elements are stored.
/// </returns>
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();
/// <summary><inheritDoc></inheritDoc></summary>
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();
/// <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);
/// <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);
/// <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();
/// <summary><inheritDoc></inheritDoc></summary>
string ToString();
}
}

View File

@ -38,28 +38,37 @@ using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>
/// 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).
/// This class implements the
/// <see cref="IIntSet">IIntSet</see>
/// 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>
/// <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 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();
static IntervalSet()
{
EmptySet.SetReadonly(true);
}
/// <summary>The list of sorted, disjoint intervals.</summary>
/// <remarks>The list of sorted, disjoint intervals.</remarks>
protected internal IList<Interval> intervals;
@ -226,17 +235,23 @@ namespace Antlr4.Runtime.Misc
{
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;
// walk set and add each interval
int n = other.intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = other.intervals[i];
this.Add(I.a, I.b);
}
}
Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set;
// walk set and add each interval
int n = other.intervals.Count;
for (int i = 0; i < n; i++)
else
{
Interval I = other.intervals[i];
this.Add(I.a, I.b);
foreach (int value in set.ToList())
{
Add(value);
}
}
return this;
}
@ -247,79 +262,133 @@ namespace Antlr4.Runtime.Misc
}
/// <summary>
/// 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.
/// <inheritDoc></inheritDoc>
///
/// </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)
{
if (vocabulary == null)
if (vocabulary == null || vocabulary.IsNil())
{
return null;
}
// 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);
int maxElement = vocabularyIS.GetMaxElement();
Antlr4.Runtime.Misc.IntervalSet compl = new Antlr4.Runtime.Misc.IntervalSet();
int n = intervals.Count;
if (n == 0)
else
{
return compl;
vocabularyIS = new Antlr4.Runtime.Misc.IntervalSet();
vocabularyIS.AddAll(vocabulary);
}
Interval first = intervals[0];
// 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;
return vocabularyIS.Subtract(this);
}
/// <summary>Compute this-other via this&amp;~other.</summary>
/// <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)
public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet a)
{
// assume the whole unicode range here for the complement
// because it doesn't matter. Anything beyond the max of this' set
// will be ignored since we are doing this & ~other. The intersection
// 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
// will prevent this.
return this.And(((Antlr4.Runtime.Misc.IntervalSet)other).Complement(CompleteCharSet));
if (a == null || a.IsNil())
{
return new Antlr4.Runtime.Misc.IntervalSet(this);
}
if (a is Antlr4.Runtime.Misc.IntervalSet)
{
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)
@ -330,13 +399,10 @@ namespace Antlr4.Runtime.Misc
return o;
}
/// <summary>Return a new set with the intersection of this set with other.</summary>
/// <remarks>
/// 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
/// just walk them together. This is roughly O(min(n,m)) for interval
/// list lengths n and m.
/// </remarks>
/// <summary>
/// <inheritDoc></inheritDoc>
///
/// </summary>
public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other)
{
if (other == null)
@ -435,7 +501,10 @@ namespace Antlr4.Runtime.Misc
return intersection;
}
/// <summary>Is el in any range of this set?</summary>
/// <summary>
/// <inheritDoc></inheritDoc>
///
/// </summary>
public virtual bool Contains(int el)
{
int n = intervals.Count;
@ -458,13 +527,19 @@ namespace Antlr4.Runtime.Misc
return false;
}
/// <summary>return true if this set has no members</summary>
/// <summary>
/// <inheritDoc></inheritDoc>
///
/// </summary>
public virtual bool IsNil()
{
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()
{
if (intervals != null && intervals.Count == 1)
@ -478,6 +553,14 @@ namespace Antlr4.Runtime.Misc
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()
{
if (IsNil())
@ -488,28 +571,21 @@ namespace Antlr4.Runtime.Misc
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()
{
if (IsNil())
{
return TokenConstants.InvalidType;
}
int n = intervals.Count;
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;
return intervals[0].a;
}
/// <summary>Return a list of Interval objects.</summary>
@ -580,7 +656,7 @@ namespace Antlr4.Runtime.Misc
int b = I.b;
if (a == b)
{
if (a == -1)
if (a == TokenConstants.Eof)
{
buf.Append("<EOF>");
}
@ -804,6 +880,10 @@ namespace Antlr4.Runtime.Misc
public virtual void SetReadonly(bool @readonly)
{
if (this.@readonly && !@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
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
/// <summary>
/// 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>
[return: NotNull]
public virtual string GetErrorHeader(RecognitionException e)