Merge branch 'master_upstream'

This commit is contained in:
Mike Lischke 2016-12-13 09:00:13 +01:00
commit 31b259e636
126 changed files with 6192 additions and 7536 deletions

View File

@ -3,4 +3,6 @@
- [ ] I am not submitting a question on how to use ANTLR; instead, go to [antlr4-discussion google group](https://groups.google.com/forum/#!forum/antlr-discussion) or ask at [stackoverflow](http://stackoverflow.com/questions/tagged/antlr4)
- [ ] I have done a search of the existing issues to make sure I'm not sending in a duplicate
[cut]
Please include information about the expected behavior, actual behavior, and the smallest grammar or code that reproduces the behavior. If appropriate, please indicate the code generation targets such as Java, C#, ... Pointers into offending code regions are also very welcome.
[/cut]

View File

@ -1,5 +1,5 @@
[snip]
[cut]
Thank you for proposing a contribution to the ANTLR project. In order to accept changes from the outside world, all contributors most "sign" the [contributors.txt](https://github.com/antlr/antlr4/blob/master/contributors.txt) contributors certificate of origin. It's an unfortunate reality of today's fuzzy and bizarre world of open-source ownership.
Make sure you are already in the contributors.txt file or add a commit to this pull request with the appropriate change. Thanks!
[/snip]
[/cut]

View File

@ -126,3 +126,4 @@ YYYY/MM/DD, github id, Full name, email
2016/11/29, Naios, Denis Blank, naios@users.noreply.github.com
2016/12/01, samtatasurya, Samuel Tatasurya, xemradiant@gmail.com
2016/12/03, redxdev, Samuel Bloomberg, sam@redxdev.com
2016/12/11, Gaulouis, Gaulouis, gaulouis.com@gmail.com

View File

@ -85,6 +85,47 @@ Here is the file template
</settings>
```
## Maven deploy snapshot
The goal is to get a snapshot, such as `4.6-SNAPSHOT`, to the staging server: [antlr4 tool](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4) and [antlr4 java runtime](https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-runtime).
Do this:
```bash
$ mvn deploy -DskipTests
...
[INFO] --- maven-deploy-plugin:2.7:deploy (default-deploy) @ antlr4-tool-testsuite ---
Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/maven-metadata.xml
Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/antlr4-tool-testsuite-4.6-20161211.173752-1.jar
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/antlr4-tool-testsuite-4.6-20161211.173752-1.jar (3 KB at 3.4 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/antlr4-tool-testsuite-4.6-20161211.173752-1.pom
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/antlr4-tool-testsuite-4.6-20161211.173752-1.pom (3 KB at 6.5 KB/sec)
Downloading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml
Downloaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml (371 B at 1.4 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/maven-metadata.xml
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/4.6-SNAPSHOT/maven-metadata.xml (774 B at 1.8 KB/sec)
Uploading: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml
Uploaded: https://oss.sonatype.org/content/repositories/snapshots/org/antlr/antlr4-tool-testsuite/maven-metadata.xml (388 B at 0.9 KB/sec)
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO]
[INFO] ANTLR 4 ............................................ SUCCESS [ 4.073 s]
[INFO] ANTLR 4 Runtime .................................... SUCCESS [ 13.828 s]
[INFO] ANTLR 4 Tool ....................................... SUCCESS [ 14.032 s]
[INFO] ANTLR 4 Maven plugin ............................... SUCCESS [ 6.547 s]
[INFO] ANTLR 4 Runtime Test Annotations ................... SUCCESS [ 2.519 s]
[INFO] ANTLR 4 Runtime Test Processors .................... SUCCESS [ 2.385 s]
[INFO] ANTLR 4 Runtime Tests (2nd generation) ............. SUCCESS [ 15.276 s]
[INFO] ANTLR 4 Tool Tests ................................. SUCCESS [ 2.233 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:01 min
[INFO] Finished at: 2016-12-11T09:37:54-08:00
[INFO] Final Memory: 44M/470M
[INFO] ------------------------------------------------------------------------
```
## Maven release
The maven deploy lifecycle phased deploys the artifacts and the poms for the ANTLR project to the [sonatype remote staging server](https://oss.sonatype.org/content/repositories/snapshots/).

View File

@ -64,9 +64,9 @@ PlusText(a) ::= <%"<a>" + this.Text%>
InputText() ::= "this.TokenStream.GetText()"
LTEquals(i, v) ::= <%this.TokenStream.Lt(<i>).Text.Equals(<v>)%>
LTEquals(i, v) ::= <%this.TokenStream.LT(<i>).Text.Equals(<v>)%>
LANotEquals(i, v) ::= <%this.InputStream.La(<i>)!=<v>%>
LANotEquals(i, v) ::= <%this.InputStream.LA(<i>)!=<v>%>
TokenStartColumnEquals(i) ::= <%this.TokenStartColumn==<i>%>
@ -76,7 +76,7 @@ GetExpectedTokenNames() ::= "this.GetExpectedTokens().ToString(this.Vocabulary)"
RuleInvocationStack() ::= "GetRuleInvocationStackAsString()"
LL_EXACT_AMBIG_DETECTION() ::= <<Interpreter.PredictionMode = PredictionMode.LlExactAmbigDetection;>>
LL_EXACT_AMBIG_DETECTION() ::= <<Interpreter.PredictionMode = PredictionMode.LL_EXACT_AMBIG_DETECTION;>>
ParserToken(parser, token) ::= <%<parser>.<token>%>
@ -98,7 +98,7 @@ PositionAdjustingLexer() ::= <<
public override IToken NextToken() {
if (!(Interpreter is PositionAdjustingLexerATNSimulator)) {
Interpreter = new PositionAdjustingLexerATNSimulator(this, _ATN);
Interpreter = new PositionAdjustingLexerATNSimulator(this, _ATN, decisionToDFA, sharedContextCache);
}
return base.NextToken();
@ -157,8 +157,8 @@ private static bool IsIdentifierChar(char c) {
public class PositionAdjustingLexerATNSimulator : LexerATNSimulator {
public PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn)
: base(recog, atn)
public PositionAdjustingLexerATNSimulator(Lexer recog, ATN atn, DFA[] decisionToDFA, PredictionContextCache sharedContextCache)
: base(recog, atn, decisionToDFA, sharedContextCache)
{
}

View File

@ -70,14 +70,14 @@ ParserPropertyCall(p, call) ::= "<call>"
PositionAdjustingLexer() ::= <<
protected:
class PositionAdjustingLexerATNSimulator : public atn::LexerATNSimulator {
class PositionAdjustingLexerATNSimulator : public antlr4::atn::LexerATNSimulator {
public:
PositionAdjustingLexerATNSimulator(Lexer *recog, const atn::ATN &atn, std::vector\<dfa::DFA> &decisionToDFA,
atn::PredictionContextCache &sharedContextCache)
: atn::LexerATNSimulator(recog, atn, decisionToDFA, sharedContextCache) {
PositionAdjustingLexerATNSimulator(antlr4::Lexer *recog, const antlr4::atn::ATN &atn, std::vector\<antlr4::dfa::DFA> &decisionToDFA,
antlr4::atn::PredictionContextCache &sharedContextCache)
: antlr4::atn::LexerATNSimulator(recog, atn, decisionToDFA, sharedContextCache) {
}
void resetAcceptPosition(CharStream *input, int index, int line, int charPositionInLine) {
void resetAcceptPosition(antlr4::CharStream *input, int index, int line, int charPositionInLine) {
input->seek(index);
_line = line;
_charPositionInLine = charPositionInLine;
@ -87,16 +87,16 @@ protected:
};
public:
virtual std::unique_ptr\<Token> nextToken() override {
virtual std::unique_ptr\<antlr4::Token> nextToken() override {
if (dynamic_cast\<PositionAdjustingLexerATNSimulator *>(_interpreter) == nullptr) {
delete _interpreter;
_interpreter = new PositionAdjustingLexerATNSimulator(this, _atn, _decisionToDFA, _sharedContextCache);
}
return Lexer::nextToken();
return antlr4::Lexer::nextToken();
}
virtual Token* emit() override {
virtual antlr4::Token* emit() override {
switch (type) {
case TOKENS:
handleAcceptPositionForKeyword("tokens");
@ -109,7 +109,7 @@ public:
default:
break;
}
return Lexer::emit();
return antlr4::Lexer::emit();
}
private:
@ -167,11 +167,11 @@ tree::ParseTreeWalker::DEFAULT.walk(&listener, <s>);
TreeNodeWithAltNumField(X) ::= <<
@parser::members {
class MyRuleNode : public ParserRuleContext {
class MyRuleNode : public antlr4::ParserRuleContext {
public:
size_t altNum;
MyRuleNode(ParserRuleContext *parent, int invokingStateNumber)
: ParserRuleContext(parent, invokingStateNumber) {
MyRuleNode(antlr4::ParserRuleContext *parent, int invokingStateNumber)
: antlr4::ParserRuleContext(parent, invokingStateNumber) {
}
virtual size_t getAltNumber() const override { return altNum; }
virtual void setAltNumber(size_t altNum) override { this->altNum = altNum; }

View File

@ -13,7 +13,6 @@ import org.antlr.v4.runtime.WritableToken;
import org.antlr.v4.runtime.misc.Utils;
import org.antlr.v4.test.runtime.ErrorQueue;
import org.antlr.v4.test.runtime.RuntimeTestSupport;
import org.antlr.v4.test.runtime.SpecialRuntimeTestAssert;
import org.antlr.v4.tool.ANTLRMessage;
import org.antlr.v4.tool.GrammarSemanticsMessage;
import org.junit.rules.TestRule;
@ -54,7 +53,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAssert {
public class BaseCSharpTest implements RuntimeTestSupport /*, SpecialRuntimeTestAssert*/ {
public static final String newline = System.getProperty("line.separator");
public static final String pathSep = System.getProperty("path.separator");
@ -691,7 +690,7 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
" tokens.Fill();\n" +
" foreach (object t in tokens.GetTokens())\n" +
" Console.WriteLine(t);\n" +
(showDFA?"Console.Write(lex.Interpreter.GetDFA(Lexer.DefaultMode).ToLexerString());\n":"")+
(showDFA?" Console.Write(lex.Interpreter.GetDFA(Lexer.DEFAULT_MODE).ToLexerString());\n":"")+
" }\n" +
"}"
);
@ -788,64 +787,8 @@ public class BaseCSharpTest implements RuntimeTestSupport, SpecialRuntimeTestAss
org.junit.Assert.assertEquals(msg, a, b);
}
@Override
public void assertEqualStrings(String a, String b) {
assertEquals(a, b);
}
protected static void assertEquals(String a, String b) {
a = absorbExpectedDifferences(a);
b = absorbActualDifferences(b);
org.junit.Assert.assertEquals(a, b);
}
protected static void assertNull(String a) {
a = absorbActualDifferences(a);
org.junit.Assert.assertNull(a);
}
private static String absorbExpectedDifferences(String a) {
if(a==null)
return a;
// work around the lack of requiresFullContext field in DFAState
if(a.startsWith("Decision"))
a = a.replaceAll("\\^", "");
// work around the algo difference for full context
a = stripOutUnwantedLinesWith(a, "reportAttemptingFullContext","reportContextSensitivity", "reportAmbiguity");
if(a.isEmpty()) {
a = null;
}
return a;
}
private static String absorbActualDifferences(String a) {
if(a==null) return a;
// work around the algo difference for full context
// work around the algo difference for semantic predicates
a = stripOutUnwantedLinesWith(a, "reportContextSensitivity","eval=false");
if(a.isEmpty()) {
a = null;
}
return a;
}
private static String stripOutUnwantedLinesWith(String a, String ... unwanteds) {
String[] lines = a.split("\n");
StringBuilder sb = new StringBuilder();
for(String line : lines) {
boolean wanted = true;
for(String unwanted : unwanteds) {
if(line.contains(unwanted) ) {
wanted = false;
break;
}
}
if(!wanted)
continue;
sb.append(line);
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -112,7 +112,7 @@ public class ParseTreesDescriptors {
@Override
public boolean ignore(String targetName) {
return !targetName.equals("Java");
return !targetName.matches("Java|Python2|Python3|Node");
}
}

View File

@ -113,8 +113,7 @@ public class PerformanceDescriptors {
@Override
public boolean ignore(String targetName) {
// return !Arrays.asList("Java", "Python2", "Python3", "Node").contains(targetName);
return !Arrays.asList("Java").contains(targetName);
return !Arrays.asList("Java", "CSharp", "Python2", "Python3", "Node").contains(targetName);
}
}
@ -196,6 +195,12 @@ public class PerformanceDescriptors {
*/
@CommentHasStringValue
public String input;
@Override
public boolean ignore(String targetName) {
// passes, but still too slow in Python and JavaScript
return !Arrays.asList("Java", "CSharp").contains(targetName);
}
}
public static class DropLoopEntryBranchInLRRule_5 extends DropLoopEntryBranchInLRRule {

View File

@ -25,7 +25,7 @@
<DefineConstants>DEBUG;TRACE;NET35PLUS</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoWarn>1591</NoWarn>
<NoWarn>1591 0659</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
@ -87,7 +87,6 @@
<Compile Include="Atn\LookaheadEventInfo.cs" />
<Compile Include="Atn\LoopEndState.cs" />
<Compile Include="Atn\NotSetTransition.cs" />
<Compile Include="Atn\OrderedATNConfigSet.cs" />
<Compile Include="Atn\ParseInfo.cs" />
<Compile Include="Atn\ParserATNSimulator.cs" />
<Compile Include="Atn\PlusBlockStartState.cs" />
@ -232,6 +231,10 @@
<Compile Include="Dfa\IEdgeMap.cs" />
<Compile Include="Dfa\SingletonEdgeMap.cs" />
<Compile Include="Dfa\SparseEdgeMap.cs" />
<Compile Include="Misc\Pair.cs" />
<Compile Include="Atn\LexerATNConfig.cs" />
<Compile Include="Atn\MergeCache.cs" />
<Compile Include="Misc\ArrayList.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -94,6 +94,7 @@
<Compile Include="Atn\ILexerAction.cs" />
<Compile Include="Atn\LexerActionExecutor.cs" />
<Compile Include="Atn\LexerActionType.cs" />
<Compile Include="Atn\LexerATNConfig.cs" />
<Compile Include="Atn\LexerATNSimulator.cs" />
<Compile Include="Atn\LexerChannelAction.cs" />
<Compile Include="Atn\LexerCustomAction.cs" />
@ -107,8 +108,8 @@
<Compile Include="Atn\LL1Analyzer.cs" />
<Compile Include="Atn\LookaheadEventInfo.cs" />
<Compile Include="Atn\LoopEndState.cs" />
<Compile Include="Atn\MergeCache.cs" />
<Compile Include="Atn\NotSetTransition.cs" />
<Compile Include="Atn\OrderedATNConfigSet.cs" />
<Compile Include="Atn\ParseInfo.cs" />
<Compile Include="Atn\ParserATNSimulator.cs" />
<Compile Include="Atn\PlusBlockStartState.cs" />
@ -168,12 +169,14 @@
<Compile Include="LexerNoViableAltException.cs" />
<Compile Include="ListTokenSource.cs" />
<Compile Include="Misc\Args.cs" />
<Compile Include="Misc\ArrayList.cs" />
<Compile Include="Misc\MurmurHash.cs" />
<Compile Include="Misc\NullableAttribute.cs" />
<Compile Include="Misc\IIntSet.cs" />
<Compile Include="Misc\Interval.cs" />
<Compile Include="Misc\IntervalSet.cs" />
<Compile Include="Misc\NotNullAttribute.cs" />
<Compile Include="Misc\Pair.cs" />
<Compile Include="Misc\ParseCanceledException.cs" />
<Compile Include="Misc\RuleDependencyChecker.cs" />
<Compile Include="Misc\Utils.cs" />

View File

@ -128,7 +128,7 @@ namespace Antlr4.Runtime
{
if (p >= n)
{
System.Diagnostics.Debug.Assert(La(1) == IntStreamConstants.Eof);
System.Diagnostics.Debug.Assert(LA(1) == IntStreamConstants.EOF);
throw new InvalidOperationException("cannot consume EOF");
}
//System.out.println("prev p="+p+", c="+(char)data[p]);
@ -139,7 +139,7 @@ namespace Antlr4.Runtime
}
//System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')");
public virtual int La(int i)
public virtual int LA(int i)
{
if (i == 0)
{
@ -152,14 +152,14 @@ namespace Antlr4.Runtime
// e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
if ((p + i - 1) < 0)
{
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
}
// invalid; no char before first char
if ((p + i - 1) >= n)
{
//System.out.println("char LA("+i+")=EOF; p="+p);
return IntStreamConstants.Eof;
return IntStreamConstants.EOF;
}
//System.out.println("char LA("+i+")="+(char)data[p+i-1]+"; p="+p);
//System.out.println("LA("+i+"); p="+p+" n="+n+" data.length="+data.length);
@ -168,7 +168,7 @@ namespace Antlr4.Runtime
public virtual int Lt(int i)
{
return La(i);
return LA(i);
}
/// <summary>

View File

@ -15,7 +15,7 @@ namespace Antlr4.Runtime.Atn
{
public class ATN
{
public const int InvalidAltNumber = 0;
public const int INVALID_ALT_NUMBER = 0;
[NotNull]
public readonly IList<ATNState> states = new List<ATNState>();
@ -74,7 +74,7 @@ namespace Antlr4.Runtime.Atn
[NotNull]
public readonly IList<TokensStartState> modeToStartState = new List<TokensStartState>();
private readonly ConcurrentDictionary<PredictionContext, PredictionContext> contextCache = new ConcurrentDictionary<PredictionContext, PredictionContext>();
private readonly PredictionContextCache contextCache = new PredictionContextCache();
[NotNull]
public DFA[] decisionToDFA = new DFA[0];
@ -91,29 +91,6 @@ namespace Antlr4.Runtime.Atn
this.maxTokenType = maxTokenType;
}
public void ClearDFA()
{
decisionToDFA = new DFA[decisionToState.Count];
for (int i = 0; i < decisionToDFA.Length; i++)
{
decisionToDFA[i] = new DFA(decisionToState[i], i);
}
modeToDFA = new DFA[modeToStartState.Count];
for (int i_1 = 0; i_1 < modeToDFA.Length; i_1++)
{
modeToDFA[i_1] = new DFA(modeToStartState[i_1]);
}
contextCache.Clear();
LL1Table.Clear();
}
public virtual int ContextCacheSize
{
get
{
return contextCache.Count;
}
}
public virtual PredictionContext GetCachedContext(PredictionContext context)
{
@ -137,9 +114,8 @@ namespace Antlr4.Runtime.Atn
/// 's rule.
/// </summary>
[return: NotNull]
public virtual IntervalSet NextTokens(ATNState s, PredictionContext ctx)
public virtual IntervalSet NextTokens(ATNState s, RuleContext ctx)
{
Args.NotNull("ctx", ctx);
LL1Analyzer anal = new LL1Analyzer(this);
IntervalSet next = anal.Look(s, ctx);
return next;
@ -150,7 +126,7 @@ namespace Antlr4.Runtime.Atn
/// <paramref name="s"/>
/// and
/// staying in same rule.
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is in set if we reach end of
/// rule.
/// </summary>
@ -161,7 +137,7 @@ namespace Antlr4.Runtime.Atn
{
return s.nextTokenWithinRule;
}
s.nextTokenWithinRule = NextTokens(s, PredictionContext.EmptyLocal);
s.nextTokenWithinRule = NextTokens(s, null);
s.nextTokenWithinRule.SetReadonly(true);
return s.nextTokenWithinRule;
}
@ -229,7 +205,7 @@ namespace Antlr4.Runtime.Atn
/// <see cref="RuleStopState"/>
/// of the outermost context without matching any
/// symbols,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the returned set.
/// <p>If
/// <paramref name="context"/>
@ -260,25 +236,25 @@ namespace Antlr4.Runtime.Atn
RuleContext ctx = context;
ATNState s = states[stateNumber];
IntervalSet following = NextTokens(s);
if (!following.Contains(TokenConstants.Epsilon))
if (!following.Contains(TokenConstants.EPSILON))
{
return following;
}
IntervalSet expected = new IntervalSet();
expected.AddAll(following);
expected.Remove(TokenConstants.Epsilon);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.Epsilon))
expected.Remove(TokenConstants.EPSILON);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
{
ATNState invokingState = states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
following = NextTokens(rt.followState);
expected.AddAll(following);
expected.Remove(TokenConstants.Epsilon);
expected.Remove(TokenConstants.EPSILON);
ctx = ctx.Parent;
}
if (following.Contains(TokenConstants.Epsilon))
if (following.Contains(TokenConstants.EPSILON))
{
expected.Add(TokenConstants.Eof);
expected.Add(TokenConstants.EOF);
}
return expected;
}

View File

@ -12,581 +12,235 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>A tuple: (ATN state, predicted alt, syntactic, semantic context).</summary>
/// <remarks>
/// A tuple: (ATN state, predicted alt, syntactic, semantic context).
/// The syntactic context is a graph-structured stack node whose
/// path(s) to the root is the rule invocation(s)
/// chain used to arrive at the state. The semantic context is
/// the tree of semantic predicates encountered before reaching
/// an ATN state.
/// </remarks>
/** A tuple: (ATN state, predicted alt, syntactic, semantic context).
* The syntactic context is a graph-structured stack node whose
* path(s) to the root is the rule invocation(s)
* chain used to arrive at the state. The semantic context is
* the tree of semantic predicates encountered before reaching
* an ATN state.
*/
public class ATNConfig
{
/// <summary>
/// This field stores the bit mask for implementing the
/// <see cref="PrecedenceFilterSuppressed()"/>
/// property as a bit within the
/// existing
/// <see cref="altAndOuterContextDepth"/>
/// field.
/// </summary>
private const int SuppressPrecedenceFilter = unchecked((int)(0x80000000));
/**
* This field stores the bit mask for implementing the
* {@link #isPrecedenceFilterSuppressed} property as a bit within the
* existing {@link #reachesIntoOuterContext} field.
*/
private static readonly int SUPPRESS_PRECEDENCE_FILTER = 0x40000000;
/// <summary>The ATN state associated with this configuration</summary>
[NotNull]
private readonly ATNState state;
/** The ATN state associated with this configuration */
public readonly ATNState state;
/// <summary>This is a bit-field currently containing the following values.</summary>
/// <remarks>
/// This is a bit-field currently containing the following values.
/// <ul>
/// <li>0x00FFFFFF: Alternative</li>
/// <li>0x7F000000: Outer context depth</li>
/// <li>0x80000000: Suppress precedence filter</li>
/// </ul>
/// </remarks>
private int altAndOuterContextDepth;
/** What alt (or lexer rule) is predicted by this configuration */
public readonly int alt;
/// <summary>
/// The stack of invoking states leading to the rule/states associated
/// with this config.
/// </summary>
/// <remarks>
/// The stack of invoking states leading to the rule/states associated
/// with this config. We track only those contexts pushed during
/// execution of the ATN simulator.
/// </remarks>
[NotNull]
private PredictionContext context;
/** The stack of invoking states leading to the rule/states associated
* with this config. We track only those contexts pushed during
* execution of the ATN simulator.
*/
public PredictionContext context;
protected internal ATNConfig(ATNState state, int alt, PredictionContext context)
{
System.Diagnostics.Debug.Assert((alt & unchecked((int)(0xFFFFFF))) == alt);
this.state = state;
this.altAndOuterContextDepth = alt;
this.context = context;
/**
* We cannot execute predicates dependent upon local context unless
* we know for sure we are in the correct context. Because there is
* no way to do this efficiently, we simply cannot evaluate
* dependent predicates unless we are in the rule that initially
* invokes the ATN simulator.
*
* <p>
* closure() tracks the depth of how far we dip into the outer context:
* depth &gt; 0. Note that it may not be totally accurate depth since I
* don't ever decrement. TODO: make it a boolean then</p>
*
* <p>
* For memory efficiency, the {@link #isPrecedenceFilterSuppressed} method
* is also backed by this field. Since the field is publicly accessible, the
* highest bit which would not cause the value to become negative is used to
* store this field. This choice minimizes the risk that code which only
* compares this value to 0 would be affected by the new purpose of the
* flag. It also ensures the performance of the existing {@link ATNConfig}
* constructors as well as certain operations like
* {@link ATNConfigSet#add(ATNConfig, DoubleKeyMap)} method are
* <em>completely</em> unaffected by the change.</p>
*/
public int reachesIntoOuterContext;
public readonly SemanticContext semanticContext;
public ATNConfig(ATNConfig old)
{ // dup
this.state = old.state;
this.alt = old.alt;
this.context = old.context;
this.semanticContext = old.semanticContext;
this.reachesIntoOuterContext = old.reachesIntoOuterContext;
}
protected internal ATNConfig(Antlr4.Runtime.Atn.ATNConfig c, ATNState state, PredictionContext context)
public ATNConfig(ATNState state,
int alt,
PredictionContext context)
: this(state, alt, context, SemanticContext.NONE)
{
}
public ATNConfig(ATNState state,
int alt,
PredictionContext context,
SemanticContext semanticContext)
{
this.state = state;
this.altAndOuterContextDepth = c.altAndOuterContextDepth;
this.alt = alt;
this.context = context;
this.semanticContext = semanticContext;
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context)
public ATNConfig(ATNConfig c, ATNState state)
: this(c, state, c.context, c.semanticContext)
{
return Create(state, alt, context, Antlr4.Runtime.Atn.SemanticContext.None, null);
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext)
public ATNConfig(ATNConfig c, ATNState state,
SemanticContext semanticContext)
: this(c, state, c.context, semanticContext)
{
return Create(state, alt, context, semanticContext, null);
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext, LexerActionExecutor lexerActionExecutor)
public ATNConfig(ATNConfig c,
SemanticContext semanticContext)
: this(c, c.state, c.context, semanticContext)
{
if (semanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
if (lexerActionExecutor != null)
{
return new ATNConfig.ActionSemanticContextATNConfig(lexerActionExecutor, semanticContext, state, alt, context, false);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, state, alt, context);
}
}
else
{
if (lexerActionExecutor != null)
{
return new ATNConfig.ActionATNConfig(lexerActionExecutor, state, alt, context, false);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(state, alt, context);
}
}
}
/// <summary>Gets the ATN state associated with this configuration.</summary>
/// <remarks>Gets the ATN state associated with this configuration.</remarks>
public ATNState State
public ATNConfig(ATNConfig c, ATNState state,
PredictionContext context)
: this(c, state, context, c.semanticContext)
{
get
{
return state;
}
}
/// <summary>What alt (or lexer rule) is predicted by this configuration.</summary>
/// <remarks>What alt (or lexer rule) is predicted by this configuration.</remarks>
public int Alt
public ATNConfig(ATNConfig c, ATNState state,
PredictionContext context,
SemanticContext semanticContext)
{
get
{
return altAndOuterContextDepth & unchecked((int)(0x00FFFFFF));
}
}
public virtual PredictionContext Context
{
get
{
return context;
}
set
{
PredictionContext context = value;
this.state = state;
this.alt = c.alt;
this.context = context;
}
this.semanticContext = semanticContext;
this.reachesIntoOuterContext = c.reachesIntoOuterContext;
}
public bool ReachesIntoOuterContext
/**
* This method gets the value of the {@link #reachesIntoOuterContext} field
* as it existed prior to the introduction of the
* {@link #isPrecedenceFilterSuppressed} method.
*/
public int OuterContextDepth
{
get
{
return OuterContextDepth != 0;
return reachesIntoOuterContext & ~SUPPRESS_PRECEDENCE_FILTER;
}
}
/// <summary>
/// We cannot execute predicates dependent upon local context unless
/// we know for sure we are in the correct context.
/// </summary>
/// <remarks>
/// We cannot execute predicates dependent upon local context unless
/// we know for sure we are in the correct context. Because there is
/// no way to do this efficiently, we simply cannot evaluate
/// dependent predicates unless we are in the rule that initially
/// invokes the ATN simulator.
/// <p>
/// closure() tracks the depth of how far we dip into the outer context:
/// depth &gt; 0. Note that it may not be totally accurate depth since I
/// don't ever decrement. TODO: make it a boolean then</p>
/// </remarks>
public virtual int OuterContextDepth
public bool IsPrecedenceFilterSuppressed
{
get
{
return ((int)(((uint)altAndOuterContextDepth) >> 24)) & unchecked((int)(0x7F));
}
set
{
int outerContextDepth = value;
System.Diagnostics.Debug.Assert(outerContextDepth >= 0);
// saturate at 0x7F - everything but zero/positive is only used for debug information anyway
outerContextDepth = Math.Min(outerContextDepth, unchecked((int)(0x7F)));
this.altAndOuterContextDepth = (outerContextDepth << 24) | (altAndOuterContextDepth & ~unchecked((int)(0x7F000000)));
return (reachesIntoOuterContext & SUPPRESS_PRECEDENCE_FILTER) != 0;
}
}
public virtual LexerActionExecutor ActionExecutor
{
get
{
return null;
}
}
public virtual Antlr4.Runtime.Atn.SemanticContext SemanticContext
{
get
{
return Antlr4.Runtime.Atn.SemanticContext.None;
}
}
public virtual bool PassedThroughNonGreedyDecision
{
get
{
return false;
}
}
public Antlr4.Runtime.Atn.ATNConfig Clone()
{
return Transform(this.State, false);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, bool checkNonGreedy)
{
return Transform(state, this.context, this.SemanticContext, checkNonGreedy, this.ActionExecutor);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, Antlr4.Runtime.Atn.SemanticContext semanticContext, bool checkNonGreedy)
{
return Transform(state, this.context, semanticContext, checkNonGreedy, this.ActionExecutor);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext context, bool checkNonGreedy)
{
return Transform(state, context, this.SemanticContext, checkNonGreedy, this.ActionExecutor);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, LexerActionExecutor lexerActionExecutor, bool checkNonGreedy)
{
return Transform(state, context, this.SemanticContext, checkNonGreedy, lexerActionExecutor);
}
private Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext context, Antlr4.Runtime.Atn.SemanticContext semanticContext, bool checkNonGreedy, LexerActionExecutor lexerActionExecutor)
{
bool passedThroughNonGreedy = checkNonGreedy && CheckNonGreedyDecision(this, state);
if (semanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
if (lexerActionExecutor != null || passedThroughNonGreedy)
{
return new ATNConfig.ActionSemanticContextATNConfig(lexerActionExecutor, semanticContext, this, state, context, passedThroughNonGreedy);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, this, state, context);
}
}
else
{
if (lexerActionExecutor != null || passedThroughNonGreedy)
{
return new ATNConfig.ActionATNConfig(lexerActionExecutor, this, state, context, passedThroughNonGreedy);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(this, state, context);
}
}
}
private static bool CheckNonGreedyDecision(Antlr4.Runtime.Atn.ATNConfig source, ATNState target)
{
return source.PassedThroughNonGreedyDecision || target is DecisionState && ((DecisionState)target).nonGreedy;
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(int context, PredictionContextCache contextCache)
{
PredictionContext appendedContext = Context.AppendContext(context, contextCache);
Antlr4.Runtime.Atn.ATNConfig result = Transform(State, appendedContext, false);
return result;
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(PredictionContext context, PredictionContextCache contextCache)
{
PredictionContext appendedContext = Context.AppendContext(context, contextCache);
Antlr4.Runtime.Atn.ATNConfig result = Transform(State, appendedContext, false);
return result;
}
public virtual bool Contains(Antlr4.Runtime.Atn.ATNConfig subconfig)
{
if (this.state.stateNumber != subconfig.State.stateNumber || this.Alt != subconfig.Alt || !this.SemanticContext.Equals(subconfig.SemanticContext))
{
return false;
}
Stack<PredictionContext> leftWorkList = new Stack<PredictionContext>();
Stack<PredictionContext> rightWorkList = new Stack<PredictionContext>();
leftWorkList.Push(Context);
rightWorkList.Push(subconfig.Context);
while (leftWorkList.Count > 0)
{
PredictionContext left = leftWorkList.Pop();
PredictionContext right = rightWorkList.Pop();
if (left == right)
{
return true;
}
if (left.Size < right.Size)
{
return false;
}
if (right.IsEmpty)
{
return left.HasEmpty;
}
else
{
for (int i = 0; i < right.Size; i++)
{
int index = left.FindReturnState(right.GetReturnState(i));
if (index < 0)
{
// assumes invokingStates has no duplicate entries
return false;
}
leftWorkList.Push(left.GetParent(index));
rightWorkList.Push(right.GetParent(i));
}
}
}
return false;
}
public bool PrecedenceFilterSuppressed
{
get
{
return (altAndOuterContextDepth & SuppressPrecedenceFilter) != 0;
}
set
public void SetPrecedenceFilterSuppressed(bool value)
{
if (value)
{
this.altAndOuterContextDepth |= SuppressPrecedenceFilter;
}
else
{
this.altAndOuterContextDepth &= ~SuppressPrecedenceFilter;
this.reachesIntoOuterContext |= SUPPRESS_PRECEDENCE_FILTER;
}
else {
this.reachesIntoOuterContext &= ~SUPPRESS_PRECEDENCE_FILTER;
}
}
/// <summary>
/// An ATN configuration is equal to another if both have
/// the same state, they predict the same alternative, and
/// syntactic/semantic contexts are the same.
/// </summary>
/// <remarks>
/// An ATN configuration is equal to another if both have
/// the same state, they predict the same alternative, and
/// syntactic/semantic contexts are the same.
/// </remarks>
public override bool Equals(object o)
{
if (!(o is Antlr4.Runtime.Atn.ATNConfig))
/** An ATN configuration is equal to another if both have
* the same state, they predict the same alternative, and
* syntactic/semantic contexts are the same.
*/
public override bool Equals(Object o)
{
if (!(o is ATNConfig)) {
return false;
}
return this.Equals((Antlr4.Runtime.Atn.ATNConfig)o);
return this.Equals((ATNConfig)o);
}
public virtual bool Equals(Antlr4.Runtime.Atn.ATNConfig other)
public virtual bool Equals(ATNConfig other)
{
if (this == other)
{
return true;
}
else
{
if (other == null)
else if (other == null)
{
return false;
}
}
return this.State.stateNumber == other.State.stateNumber && this.Alt == other.Alt && this.ReachesIntoOuterContext == other.ReachesIntoOuterContext && this.Context.Equals(other.Context) && this.SemanticContext.Equals(other.SemanticContext) && this.PrecedenceFilterSuppressed == other.PrecedenceFilterSuppressed && this.PassedThroughNonGreedyDecision == other.PassedThroughNonGreedyDecision && EqualityComparer<LexerActionExecutor>.Default.Equals(this.ActionExecutor, other.ActionExecutor);
return this.state.stateNumber == other.state.stateNumber
&& this.alt == other.alt
&& (this.context == other.context || (this.context != null && this.context.Equals(other.context)))
&& this.semanticContext.Equals(other.semanticContext)
&& this.IsPrecedenceFilterSuppressed == other.IsPrecedenceFilterSuppressed;
}
public override int GetHashCode()
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, State.stateNumber);
hashCode = MurmurHash.Update(hashCode, Alt);
hashCode = MurmurHash.Update(hashCode, ReachesIntoOuterContext ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, Context);
hashCode = MurmurHash.Update(hashCode, SemanticContext);
hashCode = MurmurHash.Update(hashCode, PassedThroughNonGreedyDecision ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, ActionExecutor);
hashCode = MurmurHash.Finish(hashCode, 7);
hashCode = MurmurHash.Update(hashCode, state.stateNumber);
hashCode = MurmurHash.Update(hashCode, alt);
hashCode = MurmurHash.Update(hashCode, context);
hashCode = MurmurHash.Update(hashCode, semanticContext);
hashCode = MurmurHash.Finish(hashCode, 4);
return hashCode;
}
public virtual string ToDotString()
public override String ToString()
{
#if COMPACT
throw new NotImplementedException("The current platform does not provide RuntimeHelpers.GetHashCode(object).");
#else
StringBuilder builder = new StringBuilder();
builder.Append("digraph G {\n");
builder.Append("rankdir=LR;\n");
HashSet<PredictionContext> visited = new HashSet<PredictionContext>();
Stack<PredictionContext> workList = new Stack<PredictionContext>();
workList.Push(Context);
visited.Add(Context);
while (workList.Count > 0)
{
PredictionContext current = workList.Pop();
for (int i = 0; i < current.Size; i++)
{
builder.Append(" s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current));
builder.Append("->");
builder.Append("s").Append(System.Runtime.CompilerServices.RuntimeHelpers.GetHashCode(current.GetParent(i)));
builder.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"];\n");
if (visited.Add(current.GetParent(i)))
{
workList.Push(current.GetParent(i));
}
}
}
builder.Append("}\n");
return builder.ToString();
#endif
return ToString(null, true);
}
public override string ToString()
{
return ToString(null, true, false);
}
public virtual string ToString(IRecognizer recog, bool showAlt)
{
return ToString(recog, showAlt, true);
}
public virtual string ToString(IRecognizer recog, bool showAlt, bool showContext)
public String ToString(IRecognizer recog, bool showAlt)
{
StringBuilder buf = new StringBuilder();
// if ( state.ruleIndex>=0 ) {
// if ( recog!=null ) buf.append(recog.getRuleNames()[state.ruleIndex]+":");
// else buf.append(state.ruleIndex+":");
// }
string[] contexts;
if (showContext)
{
contexts = Context.ToStrings(recog, this.State.stateNumber);
}
else
{
contexts = new string[] { "?" };
}
bool first = true;
foreach (string contextDesc in contexts)
{
if (first)
{
first = false;
}
else
{
buf.Append(", ");
}
buf.Append('(');
buf.Append(State);
buf.Append(state);
if (showAlt)
{
buf.Append(",");
buf.Append(Alt);
buf.Append(alt);
}
if (Context != null)
if (context != null)
{
buf.Append(",[");
buf.Append(context.ToString());
buf.Append("]");
}
if (semanticContext != null && semanticContext != SemanticContext.NONE)
{
buf.Append(",");
buf.Append(contextDesc);
buf.Append(semanticContext);
}
if (SemanticContext != null && SemanticContext != Antlr4.Runtime.Atn.SemanticContext.None)
{
buf.Append(",");
buf.Append(SemanticContext);
}
if (ReachesIntoOuterContext)
if (OuterContextDepth > 0)
{
buf.Append(",up=").Append(OuterContextDepth);
}
buf.Append(')');
}
return buf.ToString();
}
private class SemanticContextATNConfig : ATNConfig
{
[NotNull]
private readonly Antlr4.Runtime.Atn.SemanticContext semanticContext;
public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNState state, int alt, PredictionContext context)
: base(state, alt, context)
{
this.semanticContext = semanticContext;
}
public SemanticContextATNConfig(Antlr4.Runtime.Atn.SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context)
: base(c, state, context)
{
this.semanticContext = semanticContext;
}
public override Antlr4.Runtime.Atn.SemanticContext SemanticContext
{
get
{
return semanticContext;
}
}
}
private class ActionATNConfig : ATNConfig
{
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNState state, int alt, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(state, alt, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
protected internal ActionATNConfig(LexerActionExecutor lexerActionExecutor, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(c, state, context)
{
if (c.SemanticContext != SemanticContext.None)
{
throw new NotSupportedException();
}
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public override LexerActionExecutor ActionExecutor
{
get
{
return lexerActionExecutor;
}
}
public override bool PassedThroughNonGreedyDecision
{
get
{
return passedThroughNonGreedyDecision;
}
}
}
private class ActionSemanticContextATNConfig : ATNConfig.SemanticContextATNConfig
{
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNState state, int alt, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(semanticContext, state, alt, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public ActionSemanticContextATNConfig(LexerActionExecutor lexerActionExecutor, SemanticContext semanticContext, ATNConfig c, ATNState state, PredictionContext context, bool passedThroughNonGreedyDecision)
: base(semanticContext, c, state, context)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = passedThroughNonGreedyDecision;
}
public override LexerActionExecutor ActionExecutor
{
get
{
return lexerActionExecutor;
}
}
public override bool PassedThroughNonGreedyDecision
{
get
{
return passedThroughNonGreedyDecision;
}
}
}
}
}

View File

@ -6,216 +6,245 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
using IEnumerable = System.Collections.IEnumerable;
using IEnumerator = System.Collections.IEnumerator;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public class ATNConfigSet : IEnumerable<ATNConfig>
public class ATNConfigSet
{
/// <summary>
/// This maps (state, alt) -&gt; merged
/// <see cref="ATNConfig"/>
/// . The key does not account for
/// the
/// <see cref="ATNConfig.SemanticContext()"/>
/// of the value, which is only a problem if a single
/// <c>ATNConfigSet</c>
/// contains two configs with the same state and alternative
/// but different semantic contexts. When this case arises, the first config
/// added to this map stays, and the remaining configs are placed in
/// <see cref="unmerged"/>
/// .
/// <p/>
/// This map is only used for optimizing the process of adding configs to the set,
/// and is
/// <see langword="null"/>
/// for read-only sets stored in the DFA.
/// </summary>
private readonly Dictionary<long, ATNConfig> mergedConfigs;
/// <summary>
/// This is an "overflow" list holding configs which cannot be merged with one
/// of the configs in
/// <see cref="mergedConfigs"/>
/// but have a colliding key. This
/// occurs when two configs in the set have the same state and alternative but
/// different semantic contexts.
/// <p/>
/// This list is only used for optimizing the process of adding configs to the set,
/// and is
/// <see langword="null"/>
/// for read-only sets stored in the DFA.
/// </summary>
private readonly List<ATNConfig> unmerged;
/// <summary>This is a list of all configs in this set.</summary>
/// <remarks>This is a list of all configs in this set.</remarks>
private readonly List<ATNConfig> configs;
/** Indicates that the set of configurations is read-only. Do not
* allow any code to manipulate the set; DFA states will point at
* the sets and they must not change. This does not protect the other
* fields; in particular, conflictingAlts is set after
* we've made this readonly.
*/
protected bool readOnly = false;
private int uniqueAlt;
/**
* All configs but hashed by (s, i, _, pi) not including context. Wiped out
* when we go readonly as this set becomes a DFA state.
*/
public ConfigHashSet configLookup;
private ConflictInfo conflictInfo;
/** Track the elements as they are added to the set; supports get(i) */
public ArrayList<ATNConfig> configs = new ArrayList<ATNConfig>(7);
private bool hasSemanticContext;
// TODO: these fields make me pretty uncomfortable but nice to pack up info together, saves recomputation
// TODO: can we track conflicts as they are added to save scanning configs later?
public int uniqueAlt;
/** Currently this is only used when we detect SLL conflict; this does
* not necessarily represent the ambiguous alternatives. In fact,
* I should also point out that this seems to include predicated alternatives
* that have predicates that evaluate to false. Computed in computeTargetState().
*/
public BitSet conflictingAlts;
private bool dipsIntoOuterContext;
// Used in parser and lexer. In lexer, it indicates we hit a pred
// while computing a closure operation. Don't make a DFA state from this.
public bool hasSemanticContext;
public bool dipsIntoOuterContext;
/// <summary>
/// When
/// <see langword="true"/>
/// , this config set represents configurations where the entire
/// outer context has been consumed by the ATN interpreter. This prevents the
/// <see cref="ParserATNSimulator.Closure(ATNConfigSet, ATNConfigSet, bool, bool, PredictionContextCache, bool)"/>
/// from pursuing the global FOLLOW when a
/// rule stop state is reached with an empty prediction context.
/// <p/>
/// Note:
/// <c>outermostConfigSet</c>
/// and
/// <see cref="dipsIntoOuterContext"/>
/// should never
/// be true at the same time.
/// </summary>
private bool outermostConfigSet;
/** Indicates that this configuration set is part of a full context
* LL prediction. It will be used to determine how to merge $. With SLL
* it's a wildcard whereas it is not for LL context merge.
*/
public readonly bool fullCtx;
private int cachedHashCode = -1;
public ATNConfigSet(bool fullCtx)
{
configLookup = new ConfigHashSet();
this.fullCtx = fullCtx;
}
public ATNConfigSet()
: this(true)
{
// Used in parser and lexer. In lexer, it indicates we hit a pred
// while computing a closure operation. Don't make a DFA state from this.
this.mergedConfigs = new Dictionary<long, ATNConfig>();
this.unmerged = new List<ATNConfig>();
this.configs = new List<ATNConfig>();
this.uniqueAlt = ATN.InvalidAltNumber;
}
protected internal ATNConfigSet(Antlr4.Runtime.Atn.ATNConfigSet set, bool @readonly)
public ATNConfigSet(ATNConfigSet old)
: this(old.fullCtx)
{
if (@readonly)
{
this.mergedConfigs = null;
this.unmerged = null;
}
else
{
if (!set.IsReadOnly)
{
this.mergedConfigs = new Dictionary<long, ATNConfig>(set.mergedConfigs);
this.unmerged = new List<ATNConfig>(set.unmerged);
}
else
{
this.mergedConfigs = new Dictionary<long, ATNConfig>(set.configs.Count);
this.unmerged = new List<ATNConfig>();
}
}
this.configs = new List<ATNConfig>(set.configs);
this.dipsIntoOuterContext = set.dipsIntoOuterContext;
this.hasSemanticContext = set.hasSemanticContext;
this.outermostConfigSet = set.outermostConfigSet;
if (@readonly || !set.IsReadOnly)
{
this.uniqueAlt = set.uniqueAlt;
this.conflictInfo = set.conflictInfo;
}
AddAll(old.configs);
this.uniqueAlt = old.uniqueAlt;
this.conflictingAlts = old.conflictingAlts;
this.hasSemanticContext = old.hasSemanticContext;
this.dipsIntoOuterContext = old.dipsIntoOuterContext;
}
/// <summary>
/// Get the set of all alternatives represented by configurations in this
/// set.
/// </summary>
/// <remarks>
/// Get the set of all alternatives represented by configurations in this
/// set.
/// </remarks>
[NotNull]
public virtual BitSet RepresentedAlternatives
public bool Add(ATNConfig config)
{
return Add(config, null);
}
/**
* Adding a new config means merging contexts with existing configs for
* {@code (s, i, pi, _)}, where {@code s} is the
* {@link ATNConfig#state}, {@code i} is the {@link ATNConfig#alt}, and
* {@code pi} is the {@link ATNConfig#semanticContext}. We use
* {@code (s,i,pi)} as key.
*
* <p>This method updates {@link #dipsIntoOuterContext} and
* {@link #hasSemanticContext} when necessary.</p>
*/
public bool Add(ATNConfig config, MergeCache mergeCache)
{
if (readOnly)
throw new Exception("This set is readonly");
if (config.semanticContext != SemanticContext.NONE)
{
hasSemanticContext = true;
}
if (config.OuterContextDepth > 0)
{
dipsIntoOuterContext = true;
}
ATNConfig existing = configLookup.GetOrAdd(config);
if (existing == config)
{ // we added this new one
cachedHashCode = -1;
configs.Add(config); // track order here
return true;
}
// a previous (s,i,pi,_), merge with it and save result
bool rootIsWildcard = !fullCtx;
PredictionContext merged = PredictionContext.Merge(existing.context, config.context, rootIsWildcard, mergeCache);
// no need to check for existing.context, config.context in cache
// since only way to create new graphs is "call rule" and here. We
// cache at both places.
existing.reachesIntoOuterContext = Math.Max(existing.reachesIntoOuterContext, config.reachesIntoOuterContext);
// make sure to preserve the precedence filter suppression during the merge
if (config.IsPrecedenceFilterSuppressed)
{
existing.SetPrecedenceFilterSuppressed(true);
}
existing.context = merged; // replace context; no need to alt mapping
return true;
}
/** Return a List holding list of configs */
public List<ATNConfig> Elements
{
get
{
// if (!readonly && set.isReadOnly()) -> addAll is called from clone()
if (conflictInfo != null)
{
return (BitSet)conflictInfo.ConflictedAlts.Clone();
}
BitSet alts = new BitSet();
foreach (ATNConfig config in this)
{
alts.Set(config.Alt);
}
return alts;
return configs;
}
}
public bool IsReadOnly
{
get
{
return mergedConfigs == null;
}
}
public virtual bool IsOutermostConfigSet
{
get
{
return outermostConfigSet;
}
set
{
bool outermostConfigSet = value;
if (this.outermostConfigSet && !outermostConfigSet)
{
throw new InvalidOperationException();
}
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
this.outermostConfigSet = outermostConfigSet;
}
}
public virtual HashSet<ATNState> States
{
get
public HashSet<ATNState> GetStates()
{
HashSet<ATNState> states = new HashSet<ATNState>();
foreach (ATNConfig c in this.configs)
foreach (ATNConfig c in configs)
{
states.Add(c.State);
states.Add(c.state);
}
return states;
}
/**
* Gets the complete set of represented alternatives for the configuration
* set.
*
* @return the set of represented alternatives in this configuration set
*
* @since 4.3
*/
public BitSet GetAlts()
{
BitSet alts = new BitSet();
foreach (ATNConfig config in configs)
{
alts.Set(config.alt);
}
return alts;
}
public virtual void OptimizeConfigs(ATNSimulator interpreter)
public List<SemanticContext> GetPredicates()
{
if (configs.Count == 0)
List<SemanticContext> preds = new List<SemanticContext>();
foreach (ATNConfig c in configs)
{
if (c.semanticContext != SemanticContext.NONE)
{
preds.Add(c.semanticContext);
}
}
return preds;
}
public ATNConfig Get(int i) { return configs[i]; }
public void OptimizeConfigs(ATNSimulator interpreter)
{
if (readOnly)
throw new Exception("This set is readonly");
if (configLookup.Count == 0)
return;
}
for (int i = 0; i < configs.Count; i++)
foreach (ATNConfig config in configs)
{
ATNConfig config = configs[i];
config.Context = interpreter.atn.GetCachedContext(config.Context);
// int before = PredictionContext.getAllContextNodes(config.context).size();
config.context = interpreter.getCachedContext(config.context);
// int after = PredictionContext.getAllContextNodes(config.context).size();
// System.out.println("configs "+before+"->"+after);
}
}
public virtual Antlr4.Runtime.Atn.ATNConfigSet Clone(bool @readonly)
public bool AddAll(ICollection<ATNConfig> coll)
{
Antlr4.Runtime.Atn.ATNConfigSet copy = new Antlr4.Runtime.Atn.ATNConfigSet(this, @readonly);
if (!@readonly && this.IsReadOnly)
{
copy.AddAll(configs);
}
return copy;
foreach (ATNConfig c in coll) Add(c);
return false;
}
public virtual int Count
public override bool Equals(Object o)
{
if (o == this)
{
return true;
}
else if (!(o is ATNConfigSet))
{
return false;
}
// System.out.print("equals " + this + ", " + o+" = ");
ATNConfigSet other = (ATNConfigSet)o;
bool same = configs != null &&
configs.Equals(other.configs) && // includes stack context
this.fullCtx == other.fullCtx &&
this.uniqueAlt == other.uniqueAlt &&
this.conflictingAlts == other.conflictingAlts &&
this.hasSemanticContext == other.hasSemanticContext &&
this.dipsIntoOuterContext == other.dipsIntoOuterContext;
// System.out.println(same);
return same;
}
public override int GetHashCode()
{
if (IsReadOnly)
{
if (cachedHashCode == -1)
{
cachedHashCode = configs.GetHashCode();
}
return cachedHashCode;
}
return configs.GetHashCode();
}
public int Count
{
get
{
@ -223,434 +252,172 @@ namespace Antlr4.Runtime.Atn
}
}
public virtual bool IsEmpty()
public bool Empty
{
get
{
return configs.Count == 0;
}
public virtual bool Contains(object o)
{
if (!(o is ATNConfig))
{
return false;
}
ATNConfig config = (ATNConfig)o;
long configKey = GetKey(config);
ATNConfig mergedConfig;
if (mergedConfigs.TryGetValue(configKey, out mergedConfig) && CanMerge(config, configKey, mergedConfig))
{
return mergedConfig.Contains(config);
}
foreach (ATNConfig c in unmerged)
{
if (c.Contains(config))
{
return true;
}
}
return false;
}
public virtual IEnumerator<ATNConfig> GetEnumerator()
public bool Contains(Object o)
{
return configs.GetEnumerator();
if (configLookup == null)
{
throw new Exception("This method is not implemented for readonly sets.");
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
return configLookup.ContainsKey((ATNConfig)o);
}
public virtual object[] ToArray()
{
return configs.ToArray();
}
public virtual bool Add(ATNConfig e)
public void Clear()
{
return Add(e, null);
}
public virtual bool Add(ATNConfig e, PredictionContextCache contextCache)
{
EnsureWritable();
System.Diagnostics.Debug.Assert(!outermostConfigSet || !e.ReachesIntoOuterContext);
if (contextCache == null)
{
contextCache = PredictionContextCache.Uncached;
}
bool addKey;
long key = GetKey(e);
ATNConfig mergedConfig;
addKey = !mergedConfigs.TryGetValue(key, out mergedConfig);
if (mergedConfig != null && CanMerge(e, key, mergedConfig))
{
mergedConfig.OuterContextDepth = Math.Max(mergedConfig.OuterContextDepth, e.OuterContextDepth);
if (e.PrecedenceFilterSuppressed)
{
mergedConfig.PrecedenceFilterSuppressed = true;
}
PredictionContext joined = PredictionContext.Join(mergedConfig.Context, e.Context, contextCache);
UpdatePropertiesForMergedConfig(e);
if (mergedConfig.Context == joined)
{
return false;
}
mergedConfig.Context = joined;
return true;
}
for (int i = 0; i < unmerged.Count; i++)
{
ATNConfig unmergedConfig = unmerged[i];
if (CanMerge(e, key, unmergedConfig))
{
unmergedConfig.OuterContextDepth = Math.Max(unmergedConfig.OuterContextDepth, e.OuterContextDepth);
if (e.PrecedenceFilterSuppressed)
{
unmergedConfig.PrecedenceFilterSuppressed = true;
}
PredictionContext joined = PredictionContext.Join(unmergedConfig.Context, e.Context, contextCache);
UpdatePropertiesForMergedConfig(e);
if (unmergedConfig.Context == joined)
{
return false;
}
unmergedConfig.Context = joined;
if (addKey)
{
mergedConfigs[key] = unmergedConfig;
unmerged.RemoveAt(i);
}
return true;
}
}
configs.Add(e);
if (addKey)
{
mergedConfigs[key] = e;
}
else
{
unmerged.Add(e);
}
UpdatePropertiesForAddedConfig(e);
return true;
}
private void UpdatePropertiesForMergedConfig(ATNConfig config)
{
// merged configs can't change the alt or semantic context
dipsIntoOuterContext |= config.ReachesIntoOuterContext;
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
private void UpdatePropertiesForAddedConfig(ATNConfig config)
{
if (configs.Count == 1)
{
uniqueAlt = config.Alt;
}
else
{
if (uniqueAlt != config.Alt)
{
uniqueAlt = ATN.InvalidAltNumber;
}
}
hasSemanticContext |= !SemanticContext.None.Equals(config.SemanticContext);
dipsIntoOuterContext |= config.ReachesIntoOuterContext;
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
protected internal virtual bool CanMerge(ATNConfig left, long leftKey, ATNConfig right)
{
if (left.State.stateNumber != right.State.stateNumber)
{
return false;
}
if (leftKey != GetKey(right))
{
return false;
}
return left.SemanticContext.Equals(right.SemanticContext);
}
protected internal virtual long GetKey(ATNConfig e)
{
long key = e.State.stateNumber;
key = (key << 12) | (e.Alt & 0xFFFL);
return key;
}
public virtual bool Remove(object o)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public virtual bool ContainsAll(IEnumerable<ATNConfig> c)
{
foreach (ATNConfig o in c)
{
if (!Contains(o))
{
return false;
}
}
return true;
}
public virtual bool AddAll(IEnumerable<ATNConfig> c)
{
return AddAll(c, null);
}
public virtual bool AddAll(IEnumerable<ATNConfig> c, PredictionContextCache contextCache)
{
EnsureWritable();
bool changed = false;
foreach (ATNConfig group in c)
{
changed |= Add(group, contextCache);
}
return changed;
}
public virtual bool RetainAll<_T0>(ICollection<_T0> c)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public virtual bool RemoveAll<_T0>(ICollection<_T0> c)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public virtual void Clear()
{
EnsureWritable();
mergedConfigs.Clear();
unmerged.Clear();
if (readOnly)
throw new Exception("This set is readonly");
configs.Clear();
dipsIntoOuterContext = false;
hasSemanticContext = false;
uniqueAlt = ATN.InvalidAltNumber;
conflictInfo = null;
cachedHashCode = -1;
configLookup.Clear();
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (!(obj is Antlr4.Runtime.Atn.ATNConfigSet))
{
return false;
}
Antlr4.Runtime.Atn.ATNConfigSet other = (Antlr4.Runtime.Atn.ATNConfigSet)obj;
return this.outermostConfigSet == other.outermostConfigSet && Utils.Equals(conflictInfo, other.conflictInfo) && configs.SequenceEqual(other.configs);
}
public override int GetHashCode()
{
if (IsReadOnly && cachedHashCode != -1)
{
return cachedHashCode;
}
int hashCode = 1;
hashCode = 5 * hashCode ^ (outermostConfigSet ? 1 : 0);
hashCode = 5 * hashCode ^ SequenceEqualityComparer<ATNConfig>.Default.GetHashCode(configs);
if (IsReadOnly)
{
cachedHashCode = hashCode;
}
return hashCode;
}
public override string ToString()
{
return ToString(false);
}
public virtual string ToString(bool showContext)
{
StringBuilder buf = new StringBuilder();
List<ATNConfig> sortedConfigs = new List<ATNConfig>(configs);
sortedConfigs.Sort(new _IComparer_475());
buf.Append("[");
for (int i = 0; i < sortedConfigs.Count; i++)
{
if (i > 0)
{
buf.Append(", ");
}
buf.Append(sortedConfigs[i].ToString(null, true, showContext));
}
buf.Append("]");
if (hasSemanticContext)
{
buf.Append(",hasSemanticContext=").Append(hasSemanticContext);
}
if (uniqueAlt != ATN.InvalidAltNumber)
{
buf.Append(",uniqueAlt=").Append(uniqueAlt);
}
if (conflictInfo != null)
{
buf.Append(",conflictingAlts=").Append(conflictInfo.ConflictedAlts);
if (!conflictInfo.IsExact)
{
buf.Append("*");
}
}
if (dipsIntoOuterContext)
{
buf.Append(",dipsIntoOuterContext");
}
return buf.ToString();
}
private sealed class _IComparer_475 : IComparer<ATNConfig>
{
public _IComparer_475()
{
}
public int Compare(ATNConfig o1, ATNConfig o2)
{
if (o1.Alt != o2.Alt)
{
return o1.Alt - o2.Alt;
}
else
{
if (o1.State.stateNumber != o2.State.stateNumber)
{
return o1.State.stateNumber - o2.State.stateNumber;
}
else
{
return string.CompareOrdinal(o1.SemanticContext.ToString(), o2.SemanticContext.ToString());
}
}
}
}
public virtual int UniqueAlt
public bool IsReadOnly
{
get
{
return uniqueAlt;
}
}
public virtual bool HasSemanticContext
{
get
{
return hasSemanticContext;
}
}
public virtual void ClearExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = false;
}
public virtual void MarkExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = true;
}
public virtual ConflictInfo ConflictInformation
{
get
{
return conflictInfo;
return readOnly;
}
set
{
ConflictInfo conflictInfo = value;
EnsureWritable();
this.conflictInfo = conflictInfo;
this.readOnly = value;
configLookup = null; // can't mod, no need for lookup cache
}
}
public virtual BitSet ConflictingAlts
public override String ToString()
{
get
StringBuilder buf = new StringBuilder();
buf.Append('[');
List<ATNConfig> cfgs = Elements;
if (cfgs.Count > 0)
{
if (conflictInfo == null)
foreach (ATNConfig c in cfgs)
{
buf.Append(c.ToString());
buf.Append(", ");
}
buf.Length = buf.Length - 2;
}
buf.Append(']');
if (hasSemanticContext)
buf.Append(",hasSemanticContext=")
.Append(hasSemanticContext);
if (uniqueAlt != ATN.INVALID_ALT_NUMBER)
buf.Append(",uniqueAlt=")
.Append(uniqueAlt);
if (conflictingAlts != null)
buf.Append(",conflictingAlts=")
.Append(conflictingAlts);
if (dipsIntoOuterContext)
buf.Append(",dipsIntoOuterContext");
return buf.ToString();
}
}
public class OrderedATNConfigSet : ATNConfigSet
{
public OrderedATNConfigSet()
{
this.configLookup = new LexerConfigHashSet();
}
public class LexerConfigHashSet : ConfigHashSet
{
public LexerConfigHashSet()
: base(new ObjectEqualityComparator())
{
return null;
}
return conflictInfo.ConflictedAlts;
}
}
public virtual bool IsExactConflict
public class ObjectEqualityComparator : IEqualityComparer<ATNConfig>
{
get
public int GetHashCode(ATNConfig o)
{
if (conflictInfo == null)
{
return false;
if (o == null)
return 0;
else
return o.GetHashCode();
}
return conflictInfo.IsExact;
public bool Equals(ATNConfig a, ATNConfig b)
{
if (a == b) return true;
if (a == null || b == null) return false;
return a.Equals(b);
}
}
public virtual bool DipsIntoOuterContext
/**
* The reason that we need this is because we don't want the hash map to use
* the standard hash code and equals. We need all configurations with the same
* {@code (s,i,_,semctx)} to be equal. Unfortunately, this key effectively doubles
* the number of objects associated with ATNConfigs. The other solution is to
* use a hash table that lets us specify the equals/hashcode operation.
*/
public class ConfigHashSet : Dictionary<ATNConfig, ATNConfig>
{
get
public ConfigHashSet(IEqualityComparer<ATNConfig> comparer)
: base(comparer)
{
return dipsIntoOuterContext;
}
}
public virtual ATNConfig this[int index]
public ConfigHashSet()
: base(new ConfigEqualityComparator())
{
get
{
return configs[index];
}
}
public virtual void Remove(int index)
public ATNConfig GetOrAdd(ATNConfig config)
{
EnsureWritable();
ATNConfig config = configs[index];
configs.Remove(config);
long key = GetKey(config);
ATNConfig existing;
if (mergedConfigs.TryGetValue(key, out existing) && existing == config)
{
mergedConfigs.Remove(key);
}
if (this.TryGetValue(config, out existing))
return existing;
else
{
for (int i = 0; i < unmerged.Count; i++)
{
if (unmerged[i] == config)
{
unmerged.RemoveAt(i);
return;
}
}
this.Put(config, config);
return config;
}
}
protected internal void EnsureWritable()
}
public class ConfigEqualityComparator : IEqualityComparer<ATNConfig>
{
if (IsReadOnly)
public int GetHashCode(ATNConfig o)
{
throw new InvalidOperationException("This ATNConfigSet is read only.");
}
int hashCode = 7;
hashCode = 31 * hashCode + o.state.stateNumber;
hashCode = 31 * hashCode + o.alt;
hashCode = 31 * hashCode + o.semanticContext.GetHashCode();
return hashCode;
}
public bool Equals(ATNConfig a, ATNConfig b)
{
if (a == b) return true;
if (a == null || b == null) return false;
return a.state.stateNumber == b.state.stateNumber
&& a.alt == b.alt
&& a.semanticContext.Equals(b.semanticContext);
}
}
}

View File

@ -441,7 +441,7 @@ namespace Antlr4.Runtime.Atn
if (atn.grammarType == ATNType.Lexer) {
int tokenType = ReadInt ();
if (tokenType == unchecked((int)(0xFFFF))) {
tokenType = TokenConstants.Eof;
tokenType = TokenConstants.EOF;
}
atn.ruleToTokenType [i_5] = tokenType;
}
@ -585,7 +585,7 @@ namespace Antlr4.Runtime.Atn
{
if (maybeLoopEndState.epsilonOnlyTransitions && maybeLoopEndState.Transition(0).target is RuleStopState)
{
((StarLoopEntryState)state).precedenceRuleDecision = true;
((StarLoopEntryState)state).isPrecedenceDecision = true;
}
}
}
@ -683,7 +683,7 @@ namespace Antlr4.Runtime.Atn
{
RuleStartState startState = atn.ruleToStartState[i];
ATNState middleState = startState;
while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.Epsilon)
while (middleState.OnlyHasEpsilonTransitions && middleState.NumberOfOptimizedTransitions == 1 && middleState.GetOptimizedTransition(0).TransitionType == TransitionType.EPSILON)
{
middleState = middleState.GetOptimizedTransition(0).target;
}
@ -699,16 +699,16 @@ namespace Antlr4.Runtime.Atn
}
switch (matchTransition.TransitionType)
{
case TransitionType.Atom:
case TransitionType.Range:
case TransitionType.Set:
case TransitionType.ATOM:
case TransitionType.RANGE:
case TransitionType.SET:
{
ruleToInlineTransition[i] = matchTransition;
break;
}
case TransitionType.NotSet:
case TransitionType.Wildcard:
case TransitionType.NOT_SET:
case TransitionType.WILDCARD:
{
// not implemented yet
continue;
@ -765,19 +765,19 @@ namespace Antlr4.Runtime.Atn
optimizedTransitions.Add(new EpsilonTransition(intermediateState));
switch (effective.TransitionType)
{
case TransitionType.Atom:
case TransitionType.ATOM:
{
intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective).token));
break;
}
case TransitionType.Range:
case TransitionType.RANGE:
{
intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective).from, ((RangeTransition)effective).to));
break;
}
case TransitionType.Set:
case TransitionType.SET:
{
intermediateState.AddTransition(new SetTransition(target, effective.Label));
break;
@ -821,7 +821,7 @@ namespace Antlr4.Runtime.Atn
{
Transition transition = state.GetOptimizedTransition(i);
ATNState intermediate = transition.target;
if (transition.TransitionType != TransitionType.Epsilon || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
if (transition.TransitionType != TransitionType.EPSILON || ((EpsilonTransition)transition).OutermostPrecedenceReturn != -1 || intermediate.StateType != StateType.Basic || !intermediate.OnlyHasEpsilonTransitions)
{
if (optimizedTransitions != null)
{
@ -831,7 +831,7 @@ namespace Antlr4.Runtime.Atn
}
for (int j = 0; j < intermediate.NumberOfOptimizedTransitions; j++)
{
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.Epsilon || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
if (intermediate.GetOptimizedTransition(j).TransitionType != TransitionType.EPSILON || ((EpsilonTransition)intermediate.GetOptimizedTransition(j)).OutermostPrecedenceReturn != -1)
{
if (optimizedTransitions != null)
{
@ -1044,7 +1044,7 @@ nextTransition_continue: ;
IList<Transition> transitions = optimizedPath ? state.optimizedTransitions : state.transitions;
foreach (Transition t in transitions)
{
if (t.TransitionType != TransitionType.Epsilon)
if (t.TransitionType != TransitionType.EPSILON)
{
return false;
}
@ -1087,16 +1087,16 @@ nextTransition_continue: ;
ATNState target = atn.states[trg];
switch (type)
{
case TransitionType.Epsilon:
case TransitionType.EPSILON:
{
return new EpsilonTransition(target);
}
case TransitionType.Range:
case TransitionType.RANGE:
{
if (arg3 != 0)
{
return new RangeTransition(target, TokenConstants.Eof, arg2);
return new RangeTransition(target, TokenConstants.EOF, arg2);
}
else
{
@ -1104,28 +1104,28 @@ nextTransition_continue: ;
}
}
case TransitionType.Rule:
case TransitionType.RULE:
{
RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3, target);
return rt;
}
case TransitionType.Predicate:
case TransitionType.PREDICATE:
{
PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
return pt;
}
case TransitionType.Precedence:
case TransitionType.PRECEDENCE:
{
return new PrecedencePredicateTransition(target, arg1);
}
case TransitionType.Atom:
case TransitionType.ATOM:
{
if (arg3 != 0)
{
return new AtomTransition(target, TokenConstants.Eof);
return new AtomTransition(target, TokenConstants.EOF);
}
else
{
@ -1133,23 +1133,23 @@ nextTransition_continue: ;
}
}
case TransitionType.Action:
case TransitionType.ACTION:
{
ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
return a;
}
case TransitionType.Set:
case TransitionType.SET:
{
return new SetTransition(target, sets[arg1]);
}
case TransitionType.NotSet:
case TransitionType.NOT_SET:
{
return new NotSetTransition(target, sets[arg1]);
}
case TransitionType.Wildcard:
case TransitionType.WILDCARD:
{
return new WildcardTransition(target);
}

View File

@ -13,72 +13,86 @@ namespace Antlr4.Runtime.Atn
{
public abstract class ATNSimulator
{
[Obsolete(@"Use ATNDeserializer.SerializedVersion instead.")]
public static readonly int SerializedVersion = ATNDeserializer.SerializedVersion;
/// <summary>This is the current serialized UUID.</summary>
/// <remarks>This is the current serialized UUID.</remarks>
[Obsolete(@"Use ATNDeserializer.CheckCondition(bool) instead.")]
public static readonly Guid SerializedUuid = ATNDeserializer.SerializedUuid;
public const char RuleVariantDelimiter = '$';
/** Must distinguish between missing edge and edge we know leads nowhere */
public const string RuleLfVariantMarker = "$lf$";
public static readonly DFAState ERROR = InitERROR();
public const string RuleNolfVariantMarker = "$nolf$";
/// <summary>Must distinguish between missing edge and edge we know leads nowhere</summary>
[NotNull]
public static readonly DFAState Error =
new DFAState(new EmptyEdgeMap<DFAState>(0, -1), new EmptyEdgeMap<DFAState>(0, -1), new ATNConfigSet())
static DFAState InitERROR()
{
stateNumber = int.MaxValue
};
DFAState state = new DFAState(new ATNConfigSet());
state.stateNumber = Int32.MaxValue;
return state;
}
[NotNull]
public readonly ATN atn;
public ATNSimulator(ATN atn)
/** The context cache maps all PredictionContext objects that are equals()
* to a single cached copy. This cache is shared across all contexts
* in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet
* to use only cached nodes/graphs in addDFAState(). We don't want to
* fill this during closure() since there are lots of contexts that
* pop up but are not used ever again. It also greatly slows down closure().
*
* <p>This cache makes a huge difference in memory and a little bit in speed.
* For the Java grammar on java.*, it dropped the memory requirements
* at the end from 25M to 16M. We don't store any of the full context
* graphs in the DFA because they are limited to local context only,
* but apparently there's a lot of repetition there as well. We optimize
* the config contexts before storing the config set in the DFA states
* by literally rebuilding them with cached subgraphs only.</p>
*
* <p>I tried a cache for use during closure operations, that was
* whacked after each adaptivePredict(). It cost a little bit
* more time I think and doesn't save on the overall footprint
* so it's not worth the complexity.</p>
*/
protected readonly PredictionContextCache sharedContextCache;
public ATNSimulator(ATN atn, PredictionContextCache sharedContextCache)
{
this.atn = atn;
this.sharedContextCache = sharedContextCache;
}
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>
/**
* 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.
*
* @throws UnsupportedOperationException if the current instance does not
* support clearing the DFA.
*
* @since 4.3
*/
public virtual void ClearDFA()
{
atn.ClearDFA();
throw new Exception("This ATN simulator does not support clearing the DFA.");
}
[Obsolete(@"Use ATNDeserializer.Deserialize(char[]) instead.")]
public static ATN Deserialize(char[] data)
public PredictionContextCache getSharedContextCache()
{
return new ATNDeserializer().Deserialize(data);
return sharedContextCache;
}
[return: NotNull]
[Obsolete(@"Use ATNDeserializer.EdgeFactory(ATN, TransitionType, int, int, int, int, int, System.Collections.Generic.IList{E}) instead.")]
public static Transition EdgeFactory(ATN atn, TransitionType type, int src, int trg, int arg1, int arg2, int arg3, IList<IntervalSet> sets)
public PredictionContext getCachedContext(PredictionContext context)
{
return new ATNDeserializer().EdgeFactory(atn, type, src, trg, arg1, arg2, arg3, sets);
if (sharedContextCache == null) return context;
lock (sharedContextCache)
{
PredictionContext.IdentityHashMap visited =
new PredictionContext.IdentityHashMap();
return PredictionContext.GetCachedContext(context,
sharedContextCache,
visited);
}
}
[Obsolete(@"Use ATNDeserializer.StateFactory(StateType, int) instead.")]
public static ATNState StateFactory(StateType type, int ruleIndex)
{
return new ATNDeserializer().StateFactory(type, ruleIndex);
}
}
}

View File

@ -5,68 +5,11 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// The following images show the relation of states and
/// <see cref="transitions"/>
/// for various grammar constructs.
/// <ul>
/// <li>Solid edges marked with an &#0949; indicate a required
/// <see cref="EpsilonTransition"/>
/// .</li>
/// <li>Dashed edges indicate locations where any transition derived from
/// <see cref="Transition"/>
/// might appear.</li>
/// <li>Dashed nodes are place holders for either a sequence of linked
/// <see cref="BasicState"/>
/// states or the inclusion of a block representing a nested
/// construct in one of the forms below.</li>
/// <li>Nodes showing multiple outgoing alternatives with a
/// <c>...</c>
/// support
/// any number of alternatives (one or more). Nodes without the
/// <c>...</c>
/// only
/// support the exact number of alternatives shown in the diagram.</li>
/// </ul>
/// <h2>Basic Blocks</h2>
/// <h3>Rule</h3>
/// <embed src="images/Rule.svg" type="image/svg+xml"/>
/// <h3>Block of 1 or more alternatives</h3>
/// <embed src="images/Block.svg" type="image/svg+xml"/>
/// <h2>Greedy Loops</h2>
/// <h3>Greedy Closure:
/// <c>(...)*</c>
/// </h3>
/// <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Positive Closure:
/// <c>(...)+</c>
/// </h3>
/// <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Optional:
/// <c>(...)?</c>
/// </h3>
/// <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
/// <h2>Non-Greedy Loops</h2>
/// <h3>Non-Greedy Closure:
/// <c>(...)*?</c>
/// </h3>
/// <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Positive Closure:
/// <c>(...)+?</c>
/// </h3>
/// <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Optional:
/// <c>(...)??</c>
/// </h3>
/// <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
/// </summary>
public abstract class ATNState
{
public const int InitialNumTransitions = 4;
@ -75,7 +18,6 @@ namespace Antlr4.Runtime.Atn
public const int InvalidStateNumber = -1;
/// <summary>Which ATN are we in?</summary>
public ATN atn = null;
public int stateNumber = InvalidStateNumber;
@ -84,26 +26,12 @@ namespace Antlr4.Runtime.Atn
public bool epsilonOnlyTransitions = false;
/// <summary>Track the transitions emanating from this ATN state.</summary>
/// <remarks>Track the transitions emanating from this ATN state.</remarks>
protected internal readonly List<Antlr4.Runtime.Atn.Transition> transitions = new List<Antlr4.Runtime.Atn.Transition>(InitialNumTransitions);
protected internal readonly List<Transition> transitions = new List<Transition>(InitialNumTransitions);
protected internal List<Antlr4.Runtime.Atn.Transition> optimizedTransitions;
protected internal List<Transition> optimizedTransitions;
/// <summary>Used to cache lookahead during parsing, not used during construction</summary>
public IntervalSet nextTokenWithinRule;
/// <summary>
/// For all states except
/// <see cref="RuleStopState"/>
/// , this returns the state
/// number. Returns -1 for stop states.
/// </summary>
/// <returns>
/// -1 for
/// <see cref="RuleStopState"/>
/// , otherwise the state number
/// </returns>
public virtual int NonStopStateNumber
{
get
@ -119,12 +47,8 @@ namespace Antlr4.Runtime.Atn
public override bool Equals(object o)
{
// are these states same object?
if (o is ATNState)
{
return stateNumber == ((ATNState)o).stateNumber;
}
return false;
return o==this ||
(o is ATNState && stateNumber == ((ATNState)o).stateNumber);
}
public virtual bool IsNonGreedyExitState

View File

@ -33,7 +33,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Action;
return Antlr4.Runtime.Atn.TransitionType.ACTION;
}
}

View File

@ -31,7 +31,7 @@ namespace Antlr4.Runtime.Atn
/// 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"/>
/// <see cref="PredictionMode.SLL"/>
/// , which in turn means
/// they cannot use the two-stage parsing strategy to improve parsing performance
/// for that input.</p>

View File

@ -3,38 +3,56 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using System.Text;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public class ArrayPredictionContext : PredictionContext
{
[NotNull]
/** Parent can be null only if full ctx mode and we make an array
* from {@link #EMPTY} and non-empty. We merge {@link #EMPTY} by using null parent and
* returnState == {@link #EMPTY_RETURN_STATE}.
*/
public readonly PredictionContext[] parents;
[NotNull]
/** Sorted for merge, no duplicates; if present,
* {@link #EMPTY_RETURN_STATE} is always last.
*/
public readonly int[] returnStates;
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates)
public ArrayPredictionContext(SingletonPredictionContext a)
: this(new PredictionContext[] { a.parent }, new int[] { a.returnState })
{
}
public ArrayPredictionContext(PredictionContext[] parents, int[] returnStates)
: base(CalculateHashCode(parents, returnStates))
{
System.Diagnostics.Debug.Assert(parents.Length == returnStates.Length);
System.Diagnostics.Debug.Assert(returnStates.Length > 1 || returnStates[0] != EmptyFullStateKey, "Should be using PredictionContext.EMPTY instead.");
// System.err.println("CREATE ARRAY: "+Arrays.toString(parents)+", "+Arrays.toString(returnStates));
this.parents = parents;
this.returnStates = returnStates;
}
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates, int hashCode)
: base(hashCode)
public override bool IsEmpty
{
System.Diagnostics.Debug.Assert(parents.Length == returnStates.Length);
System.Diagnostics.Debug.Assert(returnStates.Length > 1 || returnStates[0] != EmptyFullStateKey, "Should be using PredictionContext.EMPTY instead.");
this.parents = parents;
this.returnStates = returnStates;
get
{
// since EMPTY_RETURN_STATE can only appear in the last position, we
// don't need to verify that size==1
return returnStates[0] == EMPTY_RETURN_STATE;
}
}
public override int Size
{
get
{
return returnStates.Length;
}
}
public override PredictionContext GetParent(int index)
@ -47,201 +65,60 @@ namespace Antlr4.Runtime.Atn
return returnStates[index];
}
public override int FindReturnState(int returnState)
{
return System.Array.BinarySearch(returnStates, returnState);
}
// @Override
// public int findReturnState(int returnState) {
// return Arrays.binarySearch(returnStates, returnState);
// }
public override int Size
{
get
{
return returnStates.Length;
}
}
public override bool IsEmpty
{
get
{
return false;
}
}
public override bool HasEmpty
{
get
{
return returnStates[returnStates.Length - 1] == EmptyFullStateKey;
}
}
protected internal override PredictionContext AddEmptyContext()
{
if (HasEmpty)
{
return this;
}
PredictionContext[] parents2 = Arrays.CopyOf(parents, parents.Length + 1);
int[] returnStates2 = Arrays.CopyOf(returnStates, returnStates.Length + 1);
parents2[parents2.Length - 1] = PredictionContext.EmptyFull;
returnStates2[returnStates2.Length - 1] = PredictionContext.EmptyFullStateKey;
return new Antlr4.Runtime.Atn.ArrayPredictionContext(parents2, returnStates2);
}
protected internal override PredictionContext RemoveEmptyContext()
{
if (!HasEmpty)
{
return this;
}
if (returnStates.Length == 2)
{
return new SingletonPredictionContext(parents[0], returnStates[0]);
}
else
{
PredictionContext[] parents2 = Arrays.CopyOf(parents, parents.Length - 1);
int[] returnStates2 = Arrays.CopyOf(returnStates, returnStates.Length - 1);
return new Antlr4.Runtime.Atn.ArrayPredictionContext(parents2, returnStates2);
}
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return AppendContext(this, suffix, new PredictionContext.IdentityHashMap());
}
private static PredictionContext AppendContext(PredictionContext context, PredictionContext suffix, PredictionContext.IdentityHashMap visited)
{
if (suffix.IsEmpty)
{
if (IsEmptyLocal(suffix))
{
if (context.HasEmpty)
{
return EmptyLocal;
}
throw new NotSupportedException("what to do here?");
}
return context;
}
if (suffix.Size != 1)
{
throw new NotSupportedException("Appending a tree suffix is not yet supported.");
}
PredictionContext result;
if (!visited.TryGetValue(context, out result))
{
if (context.IsEmpty)
{
result = suffix;
}
else
{
int parentCount = context.Size;
if (context.HasEmpty)
{
parentCount--;
}
PredictionContext[] updatedParents = new PredictionContext[parentCount];
int[] updatedReturnStates = new int[parentCount];
for (int i = 0; i < parentCount; i++)
{
updatedReturnStates[i] = context.GetReturnState(i);
}
for (int i_1 = 0; i_1 < parentCount; i_1++)
{
updatedParents[i_1] = AppendContext(context.GetParent(i_1), suffix, visited);
}
if (updatedParents.Length == 1)
{
result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]);
}
else
{
System.Diagnostics.Debug.Assert(updatedParents.Length > 1);
result = new Antlr4.Runtime.Atn.ArrayPredictionContext(updatedParents, updatedReturnStates);
}
if (context.HasEmpty)
{
result = PredictionContext.Join(result, suffix);
}
}
visited[context] = result;
}
return result;
}
public override bool Equals(object o)
public override bool Equals(Object o)
{
if (this == o)
{
return true;
}
else
{
if (!(o is Antlr4.Runtime.Atn.ArrayPredictionContext))
else if (!(o is ArrayPredictionContext))
{
return false;
}
}
if (this.GetHashCode() != o.GetHashCode())
{
return false;
}
// can't be same if hash is different
Antlr4.Runtime.Atn.ArrayPredictionContext other = (Antlr4.Runtime.Atn.ArrayPredictionContext)o;
return Equals(other, new HashSet<PredictionContextCache.IdentityCommutativePredictionContextOperands>());
}
private bool Equals(Antlr4.Runtime.Atn.ArrayPredictionContext other, HashSet<PredictionContextCache.IdentityCommutativePredictionContextOperands> visited)
if (this.GetHashCode() != o.GetHashCode())
{
Stack<PredictionContext> selfWorkList = new Stack<PredictionContext>();
Stack<PredictionContext> otherWorkList = new Stack<PredictionContext>();
selfWorkList.Push(this);
otherWorkList.Push(other);
while (selfWorkList.Count > 0)
return false; // can't be same if hash is different
}
ArrayPredictionContext a = (ArrayPredictionContext)o;
return Arrays.Equals(returnStates, a.returnStates) &&
Arrays.Equals(parents, a.parents);
}
public override String ToString()
{
PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(selfWorkList.Pop(), otherWorkList.Pop());
if (!visited.Add(operands))
if (IsEmpty)
return "[]";
StringBuilder buf = new StringBuilder();
buf.Append("[");
for (int i = 0; i < returnStates.Length; i++)
{
if (i > 0) buf.Append(", ");
if (returnStates[i] == EMPTY_RETURN_STATE)
{
buf.Append("$");
continue;
}
int selfSize = operands.X.Size;
if (selfSize == 0)
buf.Append(returnStates[i]);
if (parents[i] != null)
{
if (!operands.X.Equals(operands.Y))
{
return false;
buf.Append(' ');
buf.Append(parents[i].ToString());
}
continue;
}
int otherSize = operands.Y.Size;
if (selfSize != otherSize)
{
return false;
}
for (int i = 0; i < selfSize; i++)
{
if (operands.X.GetReturnState(i) != operands.Y.GetReturnState(i))
{
return false;
}
PredictionContext selfParent = operands.X.GetParent(i);
PredictionContext otherParent = operands.Y.GetParent(i);
if (selfParent.GetHashCode() != otherParent.GetHashCode())
{
return false;
}
if (selfParent != otherParent)
{
selfWorkList.Push(selfParent);
otherWorkList.Push(otherParent);
else {
buf.Append("null");
}
}
}
return true;
buf.Append("]");
return buf.ToString();
}
}
}

View File

@ -25,7 +25,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Atom;
return Antlr4.Runtime.Atn.TransitionType.ATOM;
}
}

View File

@ -8,7 +8,6 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>This class stores information about a configuration conflict.</summary>
/// <remarks>This class stores information about a configuration conflict.</remarks>
/// <author>Sam Harwell</author>
public class ConflictInfo
{
@ -43,7 +42,7 @@ namespace Antlr4.Runtime.Atn
/// conflict indicates a true ambiguity in the input.
/// <p>
/// For the
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// <see cref="PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// prediction mode,
/// accept states are conflicting but not exact are treated as non-accept
/// states.</p>

View File

@ -18,7 +18,7 @@ namespace Antlr4.Runtime.Atn
/// 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"/>
/// <see cref="PredictionMode.SLL"/>
/// , which in turn means they cannot use
/// the two-stage parsing strategy to improve parsing performance for that
/// input.</p>

View File

@ -24,249 +24,206 @@ namespace Antlr4.Runtime.Atn
/// <since>4.3</since>
public class DecisionInfo
{
/// <summary>
/// The decision number, which is an index into
/// <see cref="ATN.decisionToState"/>
/// .
/// </summary>
/**
* The decision number, which is an index into {@link ATN#decisionToState}.
*/
public readonly int decision;
/// <summary>
/// The total number of times
/// <see cref="ParserATNSimulator.AdaptivePredict(ITokenStream, int, ParserRuleContext)"/>
/// was
/// invoked for this decision.
/// </summary>
/**
* The total number of times {@link ParserATNSimulator#adaptivePredict} was
* invoked for this decision.
*/
public long invocations;
/// <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"/>
/// or
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// is used.
/// </remarks>
/**
* The total time spent in {@link ParserATNSimulator#adaptivePredict} for
* this decision, in nanoseconds.
*
* <p>
* The value of this field contains the sum of differential results obtained
* by {@link System#nanoTime()}, 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
* {@link System#nanoTime()}, and perform profiling in a separate process
* which is warmed up by parsing the input prior to profiling. If desired,
* call {@link ATNSimulator#clearDFA} to reset the DFA cache to its initial
* state before starting the profiling measurement pass.</p>
*/
public long timeInPrediction;
/**
* 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 {@link PredictionMode#LL} or
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION} is used.
*/
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>
/**
* 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.
*/
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>
/**
* 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.
*/
public long SLL_MaxLook;
/// <summary>
/// Gets the
/// <see cref="LookaheadEventInfo"/>
/// associated with the event where the
/// <see cref="SLL_MaxLook"/>
/// value was set.
/// </summary>
/**
* Gets the {@link LookaheadEventInfo} associated with the event where the
* {@link #SLL_MaxLook} value was set.
*/
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>
/**
* 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.
*/
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"/>
/// , an ambiguity state (for
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// , or a syntax error.
/// </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
* {@link PredictionMode#LL}, an ambiguity state (for
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION}, or a syntax error.
*/
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"/>
/// , an ambiguity state (for
/// <see cref="PredictionMode.LlExactAmbigDetection"/>
/// , or a syntax error.
/// </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
* {@link PredictionMode#LL}, an ambiguity state (for
* {@link PredictionMode#LL_EXACT_AMBIG_DETECTION}, or a syntax error.
*/
public long LL_MaxLook;
/// <summary>
/// Gets the
/// <see cref="LookaheadEventInfo"/>
/// associated with the event where the
/// <see cref="LL_MaxLook"/>
/// value was set.
/// </summary>
/**
* Gets the {@link LookaheadEventInfo} associated with the event where the
* {@link #LL_MaxLook} value was set.
*/
public LookaheadEventInfo LL_MaxLookEvent;
/// <summary>
/// A collection of
/// <see cref="ContextSensitivityInfo"/>
/// instances describing the
/// context sensitivities encountered during LL prediction for this decision.
/// </summary>
/// <seealso cref="ContextSensitivityInfo"/>
public readonly IList<ContextSensitivityInfo> contextSensitivities = new List<ContextSensitivityInfo>();
/**
* A collection of {@link ContextSensitivityInfo} instances describing the
* context sensitivities encountered during LL prediction for this decision.
*
* @see ContextSensitivityInfo
*/
public readonly List<ContextSensitivityInfo> contextSensitivities = new List<ContextSensitivityInfo>();
/// <summary>
/// A collection of
/// <see cref="ErrorInfo"/>
/// instances describing the parse errors
/// identified during calls to
/// <see cref="ParserATNSimulator.AdaptivePredict(ITokenStream, int, ParserRuleContext)"/>
/// for
/// this decision.
/// </summary>
/// <seealso cref="ErrorInfo"/>
public readonly IList<ErrorInfo> errors = new List<ErrorInfo>();
/**
* A collection of {@link ErrorInfo} instances describing the parse errors
* identified during calls to {@link ParserATNSimulator#adaptivePredict} for
* this decision.
*
* @see ErrorInfo
*/
public readonly List<ErrorInfo> errors = new List<ErrorInfo>();
/// <summary>
/// A collection of
/// <see cref="AmbiguityInfo"/>
/// instances describing the
/// ambiguities encountered during LL prediction for this decision.
/// </summary>
/// <seealso cref="AmbiguityInfo"/>
public readonly IList<AmbiguityInfo> ambiguities = new List<AmbiguityInfo>();
/**
* A collection of {@link AmbiguityInfo} instances describing the
* ambiguities encountered during LL prediction for this decision.
*
* @see AmbiguityInfo
*/
public readonly List<AmbiguityInfo> ambiguities = new List<AmbiguityInfo>();
/// <summary>
/// A collection of
/// <see cref="PredicateEvalInfo"/>
/// instances describing the
/// results of evaluating individual predicates during prediction for this
/// decision.
/// </summary>
/// <seealso cref="PredicateEvalInfo"/>
public readonly IList<PredicateEvalInfo> predicateEvals = new List<PredicateEvalInfo>();
/**
* A collection of {@link PredicateEvalInfo} instances describing the
* results of evaluating individual predicates during prediction for this
* decision.
*
* @see PredicateEvalInfo
*/
public readonly List<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"/>
/// <seealso cref="ParserATNSimulator.ComputeTargetState"/>
/// <seealso cref="LexerATNSimulator.ComputeTargetState"/>
/**
* 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>
*
* @see #SLL_ATNTransitions
* @see ParserATNSimulator#computeTargetState
* @see LexerATNSimulator#computeTargetState
*/
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"/>
/// <seealso cref="LexerATNSimulator.GetExistingTargetState"/>
/**
* 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>
*
* @see ParserATNSimulator#getExistingTargetState
* @see LexerATNSimulator#getExistingTargetState
*/
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"/>
/// 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"/>
/// would produce the same overall
/// parsing result as
/// <see cref="PredictionMode.Ll"/>
/// .</p>
/// </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
* {@link PredictionMode#SLL} 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, {@link PredictionMode#SLL} would produce the same overall
* parsing result as {@link PredictionMode#LL}.</p>
*/
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"/>
/// <seealso cref="ParserATNSimulator.ComputeTargetState"/>
/// <seealso cref="LexerATNSimulator.ComputeTargetState"/>
/**
* 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>
*
* @see #LL_DFATransitions
* @see ParserATNSimulator#computeTargetState
* @see LexerATNSimulator#computeTargetState
*/
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"/>
/// <seealso cref="LexerATNSimulator.GetExistingTargetState"/>
/**
* 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>
*
* @see ParserATNSimulator#getExistingTargetState
* @see LexerATNSimulator#getExistingTargetState
*/
public long LL_DFATransitions;
/// <summary>
/// Constructs a new instance of the
/// <see cref="DecisionInfo"/>
/// class to contain
/// statistics for a particular decision.
/// </summary>
/// <param name="decision">The decision number</param>
/**
* Constructs a new instance of the {@link DecisionInfo} class to contain
* statistics for a particular decision.
*
* @param decision The decision number
*/
public DecisionInfo(int decision)
{
this.decision = decision;
@ -274,7 +231,18 @@ namespace Antlr4.Runtime.Atn
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 + '}';
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

@ -10,71 +10,35 @@ using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public sealed class EmptyPredictionContext : PredictionContext
public sealed class EmptyPredictionContext : SingletonPredictionContext
{
public static readonly Antlr4.Runtime.Atn.EmptyPredictionContext LocalContext = new Antlr4.Runtime.Atn.EmptyPredictionContext(false);
public static readonly Antlr4.Runtime.Atn.EmptyPredictionContext FullContext = new Antlr4.Runtime.Atn.EmptyPredictionContext(true);
private readonly bool fullContext;
private EmptyPredictionContext(bool fullContext)
: base(CalculateEmptyHashCode())
internal EmptyPredictionContext()
: base(null, EMPTY_RETURN_STATE)
{
this.fullContext = fullContext;
}
public bool IsFullContext
{
get
{
return fullContext;
}
}
protected internal override PredictionContext AddEmptyContext()
{
return this;
}
protected internal override PredictionContext RemoveEmptyContext()
{
throw new NotSupportedException("Cannot remove the empty context from itself.");
}
public override PredictionContext GetParent(int index)
{
throw new ArgumentOutOfRangeException();
return null;
}
public override int GetReturnState(int index)
{
throw new ArgumentOutOfRangeException();
return returnState;
}
public override int FindReturnState(int returnState)
{
return -1;
}
public override int Size
{
get
{
return 0;
return 1;
}
}
public override PredictionContext AppendContext(int returnContext, PredictionContextCache contextCache)
{
return contextCache.GetChild(this, returnContext);
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return suffix;
}
public override bool IsEmpty
{
get
@ -83,19 +47,16 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmpty
{
get
{
return true;
}
}
public override bool Equals(object o)
{
return this == o;
}
public override string ToString()
{
return "$";
}
public override string[] ToStrings(IRecognizer recognizer, int currentState)
{
return new string[] { "[]" };

View File

@ -42,7 +42,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Epsilon;
return Antlr4.Runtime.Atn.TransitionType.EPSILON;
}
}

View File

@ -61,7 +61,7 @@ namespace Antlr4.Runtime.Atn
HashSet<ATNConfig> lookBusy = new HashSet<ATNConfig>();
bool seeThruPreds = false;
// fail to get lookahead upon pred
Look(s.Transition(alt).target, null, PredictionContext.EmptyLocal, look[alt], lookBusy, new BitSet(), seeThruPreds, false);
Look(s.Transition(alt).target, null, PredictionContext.EMPTY, look[alt], lookBusy, new BitSet(), seeThruPreds, false);
// Wipe out lookahead for this alternative if we found nothing
// or we had a predicate when we !seeThruPreds
if (look[alt].Count == 0 || look[alt].Contains(HitPred))
@ -86,7 +86,7 @@ namespace Antlr4.Runtime.Atn
/// and the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set.
/// If
/// <paramref name="ctx"/>
@ -94,7 +94,7 @@ namespace Antlr4.Runtime.Atn
/// <see langword="null"/>
/// and the end of the outermost rule is
/// reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.</p>
/// </summary>
/// <param name="s">the ATN state</param>
@ -113,9 +113,9 @@ namespace Antlr4.Runtime.Atn
/// .
/// </returns>
[return: NotNull]
public virtual IntervalSet Look(ATNState s, PredictionContext ctx)
public virtual IntervalSet Look(ATNState s, RuleContext ctx)
{
return Look(s, s.atn.ruleToStopState[s.ruleIndex], ctx);
return Look(s, null, ctx);
}
/// <summary>
@ -132,7 +132,7 @@ namespace Antlr4.Runtime.Atn
/// and the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set.
/// If
/// <paramref name="ctx"/>
@ -140,7 +140,7 @@ namespace Antlr4.Runtime.Atn
/// <c>PredictionContext#EMPTY_LOCAL</c>
/// and the end of the outermost rule is
/// reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.</p>
/// </summary>
/// <param name="s">the ATN state</param>
@ -164,13 +164,12 @@ namespace Antlr4.Runtime.Atn
/// .
/// </returns>
[return: NotNull]
public virtual IntervalSet Look(ATNState s, ATNState stopState, PredictionContext ctx)
public virtual IntervalSet Look(ATNState s, ATNState stopState, RuleContext ctx)
{
IntervalSet r = new IntervalSet();
bool seeThruPreds = true;
// ignore preds; get all lookahead
bool addEOF = true;
Look(s, stopState, ctx, r, new HashSet<ATNConfig>(), new BitSet(), seeThruPreds, addEOF);
PredictionContext lookContext = ctx != null ? PredictionContext.FromRuleContext(s.atn, ctx) : null;
Look(s, stopState, lookContext, r, new HashSet<ATNConfig>(), new BitSet(), seeThruPreds, true);
return r;
}
@ -191,7 +190,7 @@ namespace Antlr4.Runtime.Atn
/// or the end of the rule containing
/// <paramref name="s"/>
/// is reached,
/// <see cref="TokenConstants.Epsilon"/>
/// <see cref="TokenConstants.EPSILON"/>
/// is added to the result set. If
/// <paramref name="ctx"/>
/// is not
@ -203,7 +202,7 @@ namespace Antlr4.Runtime.Atn
/// and
/// <paramref name="stopState"/>
/// or the end of the outermost rule is reached,
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// is added to the result set.
/// </summary>
/// <param name="s">the ATN state.</param>
@ -246,7 +245,7 @@ namespace Antlr4.Runtime.Atn
/// </param>
/// <param name="addEOF">
/// Add
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// to the result if the end of the
/// outermost context is reached. This parameter has no effect if
/// <paramref name="ctx"/>
@ -257,63 +256,57 @@ namespace Antlr4.Runtime.Atn
protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet<ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF)
{
// System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
ATNConfig c = ATNConfig.Create(s, 0, ctx);
ATNConfig c = new ATNConfig(s, 0, ctx);
if (!lookBusy.Add(c))
{
return;
}
if (s == stopState)
{
if (PredictionContext.IsEmptyLocal(ctx))
if (ctx == null)
{
look.Add(TokenConstants.Epsilon);
look.Add(TokenConstants.EPSILON);
return;
}
else
{
if (ctx.IsEmpty)
{
if (addEOF)
{
look.Add(TokenConstants.Eof);
}
else if (ctx.IsEmpty && addEOF) {
look.Add(TokenConstants.EOF);
return;
}
}
}
if (s is RuleStopState)
{
if (ctx.IsEmpty && !PredictionContext.IsEmptyLocal(ctx))
if (ctx == null)
{
if (addEOF)
{
look.Add(TokenConstants.Eof);
}
look.Add(TokenConstants.EPSILON);
return;
}
bool removed = calledRuleStack.Get(s.ruleIndex);
try
else if (ctx.IsEmpty && addEOF)
{
look.Add(TokenConstants.EOF);
return;
}
if (ctx != PredictionContext.EMPTY)
{
calledRuleStack.Clear(s.ruleIndex);
for (int i = 0; i < ctx.Size; i++)
{
if (ctx.GetReturnState(i) == PredictionContext.EmptyFullStateKey)
{
continue;
}
ATNState returnState = atn.states[ctx.GetReturnState(i)];
// System.out.println("popping back to "+retState);
bool removed = calledRuleStack.Get(returnState.ruleIndex);
try
{
calledRuleStack.Clear(returnState.ruleIndex);
Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
}
}
finally
{
if (removed)
{
calledRuleStack.Set(s.ruleIndex);
calledRuleStack.Set(returnState.ruleIndex);
}
}
}
return;
}
}
int n = s.NumberOfTransitions;
for (int i_1 = 0; i_1 < n; i_1++)
{
@ -325,15 +318,15 @@ namespace Antlr4.Runtime.Atn
{
continue;
}
PredictionContext newContext = ctx.GetChild(ruleTransition.followState.stateNumber);
PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
try
{
calledRuleStack.Set(ruleTransition.ruleIndex);
calledRuleStack.Set(ruleTransition.target.ruleIndex);
Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
}
finally
{
calledRuleStack.Clear(ruleTransition.ruleIndex);
calledRuleStack.Clear(ruleTransition.target.ruleIndex);
}
}
else
@ -357,13 +350,12 @@ namespace Antlr4.Runtime.Atn
}
else
{
if (t.GetType() == typeof(WildcardTransition))
if (t is WildcardTransition)
{
look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
}
else
{
// System.out.println("adding "+ t);
IntervalSet set = t.Label;
if (set != null)
{

View File

@ -0,0 +1,120 @@
/* Copyright (c) 2012-2016 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime.Misc;
namespace Antlr4.Runtime.Atn
{
public class LexerATNConfig : ATNConfig
{
/**
* This is the backing field for {@link #getLexerActionExecutor}.
*/
private readonly LexerActionExecutor lexerActionExecutor;
private readonly bool passedThroughNonGreedyDecision;
public LexerATNConfig(ATNState state,
int alt,
PredictionContext context)
: base(state, alt, context/*, SemanticContext.NONE*/) // TODO
{
this.passedThroughNonGreedyDecision = false;
this.lexerActionExecutor = null;
}
public LexerATNConfig(ATNState state,
int alt,
PredictionContext context,
LexerActionExecutor lexerActionExecutor)
: base(state, alt, context, SemanticContext.NONE)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = false;
}
public LexerATNConfig(LexerATNConfig c, ATNState state)
: base(c, state, c.context, c.semanticContext)
{
this.lexerActionExecutor = c.lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
public LexerATNConfig(LexerATNConfig c, ATNState state,
LexerActionExecutor lexerActionExecutor)
: base(c, state, c.context, c.semanticContext)
{
this.lexerActionExecutor = lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
public LexerATNConfig(LexerATNConfig c, ATNState state,
PredictionContext context)
: base(c, state, context, c.semanticContext)
{
this.lexerActionExecutor = c.lexerActionExecutor;
this.passedThroughNonGreedyDecision = checkNonGreedyDecision(c, state);
}
/**
* Gets the {@link LexerActionExecutor} capable of executing the embedded
* action(s) for the current configuration.
*/
public LexerActionExecutor getLexerActionExecutor()
{
return lexerActionExecutor;
}
public bool hasPassedThroughNonGreedyDecision()
{
return passedThroughNonGreedyDecision;
}
public override int GetHashCode()
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, state.stateNumber);
hashCode = MurmurHash.Update(hashCode, alt);
hashCode = MurmurHash.Update(hashCode, context);
hashCode = MurmurHash.Update(hashCode, semanticContext);
hashCode = MurmurHash.Update(hashCode, passedThroughNonGreedyDecision ? 1 : 0);
hashCode = MurmurHash.Update(hashCode, lexerActionExecutor);
hashCode = MurmurHash.Finish(hashCode, 6);
return hashCode;
}
public override bool Equals(ATNConfig other)
{
if (this == other)
{
return true;
}
else if (!(other is LexerATNConfig))
{
return false;
}
LexerATNConfig lexerOther = (LexerATNConfig)other;
if (passedThroughNonGreedyDecision != lexerOther.passedThroughNonGreedyDecision)
{
return false;
}
if (!(lexerActionExecutor==null ? lexerOther.lexerActionExecutor==null : lexerActionExecutor.Equals(lexerOther.lexerActionExecutor)))
{
return false;
}
return base.Equals(other);
}
private static bool checkNonGreedyDecision(LexerATNConfig source, ATNState target)
{
return source.passedThroughNonGreedyDecision
|| target is DecisionState && ((DecisionState)target).nonGreedy;
}
}
}

View File

@ -0,0 +1,38 @@
/* Copyright (c) 2012-2016 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
namespace Antlr4.Runtime.Atn
{
public class MergeCache
{
Dictionary<PredictionContext, Dictionary<PredictionContext, PredictionContext>> data = new Dictionary<PredictionContext, Dictionary<PredictionContext, PredictionContext>>();
public PredictionContext Get(PredictionContext a, PredictionContext b)
{
Dictionary<PredictionContext, PredictionContext> first;
if (!data.TryGetValue(a, out first))
return null;
PredictionContext value;
if (first.TryGetValue(b, out value))
return value;
else
return null;
}
public void Put(PredictionContext a, PredictionContext b, PredictionContext value)
{
Dictionary<PredictionContext, PredictionContext> first;
if (!data.TryGetValue(a, out first))
{
first = new Dictionary<PredictionContext, PredictionContext>();
data[a] = first;
}
first[b] = value;
}
}
}

View File

@ -19,7 +19,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.NotSet;
return Antlr4.Runtime.Atn.TransitionType.NOT_SET;
}
}

View File

@ -10,88 +10,78 @@ using Antlr4.Runtime.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>
/**
* This class provides access to specific and aggregate statistics gathered
* during profiling of a parser.
*
* @since 4.3
*/
public class ParseInfo
{
protected internal readonly ProfilingATNSimulator atnSimulator;
protected readonly ProfilingATNSimulator atnSimulator;
public ParseInfo(ProfilingATNSimulator atnSimulator)
{
this.atnSimulator = atnSimulator;
}
/// <summary>
/// Gets an array of
/// <see cref="DecisionInfo"/>
/// instances containing the profiling
/// information gathered for each decision in the ATN.
/// </summary>
/// <returns>
/// An array of
/// <see cref="DecisionInfo"/>
/// instances, indexed by decision
/// number.
/// </returns>
[NotNull]
public virtual Antlr4.Runtime.Atn.DecisionInfo[] DecisionInfo
/**
* Gets an array of {@link DecisionInfo} instances containing the profiling
* information gathered for each decision in the ATN.
*
* @return An array of {@link DecisionInfo} instances, indexed by decision
* number.
*/
public DecisionInfo[] getDecisionInfo()
{
get
{
return atnSimulator.DecisionInfo;
}
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="Antlr4.Runtime.Atn.DecisionInfo.LL_Fallback"/>
/// is non-zero.
/// </remarks>
/// <returns>
/// A list of decision numbers which required one or more
/// full-context predictions during parsing.
/// </returns>
[return: NotNull]
public virtual IList<int> GetLLDecisions()
/**
* Gets the decision numbers for decisions that required one or more
* full-context predictions during parsing. These are decisions for which
* {@link DecisionInfo#LL_Fallback} is non-zero.
*
* @return A list of decision numbers which required one or more
* full-context predictions during parsing.
*/
public List<int> getLLDecisions()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
IList<int> Ll = new List<int>();
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
List<int> LL = new List<int>();
for (int i = 0; i < decisions.Length; i++)
{
long fallBack = decisions[i].LL_Fallback;
if (fallBack > 0)
{
Ll.Add(i);
if (fallBack > 0) LL.Add(i);
}
}
return Ll;
return LL;
}
/// <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="Antlr4.Runtime.Atn.DecisionInfo.SLL_TotalLook"/>
/// for all decisions.
/// </remarks>
public virtual long GetTotalSLLLookaheadOps()
/**
* Gets the total time spent during prediction across all decisions made
* during parsing. This value is the sum of
* {@link DecisionInfo#timeInPrediction} for all decisions.
*/
public long getTotalTimeInPrediction()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long t = 0;
for (int i = 0; i < decisions.Length; i++)
{
t += decisions[i].timeInPrediction;
}
return t;
}
/**
* Gets the total number of SLL lookahead operations across all decisions
* made during parsing. This value is the sum of
* {@link DecisionInfo#SLL_TotalLook} for all decisions.
*/
public long getTotalSLLLookaheadOps()
{
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
@ -100,19 +90,14 @@ namespace Antlr4.Runtime.Atn
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="Antlr4.Runtime.Atn.DecisionInfo.LL_TotalLook"/>
/// for all decisions.
/// </remarks>
public virtual long GetTotalLLLookaheadOps()
/**
* Gets the total number of LL lookahead operations across all decisions
* made during parsing. This value is the sum of
* {@link DecisionInfo#LL_TotalLook} for all decisions.
*/
public long getTotalLLLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
@ -121,17 +106,13 @@ namespace Antlr4.Runtime.Atn
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()
/**
* Gets the total number of ATN lookahead operations for SLL prediction
* across all decisions made during parsing.
*/
public long getTotalSLLATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
@ -140,17 +121,13 @@ namespace Antlr4.Runtime.Atn
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()
/**
* Gets the total number of ATN lookahead operations for LL prediction
* across all decisions made during parsing.
*/
public long getTotalLLATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
@ -159,23 +136,17 @@ namespace Antlr4.Runtime.Atn
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()"/>
/// and
/// <see cref="GetTotalLLATNLookaheadOps()"/>
/// .</p>
/// </remarks>
public virtual long GetTotalATNLookaheadOps()
/**
* 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 {@link #getTotalSLLATNLookaheadOps} and
* {@link #getTotalLLATNLookaheadOps}.</p>
*/
public long getTotalATNLookaheadOps()
{
Antlr4.Runtime.Atn.DecisionInfo[] decisions = atnSimulator.DecisionInfo;
DecisionInfo[] decisions = atnSimulator.getDecisionInfo();
long k = 0;
for (int i = 0; i < decisions.Length; i++)
{
@ -185,37 +156,30 @@ namespace Antlr4.Runtime.Atn
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()
/**
* Gets the total number of DFA states stored in the DFA cache for all
* decisions in the ATN.
*/
public int getDFASize()
{
int n = 0;
DFA[] decisionToDFA = atnSimulator.atn.decisionToDFA;
DFA[] decisionToDFA = atnSimulator.decisionToDFA;
for (int i = 0; i < decisionToDFA.Length; i++)
{
n += GetDFASize(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)
/**
* Gets the total number of DFA states stored in the DFA cache for a
* particular decision.
*/
public int getDFASize(int decision)
{
DFA decisionToDFA = atnSimulator.atn.decisionToDFA[decision];
DFA decisionToDFA = atnSimulator.decisionToDFA[decision];
return decisionToDFA.states.Count;
}
}
}

View File

@ -22,7 +22,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Precedence;
return Antlr4.Runtime.Atn.TransitionType.PRECEDENCE;
}
}

View File

@ -31,7 +31,7 @@ namespace Antlr4.Runtime.Atn
/// . Note that other ATN
/// configurations may predict the same alternative which are guarded by
/// other semantic contexts and/or
/// <see cref="SemanticContext.None"/>
/// <see cref="SemanticContext.NONE"/>
/// .
/// </summary>
public readonly int predictedAlt;

View File

@ -40,7 +40,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Predicate;
return Antlr4.Runtime.Atn.TransitionType.PREDICATE;
}
}

View File

@ -2,11 +2,8 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -14,84 +11,32 @@ namespace Antlr4.Runtime.Atn
{
public abstract class PredictionContext
{
[NotNull]
public static readonly Antlr4.Runtime.Atn.PredictionContext EmptyLocal = EmptyPredictionContext.LocalContext;
public static readonly int EMPTY_RETURN_STATE = int.MaxValue;
[NotNull]
public static readonly Antlr4.Runtime.Atn.PredictionContext EmptyFull = EmptyPredictionContext.FullContext;
public static readonly EmptyPredictionContext EMPTY = new EmptyPredictionContext();
public const int EmptyLocalStateKey = int.MinValue;
public const int EmptyFullStateKey = int.MaxValue;
private const int InitialHash = 1;
/// <summary>
/// Stores the computed hash code of this
/// <see cref="PredictionContext"/>
/// . The hash
/// code is computed in parts to match the following reference algorithm.
/// <pre>
/// private int referenceHashCode() {
/// int hash =
/// <see cref="Antlr4.Runtime.Misc.MurmurHash.Initialize()">MurmurHash.initialize</see>
/// (
/// <see cref="InitialHash"/>
/// );
/// for (int i = 0; i &lt;
/// <see cref="Size()"/>
/// ; i++) {
/// hash =
/// <see cref="Antlr4.Runtime.Misc.MurmurHash.Update(int, int)">MurmurHash.update</see>
/// (hash,
/// <see cref="GetParent(int)">getParent</see>
/// (i));
/// }
/// for (int i = 0; i &lt;
/// <see cref="Size()"/>
/// ; i++) {
/// hash =
/// <see cref="Antlr4.Runtime.Misc.MurmurHash.Update(int, int)">MurmurHash.update</see>
/// (hash,
/// <see cref="GetReturnState(int)">getReturnState</see>
/// (i));
/// }
/// hash =
/// <see cref="Antlr4.Runtime.Misc.MurmurHash.Finish(int, int)">MurmurHash.finish</see>
/// (hash, 2 *
/// <see cref="Size()"/>
/// );
/// return hash;
/// }
/// </pre>
/// </summary>
private readonly int cachedHashCode;
protected internal PredictionContext(int cachedHashCode)
{
this.cachedHashCode = cachedHashCode;
}
private static readonly int INITIAL_HASH = 1;
protected internal static int CalculateEmptyHashCode()
{
int hash = MurmurHash.Initialize(InitialHash);
int hash = MurmurHash.Initialize(INITIAL_HASH);
hash = MurmurHash.Finish(hash, 0);
return hash;
}
protected internal static int CalculateHashCode(Antlr4.Runtime.Atn.PredictionContext parent, int returnState)
protected internal static int CalculateHashCode(PredictionContext parent, int returnState)
{
int hash = MurmurHash.Initialize(InitialHash);
int hash = MurmurHash.Initialize(INITIAL_HASH);
hash = MurmurHash.Update(hash, parent);
hash = MurmurHash.Update(hash, returnState);
hash = MurmurHash.Finish(hash, 2);
return hash;
}
protected internal static int CalculateHashCode(Antlr4.Runtime.Atn.PredictionContext[] parents, int[] returnStates)
protected internal static int CalculateHashCode(PredictionContext[] parents, int[] returnStates)
{
int hash = MurmurHash.Initialize(InitialHash);
foreach (Antlr4.Runtime.Atn.PredictionContext parent in parents)
int hash = MurmurHash.Initialize(INITIAL_HASH);
foreach (PredictionContext parent in parents)
{
hash = MurmurHash.Update(hash, parent);
}
@ -103,271 +48,48 @@ namespace Antlr4.Runtime.Atn
return hash;
}
public abstract int Size
private readonly int cachedHashCode;
protected internal PredictionContext(int cachedHashCode)
{
get;
this.cachedHashCode = cachedHashCode;
}
public abstract int GetReturnState(int index);
public abstract int FindReturnState(int returnState);
[return: NotNull]
public abstract Antlr4.Runtime.Atn.PredictionContext GetParent(int index);
protected internal abstract Antlr4.Runtime.Atn.PredictionContext AddEmptyContext();
protected internal abstract Antlr4.Runtime.Atn.PredictionContext RemoveEmptyContext();
public static Antlr4.Runtime.Atn.PredictionContext FromRuleContext(ATN atn, RuleContext outerContext)
public static PredictionContext FromRuleContext(ATN atn, RuleContext outerContext)
{
return FromRuleContext(atn, outerContext, true);
}
public static Antlr4.Runtime.Atn.PredictionContext FromRuleContext(ATN atn, RuleContext outerContext, bool fullContext)
{
if (outerContext.IsEmpty)
{
return fullContext ? EmptyFull : EmptyLocal;
}
Antlr4.Runtime.Atn.PredictionContext parent;
if (outerContext.Parent != null)
{
parent = Antlr4.Runtime.Atn.PredictionContext.FromRuleContext(atn, outerContext.Parent, fullContext);
}
else
{
parent = fullContext ? EmptyFull : EmptyLocal;
}
if (outerContext == null)
outerContext = ParserRuleContext.EMPTY;
if (outerContext.Parent == null || outerContext == ParserRuleContext.EMPTY)
return PredictionContext.EMPTY;
PredictionContext parent = PredictionContext.FromRuleContext(atn, outerContext.Parent);
ATNState state = atn.states[outerContext.invokingState];
RuleTransition transition = (RuleTransition)state.Transition(0);
return parent.GetChild(transition.followState.stateNumber);
}
private static Antlr4.Runtime.Atn.PredictionContext AddEmptyContext(Antlr4.Runtime.Atn.PredictionContext context)
{
return context.AddEmptyContext();
}
private static Antlr4.Runtime.Atn.PredictionContext RemoveEmptyContext(Antlr4.Runtime.Atn.PredictionContext context)
{
return context.RemoveEmptyContext();
}
public static Antlr4.Runtime.Atn.PredictionContext Join(Antlr4.Runtime.Atn.PredictionContext context0, Antlr4.Runtime.Atn.PredictionContext context1)
{
return Join(context0, context1, PredictionContextCache.Uncached);
}
internal static Antlr4.Runtime.Atn.PredictionContext Join(Antlr4.Runtime.Atn.PredictionContext context0, Antlr4.Runtime.Atn.PredictionContext context1, PredictionContextCache contextCache)
{
if (context0 == context1)
{
return context0;
}
if (context0.IsEmpty)
{
return IsEmptyLocal(context0) ? context0 : AddEmptyContext(context1);
}
else
{
if (context1.IsEmpty)
{
return IsEmptyLocal(context1) ? context1 : AddEmptyContext(context0);
}
}
int context0size = context0.Size;
int context1size = context1.Size;
if (context0size == 1 && context1size == 1 && context0.GetReturnState(0) == context1.GetReturnState(0))
{
Antlr4.Runtime.Atn.PredictionContext merged = contextCache.Join(context0.GetParent(0), context1.GetParent(0));
if (merged == context0.GetParent(0))
{
return context0;
}
else
{
if (merged == context1.GetParent(0))
{
return context1;
}
else
{
return merged.GetChild(context0.GetReturnState(0));
}
}
}
int count = 0;
Antlr4.Runtime.Atn.PredictionContext[] parentsList = new Antlr4.Runtime.Atn.PredictionContext[context0size + context1size];
int[] returnStatesList = new int[parentsList.Length];
int leftIndex = 0;
int rightIndex = 0;
bool canReturnLeft = true;
bool canReturnRight = true;
while (leftIndex < context0size && rightIndex < context1size)
{
if (context0.GetReturnState(leftIndex) == context1.GetReturnState(rightIndex))
{
parentsList[count] = contextCache.Join(context0.GetParent(leftIndex), context1.GetParent(rightIndex));
returnStatesList[count] = context0.GetReturnState(leftIndex);
canReturnLeft = canReturnLeft && parentsList[count] == context0.GetParent(leftIndex);
canReturnRight = canReturnRight && parentsList[count] == context1.GetParent(rightIndex);
leftIndex++;
rightIndex++;
}
else
{
if (context0.GetReturnState(leftIndex) < context1.GetReturnState(rightIndex))
{
parentsList[count] = context0.GetParent(leftIndex);
returnStatesList[count] = context0.GetReturnState(leftIndex);
canReturnRight = false;
leftIndex++;
}
else
{
System.Diagnostics.Debug.Assert(context1.GetReturnState(rightIndex) < context0.GetReturnState(leftIndex));
parentsList[count] = context1.GetParent(rightIndex);
returnStatesList[count] = context1.GetReturnState(rightIndex);
canReturnLeft = false;
rightIndex++;
}
}
count++;
}
while (leftIndex < context0size)
{
parentsList[count] = context0.GetParent(leftIndex);
returnStatesList[count] = context0.GetReturnState(leftIndex);
leftIndex++;
canReturnRight = false;
count++;
}
while (rightIndex < context1size)
{
parentsList[count] = context1.GetParent(rightIndex);
returnStatesList[count] = context1.GetReturnState(rightIndex);
rightIndex++;
canReturnLeft = false;
count++;
}
if (canReturnLeft)
{
return context0;
}
else
{
if (canReturnRight)
{
return context1;
}
}
if (count < parentsList.Length)
{
parentsList = Arrays.CopyOf(parentsList, count);
returnStatesList = Arrays.CopyOf(returnStatesList, count);
}
if (parentsList.Length == 0)
{
// if one of them was EMPTY_LOCAL, it would be empty and handled at the beginning of the method
return EmptyFull;
}
else
{
if (parentsList.Length == 1)
{
return new SingletonPredictionContext(parentsList[0], returnStatesList[0]);
}
else
{
return new ArrayPredictionContext(parentsList, returnStatesList);
}
}
}
public static bool IsEmptyLocal(Antlr4.Runtime.Atn.PredictionContext context)
{
return context == EmptyLocal;
}
public static Antlr4.Runtime.Atn.PredictionContext GetCachedContext(Antlr4.Runtime.Atn.PredictionContext context, ConcurrentDictionary<Antlr4.Runtime.Atn.PredictionContext, Antlr4.Runtime.Atn.PredictionContext> contextCache, PredictionContext.IdentityHashMap visited)
{
if (context.IsEmpty)
{
return context;
}
Antlr4.Runtime.Atn.PredictionContext existing;
if (visited.TryGetValue(context, out existing))
{
return existing;
}
if (contextCache.TryGetValue(context, out existing))
{
visited[context] = existing;
return existing;
}
bool changed = false;
Antlr4.Runtime.Atn.PredictionContext[] parents = new Antlr4.Runtime.Atn.PredictionContext[context.Size];
for (int i = 0; i < parents.Length; i++)
{
Antlr4.Runtime.Atn.PredictionContext parent = GetCachedContext(context.GetParent(i), contextCache, visited);
if (changed || parent != context.GetParent(i))
{
if (!changed)
{
parents = new Antlr4.Runtime.Atn.PredictionContext[context.Size];
for (int j = 0; j < context.Size; j++)
{
parents[j] = context.GetParent(j);
}
changed = true;
}
parents[i] = parent;
}
}
if (!changed)
{
existing = contextCache.GetOrAdd(context, context);
visited[context] = existing;
return context;
}
// We know parents.length>0 because context.isEmpty() is checked at the beginning of the method.
Antlr4.Runtime.Atn.PredictionContext updated;
if (parents.Length == 1)
{
updated = new SingletonPredictionContext(parents[0], context.GetReturnState(0));
}
else
{
ArrayPredictionContext arrayPredictionContext = (ArrayPredictionContext)context;
updated = new ArrayPredictionContext(parents, arrayPredictionContext.returnStates, context.cachedHashCode);
}
existing = contextCache.GetOrAdd(updated, updated);
visited[updated] = existing;
visited[context] = existing;
return updated;
}
public virtual Antlr4.Runtime.Atn.PredictionContext AppendContext(int returnContext, PredictionContextCache contextCache)
{
return AppendContext(Antlr4.Runtime.Atn.PredictionContext.EmptyFull.GetChild(returnContext), contextCache);
}
public abstract Antlr4.Runtime.Atn.PredictionContext AppendContext(Antlr4.Runtime.Atn.PredictionContext suffix, PredictionContextCache contextCache);
public virtual Antlr4.Runtime.Atn.PredictionContext GetChild(int returnState)
{
return new SingletonPredictionContext(this, returnState);
}
public abstract bool IsEmpty
public abstract int Size
{
get;
}
public abstract bool HasEmpty
public abstract PredictionContext GetParent(int index);
public abstract int GetReturnState(int index);
public virtual bool IsEmpty
{
get;
get
{
return this == EMPTY;
}
}
public virtual bool HasEmptyPath
{
get
{
return GetReturnState(Size - 1) == EMPTY_RETURN_STATE;
}
}
public sealed override int GetHashCode()
@ -375,25 +97,396 @@ namespace Antlr4.Runtime.Atn
return cachedHashCode;
}
public abstract override bool Equals(object o);
//@Override
//public String toString() {
// return toString(null, Integer.MAX_VALUE);
//}
public virtual string[] ToStrings(IRecognizer recognizer, int currentState)
internal static PredictionContext Merge(PredictionContext a, PredictionContext b, bool rootIsWildcard, MergeCache mergeCache)
{
return ToStrings(recognizer, Antlr4.Runtime.Atn.PredictionContext.EmptyFull, currentState);
if (a == b || a.Equals(b))
{
return a;
}
if (a is SingletonPredictionContext && b is SingletonPredictionContext)
{
return MergeSingletons((SingletonPredictionContext)a,
(SingletonPredictionContext)b,
rootIsWildcard, mergeCache);
}
public virtual string[] ToStrings(IRecognizer recognizer, Antlr4.Runtime.Atn.PredictionContext stop, int currentState)
// At least one of a or b is array
// If one is $ and rootIsWildcard, return $ as * wildcard
if (rootIsWildcard)
{
if (a is EmptyPredictionContext)
return a;
if (b is EmptyPredictionContext)
return b;
}
// convert singleton so both are arrays to normalize
if (a is SingletonPredictionContext)
{
a = new ArrayPredictionContext((SingletonPredictionContext)a);
}
if (b is SingletonPredictionContext)
{
b = new ArrayPredictionContext((SingletonPredictionContext)b);
}
return MergeArrays((ArrayPredictionContext)a, (ArrayPredictionContext)b,
rootIsWildcard, mergeCache);
}
public static PredictionContext MergeSingletons(
SingletonPredictionContext a,
SingletonPredictionContext b,
bool rootIsWildcard,
MergeCache mergeCache)
{
if (mergeCache != null)
{
PredictionContext previous = mergeCache.Get(a, b);
if (previous != null) return previous;
previous = mergeCache.Get(b, a);
if (previous != null) return previous;
}
PredictionContext rootMerge = MergeRoot(a, b, rootIsWildcard);
if (rootMerge != null)
{
if (mergeCache != null) mergeCache.Put(a, b, rootMerge);
return rootMerge;
}
if (a.returnState == b.returnState)
{ // a == b
PredictionContext parent = Merge(a.parent, b.parent, rootIsWildcard, mergeCache);
// if parent is same as existing a or b parent or reduced to a parent, return it
if (parent == a.parent) return a; // ax + bx = ax, if a=b
if (parent == b.parent) return b; // ax + bx = bx, if a=b
// else: ax + ay = a'[x,y]
// merge parents x and y, giving array node with x,y then remainders
// of those graphs. dup a, a' points at merged array
// new joined parent so create new singleton pointing to it, a'
PredictionContext a_ = SingletonPredictionContext.Create(parent, a.returnState);
if (mergeCache != null) mergeCache.Put(a, b, a_);
return a_;
}
else { // a != b payloads differ
// see if we can collapse parents due to $+x parents if local ctx
int[] payloads = new int[2];
PredictionContext[] parents = new PredictionContext[2];
PredictionContext pc;
PredictionContext singleParent = null;
if (a == b || (a.parent != null && a.parent.Equals(b.parent)))
{ // ax + bx = [a,b]x
singleParent = a.parent;
}
if (singleParent != null)
{ // parents are same
// sort payloads and use same parent
if (a.returnState > b.returnState)
{
payloads[0] = b.returnState;
payloads[1] = a.returnState;
}
else {
payloads[0] = a.returnState;
payloads[1] = b.returnState;
}
parents[0] = singleParent;
parents[1] = singleParent;
pc = new ArrayPredictionContext(parents, payloads);
if (mergeCache != null)
mergeCache.Put(a, b, pc);
return pc;
}
// parents differ and can't merge them. Just pack together
// into array; can't merge.
// ax + by = [ax,by]
// sort by payload
if (a.returnState > b.returnState)
{
payloads[0] = b.returnState;
payloads[1] = a.returnState;
parents[0] = b.parent;
parents[1] = a.parent;
}
else {
payloads[0] = a.returnState;
payloads[1] = b.returnState;
parents[0] = a.parent;
parents[1] = b.parent;
}
pc = new ArrayPredictionContext(parents, payloads);
if (mergeCache != null)
mergeCache.Put(a, b, pc);
return pc;
}
}
public static PredictionContext MergeArrays(
ArrayPredictionContext a,
ArrayPredictionContext b,
bool rootIsWildcard,
MergeCache mergeCache)
{
if (mergeCache != null)
{
PredictionContext previous = mergeCache.Get(a, b);
if (previous != null)
return previous;
previous = mergeCache.Get(b, a);
if (previous != null)
return previous;
}
// merge sorted payloads a + b => M
int i = 0; // walks a
int j = 0; // walks b
int k = 0; // walks target M array
int[] mergedReturnStates =
new int[a.returnStates.Length + b.returnStates.Length];
PredictionContext[] mergedParents =
new PredictionContext[a.returnStates.Length + b.returnStates.Length];
// walk and merge to yield mergedParents, mergedReturnStates
while (i < a.returnStates.Length && j < b.returnStates.Length)
{
PredictionContext a_parent = a.parents[i];
PredictionContext b_parent = b.parents[j];
if (a.returnStates[i] == b.returnStates[j])
{
// same payload (stack tops are equal), must yield merged singleton
int payload = a.returnStates[i];
// $+$ = $
bool both_dollar = payload == EMPTY_RETURN_STATE &&
a_parent == null && b_parent == null;
bool ax_ax = (a_parent != null && b_parent != null) &&
a_parent.Equals(b_parent); // ax+ax -> ax
if (both_dollar || ax_ax ) {
mergedParents[k] = a_parent; // choose left
mergedReturnStates[k] = payload;
}
else { // ax+ay -> a'[x,y]
PredictionContext mergedParent =
Merge(a_parent, b_parent, rootIsWildcard, mergeCache);
mergedParents[k] = mergedParent;
mergedReturnStates[k] = payload;
}
i++; // hop over left one as usual
j++; // but also skip one in right side since we merge
}
else if (a.returnStates[i] < b.returnStates[j])
{ // copy a[i] to M
mergedParents[k] = a_parent;
mergedReturnStates[k] = a.returnStates[i];
i++;
}
else { // b > a, copy b[j] to M
mergedParents[k] = b_parent;
mergedReturnStates[k] = b.returnStates[j];
j++;
}
k++;
}
// copy over any payloads remaining in either array
if (i < a.returnStates.Length)
{
for (int p = i; p < a.returnStates.Length; p++)
{
mergedParents[k] = a.parents[p];
mergedReturnStates[k] = a.returnStates[p];
k++;
}
}
else {
for (int p = j; p < b.returnStates.Length; p++)
{
mergedParents[k] = b.parents[p];
mergedReturnStates[k] = b.returnStates[p];
k++;
}
}
// trim merged if we combined a few that had same stack tops
if (k < mergedParents.Length)
{ // write index < last position; trim
if (k == 1)
{ // for just one merged element, return singleton top
PredictionContext a_ = SingletonPredictionContext.Create(mergedParents[0], mergedReturnStates[0]);
if (mergeCache != null) mergeCache.Put(a, b, a_);
return a_;
}
mergedParents = Arrays.CopyOf(mergedParents, k);
mergedReturnStates = Arrays.CopyOf(mergedReturnStates, k);
}
PredictionContext M = new ArrayPredictionContext(mergedParents, mergedReturnStates);
// if we created same array as a or b, return that instead
// TODO: track whether this is possible above during merge sort for speed
if (M.Equals(a))
{
if (mergeCache != null)
mergeCache.Put(a, b, a);
return a;
}
if (M.Equals(b))
{
if (mergeCache != null)
mergeCache.Put(a, b, b);
return b;
}
CombineCommonParents(mergedParents);
if (mergeCache != null)
mergeCache.Put(a, b, M);
return M;
}
protected static void CombineCommonParents(PredictionContext[] parents)
{
Dictionary<PredictionContext, PredictionContext> uniqueParents = new Dictionary<PredictionContext, PredictionContext>();
for (int p = 0; p < parents.Length; p++)
{
PredictionContext parent = parents[p];
if (!uniqueParents.ContainsKey(parent))
{ // don't replace
uniqueParents.Put(parent, parent);
}
}
for (int p = 0; p < parents.Length; p++)
{
parents[p] = uniqueParents.Get(parents[p]);
}
}
public static PredictionContext MergeRoot(SingletonPredictionContext a,
SingletonPredictionContext b,
bool rootIsWildcard)
{
if (rootIsWildcard)
{
if (a == PredictionContext.EMPTY)
return PredictionContext.EMPTY; // * + b = *
if (b == PredictionContext.EMPTY)
return PredictionContext.EMPTY; // a + * = *
}
else {
if (a == EMPTY && b == EMPTY) return EMPTY; // $ + $ = $
if (a == EMPTY)
{ // $ + x = [$,x]
int[] payloads = { b.returnState, EMPTY_RETURN_STATE };
PredictionContext[] parents = { b.parent, null };
PredictionContext joined =
new ArrayPredictionContext(parents, payloads);
return joined;
}
if (b == EMPTY)
{ // x + $ = [$,x] ($ is always first if present)
int[] payloads = { a.returnState, EMPTY_RETURN_STATE };
PredictionContext[] parents = { a.parent, null };
PredictionContext joined =
new ArrayPredictionContext(parents, payloads);
return joined;
}
}
return null;
}
public static PredictionContext GetCachedContext(PredictionContext context, PredictionContextCache contextCache, PredictionContext.IdentityHashMap visited)
{
if (context.IsEmpty)
{
return context;
}
PredictionContext existing = visited.Get(context);
if (existing != null)
{
return existing;
}
existing = contextCache.Get(context);
if (existing != null)
{
visited.Put(context, existing);
return existing;
}
bool changed = false;
PredictionContext[] parents = new PredictionContext[context.Size];
for (int i = 0; i < parents.Length; i++)
{
PredictionContext parent = GetCachedContext(context.GetParent(i), contextCache, visited);
if (changed || parent != context.GetParent(i))
{
if (!changed)
{
parents = new PredictionContext[context.Size];
for (int j = 0; j < context.Size; j++)
{
parents[j] = context.GetParent(j);
}
changed = true;
}
parents[i] = parent;
}
}
if (!changed)
{
contextCache.Add(context);
visited.Put(context, context);
return context;
}
PredictionContext updated;
if (parents.Length == 0)
{
updated = EMPTY;
}
else if (parents.Length == 1)
{
updated = SingletonPredictionContext.Create(parents[0], context.GetReturnState(0));
}
else {
ArrayPredictionContext arrayPredictionContext = (ArrayPredictionContext)context;
updated = new ArrayPredictionContext(parents, arrayPredictionContext.returnStates);
}
contextCache.Add(updated);
visited.Put(updated, updated);
visited.Put(context, updated);
return updated;
}
public virtual PredictionContext GetChild(int returnState)
{
return new SingletonPredictionContext(this, returnState);
}
public virtual string[] ToStrings(IRecognizer recognizer, int currentState)
{
return ToStrings(recognizer, PredictionContext.EMPTY, currentState);
}
public virtual string[] ToStrings(IRecognizer recognizer, PredictionContext stop, int currentState)
{
List<string> result = new List<string>();
for (int perm = 0; ; perm++)
{
int offset = 0;
bool last = true;
Antlr4.Runtime.Atn.PredictionContext p = this;
PredictionContext p = this;
int stateNumber = currentState;
StringBuilder localBuffer = new StringBuilder();
localBuffer.Append("[");
@ -430,7 +523,7 @@ namespace Antlr4.Runtime.Atn
}
else
{
if (p.GetReturnState(index) != EmptyFullStateKey)
if (p.GetReturnState(index) != EMPTY_RETURN_STATE)
{
if (!p.IsEmpty)
{

View File

@ -2,179 +2,46 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Used to cache
/// <see cref="PredictionContext"/>
/// objects. Its used for the shared
/// context cash associated with contexts in DFA states. This cache
/// can be used for both lexers and parsers.
/// </summary>
/// <author>Sam Harwell</author>
public class PredictionContextCache
{
public static readonly Antlr4.Runtime.Atn.PredictionContextCache Uncached = new Antlr4.Runtime.Atn.PredictionContextCache(false);
protected readonly Dictionary<PredictionContext, PredictionContext> cache =
new Dictionary<PredictionContext, PredictionContext>();
private readonly IDictionary<PredictionContext, PredictionContext> contexts = new Dictionary<PredictionContext, PredictionContext>();
private readonly IDictionary<PredictionContextCache.PredictionContextAndInt, PredictionContext> childContexts = new Dictionary<PredictionContextCache.PredictionContextAndInt, PredictionContext>();
private readonly IDictionary<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext> joinContexts = new Dictionary<PredictionContextCache.IdentityCommutativePredictionContextOperands, PredictionContext>();
private readonly bool enableCache;
public PredictionContextCache()
: this(true)
/** Add a context to the cache and return it. If the context already exists,
* return that one instead and do not add a new context to the cache.
* Protect shared cache from unsafe thread access.
*/
public PredictionContext Add(PredictionContext ctx)
{
if (ctx == PredictionContext.EMPTY)
return PredictionContext.EMPTY;
PredictionContext existing = cache.Get(ctx);
if (existing != null)
{
return existing;
}
cache.Put(ctx, ctx);
return ctx;
}
private PredictionContextCache(bool enableCache)
public PredictionContext Get(PredictionContext ctx)
{
this.enableCache = enableCache;
return cache.Get(ctx);
}
public virtual PredictionContext GetAsCached(PredictionContext context)
{
if (!enableCache)
{
return context;
}
PredictionContext result;
if (!contexts.TryGetValue(context, out result))
{
result = context;
contexts[context] = context;
}
return result;
}
public virtual PredictionContext GetChild(PredictionContext context, int invokingState)
{
if (!enableCache)
{
return context.GetChild(invokingState);
}
PredictionContextCache.PredictionContextAndInt operands = new PredictionContextCache.PredictionContextAndInt(context, invokingState);
PredictionContext result;
if (!childContexts.TryGetValue(operands, out result))
{
result = context.GetChild(invokingState);
result = GetAsCached(result);
childContexts[operands] = result;
}
return result;
}
public virtual PredictionContext Join(PredictionContext x, PredictionContext y)
{
if (!enableCache)
{
return PredictionContext.Join(x, y, this);
}
PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new PredictionContextCache.IdentityCommutativePredictionContextOperands(x, y);
PredictionContext result;
if (joinContexts.TryGetValue(operands, out result))
{
return result;
}
result = PredictionContext.Join(x, y, this);
result = GetAsCached(result);
joinContexts[operands] = result;
return result;
}
protected internal sealed class PredictionContextAndInt
{
private readonly PredictionContext obj;
private readonly int value;
public PredictionContextAndInt(PredictionContext obj, int value)
{
this.obj = obj;
this.value = value;
}
public override bool Equals(object obj)
{
if (!(obj is PredictionContextCache.PredictionContextAndInt))
{
return false;
}
else
{
if (obj == this)
{
return true;
}
}
PredictionContextCache.PredictionContextAndInt other = (PredictionContextCache.PredictionContextAndInt)obj;
return this.value == other.value && (this.obj == other.obj || (this.obj != null && this.obj.Equals(other.obj)));
}
public override int GetHashCode()
{
int hashCode = 5;
hashCode = 7 * hashCode + (obj != null ? obj.GetHashCode() : 0);
hashCode = 7 * hashCode + value;
return hashCode;
}
}
protected internal sealed class IdentityCommutativePredictionContextOperands
{
private readonly PredictionContext x;
private readonly PredictionContext y;
public IdentityCommutativePredictionContextOperands(PredictionContext x, PredictionContext y)
{
this.x = x;
this.y = y;
}
public PredictionContext X
public int Count
{
get
{
return x;
return cache.Count;
}
}
public PredictionContext Y
{
get
{
return y;
}
}
public override bool Equals(object obj)
{
if (!(obj is PredictionContextCache.IdentityCommutativePredictionContextOperands))
{
return false;
}
else
{
if (this == obj)
{
return true;
}
}
PredictionContextCache.IdentityCommutativePredictionContextOperands other = (PredictionContextCache.IdentityCommutativePredictionContextOperands)obj;
return (this.x == other.x && this.y == other.y) || (this.x == other.y && this.y == other.x);
}
public override int GetHashCode()
{
return x.GetHashCode() ^ y.GetHashCode();
}
}
}
}

View File

@ -33,21 +33,21 @@ namespace Antlr4.Runtime.Atn
/// <p>
/// When using this prediction mode, the parser will either return a correct
/// parse tree (i.e. the same parse tree that would be returned with the
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction mode), or it will report a syntax error. If a
/// syntax error is encountered when using the
/// <see cref="Sll"/>
/// <see cref="SLL"/>
/// prediction mode,
/// it may be due to either an actual syntax error in the input or indicate
/// that the particular combination of grammar and input requires the more
/// powerful
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction abilities to complete successfully.</p>
/// <p>
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode Sll = new PredictionMode();
public static readonly PredictionMode SLL = new PredictionMode();
/// <summary>The LL(*) prediction mode.</summary>
/// <remarks>
@ -66,13 +66,13 @@ namespace Antlr4.Runtime.Atn
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode Ll = new PredictionMode();
public static readonly PredictionMode LL = new PredictionMode();
/// <summary>The LL(*) prediction mode with exact ambiguity detection.</summary>
/// <remarks>
/// The LL(*) prediction mode with exact ambiguity detection. In addition to
/// the correctness guarantees provided by the
/// <see cref="Ll"/>
/// <see cref="LL"/>
/// prediction mode,
/// this prediction mode instructs the prediction algorithm to determine the
/// complete and exact set of ambiguous alternatives for every ambiguous
@ -86,7 +86,7 @@ namespace Antlr4.Runtime.Atn
/// This prediction mode does not provide any guarantees for prediction
/// behavior for syntactically-incorrect inputs.</p>
/// </remarks>
public static readonly PredictionMode LlExactAmbigDetection = new PredictionMode();
public static readonly PredictionMode LL_EXACT_AMBIG_DETECTION = new PredictionMode();
/// <summary>A Map that uses just the state and the stack context as the key.</summary>
/// <remarks>A Map that uses just the state and the stack context as the key.</remarks>
@ -116,8 +116,8 @@ namespace Antlr4.Runtime.Atn
public override int GetHashCode(ATNConfig o)
{
int hashCode = MurmurHash.Initialize(7);
hashCode = MurmurHash.Update(hashCode, o.State.stateNumber);
hashCode = MurmurHash.Update(hashCode, o.Context);
hashCode = MurmurHash.Update(hashCode, o.state.stateNumber);
hashCode = MurmurHash.Update(hashCode, o.context);
hashCode = MurmurHash.Finish(hashCode, 2);
return hashCode;
}
@ -132,7 +132,7 @@ namespace Antlr4.Runtime.Atn
{
return false;
}
return a.State.stateNumber == b.State.stateNumber && a.Context.Equals(b.Context);
return a.state.stateNumber == b.state.stateNumber && a.context.Equals(b.context);
}
}
@ -240,34 +240,33 @@ namespace Antlr4.Runtime.Atn
/// <see cref="ATNConfigSet"/>
/// will merge everything ignoring predicates.</p>
/// </remarks>
public static bool HasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet configs)
public static bool HasSLLConflictTerminatingPrediction(PredictionMode mode, ATNConfigSet configSet)
{
if (AllConfigsInRuleStopStates(configs))
if (AllConfigsInRuleStopStates(configSet.configs))
{
return true;
}
// pure SLL mode parsing
if (mode == PredictionMode.Sll)
if (mode == PredictionMode.SLL)
{
// Don't bother with combining configs from different semantic
// contexts if we can fail over to full LL; costs more time
// since we'll often fail over anyway.
if (configs.HasSemanticContext)
if (configSet.hasSemanticContext)
{
// dup configs, tossing out semantic predicates
ATNConfigSet dup = new ATNConfigSet();
foreach (ATNConfig c in configs)
foreach (ATNConfig c in configSet.configs)
{
c.Transform(c.State, SemanticContext.None, false);
dup.Add(c);
dup.Add(new ATNConfig(c, SemanticContext.NONE));
}
configs = dup;
configSet = dup;
}
}
// now we have combined contexts for configs with dissimilar preds
// pure SLL or combined SLL+LL mode parsing
ICollection<BitSet> altsets = GetConflictingAltSubsets(configs);
bool heuristic = HasConflictingAltSet(altsets) && !HasStateAssociatedWithOneAlt(configs);
ICollection<BitSet> altsets = GetConflictingAltSubsets(configSet.configs);
bool heuristic = HasConflictingAltSet(altsets) && !HasStateAssociatedWithOneAlt(configSet.configs);
return heuristic;
}
@ -295,7 +294,7 @@ namespace Antlr4.Runtime.Atn
{
foreach (ATNConfig c in configs)
{
if (c.State is RuleStopState)
if (c.state is RuleStopState)
{
return true;
}
@ -327,7 +326,7 @@ namespace Antlr4.Runtime.Atn
{
foreach (ATNConfig config in configs)
{
if (!(config.State is RuleStopState))
if (!(config.state is RuleStopState))
{
return false;
}
@ -751,7 +750,7 @@ namespace Antlr4.Runtime.Atn
/// Returns the unique alternative predicted by all alternative subsets in
/// <paramref name="altsets"/>
/// . If no such alternative exists, this method returns
/// <see cref="ATN.InvalidAltNumber"/>
/// <see cref="ATN.INVALID_ALT_NUMBER"/>
/// .
/// </summary>
/// <param name="altsets">a collection of alternative subsets</param>
@ -762,7 +761,7 @@ namespace Antlr4.Runtime.Atn
{
return all.NextSetBit(0);
}
return ATN.InvalidAltNumber;
return ATN.INVALID_ALT_NUMBER;
}
/// <summary>
@ -819,7 +818,7 @@ namespace Antlr4.Runtime.Atn
alts = new BitSet();
configToAlts[c] = alts;
}
alts.Set(c.Alt);
alts.Set(c.alt);
}
return configToAlts.Values;
}
@ -846,12 +845,12 @@ namespace Antlr4.Runtime.Atn
foreach (ATNConfig c in configs)
{
BitSet alts;
if (!m.TryGetValue(c.State, out alts))
if (!m.TryGetValue(c.state, out alts))
{
alts = new BitSet();
m[c.State] = alts;
m[c.state] = alts;
}
alts.Set(c.Alt);
alts.Set(c.alt);
}
return m;
}
@ -879,7 +878,7 @@ namespace Antlr4.Runtime.Atn
if (viableAlts.Cardinality() > 1)
{
// more than 1 viable alt
return ATN.InvalidAltNumber;
return ATN.INVALID_ALT_NUMBER;
}
}
return viableAlts.NextSetBit(0);

View File

@ -3,60 +3,51 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <since>4.3</since>
/**
* @since 4.3
*/
public class ProfilingATNSimulator : ParserATNSimulator
{
protected internal readonly Antlr4.Runtime.Atn.DecisionInfo[] decisions;
protected readonly DecisionInfo[] decisions;
protected int numDecisions;
protected internal int numDecisions;
protected int sllStopIndex;
protected int llStopIndex;
private ITokenStream _input;
protected int currentDecision;
protected DFAState currentState;
private int _startIndex;
private int _sllStopIndex;
private 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;
/** 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.
*/
protected int conflictingAltResolvedBySLL;
public ProfilingATNSimulator(Parser parser)
: base(parser, parser.Interpreter.atn)
: base(parser,
parser.Interpreter.atn,
parser.Interpreter.decisionToDFA,
parser.Interpreter.getSharedContextCache())
{
optimize_ll1 = false;
reportAmbiguities = true;
numDecisions = atn.decisionToState.Count;
decisions = new Antlr4.Runtime.Atn.DecisionInfo[numDecisions];
decisions = new DecisionInfo[numDecisions];
for (int i = 0; i < numDecisions; i++)
{
decisions[i] = new Antlr4.Runtime.Atn.DecisionInfo(i);
decisions[i] = new DecisionInfo(i);
}
}
@ -64,186 +55,188 @@ namespace Antlr4.Runtime.Atn
{
try
{
this._input = input;
this._startIndex = input.Index;
// it's possible for SLL to reach a conflict state without consuming any input
this._sllStopIndex = _startIndex - 1;
this._llStopIndex = -1;
this.sllStopIndex = -1;
this.llStopIndex = -1;
this.currentDecision = decision;
this.currentState = null;
this.conflictingAltResolvedBySLL = ATN.InvalidAltNumber;
// expensive but useful info
long start = DateTime.Now.ToFileTime(); // expensive but useful info
int alt = base.AdaptivePredict(input, decision, outerContext);
long stop = DateTime.Now.ToFileTime();
decisions[decision].timeInPrediction += (stop - start);
decisions[decision].invocations++;
int SLL_k = _sllStopIndex - _startIndex + 1;
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);
decisions[decision].SLL_MaxLookEvent =
new LookaheadEventInfo(decision, null/*, alt*/, input, startIndex, sllStopIndex, false);
}
if (_llStopIndex >= 0)
if (llStopIndex >= 0)
{
int LL_k = _llStopIndex - _startIndex + 1;
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);
decisions[decision].LL_MaxLookEvent =
new LookaheadEventInfo(decision, null/*, alt*/, 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.Add(new ErrorInfo(currentDecision, previous, _input, _startIndex, _input.Index));
}
currentState = reachState;
return reachState;
}
protected internal override DFAState GetExistingTargetState(DFAState previousD, int t)
protected 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;
}
// during SLL prediction
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].SLL_DFATransitions++; // count only if we transition over a DFA state
if (existingTargetState == ERROR)
{
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.Add(new ErrorInfo(currentDecision, state, _input, _startIndex, _input.Index));
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*previousD.configs*/, input, startIndex, sllStopIndex)
);
}
}
currentState = existingTargetState;
return existingTargetState;
}
protected internal override Tuple<DFAState, ParserRuleContext> ComputeTargetState(DFA dfa, DFAState s, ParserRuleContext remainingGlobalContext, int t, bool useContext, PredictionContextCache contextCache)
protected override DFAState ComputeTargetState(DFA dfa, DFAState previousD, int t)
{
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;
DFAState state = base.ComputeTargetState(dfa, previousD, t);
currentState = state;
return state;
}
protected internal override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt)
protected override ATNConfigSet ComputeReachSet(ATNConfigSet closure, int t, bool fullCtx)
{
bool result = base.EvalSemanticContext(pred, parserCallStack, alt);
if (!(pred is SemanticContext.PrecedencePredicate))
if (fullCtx)
{
bool fullContext = _llStopIndex >= 0;
int stopIndex = fullContext ? _llStopIndex : _sllStopIndex;
decisions[currentDecision].predicateEvals.Add(new PredicateEvalInfo(currentState, currentDecision, _input, _startIndex, stopIndex, pred, result, alt));
// this method is called after each time the input position advances
// during full context prediction
llStopIndex = input.Index;
}
ATNConfigSet reachConfigs = base.ComputeReachSet(closure, t, fullCtx);
if (fullCtx)
{
decisions[currentDecision].LL_ATNTransitions++; // count computation even if error
if (reachConfigs != null)
{
}
else { // no reach on current lookahead symbol. ERROR.
// TODO: does not handle delayed errors per getSynValidOrSemInvalidAltThatFinishedDecisionEntryRule()
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*closure*/, input, startIndex, llStopIndex)
);
}
}
else {
decisions[currentDecision].SLL_ATNTransitions++;
if (reachConfigs != null)
{
}
else { // no reach on current lookahead symbol. ERROR.
decisions[currentDecision].errors.Add(
new ErrorInfo(currentDecision, null /*closure*/, input, startIndex, sllStopIndex)
);
}
}
return reachConfigs;
}
protected override bool EvalSemanticContext(SemanticContext pred, ParserRuleContext parserCallStack, int alt, bool fullCtx)
{
bool result = base.EvalSemanticContext(pred, parserCallStack, alt, fullCtx);
if (!(pred is SemanticContext.PrecedencePredicate)) {
bool fullContext = llStopIndex >= 0;
int stopIndex = fullContext ? llStopIndex : sllStopIndex;
decisions[currentDecision].predicateEvals.Add(
new PredicateEvalInfo(null , currentDecision, input, startIndex, stopIndex, pred, result, alt/*, fullCtx*/)
);
}
return result;
}
protected internal override void ReportContextSensitivity(DFA dfa, int prediction, SimulatorState acceptState, int startIndex, int stopIndex)
{
if (prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add(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)
protected override void ReportAttemptingFullContext(DFA dfa, BitSet conflictingAlts, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (conflictingAlts != null)
{
conflictingAltResolvedBySLL = conflictingAlts.NextSetBit(0);
}
else
{
conflictingAltResolvedBySLL = conflictState.s0.configs.RepresentedAlternatives.NextSetBit(0);
else {
conflictingAltResolvedBySLL = configs.GetAlts().NextSetBit(0);
}
decisions[currentDecision].LL_Fallback++;
base.ReportAttemptingFullContext(dfa, conflictingAlts, conflictState, startIndex, stopIndex);
base.ReportAttemptingFullContext(dfa, conflictingAlts, configs, startIndex, stopIndex);
}
protected internal override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact, BitSet ambigAlts, ATNConfigSet configs)
protected override void ReportContextSensitivity(DFA dfa, int prediction, ATNConfigSet configs, int startIndex, int stopIndex)
{
if (prediction != conflictingAltResolvedBySLL)
{
decisions[currentDecision].contextSensitivities.Add(
new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex)
);
}
base.ReportContextSensitivity(dfa, prediction, configs, startIndex, stopIndex);
}
protected override void ReportAmbiguity(DFA dfa, DFAState D, int startIndex, int stopIndex, bool exact,
BitSet ambigAlts, ATNConfigSet configSet)
{
int prediction;
if (ambigAlts != null)
{
prediction = ambigAlts.NextSetBit(0);
}
else
{
prediction = configs.RepresentedAlternatives.NextSetBit(0);
else {
prediction = configSet.GetAlts().NextSetBit(0);
}
if (conflictingAltResolvedBySLL != ATN.InvalidAltNumber && prediction != conflictingAltResolvedBySLL)
if (configSet.fullCtx && 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.Add(new ContextSensitivityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
decisions[currentDecision].contextSensitivities.Add( new ContextSensitivityInfo(currentDecision, null /*configs*/, input, startIndex, stopIndex) );
}
decisions[currentDecision].ambiguities.Add(new AmbiguityInfo(currentDecision, currentState, _input, startIndex, stopIndex));
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configs);
decisions[currentDecision].ambiguities.Add(
new AmbiguityInfo(currentDecision, null /*configs, ambigAlts*/,
input, startIndex, stopIndex/*, configs.IsFullContext*/)
);
base.ReportAmbiguity(dfa, D, startIndex, stopIndex, exact, ambigAlts, configSet);
}
public virtual Antlr4.Runtime.Atn.DecisionInfo[] DecisionInfo
{
get
{
// ---------------------------------------------------------------------
public DecisionInfo[] getDecisionInfo()
{
return decisions;
}
public DFAState getCurrentState()
{
return currentState;
}
}
}

View File

@ -25,7 +25,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Range;
return Antlr4.Runtime.Atn.TransitionType.RANGE;
}
}

View File

@ -3,9 +3,7 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
@ -43,7 +41,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Rule;
return Antlr4.Runtime.Atn.TransitionType.RULE;
}
}

View File

@ -5,98 +5,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// A tree structure used to record the semantic context in which
/// an ATN configuration is valid.
/// </summary>
/// <remarks>
/// A tree structure used to record the semantic context in which
/// an ATN configuration is valid. It's either a single predicate,
/// a conjunction
/// <c>p1&amp;&amp;p2</c>
/// , or a sum of products
/// <c>p1||p2</c>
/// .
/// <p>I have scoped the
/// <see cref="AND"/>
/// ,
/// <see cref="OR"/>
/// , and
/// <see cref="Predicate"/>
/// subclasses of
/// <see cref="SemanticContext"/>
/// within the scope of this outer class.</p>
/// </remarks>
public abstract class SemanticContext
{
/// <summary>
/// The default
/// <see cref="SemanticContext"/>
/// , which is semantically equivalent to
/// a predicate of the form
/// <c/>
///
/// true}?}.
/// </summary>
public static readonly SemanticContext None = new SemanticContext.Predicate();
public static readonly SemanticContext NONE = new SemanticContext.Predicate();
/// <summary>
/// For context independent predicates, we evaluate them without a local
/// context (i.e., null context).
/// </summary>
/// <remarks>
/// For context independent predicates, we evaluate them without a local
/// context (i.e., null context). That way, we can evaluate them without
/// having to create proper rule-specific context during prediction (as
/// opposed to the parser, which creates them naturally). In a practical
/// sense, this avoids a cast exception from RuleContext to myruleContext.
/// <p>For context dependent predicates, we must pass in a local context so that
/// references such as $arg evaluate properly as _localctx.arg. We only
/// capture context dependent predicates in the context in which we begin
/// 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 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="parserCallStack"/>
/// <returns>
/// The simplified semantic context after precedence predicates are
/// evaluated, which will be one of the following values.
/// <ul>
/// <li>
/// <see cref="None"/>
/// : if the predicate simplifies to
/// <see langword="true"/>
/// after
/// precedence predicates are evaluated.</li>
/// <li>
/// <see langword="null"/>
/// : if the predicate simplifies to
/// <see langword="false"/>
/// after
/// precedence predicates are evaluated.</li>
/// <li>
/// <c>this</c>
/// : if the semantic context is not changed as a result of
/// precedence predicate evaluation.</li>
/// <li>A non-
/// <see langword="null"/>
///
/// <see cref="SemanticContext"/>
/// : the new simplified
/// semantic context after precedence predicates are evaluated.</li>
/// </ul>
/// </returns>
public virtual SemanticContext EvalPrecedence<Symbol, ATNInterpreter>(Recognizer<Symbol, ATNInterpreter> parser, RuleContext parserCallStack)
where ATNInterpreter : ATNSimulator
{
@ -185,7 +105,7 @@ namespace Antlr4.Runtime.Atn
{
if (parser.Precpred(parserCallStack, precedence))
{
return SemanticContext.None;
return SemanticContext.NONE;
}
else
{
@ -226,26 +146,8 @@ namespace Antlr4.Runtime.Atn
}
}
/// <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"/>
/// operands for the
/// operator.
/// </returns>
/// <since>4.3</since>
[NotNull]
public abstract ICollection<SemanticContext> Operands
{
@ -253,14 +155,6 @@ namespace Antlr4.Runtime.Atn
}
}
/// <summary>
/// A semantic context which is true whenever none of the contained contexts
/// is false.
/// </summary>
/// <remarks>
/// A semantic context which is true whenever none of the contained contexts
/// is false.
/// </remarks>
public class AND : SemanticContext.Operator
{
[NotNull]
@ -322,12 +216,6 @@ namespace Antlr4.Runtime.Atn
return MurmurHash.HashCode(opnds, typeof(SemanticContext.AND).GetHashCode());
}
/// <summary>
/// <inheritDoc/>
/// <p>
/// 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 parserCallStack)
{
foreach (SemanticContext opnd in opnds)
@ -355,7 +243,7 @@ namespace Antlr4.Runtime.Atn
}
else
{
if (evaluated != None)
if (evaluated != NONE)
{
// Reduce the result by skipping true elements
operands.Add(evaluated);
@ -369,7 +257,7 @@ namespace Antlr4.Runtime.Atn
if (operands.Count == 0)
{
// all elements were true, so the AND context is true
return None;
return NONE;
}
SemanticContext result = operands[0];
for (int i = 1; i < operands.Count; i++)
@ -385,14 +273,6 @@ namespace Antlr4.Runtime.Atn
}
}
/// <summary>
/// A semantic context which is true whenever at least one of the contained
/// contexts is true.
/// </summary>
/// <remarks>
/// A semantic context which is true whenever at least one of the contained
/// contexts is true.
/// </remarks>
public class OR : SemanticContext.Operator
{
[NotNull]
@ -454,12 +334,6 @@ namespace Antlr4.Runtime.Atn
return MurmurHash.HashCode(opnds, typeof(SemanticContext.OR).GetHashCode());
}
/// <summary>
/// <inheritDoc/>
/// <p>
/// 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 parserCallStack)
{
foreach (SemanticContext opnd in opnds)
@ -480,10 +354,10 @@ namespace Antlr4.Runtime.Atn
{
SemanticContext evaluated = context.EvalPrecedence(parser, parserCallStack);
differs |= (evaluated != context);
if (evaluated == None)
if (evaluated == NONE)
{
// The OR context is true if any element is true
return None;
return NONE;
}
else
{
@ -519,11 +393,11 @@ namespace Antlr4.Runtime.Atn
public static SemanticContext AndOp(SemanticContext a, SemanticContext b)
{
if (a == null || a == None)
if (a == null || a == NONE)
{
return b;
}
if (b == null || b == None)
if (b == null || b == NONE)
{
return a;
}
@ -535,7 +409,6 @@ namespace Antlr4.Runtime.Atn
return result;
}
/// <seealso cref="ParserATNSimulator.GetPredsForAmbigAlts(Antlr4.Runtime.Sharpen.BitSet, ATNConfigSet, int)"/>
public static SemanticContext OrOp(SemanticContext a, SemanticContext b)
{
if (a == null)
@ -546,9 +419,9 @@ namespace Antlr4.Runtime.Atn
{
return a;
}
if (a == None || b == None)
if (a == NONE || b == NONE)
{
return None;
return NONE;
}
SemanticContext.OR result = new SemanticContext.OR(a, b);
if (result.opnds.Length == 1)

View File

@ -30,7 +30,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Set;
return Antlr4.Runtime.Atn.TransitionType.SET;
}
}

View File

@ -2,15 +2,24 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
#pragma warning disable 0659 // 'class' overrides Object.Equals(object o) but does not override Object.GetHashCode()
public class SingletonPredictionContext : PredictionContext
{
public static PredictionContext Create(PredictionContext parent, int returnState)
{
if (returnState == EMPTY_RETURN_STATE && parent == null)
{
// someone can pass in the bits of an array ctx that mean $
return PredictionContext.EMPTY;
}
return new SingletonPredictionContext(parent, returnState);
}
[NotNull]
public readonly PredictionContext parent;
@ -19,7 +28,6 @@ namespace Antlr4.Runtime.Atn
internal SingletonPredictionContext(PredictionContext parent, int returnState)
: base(CalculateHashCode(parent, returnState))
{
System.Diagnostics.Debug.Assert(returnState != EmptyFullStateKey && returnState != EmptyLocalStateKey);
this.parent = parent;
this.returnState = returnState;
}
@ -36,10 +44,6 @@ namespace Antlr4.Runtime.Atn
return returnState;
}
public override int FindReturnState(int returnState)
{
return this.returnState == returnState ? 0 : -1;
}
public override int Size
{
@ -57,31 +61,6 @@ namespace Antlr4.Runtime.Atn
}
}
public override bool HasEmpty
{
get
{
return false;
}
}
public override PredictionContext AppendContext(PredictionContext suffix, PredictionContextCache contextCache)
{
return contextCache.GetChild(parent.AppendContext(suffix, contextCache), returnState);
}
protected internal override PredictionContext AddEmptyContext()
{
PredictionContext[] parents = new PredictionContext[] { parent, EmptyFull };
int[] returnStates = new int[] { returnState, EmptyFullStateKey };
return new ArrayPredictionContext(parents, returnStates);
}
protected internal override PredictionContext RemoveEmptyContext()
{
return this;
}
public override bool Equals(object o)
{
if (o == this)
@ -95,12 +74,26 @@ namespace Antlr4.Runtime.Atn
return false;
}
}
Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext)o;
if (this.GetHashCode() != other.GetHashCode())
if (this.GetHashCode() != o.GetHashCode())
{
return false;
}
Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext)o;
return returnState == other.returnState && parent.Equals(other.parent);
}
public override string ToString()
{
string up = parent != null ? parent.ToString() : "";
if (up.Length == 0)
{
if (returnState == EMPTY_RETURN_STATE)
{
return "$";
}
return returnState.ToString();
}
return returnState.ToString() + " " + up;
}
}
}

View File

@ -2,8 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
@ -26,7 +24,7 @@ namespace Antlr4.Runtime.Atn
/// .</p>
/// </remarks>
/// <seealso cref="Antlr4.Runtime.Dfa.DFA.IsPrecedenceDfa()"/>
public bool precedenceRuleDecision;
public bool isPrecedenceDecision;
public override Antlr4.Runtime.Atn.StateType StateType
{

View File

@ -2,8 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{

View File

@ -2,8 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{

View File

@ -2,19 +2,17 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>The Tokens rule start state linking to each lexer rule start state</summary>
public sealed class TokensStartState : DecisionState
{
public override Antlr4.Runtime.Atn.StateType StateType
public override StateType StateType
{
get
{
return Antlr4.Runtime.Atn.StateType.TokenStart;
return StateType.TokenStart;
}
}
}

View File

@ -3,9 +3,7 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;

View File

@ -2,23 +2,21 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
public enum TransitionType
{
Invalid,
Epsilon,
Range,
Rule,
Predicate,
Atom,
Action,
Set,
NotSet,
Wildcard,
Precedence
INVALID,
EPSILON,
RANGE,
RULE,
PREDICATE,
ATOM,
ACTION,
SET,
NOT_SET,
WILDCARD,
PRECEDENCE
}
}

View File

@ -2,9 +2,7 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Atn
{
@ -19,7 +17,7 @@ namespace Antlr4.Runtime.Atn
{
get
{
return Antlr4.Runtime.Atn.TransitionType.Wildcard;
return Antlr4.Runtime.Atn.TransitionType.WILDCARD;
}
}

View File

@ -64,7 +64,7 @@ namespace Antlr4.Runtime
/// <see cref="p"/>
/// <c>]</c>
/// should be
/// <see cref="Lt(int)">LT(1)</see>
/// <see cref="LT(int)">LT(1)</see>
/// .
/// <p>This field is set to -1 when the stream is first constructed or when
/// <see cref="SetTokenSource(ITokenSource)"/>
@ -79,7 +79,7 @@ namespace Antlr4.Runtime
/// <summary>
/// Indicates whether the
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// token has been fetched from
/// <see cref="_tokenSource"/>
/// and added to
@ -97,7 +97,7 @@ namespace Antlr4.Runtime
/// and
/// <see cref="p"/>
/// instead of calling
/// <see cref="La(int)"/>
/// <see cref="LA(int)"/>
/// .</li>
/// <li>
/// <see cref="Fetch(int)"/>
@ -184,7 +184,7 @@ namespace Antlr4.Runtime
// not yet initialized
skipEofCheck = false;
}
if (!skipEofCheck && La(1) == IntStreamConstants.Eof)
if (!skipEofCheck && LA(1) == IntStreamConstants.EOF)
{
throw new InvalidOperationException("cannot consume EOF");
}
@ -243,7 +243,7 @@ namespace Antlr4.Runtime
((IWritableToken)t).TokenIndex = tokens.Count;
}
tokens.Add(t);
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
fetchedEOF = true;
return i + 1;
@ -278,7 +278,7 @@ namespace Antlr4.Runtime
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}
@ -287,9 +287,9 @@ namespace Antlr4.Runtime
return subset;
}
public virtual int La(int i)
public virtual int LA(int i)
{
return Lt(i).Type;
return LT(i).Type;
}
protected internal virtual IToken Lb(int k)
@ -302,7 +302,7 @@ namespace Antlr4.Runtime
}
[return: NotNull]
public virtual IToken Lt(int k)
public virtual IToken LT(int k)
{
LazyInit();
if (k == 0)
@ -452,7 +452,7 @@ namespace Antlr4.Runtime
IToken token = tokens[i];
while (token.Channel != channel)
{
if (token.Type == TokenConstants.Eof)
if (token.Type == TokenConstants.EOF)
{
return i;
}
@ -495,7 +495,7 @@ namespace Antlr4.Runtime
while (i >= 0)
{
IToken token = tokens[i];
if (token.Type == TokenConstants.Eof || token.Channel == channel)
if (token.Type == TokenConstants.EOF || token.Channel == channel)
{
return i;
}
@ -656,7 +656,7 @@ namespace Antlr4.Runtime
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}

View File

@ -20,9 +20,9 @@ namespace Antlr4.Runtime
/// <see cref="BufferedTokenStream.GetText()"/>
/// . The channel filtering is only used for code
/// accessing tokens via the lookahead methods
/// <see cref="BufferedTokenStream.La(int)"/>
/// <see cref="BufferedTokenStream.LA(int)"/>
/// ,
/// <see cref="Lt(int)"/>
/// <see cref="LT(int)"/>
/// , and
/// <see cref="Lb(int)"/>
/// .</p>
@ -84,7 +84,7 @@ namespace Antlr4.Runtime
/// or have the
/// <see cref="IToken.Type()"/>
/// equal to
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// will be returned by the
/// token stream lookahead methods.
/// </summary>
@ -123,7 +123,7 @@ namespace Antlr4.Runtime
return tokens[i];
}
public override IToken Lt(int k)
public override IToken LT(int k)
{
//System.out.println("enter LT("+k+")");
LazyInit();
@ -165,7 +165,7 @@ namespace Antlr4.Runtime
{
n++;
}
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
break;
}

View File

@ -263,9 +263,9 @@ namespace Antlr4.Runtime
return;
}
ITokenStream tokens = ((ITokenStream)recognizer.InputStream);
int la = tokens.La(1);
int la = tokens.LA(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.Eof)
if (recognizer.Atn.NextTokens(s).Contains(la) || la == TokenConstants.EOF)
{
return;
}
@ -324,7 +324,7 @@ namespace Antlr4.Runtime
string input;
if (tokens != null)
{
if (e.StartToken.Type == TokenConstants.Eof)
if (e.StartToken.Type == TokenConstants.EOF)
{
input = "<EOF>";
}
@ -588,15 +588,14 @@ namespace Antlr4.Runtime
/// </returns>
protected internal virtual bool SingleTokenInsertion(Parser recognizer)
{
int currentSymbolType = ((ITokenStream)recognizer.InputStream).La(1);
int currentSymbolType = ((ITokenStream)recognizer.InputStream).LA(1);
// if current token is consistent with what could come after current
// ATN state, then we know we're missing a token; error recovery
// is free to conjure up and insert the missing token
ATNState currentState = recognizer.Interpreter.atn.states[recognizer.State];
ATNState next = currentState.Transition(0).target;
ATN atn = recognizer.Interpreter.atn;
IntervalSet expectingAtLL2 = atn.NextTokens(next, PredictionContext.FromRuleContext(atn, recognizer.RuleContext));
// System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
IntervalSet expectingAtLL2 = atn.NextTokens(next, recognizer.RuleContext);
if (expectingAtLL2.Contains(currentSymbolType))
{
ReportMissingToken(recognizer);
@ -640,7 +639,7 @@ namespace Antlr4.Runtime
[return: Nullable]
protected internal virtual IToken SingleTokenDeletion(Parser recognizer)
{
int nextTokenType = ((ITokenStream)recognizer.InputStream).La(2);
int nextTokenType = ((ITokenStream)recognizer.InputStream).LA(2);
IntervalSet expecting = GetExpectedTokens(recognizer);
if (expecting.Contains(nextTokenType))
{
@ -684,7 +683,7 @@ namespace Antlr4.Runtime
int expectedTokenType = expecting.MinElement;
// get any element
string tokenText;
if (expectedTokenType == TokenConstants.Eof)
if (expectedTokenType == TokenConstants.EOF)
{
tokenText = "<missing EOF>";
}
@ -693,8 +692,8 @@ namespace Antlr4.Runtime
tokenText = "<missing " + recognizer.Vocabulary.GetDisplayName(expectedTokenType) + ">";
}
IToken current = currentSymbol;
IToken lookback = ((ITokenStream)recognizer.InputStream).Lt(-1);
if (current.Type == TokenConstants.Eof && lookback != null)
IToken lookback = ((ITokenStream)recognizer.InputStream).LT(-1);
if (current.Type == TokenConstants.EOF && lookback != null)
{
current = lookback;
}
@ -736,7 +735,7 @@ namespace Antlr4.Runtime
string s = GetSymbolText(t);
if (s == null)
{
if (GetSymbolType(t) == TokenConstants.Eof)
if (GetSymbolType(t) == TokenConstants.EOF)
{
s = "<EOF>";
}
@ -783,7 +782,7 @@ namespace Antlr4.Runtime
recoverSet.AddAll(follow);
ctx = ctx.Parent;
}
recoverSet.Remove(TokenConstants.Epsilon);
recoverSet.Remove(TokenConstants.EPSILON);
// System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
return recoverSet;
}
@ -793,13 +792,13 @@ namespace Antlr4.Runtime
protected internal virtual void ConsumeUntil(Parser recognizer, IntervalSet set)
{
// System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")");
int ttype = ((ITokenStream)recognizer.InputStream).La(1);
while (ttype != TokenConstants.Eof && !set.Contains(ttype))
int ttype = ((ITokenStream)recognizer.InputStream).LA(1);
while (ttype != TokenConstants.EOF && !set.Contains(ttype))
{
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
// recognizer.getInputStream().consume();
recognizer.Consume();
ttype = ((ITokenStream)recognizer.InputStream).La(1);
ttype = ((ITokenStream)recognizer.InputStream).LA(1);
}
}
}

View File

@ -3,333 +3,166 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
using Interlocked = System.Threading.Interlocked;
namespace Antlr4.Runtime.Dfa
{
public class DFA
{
/// <summary>A set of all DFA states.</summary>
/// <remarks>
/// A set of all DFA states. Use
/// <see cref="System.Collections.Generic.IDictionary{K, V}"/>
/// so we can get old state back
/// (
/// <see cref="HashSet{T}"/>
/// only allows you to see if it's there).
/// </remarks>
[NotNull]
public readonly ConcurrentDictionary<DFAState, DFAState> states = new ConcurrentDictionary<DFAState, DFAState>();
/** A set of all DFA states. Use {@link Map} so we can get old state back
* ({@link Set} only allows you to see if it's there).
*/
[NotNull]
public readonly AtomicReference<DFAState> s0 = new AtomicReference<DFAState>();
public Dictionary<DFAState, DFAState> states = new Dictionary<DFAState, DFAState>();
[NotNull]
public readonly AtomicReference<DFAState> s0full = new AtomicReference<DFAState>();
public DFAState s0;
public readonly int decision;
public int decision;
/// <summary>From which ATN state did we create this DFA?</summary>
[NotNull]
public readonly ATNState atnStartState;
/** From which ATN state did we create this DFA? */
private int nextStateNumber;
public DecisionState atnStartState;
private readonly int minDfaEdge;
/**
* {@code true} if this DFA is for a precedence decision; otherwise,
* {@code false}. This is the backing field for {@link #isPrecedenceDfa}.
*/
private bool precedenceDfa;
private readonly int maxDfaEdge;
[NotNull]
private static readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyPrecedenceEdges = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(0, 200);
[NotNull]
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyEdgeMap;
[NotNull]
private readonly Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> emptyContextEdgeMap;
/// <summary>
/// <see langword="true"/>
/// if this DFA is for a precedence decision; otherwise,
/// <see langword="false"/>
/// . This is the backing field for <see cref="IsPrecedenceDfa"/>.
/// </summary>
private volatile bool precedenceDfa;
public DFA(ATNState atnStartState)
public DFA(DecisionState atnStartState)
: this(atnStartState, 0)
{
}
public DFA(ATNState atnStartState, int decision)
public DFA(DecisionState atnStartState, int decision)
{
this.atnStartState = atnStartState;
this.decision = decision;
if (this.atnStartState.atn.grammarType == ATNType.Lexer)
{
minDfaEdge = LexerATNSimulator.MinDfaEdge;
maxDfaEdge = LexerATNSimulator.MaxDfaEdge;
}
else
{
minDfaEdge = TokenConstants.Eof;
maxDfaEdge = atnStartState.atn.maxTokenType;
}
this.emptyEdgeMap = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(minDfaEdge, maxDfaEdge);
this.emptyContextEdgeMap = new Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState>(-1, atnStartState.atn.states.Count - 1);
}
public int MinDfaEdge
this.precedenceDfa = false;
if (atnStartState is StarLoopEntryState && ((StarLoopEntryState)atnStartState).isPrecedenceDecision)
{
get
{
return minDfaEdge;
this.precedenceDfa = true;
DFAState precedenceState = new DFAState(new ATNConfigSet());
precedenceState.edges = new DFAState[0];
precedenceState.isAcceptState = false;
precedenceState.requiresFullContext = false;
this.s0 = precedenceState;
}
}
public int MaxDfaEdge
{
get
{
return maxDfaEdge;
}
}
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyEdgeMap
{
get
{
return emptyEdgeMap;
}
}
public virtual Antlr4.Runtime.Dfa.EmptyEdgeMap<DFAState> EmptyContextEdgeMap
{
get
{
return emptyContextEdgeMap;
}
}
/// <summary>Gets whether this DFA is a precedence DFA.</summary>
/// <remarks>
/// Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
/// start state
/// <see cref="s0"/>
/// which is not stored in
/// <see cref="states"/>
/// . The
/// <see cref="DFAState.edges"/>
/// array for this start state contains outgoing edges
/// supplying individual start states corresponding to specific precedence
/// values.
/// </remarks>
/// <returns>
///
/// <see langword="true"/>
/// if this is a precedence DFA; otherwise,
/// <see langword="false"/>
/// .
/// </returns>
/// <seealso cref="Antlr4.Runtime.Parser.Precedence()"/>
/// <summary>Sets whether this is a precedence DFA.</summary>
/// <remarks>
/// Sets whether this is a precedence DFA. If the specified value differs
/// from the current DFA configuration, the following actions are taken;
/// otherwise no changes are made to the current DFA.
/// <ul>
/// <li>The
/// <see cref="states"/>
/// map is cleared</li>
/// <li>If
/// <c>precedenceDfa</c>
/// is
/// <see langword="false"/>
/// , the initial state
/// <see cref="s0"/>
/// is set to
/// <see langword="null"/>
/// ; otherwise, it is initialized to a new
/// <see cref="DFAState"/>
/// with an empty outgoing
/// <see cref="DFAState.edges"/>
/// array to
/// store the start states for individual precedence values.</li>
/// <li>The
/// <see cref="precedenceDfa"/>
/// field is updated</li>
/// </ul>
/// </remarks>
/// <value>
///
/// <see langword="true"/>
/// if this is a precedence DFA; otherwise,
/// <see langword="false"/>
/// </value>
/**
* Gets whether this DFA is a precedence DFA. Precedence DFAs use a special
* start state {@link #s0} which is not stored in {@link #states}. The
* {@link DFAState#edges} array for this start state contains outgoing edges
* supplying individual start states corresponding to specific precedence
* values.
*
* @return {@code true} if this is a precedence DFA; otherwise,
* {@code false}.
* @see Parser#getPrecedence()
*/
public bool IsPrecedenceDfa
{
get
{
return precedenceDfa;
}
set
{
bool precedenceDfa = value;
// s0.get() and s0full.get() are never null for a precedence DFA
// s0full.get() is never null for a precedence DFA
// s0.get() is never null for a precedence DFA
lock (this)
{
if (this.precedenceDfa != precedenceDfa)
{
this.states.Clear();
if (precedenceDfa)
{
this.s0.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
this.s0full.Set(new DFAState(emptyPrecedenceEdges, EmptyContextEdgeMap, new ATNConfigSet()));
}
else
{
this.s0.Set(null);
this.s0full.Set(null);
}
this.precedenceDfa = precedenceDfa;
}
}
}
}
/// <summary>Get the start state for a specific precedence value.</summary>
/// <remarks>Get the start state for a specific precedence value.</remarks>
/// <param name="precedence">The current precedence.</param>
/// <param name="fullContext">Whether to get from local of full context.</param>
/// <returns>
/// The start state corresponding to the specified precedence, or
/// <see langword="null"/>
/// if no start state exists for the specified precedence.
/// </returns>
/// <exception cref="System.InvalidOperationException">if this is not a precedence DFA.</exception>
/// <seealso cref="IsPrecedenceDfa()"/>
public DFAState GetPrecedenceStartState(int precedence, bool fullContext)
/**
* Get the start state for a specific precedence value.
*
* @param precedence The current precedence.
* @return The start state corresponding to the specified precedence, or
* {@code null} if no start state exists for the specified precedence.
*
* @throws IllegalStateException if this is not a precedence DFA.
* @see #isPrecedenceDfa()
*/
public DFAState GetPrecedenceStartState(int precedence)
{
if (!IsPrecedenceDfa)
{
throw new InvalidOperationException("Only precedence DFAs may contain a precedence start state.");
}
if (fullContext)
{
return s0full.Get().GetTarget(precedence);
}
else
{
return s0.Get().GetTarget(precedence);
}
throw new Exception("Only precedence DFAs may contain a precedence start state.");
}
/// <summary>Set the start state for a specific precedence value.</summary>
/// <remarks>Set the start state for a specific precedence value.</remarks>
/// <param name="precedence">The current precedence.</param>
/// <param name="fullContext">Whether to set local of full context.</param>
/// <param name="startState">
/// The start state corresponding to the specified
/// precedence.
/// </param>
/// <exception cref="System.InvalidOperationException">if this is not a precedence DFA.</exception>
/// <seealso cref="IsPrecedenceDfa()"/>
public void SetPrecedenceStartState(int precedence, bool fullContext, DFAState startState)
// s0.edges is never null for a precedence DFA
if (precedence < 0 || precedence >= s0.edges.Length)
{
return null;
}
return s0.edges[precedence];
}
/**
* Set the start state for a specific precedence value.
*
* @param precedence The current precedence.
* @param startState The start state corresponding to the specified
* precedence.
*
* @throws IllegalStateException if this is not a precedence DFA.
* @see #isPrecedenceDfa()
*/
public void SetPrecedenceStartState(int precedence, DFAState startState)
{
if (!IsPrecedenceDfa)
{
throw new InvalidOperationException("Only precedence DFAs may contain a precedence start state.");
throw new Exception("Only precedence DFAs may contain a precedence start state.");
}
if (precedence < 0)
{
return;
}
if (fullContext)
{
lock (s0full)
{
s0full.Get().SetTarget(precedence, startState);
}
}
else
{
// synchronization on s0 here is ok. when the DFA is turned into a
// precedence DFA, s0 will be initialized once and not updated again
lock (s0)
{
s0.Get().SetTarget(precedence, startState);
// s0.edges is never null for a precedence DFA
if (precedence >= s0.edges.Length)
{
s0.edges = Arrays.CopyOf(s0.edges, precedence + 1);
}
s0.edges[precedence] = startState;
}
}
public virtual bool IsEmpty
/**
* Return a list of all states in this DFA, ordered by state number.
*/
public List<DFAState> GetStates()
{
get
{
if (IsPrecedenceDfa)
{
return s0.Get().EdgeMap.Count == 0 && s0full.Get().EdgeMap.Count == 0;
}
return s0.Get() == null && s0full.Get() == null;
}
List<DFAState> result = new List<DFAState>(states.Keys);
result.Sort((x, y) => x.stateNumber - y.stateNumber);
return result;
}
public virtual bool IsContextSensitive
public override String ToString() { return ToString(Vocabulary.EmptyVocabulary); }
public String ToString(IVocabulary vocabulary)
{
get
if (s0 == null)
{
if (IsPrecedenceDfa)
{
return s0full.Get().EdgeMap.Count != 0;
}
return s0full.Get() != null;
}
return "";
}
public virtual DFAState AddState(DFAState state)
{
state.stateNumber = Interlocked.Increment(ref nextStateNumber) - 1;
return states.GetOrAdd(state, state);
}
public override string ToString()
{
return ToString(Vocabulary.EmptyVocabulary);
}
public virtual string ToString(IVocabulary vocabulary)
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new DFASerializer(this, vocabulary);
return serializer.ToString();
}
public virtual string ToString(IVocabulary vocabulary, string[] ruleNames)
public String ToLexerString()
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new DFASerializer(this, vocabulary, ruleNames, atnStartState.atn);
return serializer.ToString();
}
public virtual string ToLexerString()
{
if (s0.Get() == null)
{
return string.Empty;
}
if (s0 == null)
return "";
DFASerializer serializer = new LexerDFASerializer(this);
return serializer.ToString();
}

View File

@ -5,9 +5,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -49,7 +47,7 @@ namespace Antlr4.Runtime.Dfa
public override string ToString()
{
if (dfa.s0.Get() == null)
if (dfa.s0 == null)
{
return null;
}
@ -57,42 +55,22 @@ namespace Antlr4.Runtime.Dfa
if (dfa.states != null)
{
List<DFAState> states = new List<DFAState>(dfa.states.Values);
states.Sort(new _IComparer_103());
states.Sort((x,y)=>x.stateNumber - y.stateNumber);
foreach (DFAState s in states)
{
IEnumerable<KeyValuePair<int, DFAState>> edges = s.EdgeMap;
IEnumerable<KeyValuePair<int, DFAState>> contextEdges = s.ContextEdgeMap;
foreach (KeyValuePair<int, DFAState> entry in edges)
int n = s.edges != null ? s.edges.Length : 0;
for (int i = 0; i < n; i++)
{
if ((entry.Value == null || entry.Value == ATNSimulator.Error) && !s.IsContextSymbol(entry.Key))
{
continue;
}
bool contextSymbol = false;
buf.Append(GetStateString(s)).Append("-").Append(GetEdgeLabel(entry.Key)).Append("->");
if (s.IsContextSymbol(entry.Key))
{
buf.Append("!");
contextSymbol = true;
}
DFAState t = entry.Value;
DFAState t = s.edges[i];
if (t != null && t.stateNumber != int.MaxValue)
{
buf.Append(GetStateString(t)).Append('\n');
}
else
{
if (contextSymbol)
{
buf.Append("ctx\n");
}
}
}
if (s.IsContextSensitive)
{
foreach (KeyValuePair<int, DFAState> entry_1 in contextEdges)
{
buf.Append(GetStateString(s)).Append("-").Append(GetContextLabel(entry_1.Key)).Append("->").Append(GetStateString(entry_1.Value)).Append("\n");
buf.Append(GetStateString(s));
String label = GetEdgeLabel(i);
buf.Append("-");
buf.Append(label);
buf.Append("->");
buf.Append(GetStateString(t));
buf.Append('\n');
}
}
}
@ -102,34 +80,16 @@ namespace Antlr4.Runtime.Dfa
{
return null;
}
//return Utils.sortLinesInString(output);
return output;
}
private sealed class _IComparer_103 : IComparer<DFAState>
{
public _IComparer_103()
{
}
public int Compare(DFAState o1, DFAState o2)
{
return o1.stateNumber - o2.stateNumber;
}
}
protected internal virtual string GetContextLabel(int i)
{
if (i == PredictionContext.EmptyFullStateKey)
if (i == PredictionContext.EMPTY_RETURN_STATE)
{
return "ctx:EMPTY_FULL";
}
else
{
if (i == PredictionContext.EmptyLocalStateKey)
{
return "ctx:EMPTY_LOCAL";
}
return "ctx:EMPTY";
}
if (atn != null && i > 0 && i <= atn.states.Count)
{
@ -145,24 +105,24 @@ namespace Antlr4.Runtime.Dfa
protected internal virtual string GetEdgeLabel(int i)
{
return vocabulary.GetDisplayName(i);
return vocabulary.GetDisplayName(i - 1);
}
internal virtual string GetStateString(DFAState s)
{
if (s == ATNSimulator.Error)
if (s == ATNSimulator.ERROR)
{
return "ERROR";
}
int n = s.stateNumber;
string baseStateStr = (s.IsAcceptState ? ":" : "") + "s" + n + (s.IsContextSensitive ? "^" : "");
if ( s.IsAcceptState ) {
string baseStateStr = (s.isAcceptState ? ":" : "") + "s" + n + (s.requiresFullContext ? "^" : "");
if ( s.isAcceptState ) {
if ( s.predicates!=null ) {
return baseStateStr + "=>" + Arrays.ToString(s.predicates);
}
else {
return baseStateStr + "=>" + s.Prediction;
return baseStateStr + "=>" + s.prediction;
}
}
else {

View File

@ -4,11 +4,8 @@
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -42,304 +39,146 @@ namespace Antlr4.Runtime.Dfa
{
public int stateNumber = -1;
[NotNull]
public readonly ATNConfigSet configs;
/// <summary>
/// <c>edges.get(symbol)</c>
/// points to target of symbol.
/// </summary>
[NotNull]
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> edges;
public ATNConfigSet configSet = new ATNConfigSet();
private Antlr4.Runtime.Dfa.AcceptStateInfo acceptStateInfo;
/** {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1)
* {@link Token#EOF} maps to {@code edges[0]}.
*/
/// <summary>These keys for these edges are the top level element of the global context.</summary>
/// <remarks>These keys for these edges are the top level element of the global context.</remarks>
[NotNull]
private volatile AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> contextEdges;
public DFAState[] edges;
/// <summary>Symbols in this set require a global context transition before matching an input symbol.</summary>
/// <remarks>Symbols in this set require a global context transition before matching an input symbol.</remarks>
[Nullable]
private BitSet contextSymbols;
public bool isAcceptState = false;
/// <summary>
/// This list is computed by
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.PredicateDFAState(DFAState, Antlr4.Runtime.Atn.ATNConfigSet, int)"/>
/// .
/// </summary>
[Nullable]
public DFAState.PredPrediction[] predicates;
/** if accept state, what ttype do we match or alt do we predict?
* This is set to {@link ATN#INVALID_ALT_NUMBER} when {@link #predicates}{@code !=null} or
* {@link #requiresFullContext}.
*/
public int prediction;
/// <summary>Map a predicate to a predicted alternative.</summary>
/// <remarks>Map a predicate to a predicted alternative.</remarks>
public class PredPrediction
{
[NotNull]
public SemanticContext pred;
public LexerActionExecutor lexerActionExecutor;
public int alt;
/**
* Indicates that this state was created during SLL prediction that
* discovered a conflict between the configurations in the state. Future
* {@link ParserATNSimulator#execATN} invocations immediately jumped doing
* full context prediction if this field is true.
*/
public bool requiresFullContext;
public PredPrediction(SemanticContext pred, int alt)
{
// never null; at least SemanticContext.NONE
this.alt = alt;
this.pred = pred;
}
/** During SLL parsing, this is a list of predicates associated with the
* ATN configurations of the DFA state. When we have predicates,
* {@link #requiresFullContext} is {@code false} since full context prediction evaluates predicates
* on-the-fly. If this is not null, then {@link #prediction} is
* {@link ATN#INVALID_ALT_NUMBER}.
*
* <p>We only use these for non-{@link #requiresFullContext} but conflicting states. That
* means we know from the context (it's $ or we don't dip into outer
* context) that it's an ambiguity not a conflict.</p>
*
* <p>This list is computed by {@link ParserATNSimulator#predicateDFAState}.</p>
*/
public override string ToString()
{
return "(" + pred + ", " + alt + ")";
}
}
public PredPrediction[] predicates;
public DFAState(DFA dfa, ATNConfigSet configs)
: this(dfa.EmptyEdgeMap, dfa.EmptyContextEdgeMap, configs)
{
}
public DFAState(EmptyEdgeMap<DFAState> emptyEdges, EmptyEdgeMap<DFAState> emptyContextEdges, ATNConfigSet configs)
{
this.configs = configs;
this.edges = emptyEdges;
this.contextEdges = emptyContextEdges;
}
public bool IsContextSensitive
{
get
{
return contextSymbols != null;
}
}
public DFAState() { }
public bool IsContextSymbol(int symbol)
{
if (!IsContextSensitive || symbol < edges.minIndex)
{
return false;
}
return contextSymbols.Get(symbol - edges.minIndex);
}
public DFAState(int stateNumber) { this.stateNumber = stateNumber; }
public void SetContextSymbol(int symbol)
{
System.Diagnostics.Debug.Assert(IsContextSensitive);
if (symbol < edges.minIndex)
{
return;
}
contextSymbols.Set(symbol - edges.minIndex);
}
public DFAState(ATNConfigSet configs) { this.configSet = configs; }
public virtual void SetContextSensitive(ATN atn)
/** Get the set of all alts mentioned by all ATN configurations in this
* DFA state.
*/
public HashSet<int> getAltSet()
{
System.Diagnostics.Debug.Assert(!configs.IsOutermostConfigSet);
if (IsContextSensitive)
HashSet<int> alts = new HashSet<int>();
if (configSet != null)
{
return;
}
lock (this)
foreach (ATNConfig c in configSet.configs)
{
if (contextSymbols == null)
{
contextSymbols = new BitSet();
alts.Add(c.alt);
}
}
}
public AcceptStateInfo AcceptStateInfo
{
get
{
return acceptStateInfo;
}
set
{
AcceptStateInfo acceptStateInfo = value;
this.acceptStateInfo = acceptStateInfo;
}
}
public bool IsAcceptState
{
get
{
return acceptStateInfo != null;
}
}
public int Prediction
{
get
{
if (acceptStateInfo == null)
{
return ATN.InvalidAltNumber;
}
return acceptStateInfo.Prediction;
}
}
public LexerActionExecutor LexerActionExecutor
{
get
{
if (acceptStateInfo == null)
{
if (alts.Count==0)
return null;
}
return acceptStateInfo.LexerActionExecutor;
}
}
public virtual DFAState GetTarget(int symbol)
{
return edges[symbol];
}
public virtual void SetTarget(int symbol, DFAState target)
{
edges = edges.Put(symbol, target);
}
#if NET45PLUS
public virtual IReadOnlyDictionary<int, DFAState> EdgeMap
#else
public virtual IDictionary<int, DFAState> EdgeMap
#endif
{
get
{
return edges.ToMap();
}
}
public virtual DFAState GetContextTarget(int invokingState)
{
lock (this)
{
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
return contextEdges[invokingState];
}
}
public virtual void SetContextTarget(int invokingState, DFAState target)
{
lock (this)
{
if (!IsContextSensitive)
{
throw new InvalidOperationException("The state is not context sensitive.");
}
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
contextEdges = contextEdges.Put(invokingState, target);
}
}
#if NET45PLUS
public virtual IReadOnlyDictionary<int, DFAState> ContextEdgeMap
#else
public virtual IDictionary<int, DFAState> ContextEdgeMap
#endif
{
get
{
var map = contextEdges.ToMap();
if (map.ContainsKey(-1))
{
if (map.Count == 1)
{
return Sharpen.Collections.SingletonMap(PredictionContext.EmptyFullStateKey, map[-1]);
}
else
{
#if NET45PLUS
Dictionary<int, DFAState> result = map.ToDictionary(i => i.Key, i => i.Value);
#else
Dictionary<int, DFAState> result = new Dictionary<int, DFAState>(map);
#endif
result.Add(PredictionContext.EmptyFullStateKey, result[-1]);
result.Remove(-1);
#if NET45PLUS
map = new ReadOnlyDictionary<int, DFAState>(new SortedDictionary<int, DFAState>(result));
#elif COMPACT
map = new SortedList<int, DFAState>(result);
#elif PORTABLE && !NET45PLUS
map = new Dictionary<int, DFAState>(result);
#else
map = new SortedDictionary<int, DFAState>(result);
#endif
}
}
return map;
}
return alts;
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize(7);
hash = MurmurHash.Update(hash, configs.GetHashCode());
hash = MurmurHash.Update(hash, configSet.GetHashCode());
hash = MurmurHash.Finish(hash, 1);
return hash;
}
/// <summary>
/// Two
/// <see cref="DFAState"/>
/// instances are equal if their ATN configuration sets
/// are the same. This method is used to see if a state already exists.
/// <p>Because the number of alternatives and number of ATN configurations are
/// finite, there is a finite number of DFA states that can be processed.
/// This is necessary to show that the algorithm terminates.</p>
/// <p>Cannot test the DFA state numbers here because in
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.AddDFAState(DFA, Antlr4.Runtime.Atn.ATNConfigSet, Antlr4.Runtime.Atn.PredictionContextCache)"/>
/// we need to know if any other state
/// exists that has this exact set of ATN configurations. The
/// <see cref="stateNumber"/>
/// is irrelevant.</p>
/// </summary>
public override bool Equals(object o)
/**
* Two {@link DFAState} instances are equal if their ATN configuration sets
* are the same. This method is used to see if a state already exists.
*
* <p>Because the number of alternatives and number of ATN configurations are
* finite, there is a finite number of DFA states that can be processed.
* This is necessary to show that the algorithm terminates.</p>
*
* <p>Cannot test the DFA state numbers here because in
* {@link ParserATNSimulator#addDFAState} we need to know if any other state
* exists that has this exact set of ATN configurations. The
* {@link #stateNumber} is irrelevant.</p>
*/
public override bool Equals(Object o)
{
// compare set of ATN configurations in this set with other
if (this == o)
{
return true;
}
if (this == o) return true;
if (!(o is DFAState))
{
return false;
}
DFAState other = (DFAState)o;
bool sameSet = this.configs.Equals(other.configs);
// TODO (sam): what to do when configs==null?
bool sameSet = this.configSet.Equals(other.configSet);
// System.out.println("DFAState.equals: "+configs+(sameSet?"==":"!=")+other.configs);
return sameSet;
}
public override string ToString()
public override String ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(stateNumber).Append(":").Append(configs);
if (IsAcceptState)
buf.Append(stateNumber).Append(":").Append(configSet);
if (isAcceptState)
{
buf.Append("=>");
if (predicates != null)
{
buf.Append(Arrays.ToString(predicates));
}
else
{
buf.Append(Prediction);
else {
buf.Append(prediction);
}
}
return buf.ToString();
}
}
/** Map a predicate to a predicted alternative. */
public class PredPrediction
{
public SemanticContext pred; // never null; at least SemanticContext.NONE
public int alt;
public PredPrediction(SemanticContext pred, int alt)
{
this.alt = alt;
this.pred = pred;
}
public override String ToString()
{
return "(" + pred + ", " + alt + ")";
}
}
}

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
#if NET45PLUS

View File

@ -3,9 +3,7 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Dfa
{

View File

@ -2,10 +2,7 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Dfa
{

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Dfa

View File

@ -4,8 +4,6 @@
*/
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Dfa

View File

@ -134,7 +134,7 @@ namespace Antlr4.Runtime
/// The set of conflicting or ambiguous alternatives, as
/// reported by the parser.
/// </param>
/// <param name="configs">The conflicting or ambiguous configuration set.</param>
/// <param name="configSet">The conflicting or ambiguous configuration set.</param>
/// <returns>
/// Returns
/// <paramref name="reportedAlts"/>
@ -142,20 +142,20 @@ namespace Antlr4.Runtime
/// <see langword="null"/>
/// , otherwise
/// returns the set of alternatives represented in
/// <paramref name="configs"/>
/// <paramref name="configSet"/>
/// .
/// </returns>
[return: NotNull]
protected internal virtual BitSet GetConflictingAlts(BitSet reportedAlts, ATNConfigSet configs)
protected internal virtual BitSet GetConflictingAlts(BitSet reportedAlts, ATNConfigSet configSet)
{
if (reportedAlts != null)
{
return reportedAlts;
}
BitSet result = new BitSet();
foreach (ATNConfig config in configs)
foreach (ATNConfig config in configSet.configs)
{
result.Set(config.Alt);
result.Set(config.alt);
}
return result;
}

View File

@ -20,7 +20,7 @@ namespace Antlr4.Runtime
/// the stream was constructed. The following is a list of initializing methods:</p>
/// <ul>
/// <li>
/// <see cref="La(int)"/>
/// <see cref="LA(int)"/>
/// </li>
/// <li>
/// <see cref="Consume()"/>
@ -63,7 +63,7 @@ namespace Antlr4.Runtime
/// if an attempt is made to consume the the
/// end of the stream (i.e. if
/// <c>LA(1)==</c>
/// <see cref="IntStreamConstants.Eof">EOF</see>
/// <see cref="IntStreamConstants.EOF">EOF</see>
/// before calling
/// <c>consume</c>
/// ).
@ -115,7 +115,7 @@ namespace Antlr4.Runtime
/// <paramref name="i"/>
/// represents a position at or beyond the end of the stream,
/// this method returns
/// <see cref="IntStreamConstants.Eof"/>
/// <see cref="IntStreamConstants.EOF"/>
/// .</p>
/// <p>The return value is unspecified if
/// <c>i&lt;0</c>
@ -130,7 +130,7 @@ namespace Antlr4.Runtime
/// if the stream does not support
/// retrieving the value of the specified symbol
/// </exception>
int La(int i);
int LA(int i);
/// <summary>
/// A mark provides a guarantee that
@ -261,7 +261,7 @@ namespace Antlr4.Runtime
/// <li>
/// <c>LA(1)</c>
/// returns
/// <see cref="IntStreamConstants.Eof"/>
/// <see cref="IntStreamConstants.EOF"/>
/// </li>
/// </ul>
/// This operation is guaranteed to not throw an exception if
@ -321,11 +321,11 @@ namespace Antlr4.Runtime
{
/// <summary>
/// The value returned by
/// <see cref="IIntStream.La(int)">LA()</see>
/// <see cref="IIntStream.LA(int)">LA()</see>
/// when the end of the stream is
/// reached.
/// </summary>
public const int Eof = -1;
public const int EOF = -1;
/// <summary>
/// The value returned by

View File

@ -54,7 +54,7 @@ namespace Antlr4.Runtime
/// least the <em>minimum</em> potentially viable alternative is truly
/// viable.</p>
/// <p>When the
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection"/>
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// prediction
/// mode is used, the parser is required to identify exact ambiguities so
/// <paramref name="exact"/>
@ -74,7 +74,7 @@ namespace Antlr4.Runtime
/// . This is always
/// <see langword="true"/>
/// when
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LlExactAmbigDetection"/>
/// <see cref="Antlr4.Runtime.Atn.PredictionMode.LL_EXACT_AMBIG_DETECTION"/>
/// is used.
/// </param>
/// <param name="ambigAlts">

View File

@ -131,11 +131,11 @@ namespace Antlr4.Runtime
/// During lookahead operations, this "token" signifies we hit rule end ATN state
/// and did not follow it despite needing to.
/// </remarks>
public const int Epsilon = -2;
public const int EPSILON = -2;
public const int MinUserTokenType = 1;
public const int Eof = IntStreamConstants.Eof;
public const int EOF = IntStreamConstants.EOF;
/// <summary>
/// All tokens go to the parser (unless skip() is called in that rule)

View File

@ -21,17 +21,17 @@ namespace Antlr4.Runtime
/// Get the
/// <see cref="IToken"/>
/// instance associated with the value returned by
/// <see cref="IIntStream.La(int)">LA(k)</see>
/// <see cref="IIntStream.LA(int)">LA(k)</see>
/// . This method has the same pre- and post-conditions as
/// <see cref="IIntStream.La(int)"/>
/// <see cref="IIntStream.LA(int)"/>
/// . In addition, when the preconditions of this method
/// are met, the return value is non-null and the value of
/// <c>LT(k).getType()==LA(k)</c>
/// .
/// </summary>
/// <seealso cref="IIntStream.La(int)"/>
/// <seealso cref="IIntStream.LA(int)"/>
[return: NotNull]
IToken Lt(int k);
IToken LT(int k);
/// <summary>
/// Gets the

View File

@ -96,7 +96,7 @@ namespace Antlr4.Runtime
/// <li>The implicitly defined
/// <c>EOF</c>
/// token, which has the token type
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// .</li>
/// </ul>
/// <p>The following table shows examples of lexer rules and the literal

View File

@ -21,7 +21,7 @@ namespace Antlr4.Runtime
/// </remarks>
public abstract class Lexer : Recognizer<int, LexerATNSimulator>, ITokenSource
{
public const int DefaultMode = 0;
public const int DEFAULT_MODE = 0;
public const int DefaultTokenChannel = TokenConstants.DefaultChannel;
@ -82,7 +82,7 @@ namespace Antlr4.Runtime
private readonly Stack<int> _modeStack = new Stack<int>();
private int _mode = Antlr4.Runtime.Lexer.DefaultMode;
private int _mode = Antlr4.Runtime.Lexer.DEFAULT_MODE;
/// <summary>
/// You can set the text for the current token to override what is in
@ -116,7 +116,7 @@ namespace Antlr4.Runtime
_tokenStartLine = -1;
_text = null;
_hitEOF = false;
_mode = Antlr4.Runtime.Lexer.DefaultMode;
_mode = Antlr4.Runtime.Lexer.DEFAULT_MODE;
_modeStack.Clear();
Interpreter.Reset();
}
@ -171,7 +171,7 @@ namespace Antlr4.Runtime
Recover(e);
ttype = TokenTypes.Skip;
}
if (_input.La(1) == IntStreamConstants.Eof)
if (_input.LA(1) == IntStreamConstants.EOF)
{
_hitEOF = true;
}
@ -330,7 +330,7 @@ outer_continue: ;
{
int cpos = Column;
int line = Line;
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.Eof, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, line, cpos);
IToken eof = _factory.Create(_tokenFactorySourcePair, TokenConstants.EOF, null, TokenConstants.DefaultChannel, _input.Index, _input.Index - 1, line, cpos);
Emit(eof);
return eof;
}
@ -520,7 +520,7 @@ outer_continue: ;
{
IList<IToken> tokens = new List<IToken>();
IToken t = NextToken();
while (t.Type != TokenConstants.Eof)
while (t.Type != TokenConstants.EOF)
{
tokens.Add(t);
t = NextToken();
@ -530,7 +530,7 @@ outer_continue: ;
public virtual void Recover(LexerNoViableAltException e)
{
if (_input.La(1) != IntStreamConstants.Eof)
if (_input.LA(1) != IntStreamConstants.EOF)
{
// skip a char and try again
Interpreter.Consume(_input);
@ -560,7 +560,7 @@ outer_continue: ;
string s = ((char)c).ToString();
switch (c)
{
case TokenConstants.Eof:
case TokenConstants.EOF:
{
s = "<EOF>";
break;

View File

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -25,6 +26,9 @@ namespace Antlr4.Runtime
[NotNull]
private readonly IVocabulary vocabulary;
protected DFA[] decisionToDFA;
protected PredictionContextCache sharedContextCache = new PredictionContextCache();
public LexerInterpreter(string grammarFileName, IVocabulary vocabulary, IEnumerable<string> ruleNames, IEnumerable<string> modeNames, ATN atn, ICharStream input)
: base(input)
{
@ -37,7 +41,12 @@ namespace Antlr4.Runtime
this.ruleNames = ruleNames.ToArray();
this.modeNames = modeNames.ToArray();
this.vocabulary = vocabulary;
this.Interpreter = new LexerATNSimulator(this, atn);
this.decisionToDFA = new DFA[atn.NumberOfDecisions];
for (int i = 0; i < decisionToDFA.Length; i++)
{
decisionToDFA[i] = new DFA(atn.GetDecisionState(i), i);
}
this.Interpreter = new LexerATNSimulator(this, atn, decisionToDFA, sharedContextCache);
}
public override ATN Atn

View File

@ -17,7 +17,7 @@ namespace Antlr4.Runtime
/// <see cref="IToken"/>
/// objects.
/// <p>If the final token in the list is an
/// <see cref="TokenConstants.Eof"/>
/// <see cref="TokenConstants.EOF"/>
/// token, it will be used
/// as the EOF token for every call to
/// <see cref="NextToken()"/>
@ -198,12 +198,12 @@ namespace Antlr4.Runtime
}
}
int stop = Math.Max(-1, start - 1);
eofToken = _factory.Create(Tuple.Create((ITokenSource)this, InputStream), TokenConstants.Eof, "EOF", TokenConstants.DefaultChannel, start, stop, Line, Column);
eofToken = _factory.Create(Tuple.Create((ITokenSource)this, InputStream), TokenConstants.EOF, "EOF", TokenConstants.DefaultChannel, start, stop, Line, Column);
}
return eofToken;
}
IToken t = tokens[i];
if (i == tokens.Count - 1 && t.Type == TokenConstants.Eof)
if (i == tokens.Count - 1 && t.Type == TokenConstants.EOF)
{
eofToken = t;
}

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
{

View File

@ -0,0 +1,54 @@
/* Copyright (c) 2012-2016 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
namespace Antlr4.Runtime.Misc
{
public class ArrayList<T> : List<T>
{
public ArrayList()
{
}
public ArrayList(int count)
: base(count)
{
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize(1);
foreach (T t in this)
hash = MurmurHash.Update(hash, t.GetHashCode());
hash = MurmurHash.Finish(hash, this.Count);
return hash;
}
public override bool Equals(object o)
{
return o == this
|| (o is List<T> && this.Equals((List<T>)o));
}
public bool Equals(List<T> o)
{
if (this.Count != o.Count)
return false;
IEnumerator<T> thisItems = this.GetEnumerator();
IEnumerator<T> otherItems = o.GetEnumerator();
while (thisItems.MoveNext() && otherItems.MoveNext())
{
if (!thisItems.Current.Equals(otherItems.Current))
return false;
}
return true;
}
}
}

View File

@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
namespace Antlr4.Runtime.Misc
{
public class DoubleKeyMap<K1, K2, V>
{
Dictionary<K1, Dictionary<K2, V>> data = new Dictionary<K1, Dictionary<K2, V>>();
public V put(K1 k1, K2 k2, V v)
{
Dictionary<K2, V> data2 = data.get(k1);
V prev = null;
if (data2 == null)
{
data2 = new Dict<K2, V>();
data.put(k1, data2);
}
else {
prev = data2.get(k2);
}
data2.put(k2, v);
return prev;
}
public V get(K1 k1, K2 k2)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.get(k2);
}
public Dictionary<K2, V> get(K1 k1) { return data.get(k1); }
/** Get all values associated with primary key */
public ICollection<V> values(K1 k1)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.values();
}
/** get all primary keys */
public HashSet<K1> keySet()
{
return data.keySet();
}
/** get all secondary keys associated with a primary key */
public HashSet<K2> keySet(K1 k1)
{
Dictionary<K2, V> data2 = data.get(k1);
if (data2 == null) return null;
return data2.keySet();
}
}
}

View File

@ -3,8 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
{

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
{

View File

@ -6,9 +6,6 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
{
@ -61,12 +58,12 @@ namespace Antlr4.Runtime.Misc
{
if (els == null)
{
intervals = new List<Interval>(2);
intervals = new ArrayList<Interval>(2);
}
else
{
// most sets are 1 or 2 elements
intervals = new List<Interval>(els.Length);
intervals = new ArrayList<Interval>(els.Length);
foreach (int e in els)
{
Add(e);
@ -639,7 +636,7 @@ namespace Antlr4.Runtime.Misc
int b = I.b;
if (a == b)
{
if (a == TokenConstants.Eof)
if (a == TokenConstants.EOF)
{
buf.Append("<EOF>");
}
@ -721,13 +718,13 @@ namespace Antlr4.Runtime.Misc
[return: NotNull]
protected internal virtual string ElementName(IVocabulary vocabulary, int a)
{
if (a == TokenConstants.Eof)
if (a == TokenConstants.EOF)
{
return "<EOF>";
}
else
{
if (a == TokenConstants.Epsilon)
if (a == TokenConstants.EPSILON)
{
return "<EPSILON>";
}
@ -758,9 +755,9 @@ namespace Antlr4.Runtime.Misc
}
}
public virtual List<int> ToIntegerList()
public virtual ArrayList<int> ToIntegerList()
{
List<int> values = new List<int>(Count);
ArrayList<int> values = new ArrayList<int>(Count);
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
@ -777,7 +774,7 @@ namespace Antlr4.Runtime.Misc
public virtual IList<int> ToList()
{
IList<int> values = new List<int>();
IList<int> values = new ArrayList<int>();
int n = intervals.Count;
for (int i = 0; i < n; i++)
{

View File

@ -2,9 +2,7 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
@ -19,7 +17,7 @@ namespace Antlr4.Runtime.Misc
IList<V> elementsForKey;
if (!TryGetValue(key, out elementsForKey))
{
elementsForKey = new List<V>();
elementsForKey = new ArrayList<V>();
this[key] = elementsForKey;
}
elementsForKey.Add(value);
@ -27,7 +25,7 @@ namespace Antlr4.Runtime.Misc
public virtual IList<Tuple<K, V>> GetPairs()
{
IList<Tuple<K, V>> pairs = new List<Tuple<K, V>>();
IList<Tuple<K, V>> pairs = new ArrayList<Tuple<K, V>>();
foreach (KeyValuePair<K, IList<V>> pair in this)
{
foreach (V value in pair.Value)

View File

@ -2,7 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
{

View File

@ -0,0 +1,49 @@
/* Copyright (c) 2012-2016 The ANTLR Project. All rights reserved.
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using System;
namespace Antlr4.Runtime.Misc
{
public class Pair<A, B>
{
public readonly A a;
public readonly B b;
public Pair(A a, B b)
{
this.a = a;
this.b = b;
}
public override bool Equals(Object obj)
{
if (obj == this)
{
return true;
}
else if (!(obj is Pair<A, B>)) {
return false;
}
Pair <A, B> other = (Pair <A, B>)obj;
return a==null ? other.a==null : a.Equals(other.b);
}
public override int GetHashCode()
{
int hash = MurmurHash.Initialize();
hash = MurmurHash.Update(hash, a);
hash = MurmurHash.Update(hash, b);
return MurmurHash.Finish(hash, 2);
}
public override String ToString()
{
return String.Format("(%s, %s)", a, b);
}
}
}

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System;
using Antlr4.Runtime.Sharpen;
#if COMPACT
using OperationCanceledException = System.Exception;

View File

@ -586,7 +586,7 @@ namespace Antlr4.Runtime.Misc
}
IList<Type> typesToCheck = GetTypesToCheck(assembly);
List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> dependencies = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> dependencies = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
foreach (Type clazz in typesToCheck)
{
dependencies.AddRange(GetDependencies(clazz));
@ -601,7 +601,7 @@ namespace Antlr4.Runtime.Misc
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> list;
if (!recognizerDependencies.TryGetValue(recognizerType, out list))
{
list = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
list = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
recognizerDependencies[recognizerType] = list;
}
list.Add(dependency);
@ -851,7 +851,7 @@ namespace Antlr4.Runtime.Misc
public static IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> GetDependencies(Type clazz)
{
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> result = new List<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
IList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>> result = new ArrayList<Tuple<RuleDependencyAttribute, ICustomAttributeProvider>>();
GetElementDependencies(AsCustomAttributeProvider(clazz), result);
foreach (ConstructorInfo ctor in clazz.GetConstructors(AllDeclaredMembers))
@ -909,7 +909,7 @@ namespace Antlr4.Runtime.Misc
}
foreach (Transition transition in state.transitions)
{
if (transition.TransitionType != TransitionType.Rule)
if (transition.TransitionType != TransitionType.RULE)
{
continue;
}

View File

@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime.Misc
@ -17,7 +16,7 @@ namespace Antlr4.Runtime.Misc
#if NET40PLUS
return string.Join(separator, items);
#else
List<string> elements = new List<string>();
ArrayList<string> elements = new ArrayList<string>();
foreach (T item in items)
{
if (item == null)
@ -133,7 +132,7 @@ namespace Antlr4.Runtime.Misc
return m;
}
public static char[] ToCharArray(List<int> data)
public static char[] ToCharArray(ArrayList<int> data)
{
if (data == null)
{

View File

@ -4,9 +4,7 @@
*/
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
@ -25,12 +23,12 @@ namespace Antlr4.Runtime
{
public virtual void EnterEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("enter " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
System.Console.Out.WriteLine("enter " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.LT(1).Text);
}
public virtual void ExitEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("exit " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
System.Console.Out.WriteLine("exit " + this._enclosing.RuleNames[ctx.RuleIndex] + ", LT(1)=" + this._enclosing._input.LT(1).Text);
}
public virtual void VisitErrorNode(IErrorNode node)
@ -658,7 +656,7 @@ namespace Antlr4.Runtime
{
get
{
return _input.Lt(1);
return _input.LT(1);
}
}
@ -770,7 +768,7 @@ namespace Antlr4.Runtime
{
State = state;
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_buildParseTrees)
{
AddContextToParseTree();
@ -792,7 +790,7 @@ namespace Antlr4.Runtime
localctx.AddChild(factoredContext);
}
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_buildParseTrees)
{
AddContextToParseTree();
@ -805,7 +803,7 @@ namespace Antlr4.Runtime
public virtual void ExitRule()
{
_ctx.Stop = _input.Lt(-1);
_ctx.Stop = _input.LT(-1);
// trigger event on _ctx, before it reverts to parent
if (_parseListeners != null)
{
@ -861,7 +859,7 @@ namespace Antlr4.Runtime
State = state;
_precedenceStack.Add(precedence);
_ctx = localctx;
_ctx.Start = _input.Lt(1);
_ctx.Start = _input.LT(1);
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
@ -879,7 +877,7 @@ namespace Antlr4.Runtime
ParserRuleContext previous = _ctx;
previous.Parent = localctx;
previous.invokingState = state;
previous.Stop = _input.Lt(-1);
previous.Stop = _input.LT(-1);
_ctx = localctx;
_ctx.Start = previous.Start;
if (_buildParseTrees)
@ -896,7 +894,7 @@ namespace Antlr4.Runtime
public virtual void UnrollRecursionContexts(ParserRuleContext _parentctx)
{
_precedenceStack.RemoveAt(_precedenceStack.Count - 1);
_ctx.Stop = _input.Lt(-1);
_ctx.Stop = _input.LT(-1);
ParserRuleContext retctx = _ctx;
// save current ctx (return value)
// unroll so _ctx is as it was before call to recursive method
@ -953,7 +951,7 @@ namespace Antlr4.Runtime
return precedence >= _precedenceStack[_precedenceStack.Count - 1];
}
public override IAntlrErrorListener<IToken> ErrorListenerDispatch
public new IParserErrorListener ErrorListenerDispatch
{
get
{
@ -1001,11 +999,11 @@ namespace Antlr4.Runtime
return true;
}
// System.out.println("following "+s+"="+following);
if (!following.Contains(TokenConstants.Epsilon))
if (!following.Contains(TokenConstants.EPSILON))
{
return false;
}
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.Epsilon))
while (ctx != null && ctx.invokingState >= 0 && following.Contains(TokenConstants.EPSILON))
{
ATNState invokingState = atn.states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
@ -1016,7 +1014,7 @@ namespace Antlr4.Runtime
}
ctx = (ParserRuleContext)ctx.Parent;
}
if (following.Contains(TokenConstants.Epsilon) && symbol == TokenConstants.Eof)
if (following.Contains(TokenConstants.EPSILON) && symbol == TokenConstants.EOF)
{
return true;
}
@ -1127,7 +1125,7 @@ namespace Antlr4.Runtime
for (int d = 0; d < Interpreter.atn.decisionToDFA.Length; d++)
{
DFA dfa = Interpreter.atn.decisionToDFA[d];
s.Add(dfa.ToString(Vocabulary, RuleNames));
s.Add(dfa.ToString(Vocabulary));
}
return s;
}
@ -1138,17 +1136,17 @@ namespace Antlr4.Runtime
public virtual void DumpDFA()
{
bool seenOne = false;
for (int d = 0; d < Interpreter.atn.decisionToDFA.Length; d++)
for (int d = 0; d < Interpreter.decisionToDFA.Length; d++)
{
DFA dfa = Interpreter.atn.decisionToDFA[d];
if (!dfa.IsEmpty)
DFA dfa = Interpreter.decisionToDFA[d];
if (dfa.states.Count>0)
{
if (seenOne)
{
System.Console.Out.WriteLine();
}
System.Console.Out.WriteLine("Decision " + dfa.decision + ":");
System.Console.Out.Write(dfa.ToString(Vocabulary, RuleNames));
System.Console.Out.Write(dfa.ToString(Vocabulary));
seenOne = true;
}
}
@ -1194,7 +1192,7 @@ namespace Antlr4.Runtime
{
if (interp is ProfilingATNSimulator)
{
Interpreter = new ParserATNSimulator(this, Atn);
Interpreter = new ParserATNSimulator(this, Atn, null, null);
}
}
}

View File

@ -5,7 +5,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
@ -57,13 +56,13 @@ namespace Antlr4.Runtime
{
continue;
}
if (((StarLoopEntryState)state).precedenceRuleDecision)
if (((StarLoopEntryState)state).isPrecedenceDecision)
{
this.pushRecursionContextStates.Set(state.stateNumber);
}
}
// get atn simulator that knows how to do predictions
Interpreter = new ParserATNSimulator(this, atn);
Interpreter = new ParserATNSimulator(this, atn, null, null);
}
public override ATN Atn
@ -186,7 +185,7 @@ namespace Antlr4.Runtime
Transition transition = p.Transition(edge - 1);
switch (transition.TransitionType)
{
case TransitionType.Epsilon:
case TransitionType.EPSILON:
{
if (pushRecursionContextStates.Get(p.stateNumber) && !(transition.target is LoopEndState))
{
@ -196,17 +195,17 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Atom:
case TransitionType.ATOM:
{
Match(((AtomTransition)transition).token);
break;
}
case TransitionType.Range:
case TransitionType.Set:
case TransitionType.NotSet:
case TransitionType.RANGE:
case TransitionType.SET:
case TransitionType.NOT_SET:
{
if (!transition.Matches(TokenStream.La(1), TokenConstants.MinUserTokenType, 65535))
if (!transition.Matches(TokenStream.LA(1), TokenConstants.MinUserTokenType, 65535))
{
ErrorHandler.RecoverInline(this);
}
@ -214,13 +213,13 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Wildcard:
case TransitionType.WILDCARD:
{
MatchWildcard();
break;
}
case TransitionType.Rule:
case TransitionType.RULE:
{
RuleStartState ruleStartState = (RuleStartState)transition.target;
int ruleIndex = ruleStartState.ruleIndex;
@ -236,7 +235,7 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Predicate:
case TransitionType.PREDICATE:
{
PredicateTransition predicateTransition = (PredicateTransition)transition;
if (!Sempred(RuleContext, predicateTransition.ruleIndex, predicateTransition.predIndex))
@ -246,14 +245,14 @@ namespace Antlr4.Runtime
break;
}
case TransitionType.Action:
case TransitionType.ACTION:
{
ActionTransition actionTransition = (ActionTransition)transition;
Action(RuleContext, actionTransition.ruleIndex, actionTransition.actionIndex);
break;
}
case TransitionType.Precedence:
case TransitionType.PRECEDENCE:
{
if (!Precpred(RuleContext, ((PrecedencePredicateTransition)transition).precedence))
{

View File

@ -34,7 +34,7 @@ namespace Antlr4.Runtime
/// </remarks>
public class ParserRuleContext : RuleContext
{
private static readonly Antlr4.Runtime.ParserRuleContext Empty = new Antlr4.Runtime.ParserRuleContext();
public static readonly Antlr4.Runtime.ParserRuleContext EMPTY = new Antlr4.Runtime.ParserRuleContext();
/// <summary>
/// If we are debugging or building a parse tree for a visitor,
@ -112,7 +112,7 @@ namespace Antlr4.Runtime
get
{
// public List<Integer> states;
return Empty;
return EMPTY;
}
}

View File

@ -4,9 +4,6 @@
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime
{
/// <summary>

View File

@ -3,7 +3,6 @@
* can be found in the LICENSE.txt file in the project root.
*/
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Sharpen;

View File

@ -4,10 +4,8 @@
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
#if NET40PLUS
using System.Runtime.CompilerServices;
@ -87,7 +85,7 @@ namespace Antlr4.Runtime
protected virtual IDictionary<string, int> CreateTokenTypeMap(IVocabulary vocabulary)
{
var result = new Dictionary<string, int>();
for (int i = 0; i < Atn.maxTokenType; i++)
for (int i = 0; i <= Atn.maxTokenType; i++)
{
string literalName = vocabulary.GetLiteralName(i);
if (literalName != null)
@ -100,7 +98,7 @@ namespace Antlr4.Runtime
result[symbolicName] = i;
}
}
result["EOF"] = TokenConstants.Eof;
result["EOF"] = TokenConstants.EOF;
return result;
}
@ -255,7 +253,7 @@ namespace Antlr4.Runtime
string s = t.Text;
if (s == null)
{
if (t.Type == TokenConstants.Eof)
if (t.Type == TokenConstants.EOF)
{
s = "<EOF>";
}

View File

@ -199,7 +199,7 @@ namespace Antlr4.Runtime
* option contextSuperClass.
* to set it.
*/
public virtual int getAltNumber() { return Atn.ATN.InvalidAltNumber; }
public virtual int getAltNumber() { return Atn.ATN.INVALID_ALT_NUMBER; }
/* Set the outer alternative number for this context node. Default
* implementation does nothing to avoid backing field overhead for

View File

@ -127,6 +127,18 @@ namespace Antlr4.Runtime.Sharpen
_data[element] &= ~(1UL << (index % BitsPerElement));
}
public bool this[int index]
{
get
{
return Get(index);
}
set
{
Set(index);
}
}
public bool Get(int index)
{
if (index < 0)

View File

@ -5,6 +5,7 @@
namespace Antlr4.Runtime.Sharpen
{
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
internal static class ListExtensions
{
@ -15,5 +16,8 @@ namespace Antlr4.Runtime.Sharpen
list[index] = value;
return previous;
}
}
}

View File

@ -6,9 +6,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Sharpen;
namespace Antlr4.Runtime
{
@ -162,7 +160,7 @@ namespace Antlr4.Runtime
public override int Execute(StringBuilder buf)
{
buf.Append(text);
if (tokens.Get(index).Type != TokenConstants.Eof)
if (tokens.Get(index).Type != TokenConstants.EOF)
{
buf.Append(tokens.Get(index).Text);
}
@ -493,7 +491,7 @@ namespace Antlr4.Runtime
if (op == null)
{
// no operation at that index, just dump token
if (t.Type != TokenConstants.Eof)
if (t.Type != TokenConstants.EOF)
{
buf.Append(t.Text);
}

View File

@ -2,8 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime.Tree
{

View File

@ -2,10 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime.Tree
{
/// <summary>

View File

@ -2,9 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime.Tree
{

View File

@ -2,8 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime.Tree
{

View File

@ -2,7 +2,6 @@
* Use of this file is governed by the BSD 3-clause license that
* can be found in the LICENSE.txt file in the project root.
*/
using Antlr4.Runtime.Sharpen;
using Antlr4.Runtime.Tree;
namespace Antlr4.Runtime.Tree

Some files were not shown because too many files have changed in this diff Show More