Merge branch 'sharpen'

This commit is contained in:
Sam Harwell 2013-02-16 10:12:52 -06:00
commit 1042228e26
125 changed files with 25946 additions and 3 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@
# ignore C# build directories
[Dd]ebug/
[Rr]elease/
reference/.metadata/
reference/antlr4.net/

View File

@ -0,0 +1,99 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.IO;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// This is an ANTLRInputStream that is loaded from a file
/// all at once when you construct the object.
/// </summary>
/// <remarks>
/// This is an ANTLRInputStream that is loaded from a file
/// all at once when you construct the object. This is a special case
/// since we know the exact size of the object to load. We can avoid lots
/// of data copying.
/// </remarks>
public class AntlrFileStream : AntlrInputStream
{
protected internal string fileName;
/// <exception cref="System.IO.IOException"></exception>
public AntlrFileStream(string fileName) : this(fileName, null)
{
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrFileStream(string fileName, string encoding)
{
this.fileName = fileName;
Load(fileName, encoding);
}
/// <exception cref="System.IO.IOException"></exception>
public virtual void Load(string fileName, string encoding)
{
if (fileName == null)
{
return;
}
FilePath f = new FilePath(fileName);
int size = (int)f.Length();
InputStreamReader isr;
FileInputStream fis = new FileInputStream(fileName);
if (encoding != null)
{
isr = new InputStreamReader(fis, encoding);
}
else
{
isr = new InputStreamReader(fis);
}
try
{
data = new char[size];
base.n = isr.Read(data);
}
finally
{
isr.Close();
}
}
public override string SourceName
{
get
{
return fileName;
}
}
}
}

View File

@ -0,0 +1,317 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.IO;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>Vacuum all input from a Reader/InputStream and then treat it like a char[] buffer.
/// </summary>
/// <remarks>
/// Vacuum all input from a Reader/InputStream and then treat it like a char[] buffer.
/// Can also pass in a string or char[] to use.
/// If you need encoding, pass in stream/reader with correct encoding.
/// </remarks>
public class AntlrInputStream : ICharStream
{
public const int ReadBufferSize = 1024;
public const int InitialBufferSize = 1024;
/// <summary>The data being scanned</summary>
protected internal char[] data;
/// <summary>How many characters are actually in the buffer</summary>
protected internal int n;
/// <summary>0..n-1 index into string of next char</summary>
protected internal int p = 0;
/// <summary>What is name or source of this char stream?</summary>
public string name;
public AntlrInputStream()
{
}
/// <summary>Copy data in string to a local char array</summary>
public AntlrInputStream(string input)
{
this.data = input.ToCharArray();
this.n = input.Length;
}
/// <summary>This is the preferred constructor for strings as no data is copied</summary>
public AntlrInputStream(char[] data, int numberOfActualCharsInArray)
{
this.data = data;
this.n = numberOfActualCharsInArray;
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(StreamReader r) : this(r, InitialBufferSize, ReadBufferSize
)
{
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(StreamReader r, int initialSize) : this(r, initialSize, ReadBufferSize
)
{
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(StreamReader r, int initialSize, int readChunkSize)
{
Load(r, initialSize, readChunkSize);
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(InputStream input) : this(new InputStreamReader(input), InitialBufferSize
)
{
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(InputStream input, int initialSize) : this(new InputStreamReader
(input), initialSize)
{
}
/// <exception cref="System.IO.IOException"></exception>
public AntlrInputStream(InputStream input, int initialSize, int readChunkSize) :
this(new InputStreamReader(input), initialSize, readChunkSize)
{
}
/// <exception cref="System.IO.IOException"></exception>
public virtual void Load(StreamReader r, int size, int readChunkSize)
{
if (r == null)
{
return;
}
if (size <= 0)
{
size = InitialBufferSize;
}
if (readChunkSize <= 0)
{
readChunkSize = ReadBufferSize;
}
// System.out.println("load "+size+" in chunks of "+readChunkSize);
try
{
// alloc initial buffer size.
data = new char[size];
// read all the data in chunks of readChunkSize
int numRead = 0;
int p = 0;
do
{
if (p + readChunkSize > data.Length)
{
// overflow?
// System.out.println("### overflow p="+p+", data.length="+data.length);
data = Arrays.CopyOf(data, data.Length * 2);
}
numRead = r.Read(data, p, readChunkSize);
// System.out.println("read "+numRead+" chars; p was "+p+" is now "+(p+numRead));
p += numRead;
}
while (numRead != -1);
// while not EOF
// set the actual size of the data available;
// EOF subtracted one above in p+=numRead; add one back
n = p + 1;
}
finally
{
//System.out.println("n="+n);
r.Close();
}
}
/// <summary>
/// Reset the stream so that it's in the same state it was
/// when the object was created *except* the data array is not
/// touched.
/// </summary>
/// <remarks>
/// Reset the stream so that it's in the same state it was
/// when the object was created *except* the data array is not
/// touched.
/// </remarks>
public virtual void Reset()
{
p = 0;
}
public virtual void Consume()
{
if (p >= n)
{
System.Diagnostics.Debug.Assert(La(1) == IIntStream.Eof);
throw new InvalidOperationException("cannot consume EOF");
}
//System.out.println("prev p="+p+", c="+(char)data[p]);
if (p < n)
{
p++;
}
}
//System.out.println("p moves to "+p+" (c='"+(char)data[p]+"')");
public virtual int La(int i)
{
if (i == 0)
{
return 0;
}
// undefined
if (i < 0)
{
i++;
// e.g., translate LA(-1) to use offset i=0; then data[p+0-1]
if ((p + i - 1) < 0)
{
return IIntStream.Eof;
}
}
// invalid; no char before first char
if ((p + i - 1) >= n)
{
//System.out.println("char LA("+i+")=EOF; p="+p);
return IIntStream.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);
return data[p + i - 1];
}
public virtual int Lt(int i)
{
return La(i);
}
/// <summary>
/// Return the current input symbol index 0..n where n indicates the
/// last symbol has been read.
/// </summary>
/// <remarks>
/// Return the current input symbol index 0..n where n indicates the
/// last symbol has been read. The index is the index of char to
/// be returned from LA(1).
/// </remarks>
public virtual int Index
{
get
{
return p;
}
}
public virtual int Size
{
get
{
return n;
}
}
/// <summary>mark/release do nothing; we have entire buffer</summary>
public virtual int Mark()
{
return -1;
}
public virtual void Release(int marker)
{
}
/// <summary>
/// consume() ahead until p==index; can't just set p=index as we must
/// update line and charPositionInLine.
/// </summary>
/// <remarks>
/// consume() ahead until p==index; can't just set p=index as we must
/// update line and charPositionInLine. If we seek backwards, just set p
/// </remarks>
public virtual void Seek(int index)
{
if (index <= p)
{
p = index;
// just jump; don't update stream state (line, ...)
return;
}
// seek forward, consume until p hits index
while (p < index && index < n)
{
Consume();
}
}
public override string GetText(Interval interval)
{
int start = interval.a;
int stop = interval.b;
if (stop >= n)
{
stop = n - 1;
}
int count = stop - start + 1;
if (start >= n)
{
return string.Empty;
}
// System.err.println("data: "+Arrays.toString(data)+", n="+n+
// ", start="+start+
// ", stop="+stop);
return new string(data, start, count);
}
public virtual string SourceName
{
get
{
return name;
}
}
public override string ToString()
{
return new string(data);
}
}
}

View File

@ -39,7 +39,127 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AntlrFileStream.cs" />
<Compile Include="AntlrInputStream.cs" />
<Compile Include="Atn\AbstractPredicateTransition.cs" />
<Compile Include="Atn\ActionTransition.cs" />
<Compile Include="Atn\ArrayPredictionContext.cs" />
<Compile Include="Atn\ATN.cs" />
<Compile Include="Atn\ATNConfig.cs" />
<Compile Include="Atn\ATNConfigSet.cs" />
<Compile Include="Atn\ATNSimulator.cs" />
<Compile Include="Atn\ATNState.cs" />
<Compile Include="Atn\AtomTransition.cs" />
<Compile Include="Atn\BasicBlockStartState.cs" />
<Compile Include="Atn\BasicState.cs" />
<Compile Include="Atn\BlockEndState.cs" />
<Compile Include="Atn\BlockStartState.cs" />
<Compile Include="Atn\DecisionState.cs" />
<Compile Include="Atn\EmptyPredictionContext.cs" />
<Compile Include="Atn\EpsilonTransition.cs" />
<Compile Include="Atn\LexerATNSimulator.cs" />
<Compile Include="Atn\LL1Analyzer.cs" />
<Compile Include="Atn\LoopEndState.cs" />
<Compile Include="Atn\NotSetTransition.cs" />
<Compile Include="Atn\OrderedATNConfigSet.cs" />
<Compile Include="Atn\ParserATNPathFinder.cs" />
<Compile Include="Atn\ParserATNSimulator.cs" />
<Compile Include="Atn\PlusBlockStartState.cs" />
<Compile Include="Atn\PlusLoopbackState.cs" />
<Compile Include="Atn\PrecedencePredicateTransition.cs" />
<Compile Include="Atn\PredicateTransition.cs" />
<Compile Include="Atn\PredictionContext.cs" />
<Compile Include="Atn\PredictionContextCache.cs" />
<Compile Include="Atn\RangeTransition.cs" />
<Compile Include="Atn\RuleStartState.cs" />
<Compile Include="Atn\RuleStopState.cs" />
<Compile Include="Atn\RuleTransition.cs" />
<Compile Include="Atn\SemanticContext.cs" />
<Compile Include="Atn\SetTransition.cs" />
<Compile Include="Atn\SimulatorState.cs" />
<Compile Include="Atn\SingletonPredictionContext.cs" />
<Compile Include="Atn\StarBlockStartState.cs" />
<Compile Include="Atn\StarLoopbackState.cs" />
<Compile Include="Atn\StarLoopEntryState.cs" />
<Compile Include="Atn\TokensStartState.cs" />
<Compile Include="Atn\Transition.cs" />
<Compile Include="Atn\WildcardTransition.cs" />
<Compile Include="BailErrorStrategy.cs" />
<Compile Include="BaseErrorListener.cs" />
<Compile Include="BufferedTokenStream.cs" />
<Compile Include="CommonToken.cs" />
<Compile Include="CommonTokenFactory.cs" />
<Compile Include="CommonTokenStream.cs" />
<Compile Include="ConsoleErrorListener.cs" />
<Compile Include="DefaultErrorStrategy.cs" />
<Compile Include="Dependents.cs" />
<Compile Include="Dfa\AbstractEdgeMap`1.cs" />
<Compile Include="Dfa\ArrayEdgeMap`1.cs" />
<Compile Include="Dfa\DFA.cs" />
<Compile Include="Dfa\DFASerializer.cs" />
<Compile Include="Dfa\DFAState.cs" />
<Compile Include="Dfa\IEdgeMap`1.cs" />
<Compile Include="Dfa\LexerDFASerializer.cs" />
<Compile Include="Dfa\SingletonEdgeMap`1.cs" />
<Compile Include="Dfa\SparseEdgeMap`1.cs" />
<Compile Include="DiagnosticErrorListener.cs" />
<Compile Include="FailedPredicateException.cs" />
<Compile Include="IAntlrErrorListener`1.cs" />
<Compile Include="IAntlrErrorStrategy.cs" />
<Compile Include="ICharStream.cs" />
<Compile Include="IIntStream.cs" />
<Compile Include="InputMismatchException.cs" />
<Compile Include="IParserErrorListener.cs" />
<Compile Include="IToken.cs" />
<Compile Include="ITokenFactory.cs" />
<Compile Include="ITokenSource.cs" />
<Compile Include="ITokenStream.cs" />
<Compile Include="IWritableToken.cs" />
<Compile Include="Lexer.cs" />
<Compile Include="LexerNoViableAltException.cs" />
<Compile Include="Misc\Args.cs" />
<Compile Include="Misc\Array2DHashSet`1.cs" />
<Compile Include="Misc\DoubleKeyMap`3.cs" />
<Compile Include="Misc\FlexibleHashMap`2.cs" />
<Compile Include="Misc\IFunc0`1.cs" />
<Compile Include="Misc\IFunc1`2.cs" />
<Compile Include="Misc\IIntSet.cs" />
<Compile Include="Misc\Interval.cs" />
<Compile Include="Misc\IntervalSet.cs" />
<Compile Include="Misc\IPredicate`1.cs" />
<Compile Include="Misc\MultiMap`2.cs" />
<Compile Include="Misc\OrderedHashSet`1.cs" />
<Compile Include="Misc\ParseCanceledException.cs" />
<Compile Include="Misc\RuleDependencyChecker.cs" />
<Compile Include="Misc\RuleDependencyProcessor.cs" />
<Compile Include="Misc\TestRig.cs" />
<Compile Include="Misc\Utils.cs" />
<Compile Include="NoViableAltException.cs" />
<Compile Include="Parser.cs" />
<Compile Include="ParserRuleContext.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ProxyErrorListener`1.cs" />
<Compile Include="ProxyParserErrorListener.cs" />
<Compile Include="RecognitionException.cs" />
<Compile Include="Recognizer`2.cs" />
<Compile Include="RuleContext.cs" />
<Compile Include="TokenStreamRewriter.cs" />
<Compile Include="Tree\AbstractParseTreeVisitor`1.cs" />
<Compile Include="Tree\ErrorNodeImpl.cs" />
<Compile Include="Tree\IErrorNode.cs" />
<Compile Include="Tree\IParseTree.cs" />
<Compile Include="Tree\IParseTreeListener.cs" />
<Compile Include="Tree\IParseTreeVisitor`1.cs" />
<Compile Include="Tree\IRuleNode.cs" />
<Compile Include="Tree\ISyntaxTree.cs" />
<Compile Include="Tree\ITerminalNode.cs" />
<Compile Include="Tree\ITree.cs" />
<Compile Include="Tree\ParseTreeProperty`1.cs" />
<Compile Include="Tree\ParseTreeWalker.cs" />
<Compile Include="Tree\TerminalNodeImpl.cs" />
<Compile Include="Tree\Trees.cs" />
<Compile Include="UnbufferedCharStream.cs" />
<Compile Include="UnbufferedTokenStream.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

223
Antlr4.Runtime/Atn/ATN.cs Normal file
View File

@ -0,0 +1,223 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public class ATN
{
public const int InvalidAltNumber = 0;
public const int Parser = 1;
public const int Lexer = 2;
[NotNull]
public readonly IList<ATNState> states = new List<ATNState>();
/// <summary>
/// Each subrule/rule is a decision point and we must track them so we
/// can go back later and build DFA predictors for them.
/// </summary>
/// <remarks>
/// Each subrule/rule is a decision point and we must track them so we
/// can go back later and build DFA predictors for them. This includes
/// all the rules, subrules, optional blocks, ()+, ()* etc...
/// </remarks>
[NotNull]
public readonly IList<DecisionState> decisionToState = new List<DecisionState>();
public RuleStartState[] ruleToStartState;
public RuleStopState[] ruleToStopState;
[NotNull]
public readonly IDictionary<string, TokensStartState> modeNameToStartState = new
LinkedHashMap<string, TokensStartState>();
public int grammarType;
public int maxTokenType;
public int[] ruleToTokenType;
public int[] ruleToActionIndex;
[NotNull]
public readonly IList<TokensStartState> modeToStartState = new List<TokensStartState
>();
/// <summary>used during construction from grammar AST</summary>
internal int stateNumber = 0;
private readonly IConcurrentMap<PredictionContext, PredictionContext> contextCache
= new ConcurrentHashMap<PredictionContext, PredictionContext>();
[NotNull]
public DFA[] decisionToDFA = new DFA[0];
[NotNull]
public DFA[] modeToDFA = new DFA[0];
protected internal readonly IConcurrentMap<int, int> LL1Table = new ConcurrentHashMap
<int, int>();
/// <summary>Used for runtime deserialization of ATNs from strings</summary>
public ATN()
{
}
// runtime for parsers, lexers
// ATN.LEXER, ...
// runtime for lexer only
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 GetContextCacheSize()
{
return contextCache.Count;
}
public virtual PredictionContext GetCachedContext(PredictionContext context)
{
return PredictionContext.GetCachedContext(context, contextCache, new PredictionContext.IdentityHashMap
());
}
public DFA[] GetDecisionToDFA()
{
System.Diagnostics.Debug.Assert(decisionToDFA != null && decisionToDFA.Length ==
decisionToState.Count);
return decisionToDFA;
}
/// <summary>Compute the set of valid tokens that can occur starting in s.</summary>
/// <remarks>
/// Compute the set of valid tokens that can occur starting in s.
/// If ctx is
/// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
/// , the set of tokens will not include what can follow
/// the rule surrounding s. In other words, the set will be
/// restricted to tokens reachable staying within s's rule.
/// </remarks>
public virtual IntervalSet NextTokens(ATNState s, PredictionContext ctx)
{
Args.NotNull("ctx", ctx);
LL1Analyzer anal = new LL1Analyzer(this);
IntervalSet next = anal.Look(s, ctx);
return next;
}
/// <summary>Compute the set of valid tokens that can occur starting in s and staying in same rule.
/// </summary>
/// <remarks>
/// Compute the set of valid tokens that can occur starting in s and staying in same rule.
/// EPSILON is in set if we reach end of rule.
/// </remarks>
public virtual IntervalSet NextTokens(ATNState s)
{
if (s.nextTokenWithinRule != null)
{
return s.nextTokenWithinRule;
}
s.nextTokenWithinRule = NextTokens(s, PredictionContext.EmptyLocal);
s.nextTokenWithinRule.SetReadonly(true);
return s.nextTokenWithinRule;
}
public virtual void AddState(ATNState state)
{
if (state == null)
{
states.AddItem(null);
stateNumber++;
return;
}
state.atn = this;
states.AddItem(state);
state.stateNumber = stateNumber++;
}
public virtual void RemoveState(ATNState state)
{
states.Set(state.stateNumber, null);
}
// just free mem, don't shift states in list
public virtual void DefineMode(string name, TokensStartState s)
{
modeNameToStartState.Put(name, s);
modeToStartState.AddItem(s);
modeToDFA = Arrays.CopyOf(modeToDFA, modeToStartState.Count);
modeToDFA[modeToDFA.Length - 1] = new DFA(s);
DefineDecisionState(s);
}
public virtual int DefineDecisionState(DecisionState s)
{
decisionToState.AddItem(s);
s.decision = decisionToState.Count - 1;
decisionToDFA = Arrays.CopyOf(decisionToDFA, decisionToState.Count);
decisionToDFA[decisionToDFA.Length - 1] = new DFA(s, s.decision);
return s.decision;
}
public virtual DecisionState GetDecisionState(int decision)
{
if (!decisionToState.IsEmpty())
{
return decisionToState[decision];
}
return null;
}
public virtual int GetNumberOfDecisions()
{
return decisionToState.Count;
}
}
}

View File

@ -0,0 +1,551 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using 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>
public class ATNConfig
{
/// <summary>The ATN state associated with this configuration</summary>
[NotNull]
private readonly ATNState state;
private int altAndOuterContextDepth;
/// <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;
protected internal ATNConfig(ATNState state, int alt, PredictionContext context)
{
System.Diagnostics.Debug.Assert((alt & unchecked((int)(0xFFFFFF))) == alt);
this.state = state;
this.altAndOuterContextDepth = alt & unchecked((int)(0x7FFFFFFF));
this.context = context;
}
protected internal ATNConfig(Antlr4.Runtime.Atn.ATNConfig c, ATNState state, PredictionContext
context)
{
this.state = state;
this.altAndOuterContextDepth = c.altAndOuterContextDepth & unchecked((int)(0x7FFFFFFF
));
this.context = context;
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext
context)
{
return Create(state, alt, context, SemanticContext.None, -1);
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext
context, SemanticContext semanticContext)
{
return Create(state, alt, context, semanticContext, -1);
}
public static Antlr4.Runtime.Atn.ATNConfig Create(ATNState state, int alt, PredictionContext
context, SemanticContext semanticContext, int actionIndex)
{
if (semanticContext != SemanticContext.None)
{
if (actionIndex != -1)
{
return new ATNConfig.ActionSemanticContextATNConfig(actionIndex, semanticContext,
state, alt, context);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, state, alt, context
);
}
}
else
{
if (actionIndex != -1)
{
return new ATNConfig.ActionATNConfig(actionIndex, state, alt, context);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(state, alt, context);
}
}
}
/// <summary>Gets the ATN state associated with this configuration</summary>
[NotNull]
public ATNState GetState()
{
return state;
}
/// <summary>What alt (or lexer rule) is predicted by this configuration</summary>
public int GetAlt()
{
return altAndOuterContextDepth & unchecked((int)(0x00FFFFFF));
}
public bool IsHidden()
{
return altAndOuterContextDepth < 0;
}
public virtual void SetHidden(bool value)
{
if (value)
{
altAndOuterContextDepth |= unchecked((int)(0x80000000));
}
else
{
altAndOuterContextDepth &= ~unchecked((int)(0x80000000));
}
}
[NotNull]
public PredictionContext GetContext()
{
return context;
}
public virtual void SetContext(PredictionContext context)
{
this.context = context;
}
public bool GetReachesIntoOuterContext()
{
return GetOuterContextDepth() != 0;
}
/// <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.
/// 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
/// </remarks>
public int GetOuterContextDepth()
{
return ((int)(((uint)altAndOuterContextDepth) >> 24)) & unchecked((int)(0x7F));
}
public virtual void SetOuterContextDepth(int outerContextDepth)
{
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)));
}
public virtual int GetActionIndex()
{
return -1;
}
[NotNull]
public virtual SemanticContext GetSemanticContext()
{
return SemanticContext.None;
}
public Antlr4.Runtime.Atn.ATNConfig Clone()
{
return Transform(this.GetState());
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state)
{
return Transform(state, this.context, this.GetSemanticContext(), this.GetActionIndex
());
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, SemanticContext semanticContext
)
{
return Transform(state, this.context, semanticContext, this.GetActionIndex());
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext context
)
{
return Transform(state, context, this.GetSemanticContext(), this.GetActionIndex()
);
}
public Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, int actionIndex)
{
return Transform(state, context, this.GetSemanticContext(), actionIndex);
}
private Antlr4.Runtime.Atn.ATNConfig Transform(ATNState state, PredictionContext
context, SemanticContext semanticContext, int actionIndex)
{
if (semanticContext != SemanticContext.None)
{
if (actionIndex != -1)
{
return new ATNConfig.ActionSemanticContextATNConfig(actionIndex, semanticContext,
this, state, context);
}
else
{
return new ATNConfig.SemanticContextATNConfig(semanticContext, this, state, context
);
}
}
else
{
if (actionIndex != -1)
{
return new ATNConfig.ActionATNConfig(actionIndex, this, state, context);
}
else
{
return new Antlr4.Runtime.Atn.ATNConfig(this, state, context);
}
}
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(int context, PredictionContextCache
contextCache)
{
PredictionContext appendedContext = GetContext().AppendContext(context, contextCache
);
Antlr4.Runtime.Atn.ATNConfig result = Transform(GetState(), appendedContext);
return result;
}
public virtual Antlr4.Runtime.Atn.ATNConfig AppendContext(PredictionContext context
, PredictionContextCache contextCache)
{
PredictionContext appendedContext = GetContext().AppendContext(context, contextCache
);
Antlr4.Runtime.Atn.ATNConfig result = Transform(GetState(), appendedContext);
return result;
}
public virtual bool Contains(Antlr4.Runtime.Atn.ATNConfig subconfig)
{
if (this.GetState().stateNumber != subconfig.GetState().stateNumber || this.GetAlt
() != subconfig.GetAlt() || !this.GetSemanticContext().Equals(subconfig.GetSemanticContext
()))
{
return false;
}
IDeque<PredictionContext> leftWorkList = new ArrayDeque<PredictionContext>();
IDeque<PredictionContext> rightWorkList = new ArrayDeque<PredictionContext>();
leftWorkList.AddItem(GetContext());
rightWorkList.AddItem(subconfig.GetContext());
while (!leftWorkList.IsEmpty())
{
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;
}
/// <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))
{
return false;
}
return this.Equals((Antlr4.Runtime.Atn.ATNConfig)o);
}
public virtual bool Equals(Antlr4.Runtime.Atn.ATNConfig other)
{
if (this == other)
{
return true;
}
else
{
if (other == null)
{
return false;
}
}
return this.GetState().stateNumber == other.GetState().stateNumber && this.GetAlt
() == other.GetAlt() && this.GetReachesIntoOuterContext() == other.GetReachesIntoOuterContext
() && this.GetContext().Equals(other.GetContext()) && this.GetSemanticContext
().Equals(other.GetSemanticContext()) && this.GetActionIndex() == other.GetActionIndex
();
}
public override int GetHashCode()
{
int hashCode = 7;
hashCode = 5 * hashCode + GetState().stateNumber;
hashCode = 5 * hashCode + GetAlt();
hashCode = 5 * hashCode + (GetReachesIntoOuterContext() ? 1 : 0);
hashCode = 5 * hashCode + (GetContext() != null ? GetContext().GetHashCode() : 0);
hashCode = 5 * hashCode + GetSemanticContext().GetHashCode();
return hashCode;
}
public virtual string ToDotString()
{
StringBuilder builder = new StringBuilder();
builder.Append("digraph G {\n");
builder.Append("rankdir=LR;\n");
IDictionary<PredictionContext, PredictionContext> visited = new IdentityHashMap<PredictionContext
, PredictionContext>();
IDeque<PredictionContext> workList = new ArrayDeque<PredictionContext>();
workList.AddItem(GetContext());
visited.Put(GetContext(), GetContext());
while (!workList.IsEmpty())
{
PredictionContext current = workList.Pop();
for (int i = 0; i < current.Size; i++)
{
builder.Append(" s").Append(Sharpen.Runtime.IdentityHashCode(current));
builder.Append("->");
builder.Append("s").Append(Sharpen.Runtime.IdentityHashCode(current.GetParent(i))
);
builder.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"];\n");
if (visited.Put(current.GetParent(i), current.GetParent(i)) == null)
{
workList.Push(current.GetParent(i));
}
}
}
builder.Append("}\n");
return builder.ToString();
}
public override string ToString()
{
return ToString(null, true, false);
}
public virtual string ToString<_T0>(Recognizer<_T0> recog, bool showAlt)
{
return ToString(recog, showAlt, true);
}
public virtual string ToString<_T0>(Recognizer<_T0> recog, bool showAlt, bool showContext
)
{
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 = GetContext().ToStrings(recog, this.GetState().stateNumber);
}
else
{
contexts = new string[] { "?" };
}
bool first = true;
foreach (string contextDesc in contexts)
{
if (first)
{
first = false;
}
else
{
buf.Append(", ");
}
buf.Append('(');
buf.Append(GetState());
if (showAlt)
{
buf.Append(",");
buf.Append(GetAlt());
}
if (GetContext() != null)
{
buf.Append(",");
buf.Append(contextDesc);
}
if (GetSemanticContext() != null && GetSemanticContext() != SemanticContext.None)
{
buf.Append(",");
buf.Append(GetSemanticContext());
}
if (GetReachesIntoOuterContext())
{
buf.Append(",up=").Append(GetOuterContextDepth());
}
buf.Append(')');
}
return buf.ToString();
}
private class SemanticContextATNConfig : ATNConfig
{
[NotNull]
private readonly SemanticContext semanticContext;
public SemanticContextATNConfig(SemanticContext semanticContext, ATNState state,
int alt, PredictionContext context) : base(state, alt, context)
{
this.semanticContext = semanticContext;
}
public SemanticContextATNConfig(SemanticContext semanticContext, ATNConfig c, ATNState
state, PredictionContext context) : base(c, state, context)
{
this.semanticContext = semanticContext;
}
public override SemanticContext GetSemanticContext()
{
return semanticContext;
}
}
private class ActionATNConfig : ATNConfig
{
private readonly int actionIndex;
public ActionATNConfig(int actionIndex, ATNState state, int alt, PredictionContext
context) : base(state, alt, context)
{
this.actionIndex = actionIndex;
}
protected internal ActionATNConfig(int actionIndex, ATNConfig c, ATNState state,
PredictionContext context) : base(c, state, context)
{
if (c.GetSemanticContext() != SemanticContext.None)
{
throw new NotSupportedException();
}
this.actionIndex = actionIndex;
}
public override int GetActionIndex()
{
return actionIndex;
}
}
private class ActionSemanticContextATNConfig : ATNConfig.SemanticContextATNConfig
{
private readonly int actionIndex;
public ActionSemanticContextATNConfig(int actionIndex, SemanticContext semanticContext
, ATNState state, int alt, PredictionContext context) : base(semanticContext,
state, alt, context)
{
this.actionIndex = actionIndex;
}
public ActionSemanticContextATNConfig(int actionIndex, SemanticContext semanticContext
, ATNConfig c, ATNState state, PredictionContext context) : base(semanticContext
, c, state, context)
{
this.actionIndex = actionIndex;
}
public override int GetActionIndex()
{
return actionIndex;
}
}
}
}

View File

@ -0,0 +1,692 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public class ATNConfigSet : ICollection<ATNConfig>
{
/// <summary>
/// This maps (state, alt) -&gt; merged
/// <see cref="ATNConfig">ATNConfig</see>
/// . The key does not account for
/// the
/// <see cref="ATNConfig.GetSemanticContext()">ATNConfig.GetSemanticContext()</see>
/// of the value, which is only a problem if a single
/// <code>ATNConfigSet</code>
/// 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">unmerged</see>
/// .
/// <p>
/// This map is only used for optimizing the process of adding configs to the set,
/// and is
/// <code>null</code>
/// 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">mergedConfigs</see>
/// 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
/// <code>null</code>
/// 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;
private int uniqueAlt;
private BitSet conflictingAlts;
private bool hasSemanticContext;
private bool dipsIntoOuterContext;
/// <summary>
/// When
/// <code>true</code>
/// , 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)
/// ">ParserATNSimulator.Closure(ATNConfigSet, ATNConfigSet, bool, bool, PredictionContextCache)
/// </see>
/// from pursuing the global FOLLOW when a
/// rule stop state is reached with an empty prediction context.
/// <p>
/// Note:
/// <code>outermostConfigSet</code>
/// and
/// <see cref="dipsIntoOuterContext">dipsIntoOuterContext</see>
/// should never
/// be true at the same time.
/// </summary>
private bool outermostConfigSet;
public ATNConfigSet()
{
// 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
)
{
if (@readonly)
{
this.mergedConfigs = null;
this.unmerged = null;
}
else
{
if (!set.IsReadOnly())
{
this.mergedConfigs = (Dictionary<long, ATNConfig>)set.mergedConfigs.Clone();
this.unmerged = (List<ATNConfig>)set.unmerged.Clone();
}
else
{
this.mergedConfigs = new Dictionary<long, ATNConfig>(set.configs.Count);
this.unmerged = new List<ATNConfig>();
}
}
this.configs = (List<ATNConfig>)set.configs.Clone();
this.dipsIntoOuterContext = set.dipsIntoOuterContext;
this.hasSemanticContext = set.hasSemanticContext;
this.outermostConfigSet = set.outermostConfigSet;
if (@readonly || !set.IsReadOnly())
{
this.uniqueAlt = set.uniqueAlt;
this.conflictingAlts = set.conflictingAlts;
}
}
// if (!readonly && set.isReadOnly()) -> addAll is called from clone()
/// <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 GetRepresentedAlternatives()
{
if (conflictingAlts != null)
{
return (BitSet)conflictingAlts.Clone();
}
BitSet alts = new BitSet();
foreach (ATNConfig config in this)
{
alts.Set(config.GetAlt());
}
return alts;
}
public bool IsReadOnly()
{
return mergedConfigs == null;
}
public void StripHiddenConfigs()
{
EnsureWritable();
IEnumerator<KeyValuePair<long, ATNConfig>> iterator = mergedConfigs.EntrySet().GetEnumerator
();
while (iterator.HasNext())
{
if (iterator.Next().Value.IsHidden())
{
iterator.Remove();
}
}
IListIterator<ATNConfig> iterator2 = unmerged.ListIterator();
while (iterator2.HasNext())
{
if (iterator2.Next().IsHidden())
{
iterator2.Remove();
}
}
iterator2 = configs.ListIterator();
while (iterator2.HasNext())
{
if (iterator2.Next().IsHidden())
{
iterator2.Remove();
}
}
}
public virtual bool IsOutermostConfigSet()
{
return outermostConfigSet;
}
public virtual void SetOutermostConfigSet(bool outermostConfigSet)
{
if (this.outermostConfigSet && !outermostConfigSet)
{
throw new InvalidOperationException();
}
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
this.outermostConfigSet = outermostConfigSet;
}
public virtual ICollection<ATNState> GetStates()
{
ICollection<ATNState> states = new HashSet<ATNState>();
foreach (ATNConfig c in this.configs)
{
states.AddItem(c.GetState());
}
return states;
}
public virtual void OptimizeConfigs(ATNSimulator interpreter)
{
if (configs.IsEmpty())
{
return;
}
for (int i = 0; i < configs.Count; i++)
{
ATNConfig config = configs[i];
config.SetContext(interpreter.atn.GetCachedContext(config.GetContext()));
}
}
public virtual Antlr4.Runtime.Atn.ATNConfigSet Clone(bool @readonly)
{
Antlr4.Runtime.Atn.ATNConfigSet copy = new Antlr4.Runtime.Atn.ATNConfigSet(this,
@readonly);
if (!@readonly && this.IsReadOnly())
{
Sharpen.Collections.AddAll(copy, this.configs);
}
return copy;
}
public virtual int Count
{
get
{
return configs.Count;
}
}
public virtual bool IsEmpty()
{
return configs.IsEmpty();
}
public virtual bool Contains(object o)
{
if (!(o is ATNConfig))
{
return false;
}
ATNConfig config = (ATNConfig)o;
long configKey = GetKey(config);
ATNConfig mergedConfig = mergedConfigs.Get(configKey);
if (mergedConfig != null && 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()
{
return new ATNConfigSet.ATNConfigSetIterator(this);
}
public virtual object[] ToArray()
{
return Sharpen.Collections.ToArray(configs);
}
public virtual T[] ToArray<T>(T[] a)
{
return Sharpen.Collections.ToArray(configs, a);
}
public virtual bool AddItem(ATNConfig e)
{
return Add(e, null);
}
public virtual bool Add(ATNConfig e, PredictionContextCache contextCache)
{
EnsureWritable();
System.Diagnostics.Debug.Assert(!outermostConfigSet || !e.GetReachesIntoOuterContext
());
System.Diagnostics.Debug.Assert(!e.IsHidden());
if (contextCache == null)
{
contextCache = PredictionContextCache.Uncached;
}
bool addKey;
long key = GetKey(e);
ATNConfig mergedConfig = mergedConfigs.Get(key);
addKey = (mergedConfig == null);
if (mergedConfig != null && CanMerge(e, key, mergedConfig))
{
mergedConfig.SetOuterContextDepth(Math.Max(mergedConfig.GetOuterContextDepth(), e
.GetOuterContextDepth()));
PredictionContext joined = PredictionContext.Join(mergedConfig.GetContext(), e.GetContext
(), contextCache);
UpdatePropertiesForMergedConfig(e);
if (mergedConfig.GetContext() == joined)
{
return false;
}
mergedConfig.SetContext(joined);
return true;
}
for (int i = 0; i < unmerged.Count; i++)
{
ATNConfig unmergedConfig = unmerged[i];
if (CanMerge(e, key, unmergedConfig))
{
unmergedConfig.SetOuterContextDepth(Math.Max(unmergedConfig.GetOuterContextDepth(
), e.GetOuterContextDepth()));
PredictionContext joined = PredictionContext.Join(unmergedConfig.GetContext(), e.
GetContext(), contextCache);
UpdatePropertiesForMergedConfig(e);
if (unmergedConfig.GetContext() == joined)
{
return false;
}
unmergedConfig.SetContext(joined);
if (addKey)
{
mergedConfigs.Put(key, unmergedConfig);
unmerged.Remove(i);
}
return true;
}
}
configs.AddItem(e);
if (addKey)
{
mergedConfigs.Put(key, e);
}
else
{
unmerged.AddItem(e);
}
UpdatePropertiesForAddedConfig(e);
return true;
}
private void UpdatePropertiesForMergedConfig(ATNConfig config)
{
// merged configs can't change the alt or semantic context
dipsIntoOuterContext |= config.GetReachesIntoOuterContext();
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
private void UpdatePropertiesForAddedConfig(ATNConfig config)
{
if (configs.Count == 1)
{
uniqueAlt = config.GetAlt();
}
else
{
if (uniqueAlt != config.GetAlt())
{
uniqueAlt = ATN.InvalidAltNumber;
}
}
hasSemanticContext |= !SemanticContext.None.Equals(config.GetSemanticContext());
dipsIntoOuterContext |= config.GetReachesIntoOuterContext();
System.Diagnostics.Debug.Assert(!outermostConfigSet || !dipsIntoOuterContext);
}
protected internal virtual bool CanMerge(ATNConfig left, long leftKey, ATNConfig
right)
{
if (left.GetState().stateNumber != right.GetState().stateNumber)
{
return false;
}
if (leftKey != GetKey(right))
{
return false;
}
return left.GetSemanticContext().Equals(right.GetSemanticContext());
}
protected internal virtual long GetKey(ATNConfig e)
{
long key = e.GetState().stateNumber;
key = (key << 12) | (e.GetAlt() & unchecked((int)(0xFFF)));
return key;
}
public virtual bool Remove(object o)
{
EnsureWritable();
throw new NotSupportedException("Not supported yet.");
}
public virtual bool ContainsAll<_T0>(ICollection<_T0> c)
{
foreach (object o in c)
{
if (!(o is ATNConfig))
{
return false;
}
if (!Contains((ATNConfig)o))
{
return false;
}
}
return true;
}
public virtual bool AddAll<_T0>(ICollection<_T0> c) where _T0:ATNConfig
{
return AddAll(c, null);
}
public virtual bool AddAll<_T0>(ICollection<_T0> c, PredictionContextCache contextCache
) where _T0:ATNConfig
{
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();
configs.Clear();
dipsIntoOuterContext = false;
hasSemanticContext = false;
uniqueAlt = ATN.InvalidAltNumber;
conflictingAlts = null;
}
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(conflictingAlts
, other.conflictingAlts) && configs.Equals(other.configs);
}
public override int GetHashCode()
{
int hashCode = 1;
hashCode = 5 * hashCode ^ (outermostConfigSet ? 1 : 0);
hashCode = 5 * hashCode ^ configs.GetHashCode();
return hashCode;
}
public override string ToString()
{
return ToString(false);
}
public virtual string ToString(bool showContext)
{
StringBuilder buf = new StringBuilder();
IList<ATNConfig> sortedConfigs = new List<ATNConfig>(configs);
sortedConfigs.Sort(new _IComparer_467());
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 (conflictingAlts != null)
{
buf.Append(",conflictingAlts=").Append(conflictingAlts);
}
if (dipsIntoOuterContext)
{
buf.Append(",dipsIntoOuterContext");
}
return buf.ToString();
}
private sealed class _IComparer_467 : IComparer<ATNConfig>
{
public _IComparer_467()
{
}
public int Compare(ATNConfig o1, ATNConfig o2)
{
if (o1.GetAlt() != o2.GetAlt())
{
return o1.GetAlt() - o2.GetAlt();
}
else
{
if (o1.GetState().stateNumber != o2.GetState().stateNumber)
{
return o1.GetState().stateNumber - o2.GetState().stateNumber;
}
else
{
return Sharpen.Runtime.CompareOrdinal(o1.GetSemanticContext().ToString(), o2.GetSemanticContext
().ToString());
}
}
}
}
public virtual int GetUniqueAlt()
{
return uniqueAlt;
}
public virtual bool HasSemanticContext()
{
return hasSemanticContext;
}
public virtual void ClearExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = false;
}
public virtual void MarkExplicitSemanticContext()
{
EnsureWritable();
hasSemanticContext = true;
}
public virtual BitSet GetConflictingAlts()
{
return conflictingAlts;
}
public virtual void SetConflictingAlts(BitSet conflictingAlts)
{
EnsureWritable();
this.conflictingAlts = conflictingAlts;
}
public virtual bool GetDipsIntoOuterContext()
{
return dipsIntoOuterContext;
}
public virtual ATNConfig Get(int index)
{
return configs[index];
}
public virtual void Remove(int index)
{
EnsureWritable();
ATNConfig config = configs[index];
configs.Remove(config);
long key = GetKey(config);
if (mergedConfigs.Get(key) == config)
{
Sharpen.Collections.Remove(mergedConfigs, key);
}
else
{
for (int i = 0; i < unmerged.Count; i++)
{
if (unmerged[i] == config)
{
unmerged.Remove(i);
return;
}
}
}
}
protected internal void EnsureWritable()
{
if (IsReadOnly())
{
throw new InvalidOperationException("This ATNConfigSet is read only.");
}
}
private sealed class ATNConfigSetIterator : IEnumerator<ATNConfig>
{
internal int index = -1;
internal bool removed = false;
public override bool HasNext()
{
return this.index + 1 < this._enclosing.configs.Count;
}
public override ATNConfig Next()
{
if (!this.HasNext())
{
throw new NoSuchElementException();
}
this.index++;
this.removed = false;
return this._enclosing.configs[this.index];
}
public override void Remove()
{
if (this.removed || this.index < 0 || this.index >= this._enclosing.configs.Count)
{
throw new InvalidOperationException();
}
this._enclosing.Remove(this.index);
this.removed = true;
}
internal ATNConfigSetIterator(ATNConfigSet _enclosing)
{
this._enclosing = _enclosing;
}
private readonly ATNConfigSet _enclosing;
}
}
}

View File

@ -0,0 +1,995 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public abstract class ATNSimulator
{
public static readonly int SerializedVersion;
static ATNSimulator()
{
SerializedVersion = 5;
}
public const char RuleVariantDelimiter = '$';
public static readonly string RuleLfVariantMarker = "$lf$";
public static readonly string RuleNolfVariantMarker = "$nolf$";
/// <summary>Must distinguish between missing edge and edge we know leads nowhere</summary>
[NotNull]
public static readonly DFAState Error;
[NotNull]
public readonly ATN atn;
static ATNSimulator()
{
Error = new DFAState(new ATNConfigSet(), 0, 0);
Error.stateNumber = int.MaxValue;
}
public ATNSimulator(ATN atn)
{
this.atn = atn;
}
public abstract void Reset();
public static ATN Deserialize(char[] data)
{
return Deserialize(data, true);
}
public static ATN Deserialize(char[] data, bool optimize)
{
data = data.Clone();
// don't adjust the first value since that's the version number
for (int i = 1; i < data.Length; i++)
{
data[i] = (char)(data[i] - 2);
}
ATN atn = new ATN();
IList<IntervalSet> sets = new List<IntervalSet>();
int p = 0;
int version = ToInt(data[p++]);
if (version != SerializedVersion)
{
string reason = string.Format("Could not deserialize ATN with version %d (expected %d)."
, version, SerializedVersion);
throw new NotSupportedException(new InvalidClassException(typeof(ATN).FullName, reason
));
}
atn.grammarType = ToInt(data[p++]);
atn.maxTokenType = ToInt(data[p++]);
//
// STATES
//
IList<Tuple<LoopEndState, int>> loopBackStateNumbers = new List<Tuple<LoopEndState
, int>>();
IList<Tuple<BlockStartState, int>> endStateNumbers = new List<Tuple<BlockStartState
, int>>();
int nstates = ToInt(data[p++]);
for (int i_1 = 1; i_1 <= nstates; i_1++)
{
int stype = ToInt(data[p++]);
// ignore bad type of states
if (stype == ATNState.InvalidType)
{
atn.AddState(null);
continue;
}
int ruleIndex = ToInt(data[p++]);
ATNState s = StateFactory(stype, ruleIndex);
if (stype == ATNState.LoopEnd)
{
// special case
int loopBackStateNumber = ToInt(data[p++]);
loopBackStateNumbers.AddItem(Tuple.Create((LoopEndState)s, loopBackStateNumber));
}
else
{
if (s is BlockStartState)
{
int endStateNumber = ToInt(data[p++]);
endStateNumbers.AddItem(Tuple.Create((BlockStartState)s, endStateNumber));
}
}
atn.AddState(s);
}
// delay the assignment of loop back and end states until we know all the state instances have been initialized
foreach (Tuple<LoopEndState, int> pair in loopBackStateNumbers)
{
pair.GetItem1().loopBackState = atn.states[pair.GetItem2()];
}
foreach (Tuple<BlockStartState, int> pair_1 in endStateNumbers)
{
pair_1.GetItem1().endState = (BlockEndState)atn.states[pair_1.GetItem2()];
}
int numNonGreedyStates = ToInt(data[p++]);
for (int i_2 = 0; i_2 < numNonGreedyStates; i_2++)
{
int stateNumber = ToInt(data[p++]);
((DecisionState)atn.states[stateNumber]).nonGreedy = true;
}
int numSllDecisions = ToInt(data[p++]);
for (int i_3 = 0; i_3 < numSllDecisions; i_3++)
{
int stateNumber = ToInt(data[p++]);
((DecisionState)atn.states[stateNumber]).sll = true;
}
int numPrecedenceStates = ToInt(data[p++]);
for (int i_4 = 0; i_4 < numPrecedenceStates; i_4++)
{
int stateNumber = ToInt(data[p++]);
((RuleStartState)atn.states[stateNumber]).isPrecedenceRule = true;
}
//
// RULES
//
int nrules = ToInt(data[p++]);
if (atn.grammarType == ATN.Lexer)
{
atn.ruleToTokenType = new int[nrules];
atn.ruleToActionIndex = new int[nrules];
}
atn.ruleToStartState = new RuleStartState[nrules];
for (int i_5 = 0; i_5 < nrules; i_5++)
{
int s = ToInt(data[p++]);
RuleStartState startState = (RuleStartState)atn.states[s];
startState.leftFactored = ToInt(data[p++]) != 0;
atn.ruleToStartState[i_5] = startState;
if (atn.grammarType == ATN.Lexer)
{
int tokenType = ToInt(data[p++]);
atn.ruleToTokenType[i_5] = tokenType;
int actionIndex = ToInt(data[p++]);
atn.ruleToActionIndex[i_5] = actionIndex;
}
}
atn.ruleToStopState = new RuleStopState[nrules];
foreach (ATNState state in atn.states)
{
if (!(state is RuleStopState))
{
continue;
}
RuleStopState stopState = (RuleStopState)state;
atn.ruleToStopState[state.ruleIndex] = stopState;
atn.ruleToStartState[state.ruleIndex].stopState = stopState;
}
//
// MODES
//
int nmodes = ToInt(data[p++]);
for (int i_6 = 0; i_6 < nmodes; i_6++)
{
int s = ToInt(data[p++]);
atn.modeToStartState.AddItem((TokensStartState)atn.states[s]);
}
atn.modeToDFA = new DFA[nmodes];
for (int i_7 = 0; i_7 < nmodes; i_7++)
{
atn.modeToDFA[i_7] = new DFA(atn.modeToStartState[i_7]);
}
//
// SETS
//
int nsets = ToInt(data[p++]);
for (int i_8 = 1; i_8 <= nsets; i_8++)
{
int nintervals = ToInt(data[p]);
p++;
IntervalSet set = new IntervalSet();
sets.AddItem(set);
for (int j = 1; j <= nintervals; j++)
{
set.Add(ToInt(data[p]), ToInt(data[p + 1]));
p += 2;
}
}
//
// EDGES
//
int nedges = ToInt(data[p++]);
for (int i_9 = 1; i_9 <= nedges; i_9++)
{
int src = ToInt(data[p]);
int trg = ToInt(data[p + 1]);
int ttype = ToInt(data[p + 2]);
int arg1 = ToInt(data[p + 3]);
int arg2 = ToInt(data[p + 4]);
int arg3 = ToInt(data[p + 5]);
Transition trans = EdgeFactory(atn, ttype, src, trg, arg1, arg2, arg3, sets);
// System.out.println("EDGE "+trans.getClass().getSimpleName()+" "+
// src+"->"+trg+
// " "+Transition.serializationNames[ttype]+
// " "+arg1+","+arg2+","+arg3);
ATNState srcState = atn.states[src];
srcState.AddTransition(trans);
p += 6;
}
// edges for rule stop states can be derived, so they aren't serialized
foreach (ATNState state_1 in atn.states)
{
bool returningToLeftFactored = state_1.ruleIndex >= 0 && atn.ruleToStartState[state_1
.ruleIndex].leftFactored;
for (int i_10 = 0; i_10 < state_1.GetNumberOfTransitions(); i_10++)
{
Transition t = state_1.Transition(i_10);
if (!(t is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)t;
bool returningFromLeftFactored = atn.ruleToStartState[ruleTransition.target.ruleIndex
].leftFactored;
if (!returningFromLeftFactored && returningToLeftFactored)
{
continue;
}
atn.ruleToStopState[ruleTransition.target.ruleIndex].AddTransition(new EpsilonTransition
(ruleTransition.followState));
}
}
foreach (ATNState state_2 in atn.states)
{
if (state_2 is BlockStartState)
{
// we need to know the end state to set its start state
if (((BlockStartState)state_2).endState == null)
{
throw new InvalidOperationException();
}
// block end states can only be associated to a single block start state
if (((BlockStartState)state_2).endState.startState != null)
{
throw new InvalidOperationException();
}
((BlockStartState)state_2).endState.startState = (BlockStartState)state_2;
}
if (state_2 is PlusLoopbackState)
{
PlusLoopbackState loopbackState = (PlusLoopbackState)state_2;
for (int i_10 = 0; i_10 < loopbackState.GetNumberOfTransitions(); i_10++)
{
ATNState target = loopbackState.Transition(i_10).target;
if (target is PlusBlockStartState)
{
((PlusBlockStartState)target).loopBackState = loopbackState;
}
}
}
else
{
if (state_2 is StarLoopbackState)
{
StarLoopbackState loopbackState = (StarLoopbackState)state_2;
for (int i_10 = 0; i_10 < loopbackState.GetNumberOfTransitions(); i_10++)
{
ATNState target = loopbackState.Transition(i_10).target;
if (target is StarLoopEntryState)
{
((StarLoopEntryState)target).loopBackState = loopbackState;
}
}
}
}
}
//
// DECISIONS
//
int ndecisions = ToInt(data[p++]);
for (int i_11 = 1; i_11 <= ndecisions; i_11++)
{
int s = ToInt(data[p++]);
DecisionState decState = (DecisionState)atn.states[s];
atn.decisionToState.AddItem(decState);
decState.decision = i_11 - 1;
}
atn.decisionToDFA = new DFA[ndecisions];
for (int i_12 = 0; i_12 < ndecisions; i_12++)
{
atn.decisionToDFA[i_12] = new DFA(atn.decisionToState[i_12], i_12);
}
if (optimize)
{
while (true)
{
int optimizationCount = 0;
optimizationCount += InlineSetRules(atn);
optimizationCount += CombineChainedEpsilons(atn);
bool preserveOrder = atn.grammarType == ATN.Lexer;
optimizationCount += OptimizeSets(atn, preserveOrder);
if (optimizationCount == 0)
{
break;
}
}
}
IdentifyTailCalls(atn);
VerifyATN(atn);
return atn;
}
private static void VerifyATN(ATN atn)
{
// verify assumptions
foreach (ATNState state in atn.states)
{
if (state == null)
{
continue;
}
CheckCondition(state.OnlyHasEpsilonTransitions() || state.GetNumberOfTransitions(
) <= 1);
if (state is PlusBlockStartState)
{
CheckCondition(((PlusBlockStartState)state).loopBackState != null);
}
if (state is StarLoopEntryState)
{
StarLoopEntryState starLoopEntryState = (StarLoopEntryState)state;
CheckCondition(starLoopEntryState.loopBackState != null);
CheckCondition(starLoopEntryState.GetNumberOfTransitions() == 2);
if (starLoopEntryState.Transition(0).target is StarBlockStartState)
{
CheckCondition(starLoopEntryState.Transition(1).target is LoopEndState);
CheckCondition(!starLoopEntryState.nonGreedy);
}
else
{
if (starLoopEntryState.Transition(0).target is LoopEndState)
{
CheckCondition(starLoopEntryState.Transition(1).target is StarBlockStartState);
CheckCondition(starLoopEntryState.nonGreedy);
}
else
{
throw new InvalidOperationException();
}
}
}
if (state is StarLoopbackState)
{
CheckCondition(state.GetNumberOfTransitions() == 1);
CheckCondition(state.Transition(0).target is StarLoopEntryState);
}
if (state is LoopEndState)
{
CheckCondition(((LoopEndState)state).loopBackState != null);
}
if (state is RuleStartState)
{
CheckCondition(((RuleStartState)state).stopState != null);
}
if (state is BlockStartState)
{
CheckCondition(((BlockStartState)state).endState != null);
}
if (state is BlockEndState)
{
CheckCondition(((BlockEndState)state).startState != null);
}
if (state is DecisionState)
{
DecisionState decisionState = (DecisionState)state;
CheckCondition(decisionState.GetNumberOfTransitions() <= 1 || decisionState.decision
>= 0);
}
else
{
CheckCondition(state.GetNumberOfTransitions() <= 1 || state is RuleStopState);
}
}
}
public static void CheckCondition(bool condition)
{
CheckCondition(condition, null);
}
public static void CheckCondition(bool condition, string message)
{
if (!condition)
{
throw new InvalidOperationException(message);
}
}
private static int InlineSetRules(ATN atn)
{
int inlinedCalls = 0;
Transition[] ruleToInlineTransition = new Transition[atn.ruleToStartState.Length]
;
for (int i = 0; i < atn.ruleToStartState.Length; i++)
{
RuleStartState startState = atn.ruleToStartState[i];
ATNState middleState = startState;
while (middleState.OnlyHasEpsilonTransitions() && middleState.GetNumberOfOptimizedTransitions
() == 1 && middleState.GetOptimizedTransition(0).SerializationType == Transition
.Epsilon)
{
middleState = middleState.GetOptimizedTransition(0).target;
}
if (middleState.GetNumberOfOptimizedTransitions() != 1)
{
continue;
}
Transition matchTransition = middleState.GetOptimizedTransition(0);
ATNState matchTarget = matchTransition.target;
if (matchTransition.IsEpsilon || !matchTarget.OnlyHasEpsilonTransitions() || matchTarget
.GetNumberOfOptimizedTransitions() != 1 || !(matchTarget.GetOptimizedTransition
(0).target is RuleStopState))
{
continue;
}
switch (matchTransition.SerializationType)
{
case Transition.Atom:
case Transition.Range:
case Transition.Set:
{
ruleToInlineTransition[i] = matchTransition;
break;
}
case Transition.NotSet:
case Transition.Wildcard:
{
// not implemented yet
continue;
goto default;
}
default:
{
continue;
break;
}
}
}
for (int stateNumber = 0; stateNumber < atn.states.Count; stateNumber++)
{
ATNState state = atn.states[stateNumber];
if (state.ruleIndex < 0)
{
continue;
}
IList<Transition> optimizedTransitions = null;
for (int i_1 = 0; i_1 < state.GetNumberOfOptimizedTransitions(); i_1++)
{
Transition transition = state.GetOptimizedTransition(i_1);
if (!(transition is RuleTransition))
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition;
Transition effective = ruleToInlineTransition[ruleTransition.target.ruleIndex];
if (effective == null)
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
continue;
}
if (optimizedTransitions == null)
{
optimizedTransitions = new List<Transition>();
for (int j = 0; j < i_1; j++)
{
optimizedTransitions.AddItem(state.GetOptimizedTransition(i_1));
}
}
inlinedCalls++;
ATNState target = ruleTransition.followState;
ATNState intermediateState = new BasicState();
intermediateState.SetRuleIndex(target.ruleIndex);
atn.AddState(intermediateState);
optimizedTransitions.AddItem(new EpsilonTransition(intermediateState));
switch (effective.SerializationType)
{
case Transition.Atom:
{
intermediateState.AddTransition(new AtomTransition(target, ((AtomTransition)effective
).label));
break;
}
case Transition.Range:
{
intermediateState.AddTransition(new RangeTransition(target, ((RangeTransition)effective
).from, ((RangeTransition)effective).to));
break;
}
case Transition.Set:
{
intermediateState.AddTransition(new SetTransition(target, effective.Label));
break;
}
default:
{
throw new NotSupportedException();
}
}
}
if (optimizedTransitions != null)
{
if (state.IsOptimized())
{
while (state.GetNumberOfOptimizedTransitions() > 0)
{
state.RemoveOptimizedTransition(state.GetNumberOfOptimizedTransitions() - 1);
}
}
foreach (Transition transition in optimizedTransitions)
{
state.AddOptimizedTransition(transition);
}
}
}
return inlinedCalls;
}
private static int CombineChainedEpsilons(ATN atn)
{
int removedEdges = 0;
foreach (ATNState state in atn.states)
{
if (!state.OnlyHasEpsilonTransitions() || state is RuleStopState)
{
continue;
}
IList<Transition> optimizedTransitions = null;
for (int i = 0; i < state.GetNumberOfOptimizedTransitions(); i++)
{
Transition transition = state.GetOptimizedTransition(i);
ATNState intermediate = transition.target;
if (transition.SerializationType != Transition.Epsilon || intermediate.GetStateType
() != ATNState.Basic || !intermediate.OnlyHasEpsilonTransitions())
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
goto nextTransition_continue;
}
for (int j = 0; j < intermediate.GetNumberOfOptimizedTransitions(); j++)
{
if (intermediate.GetOptimizedTransition(j).SerializationType != Transition.Epsilon)
{
if (optimizedTransitions != null)
{
optimizedTransitions.AddItem(transition);
}
goto nextTransition_continue;
}
}
removedEdges++;
if (optimizedTransitions == null)
{
optimizedTransitions = new List<Transition>();
for (int j_1 = 0; j_1 < i; j_1++)
{
optimizedTransitions.AddItem(state.GetOptimizedTransition(j_1));
}
}
for (int j_2 = 0; j_2 < intermediate.GetNumberOfOptimizedTransitions(); j_2++)
{
ATNState target = intermediate.GetOptimizedTransition(j_2).target;
optimizedTransitions.AddItem(new EpsilonTransition(target));
}
nextTransition_continue: ;
}
nextTransition_break: ;
if (optimizedTransitions != null)
{
if (state.IsOptimized())
{
while (state.GetNumberOfOptimizedTransitions() > 0)
{
state.RemoveOptimizedTransition(state.GetNumberOfOptimizedTransitions() - 1);
}
}
foreach (Transition transition in optimizedTransitions)
{
state.AddOptimizedTransition(transition);
}
}
}
nextState_break: ;
return removedEdges;
}
private static int OptimizeSets(ATN atn, bool preserveOrder)
{
if (preserveOrder)
{
// this optimization currently doesn't preserve edge order.
return 0;
}
int removedPaths = 0;
IList<DecisionState> decisions = atn.decisionToState;
foreach (DecisionState decision in decisions)
{
IntervalSet setTransitions = new IntervalSet();
for (int i = 0; i < decision.GetNumberOfOptimizedTransitions(); i++)
{
Transition epsTransition = decision.GetOptimizedTransition(i);
if (!(epsTransition is EpsilonTransition))
{
continue;
}
if (epsTransition.target.GetNumberOfOptimizedTransitions() != 1)
{
continue;
}
Transition transition = epsTransition.target.GetOptimizedTransition(0);
if (!(transition.target is BlockEndState))
{
continue;
}
if (transition is NotSetTransition)
{
// TODO: not yet implemented
continue;
}
if (transition is AtomTransition || transition is RangeTransition || transition is
SetTransition)
{
setTransitions.Add(i);
}
}
if (setTransitions.Size() <= 1)
{
continue;
}
IList<Transition> optimizedTransitions = new List<Transition>();
for (int i_1 = 0; i_1 < decision.GetNumberOfOptimizedTransitions(); i_1++)
{
if (!setTransitions.Contains(i_1))
{
optimizedTransitions.AddItem(decision.GetOptimizedTransition(i_1));
}
}
ATNState blockEndState = decision.GetOptimizedTransition(setTransitions.GetMinElement
()).target.GetOptimizedTransition(0).target;
IntervalSet matchSet = new IntervalSet();
for (int i_2 = 0; i_2 < setTransitions.GetIntervals().Count; i_2++)
{
Interval interval = setTransitions.GetIntervals()[i_2];
for (int j = interval.a; j <= interval.b; j++)
{
Transition matchTransition = decision.GetOptimizedTransition(j).target.GetOptimizedTransition
(0);
if (matchTransition is NotSetTransition)
{
throw new NotSupportedException("Not yet implemented.");
}
else
{
matchSet.AddAll(matchTransition.Label);
}
}
}
Transition newTransition;
if (matchSet.GetIntervals().Count == 1)
{
if (matchSet.Size() == 1)
{
newTransition = new AtomTransition(blockEndState, matchSet.GetMinElement());
}
else
{
Interval matchInterval = matchSet.GetIntervals()[0];
newTransition = new RangeTransition(blockEndState, matchInterval.a, matchInterval
.b);
}
}
else
{
newTransition = new SetTransition(blockEndState, matchSet);
}
ATNState setOptimizedState = new BasicState();
setOptimizedState.SetRuleIndex(decision.ruleIndex);
atn.AddState(setOptimizedState);
setOptimizedState.AddTransition(newTransition);
optimizedTransitions.AddItem(new EpsilonTransition(setOptimizedState));
removedPaths += decision.GetNumberOfOptimizedTransitions() - optimizedTransitions
.Count;
if (decision.IsOptimized())
{
while (decision.GetNumberOfOptimizedTransitions() > 0)
{
decision.RemoveOptimizedTransition(decision.GetNumberOfOptimizedTransitions() - 1
);
}
}
foreach (Transition transition_1 in optimizedTransitions)
{
decision.AddOptimizedTransition(transition_1);
}
}
return removedPaths;
}
private static void IdentifyTailCalls(ATN atn)
{
foreach (ATNState state in atn.states)
{
foreach (Transition transition in state.transitions)
{
if (!(transition is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition;
ruleTransition.tailCall = TestTailCall(atn, ruleTransition, false);
ruleTransition.optimizedTailCall = TestTailCall(atn, ruleTransition, true);
}
if (!state.IsOptimized())
{
continue;
}
foreach (Transition transition_1 in state.optimizedTransitions)
{
if (!(transition_1 is RuleTransition))
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition_1;
ruleTransition.tailCall = TestTailCall(atn, ruleTransition, false);
ruleTransition.optimizedTailCall = TestTailCall(atn, ruleTransition, true);
}
}
}
private static bool TestTailCall(ATN atn, RuleTransition transition, bool optimizedPath
)
{
if (!optimizedPath && transition.tailCall)
{
return true;
}
if (optimizedPath && transition.optimizedTailCall)
{
return true;
}
BitSet reachable = new BitSet(atn.states.Count);
IDeque<ATNState> worklist = new ArrayDeque<ATNState>();
worklist.AddItem(transition.followState);
while (!worklist.IsEmpty())
{
ATNState state = worklist.Pop();
if (reachable.Get(state.stateNumber))
{
continue;
}
if (state is RuleStopState)
{
continue;
}
if (!state.OnlyHasEpsilonTransitions())
{
return false;
}
IList<Transition> transitions = optimizedPath ? state.optimizedTransitions : state
.transitions;
foreach (Transition t in transitions)
{
if (t.SerializationType != Transition.Epsilon)
{
return false;
}
worklist.AddItem(t.target);
}
}
return true;
}
public static int ToInt(char c)
{
return c == 65535 ? -1 : c;
}
[NotNull]
public static Transition EdgeFactory(ATN atn, int type, int src, int trg, int arg1
, int arg2, int arg3, IList<IntervalSet> sets)
{
ATNState target = atn.states[trg];
switch (type)
{
case Transition.Epsilon:
{
return new EpsilonTransition(target);
}
case Transition.Range:
{
return new RangeTransition(target, arg1, arg2);
}
case Transition.Rule:
{
RuleTransition rt = new RuleTransition((RuleStartState)atn.states[arg1], arg2, arg3
, target);
return rt;
}
case Transition.Predicate:
{
PredicateTransition pt = new PredicateTransition(target, arg1, arg2, arg3 != 0);
return pt;
}
case Transition.Precedence:
{
return new PrecedencePredicateTransition(target, arg1);
}
case Transition.Atom:
{
return new AtomTransition(target, arg1);
}
case Transition.Action:
{
ActionTransition a = new ActionTransition(target, arg1, arg2, arg3 != 0);
return a;
}
case Transition.Set:
{
return new SetTransition(target, sets[arg1]);
}
case Transition.NotSet:
{
return new NotSetTransition(target, sets[arg1]);
}
case Transition.Wildcard:
{
return new WildcardTransition(target);
}
}
throw new ArgumentException("The specified transition type is not valid.");
}
public static ATNState StateFactory(int type, int ruleIndex)
{
ATNState s;
switch (type)
{
case ATNState.InvalidType:
{
return null;
}
case ATNState.Basic:
{
s = new BasicState();
break;
}
case ATNState.RuleStart:
{
s = new RuleStartState();
break;
}
case ATNState.BlockStart:
{
s = new BasicBlockStartState();
break;
}
case ATNState.PlusBlockStart:
{
s = new PlusBlockStartState();
break;
}
case ATNState.StarBlockStart:
{
s = new StarBlockStartState();
break;
}
case ATNState.TokenStart:
{
s = new TokensStartState();
break;
}
case ATNState.RuleStop:
{
s = new RuleStopState();
break;
}
case ATNState.BlockEnd:
{
s = new BlockEndState();
break;
}
case ATNState.StarLoopBack:
{
s = new StarLoopbackState();
break;
}
case ATNState.StarLoopEntry:
{
s = new StarLoopEntryState();
break;
}
case ATNState.PlusLoopBack:
{
s = new PlusLoopbackState();
break;
}
case ATNState.LoopEnd:
{
s = new LoopEndState();
break;
}
default:
{
string message = string.Format("The specified state type %d is not valid.", type);
throw new ArgumentException(message);
}
}
s.ruleIndex = ruleIndex;
return s;
}
}
}

View File

@ -0,0 +1,304 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// The following images show the relation of states and
/// <see cref="transitions">transitions</see>
/// for various grammar constructs.
/// <ul>
/// <li>Solid edges marked with an &#0949; indicate a required
/// <see cref="EpsilonTransition">EpsilonTransition</see>
/// .</li>
/// <li>Dashed edges indicate locations where any transition derived from
/// <see cref="Transition">Transition</see>
/// might appear.</li>
/// <li>Dashed nodes are place holders for either a sequence of linked
/// <see cref="BasicState">BasicState</see>
/// 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
/// <code>...</code>
/// support
/// any number of alternatives (one or more). Nodes without the
/// <code>...</code>
/// 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:
/// <code>(...)*</code>
/// </h3>
/// <embed src="images/ClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Positive Closure:
/// <code>(...)+</code>
/// </h3>
/// <embed src="images/PositiveClosureGreedy.svg" type="image/svg+xml"/>
/// <h3>Greedy Optional:
/// <code>(...)?</code>
/// </h3>
/// <embed src="images/OptionalGreedy.svg" type="image/svg+xml"/>
/// <h2>Non-Greedy Loops</h2>
/// <h3>Non-Greedy Closure:
/// <code>(...)*?</code>
/// </h3>
/// <embed src="images/ClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Positive Closure:
/// <code>(...)+?</code>
/// </h3>
/// <embed src="images/PositiveClosureNonGreedy.svg" type="image/svg+xml"/>
/// <h3>Non-Greedy Optional:
/// <code>(...)??</code>
/// </h3>
/// <embed src="images/OptionalNonGreedy.svg" type="image/svg+xml"/>
/// </summary>
public abstract class ATNState
{
public const int InitialNumTransitions = 4;
public const int InvalidType = 0;
public const int Basic = 1;
public const int RuleStart = 2;
public const int BlockStart = 3;
public const int PlusBlockStart = 4;
public const int StarBlockStart = 5;
public const int TokenStart = 6;
public const int RuleStop = 7;
public const int BlockEnd = 8;
public const int StarLoopBack = 9;
public const int StarLoopEntry = 10;
public const int PlusLoopBack = 11;
public const int LoopEnd = 12;
public static readonly IList<string> serializationNames = Sharpen.Collections.UnmodifiableList
(Arrays.AsList("INVALID", "BASIC", "RULE_START", "BLOCK_START", "PLUS_BLOCK_START"
, "STAR_BLOCK_START", "TOKEN_START", "RULE_STOP", "BLOCK_END", "STAR_LOOP_BACK"
, "STAR_LOOP_ENTRY", "PLUS_LOOP_BACK", "LOOP_END"));
public const int InvalidStateNumber = -1;
/// <summary>Which ATN are we in?</summary>
public ATN atn = null;
public int stateNumber = InvalidStateNumber;
public int ruleIndex;
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 IList<Antlr4.Runtime.Atn.Transition> transitions = new
List<Antlr4.Runtime.Atn.Transition>(InitialNumTransitions);
protected internal IList<Antlr4.Runtime.Atn.Transition> optimizedTransitions;
/// <summary>Used to cache lookahead during parsing, not used during construction</summary>
public IntervalSet nextTokenWithinRule;
// constants for serialization
// at runtime, we don't have Rule objects
/// <summary>Gets the state number.</summary>
/// <remarks>Gets the state number.</remarks>
/// <returns>the state number</returns>
public int GetStateNumber()
{
return stateNumber;
}
/// <summary>
/// For all states except
/// <see cref="RuleStopState">RuleStopState</see>
/// , this returns the state
/// number. Returns -1 for stop states.
/// </summary>
/// <returns>
/// -1 for
/// <see cref="RuleStopState">RuleStopState</see>
/// , otherwise the state number
/// </returns>
public virtual int GetNonStopStateNumber()
{
return GetStateNumber();
}
public override int GetHashCode()
{
return stateNumber;
}
public override bool Equals(object o)
{
// are these states same object?
if (o is ATNState)
{
return stateNumber == ((ATNState)o).stateNumber;
}
return false;
}
public virtual bool IsNonGreedyExitState()
{
return false;
}
public override string ToString()
{
return stateNumber.ToString();
}
public virtual Antlr4.Runtime.Atn.Transition[] GetTransitions()
{
return Sharpen.Collections.ToArray(transitions, new Antlr4.Runtime.Atn.Transition
[transitions.Count]);
}
public virtual int GetNumberOfTransitions()
{
return transitions.Count;
}
public virtual void AddTransition(Antlr4.Runtime.Atn.Transition e)
{
if (transitions.IsEmpty())
{
epsilonOnlyTransitions = e.IsEpsilon;
}
else
{
if (epsilonOnlyTransitions != e.IsEpsilon)
{
System.Console.Error.Format("ATN state %d has both epsilon and non-epsilon transitions.\n"
, stateNumber);
epsilonOnlyTransitions = false;
}
}
transitions.AddItem(e);
}
public virtual Antlr4.Runtime.Atn.Transition Transition(int i)
{
return transitions[i];
}
public virtual void SetTransition(int i, Antlr4.Runtime.Atn.Transition e)
{
transitions.Set(i, e);
}
public virtual Antlr4.Runtime.Atn.Transition RemoveTransition(int index)
{
return transitions.Remove(index);
}
public abstract int GetStateType();
public bool OnlyHasEpsilonTransitions()
{
return epsilonOnlyTransitions;
}
public virtual void SetRuleIndex(int ruleIndex)
{
this.ruleIndex = ruleIndex;
}
public virtual bool IsOptimized()
{
return optimizedTransitions != transitions;
}
public virtual int GetNumberOfOptimizedTransitions()
{
return optimizedTransitions.Count;
}
public virtual Antlr4.Runtime.Atn.Transition GetOptimizedTransition(int i)
{
return optimizedTransitions[i];
}
public virtual void AddOptimizedTransition(Antlr4.Runtime.Atn.Transition e)
{
if (!IsOptimized())
{
optimizedTransitions = new List<Antlr4.Runtime.Atn.Transition>();
}
optimizedTransitions.AddItem(e);
}
public virtual void SetOptimizedTransition(int i, Antlr4.Runtime.Atn.Transition e
)
{
if (!IsOptimized())
{
throw new InvalidOperationException();
}
optimizedTransitions.Set(i, e);
}
public virtual void RemoveOptimizedTransition(int i)
{
if (!IsOptimized())
{
throw new InvalidOperationException();
}
optimizedTransitions.Remove(i);
}
public ATNState()
{
optimizedTransitions = transitions;
}
}
}

View File

@ -0,0 +1,42 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public abstract class AbstractPredicateTransition : Transition
{
protected internal AbstractPredicateTransition(ATNState target) : base(target)
{
}
}
}

View File

@ -0,0 +1,84 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class ActionTransition : Transition
{
public readonly int ruleIndex;
public readonly int actionIndex;
public readonly bool isCtxDependent;
public ActionTransition(ATNState target, int ruleIndex) : this(target, ruleIndex,
-1, false)
{
}
public ActionTransition(ATNState target, int ruleIndex, int actionIndex, bool isCtxDependent
) : base(target)
{
// e.g., $i ref in action
this.ruleIndex = ruleIndex;
this.actionIndex = actionIndex;
this.isCtxDependent = isCtxDependent;
}
public override int SerializationType
{
get
{
return Action;
}
}
public override bool IsEpsilon
{
get
{
return true;
}
}
// we are to be ignored by analysis 'cept for predicates
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return false;
}
public override string ToString()
{
return "action_" + ruleIndex + ":" + actionIndex;
}
}
}

View File

@ -0,0 +1,283 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public class ArrayPredictionContext : PredictionContext
{
[NotNull]
public readonly PredictionContext[] parents;
[NotNull]
public readonly int[] returnStates;
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates) :
base(CalculateHashCode(CalculateParentHashCode(parents), CalculateReturnStatesHashCode
(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.");
this.parents = parents;
this.returnStates = returnStates;
}
internal ArrayPredictionContext(PredictionContext[] parents, int[] returnStates,
int hashCode) : base(hashCode)
{
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;
}
public override PredictionContext GetParent(int index)
{
return parents[index];
}
public override int GetReturnState(int index)
{
return returnStates[index];
}
public override int FindReturnState(int returnState)
{
return System.Array.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 = visited.Get(context);
if (result == null)
{
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.Put(context, result);
}
return result;
}
public override bool Equals(object o)
{
if (this == o)
{
return true;
}
else
{
if (!(o is Antlr4.Runtime.Atn.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, ICollection<
PredictionContextCache.IdentityCommutativePredictionContextOperands> visited)
{
IDeque<PredictionContext> selfWorkList = new ArrayDeque<PredictionContext>();
IDeque<PredictionContext> otherWorkList = new ArrayDeque<PredictionContext>();
selfWorkList.Push(this);
otherWorkList.Push(other);
while (!selfWorkList.IsEmpty())
{
PredictionContextCache.IdentityCommutativePredictionContextOperands operands = new
PredictionContextCache.IdentityCommutativePredictionContextOperands(selfWorkList
.Pop(), otherWorkList.Pop());
if (!visited.AddItem(operands))
{
continue;
}
int selfSize = operands.X.Size;
if (selfSize == 0)
{
if (!operands.X.Equals(operands.Y))
{
return false;
}
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);
}
}
}
return true;
}
}
}

View File

@ -0,0 +1,75 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>TODO: make all transitions sets? no, should remove set edges</summary>
public sealed class AtomTransition : Transition
{
/// <summary>The token type or character value; or, signifies special label.</summary>
/// <remarks>The token type or character value; or, signifies special label.</remarks>
public readonly int label;
public AtomTransition(ATNState target, int label) : base(target)
{
this.label = label;
}
public override int SerializationType
{
get
{
return Atom;
}
}
public override IntervalSet Label
{
get
{
return IntervalSet.Of(label);
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return label == symbol;
}
[NotNull]
public override string ToString()
{
return label.ToString();
}
}
}

View File

@ -0,0 +1,43 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public sealed class BasicBlockStartState : BlockStartState
{
public override int GetStateType()
{
return BlockStart;
}
}
}

View File

@ -0,0 +1,43 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public sealed class BasicState : ATNState
{
public override int GetStateType()
{
return Basic;
}
}
}

View File

@ -0,0 +1,49 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Terminal node of a simple
/// <code>(a|b|c)</code>
/// block.
/// </summary>
public sealed class BlockEndState : ATNState
{
public BlockStartState startState;
public override int GetStateType()
{
return BlockEnd;
}
}
}

View File

@ -0,0 +1,44 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// The start of a regular
/// <code>(...)</code>
/// block.
/// </summary>
public abstract class BlockStartState : DecisionState
{
public BlockEndState endState;
}
}

View File

@ -0,0 +1,43 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public abstract class DecisionState : ATNState
{
public int decision = -1;
public bool nonGreedy;
public bool sll;
}
}

View File

@ -0,0 +1,136 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class EmptyPredictionContext : PredictionContext
{
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(CalculateHashCode(CalculateEmptyParentHashCode
(), CalculateEmptyReturnStateHashCode()))
{
this.fullContext = fullContext;
}
public bool IsFullContext()
{
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();
}
public override int GetReturnState(int index)
{
throw new ArgumentOutOfRangeException();
}
public override int FindReturnState(int returnState)
{
return -1;
}
public override int Size
{
get
{
return 0;
}
}
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
{
return true;
}
}
public override bool HasEmpty
{
get
{
return true;
}
}
public override bool Equals(object o)
{
return this == o;
}
public override string[] ToStrings<_T0>(Recognizer<_T0> recognizer, int currentState
)
{
return new string[] { "[]" };
}
public override string[] ToStrings<_T0>(Recognizer<_T0> recognizer, PredictionContext
stop, int currentState)
{
return new string[] { "[]" };
}
}
}

View File

@ -0,0 +1,69 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class EpsilonTransition : Transition
{
protected internal EpsilonTransition(ATNState target) : base(target)
{
}
public override int SerializationType
{
get
{
return Epsilon;
}
}
public override bool IsEpsilon
{
get
{
return true;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return false;
}
[NotNull]
public override string ToString()
{
return "epsilon";
}
}
}

View File

@ -0,0 +1,232 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public class LL1Analyzer
{
/// <summary>
/// Special value added to the lookahead sets to indicate that we hit
/// a predicate during analysis if seeThruPreds==false.
/// </summary>
/// <remarks>
/// Special value added to the lookahead sets to indicate that we hit
/// a predicate during analysis if seeThruPreds==false.
/// </remarks>
public const int HitPred = IToken.InvalidType;
[NotNull]
public readonly ATN atn;
public LL1Analyzer(ATN atn)
{
this.atn = atn;
}
/// <summary>
/// From an ATN state,
/// <code>s</code>
/// , find the set of all labels reachable from
/// <code>s</code>
/// at depth k. Only for DecisionStates.
/// </summary>
[Nullable]
public virtual IntervalSet[] GetDecisionLookahead(ATNState s)
{
// System.out.println("LOOK("+s.stateNumber+")");
if (s == null)
{
return null;
}
IntervalSet[] look = new IntervalSet[s.GetNumberOfTransitions() + 1];
for (int alt = 1; alt <= s.GetNumberOfTransitions(); alt++)
{
look[alt] = new IntervalSet();
ICollection<ATNConfig> lookBusy = new HashSet<ATNConfig>();
bool seeThruPreds = false;
// fail to get lookahead upon pred
Look(s.Transition(alt - 1).target, PredictionContext.EmptyFull, look[alt], lookBusy
, seeThruPreds, false);
// Wipe out lookahead for this alternative if we found nothing
// or we had a predicate when we !seeThruPreds
if (look[alt].Size() == 0 || look[alt].Contains(HitPred))
{
look[alt] = null;
}
}
return look;
}
/// <summary>
/// Get lookahead, using
/// <code>ctx</code>
/// if we reach end of rule. If
/// <code>ctx</code>
/// is
/// <code>PredictionContext#EMPTY_LOCAL</code>
/// or
/// <see cref="PredictionContext.EmptyFull">PredictionContext.EmptyFull</see>
/// , don't chase FOLLOW. If
/// <code>ctx</code>
/// is
/// <code>PredictionContext#EMPTY_LOCAL</code>
/// ,
/// <see cref="Antlr4.Runtime.IToken.Epsilon">EPSILON</see>
/// is in set if we can reach end of rule. If
/// <code>ctx</code>
/// is
/// <see cref="PredictionContext.EmptyFull">PredictionContext.EmptyFull</see>
/// ,
/// <see cref="Antlr4.Runtime.IIntStream.Eof">EOF</see>
/// is in set
/// if we can reach end of rule.
/// </summary>
[NotNull]
public virtual IntervalSet Look(ATNState s, PredictionContext ctx)
{
Args.NotNull("ctx", ctx);
IntervalSet r = new IntervalSet();
bool seeThruPreds = true;
// ignore preds; get all lookahead
Look(s, ctx, r, new HashSet<ATNConfig>(), seeThruPreds, true);
return r;
}
/// <summary>Compute set of tokens that can come next.</summary>
/// <remarks>
/// Compute set of tokens that can come next. If the context is
/// <see cref="PredictionContext.EmptyFull">PredictionContext.EmptyFull</see>
/// ,
/// then we don't go anywhere when we hit the end of the rule. We have
/// the correct set. If the context is
/// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
/// ,
/// that means that we did not want any tokens following this rule--just the
/// tokens that could be found within this rule. Add EPSILON to the set
/// indicating we reached the end of the ruled out having to match a token.
/// </remarks>
protected internal virtual void Look(ATNState s, PredictionContext ctx, IntervalSet
look, ICollection<ATNConfig> lookBusy, bool seeThruPreds, bool addEOF)
{
// System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
ATNConfig c = ATNConfig.Create(s, 0, ctx);
if (!lookBusy.AddItem(c))
{
return;
}
if (s is RuleStopState)
{
if (PredictionContext.IsEmptyLocal(ctx))
{
look.Add(IToken.Epsilon);
return;
}
else
{
if (ctx.IsEmpty && addEOF)
{
look.Add(IToken.Eof);
return;
}
}
for (int i = 0; i < ctx.Size; i++)
{
if (ctx.GetReturnState(i) != PredictionContext.EmptyFullStateKey)
{
ATNState returnState = atn.states[ctx.GetReturnState(i)];
// System.out.println("popping back to "+retState);
for (int j = 0; j < ctx.Size; j++)
{
Look(returnState, ctx.GetParent(j), look, lookBusy, seeThruPreds, addEOF);
}
return;
}
}
}
int n = s.GetNumberOfTransitions();
for (int i_1 = 0; i_1 < n; i_1++)
{
Transition t = s.Transition(i_1);
if (t.GetType() == typeof(RuleTransition))
{
PredictionContext newContext = ctx.GetChild(((RuleTransition)t).followState.stateNumber
);
Look(t.target, newContext, look, lookBusy, seeThruPreds, addEOF);
}
else
{
if (t is AbstractPredicateTransition)
{
if (seeThruPreds)
{
Look(t.target, ctx, look, lookBusy, seeThruPreds, addEOF);
}
else
{
look.Add(HitPred);
}
}
else
{
if (t.IsEpsilon)
{
Look(t.target, ctx, look, lookBusy, seeThruPreds, addEOF);
}
else
{
if (t.GetType() == typeof(WildcardTransition))
{
look.AddAll(IntervalSet.Of(IToken.MinUserTokenType, atn.maxTokenType));
}
else
{
// System.out.println("adding "+ t);
IntervalSet set = t.Label;
if (set != null)
{
if (t is NotSetTransition)
{
set = set.Complement(IntervalSet.Of(IToken.MinUserTokenType, atn.maxTokenType));
}
look.AddAll(set);
}
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,741 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>"dup" of ParserInterpreter</summary>
public class LexerATNSimulator : ATNSimulator
{
public const bool debug = false;
public const bool dfa_debug = false;
public const int MinDfaEdge = 0;
public const int MaxDfaEdge = 127;
public bool optimize_tail_calls = true;
/// <summary>
/// When we hit an accept state in either the DFA or the ATN, we
/// have to notify the character stream to start buffering characters
/// via
/// <see cref="Antlr4.Runtime.IIntStream.Mark()">Antlr4.Runtime.IIntStream.Mark()</see>
/// and record the current state. The current sim state
/// includes the current index into the input, the current line,
/// and current character position in that line. Note that the Lexer is
/// tracking the starting line and characterization of the token. These
/// variables track the "state" of the simulator when it hits an accept state.
/// <p/>
/// We track these variables separately for the DFA and ATN simulation
/// because the DFA simulation often has to fail over to the ATN
/// simulation. If the ATN simulation fails, we need the DFA to fall
/// back to its previously accepted state, if any. If the ATN succeeds,
/// then the ATN does the accept and the DFA simulator that invoked it
/// can simply return the predicted token type.
/// </summary>
protected internal class SimState
{
protected internal int index = -1;
protected internal int line = 0;
protected internal int charPos = -1;
protected internal DFAState dfaState;
// forces unicode to stay in ATN
protected internal virtual void Reset()
{
index = -1;
line = 0;
charPos = -1;
dfaState = null;
}
}
[Nullable]
protected internal readonly Lexer recog;
/// <summary>The current token's starting index into the character stream.</summary>
/// <remarks>
/// The current token's starting index into the character stream.
/// Shared across DFA to ATN simulation in case the ATN fails and the
/// DFA did not have a previous accept state. In this case, we use the
/// ATN-generated exception object.
/// </remarks>
protected internal int startIndex = -1;
/// <summary>line number 1..n within the input</summary>
protected internal int line = 1;
/// <summary>The index of the character relative to the beginning of the line 0..n-1</summary>
protected internal int charPositionInLine = 0;
protected internal int mode = Lexer.DefaultMode;
/// <summary>Used during DFA/ATN exec to record the most recent accept configuration info
/// </summary>
[NotNull]
protected internal readonly LexerATNSimulator.SimState prevAccept = new LexerATNSimulator.SimState
();
public static int match_calls = 0;
public LexerATNSimulator(ATN atn) : this(null, atn)
{
}
public LexerATNSimulator(Lexer recog, ATN atn) : base(atn)
{
this.recog = recog;
}
public virtual void CopyState(LexerATNSimulator simulator)
{
this.charPositionInLine = simulator.charPositionInLine;
this.line = simulator.line;
this.mode = simulator.mode;
this.startIndex = simulator.startIndex;
}
public virtual int Match(ICharStream input, int mode)
{
match_calls++;
this.mode = mode;
int mark = input.Mark();
try
{
this.startIndex = input.Index;
this.prevAccept.Reset();
DFAState s0 = atn.modeToDFA[mode].s0.Get();
if (s0 == null)
{
return MatchATN(input);
}
else
{
return ExecATN(input, s0);
}
}
finally
{
input.Release(mark);
}
}
public override void Reset()
{
prevAccept.Reset();
startIndex = -1;
line = 1;
charPositionInLine = 0;
mode = Lexer.DefaultMode;
}
// only called from test code from outside
protected internal virtual int MatchATN(ICharStream input)
{
ATNState startState = atn.modeToStartState[mode];
int old_mode = mode;
ATNConfigSet s0_closure = ComputeStartState(input, startState);
bool suppressEdge = s0_closure.HasSemanticContext();
if (suppressEdge)
{
s0_closure.ClearExplicitSemanticContext();
}
DFAState next = AddDFAState(s0_closure);
if (!suppressEdge)
{
if (!atn.modeToDFA[mode].s0.CompareAndSet(null, next))
{
next = atn.modeToDFA[mode].s0.Get();
}
}
int predict = ExecATN(input, next);
return predict;
}
protected internal virtual int ExecATN(ICharStream input, DFAState ds0)
{
//System.out.println("enter exec index "+input.index()+" from "+ds0.configs);
int t = input.La(1);
DFAState s = ds0;
// s is current/from DFA state
while (true)
{
// while more work
// As we move src->trg, src->trg, we keep track of the previous trg to
// avoid looking up the DFA state again, which is expensive.
// If the previous target was already part of the DFA, we might
// be able to avoid doing a reach operation upon t. If s!=null,
// it means that semantic predicates didn't prevent us from
// creating a DFA state. Once we know s!=null, we check to see if
// the DFA state has an edge already for t. If so, we can just reuse
// it's configuration set; there's no point in re-computing it.
// This is kind of like doing DFA simulation within the ATN
// simulation because DFA simulation is really just a way to avoid
// computing reach/closure sets. Technically, once we know that
// we have a previously added DFA state, we could jump over to
// the DFA simulator. But, that would mean popping back and forth
// a lot and making things more complicated algorithmically.
// This optimization makes a lot of sense for loops within DFA.
// A character will take us back to an existing DFA state
// that already has lots of edges out of it. e.g., .* in comments.
ATNConfigSet closure = s.configs;
DFAState target = null;
target = s.GetTarget(t);
if (target == Error)
{
break;
}
if (debug && target != null)
{
System.Console.Out.WriteLine("reuse state " + s.stateNumber + " edge to " + target
.stateNumber);
}
if (target == null)
{
ATNConfigSet reach = new OrderedATNConfigSet();
// if we don't find an existing DFA state
// Fill reach starting from closure, following t transitions
GetReachableConfigSet(input, closure, reach, t);
if (reach.IsEmpty())
{
// we got nowhere on t from s
// we reached state associated with closure for sure, so
// make sure it's defined. worst case, we define s0 from
// start state configs.
DFAState from = s != null ? s : AddDFAState(closure);
// we got nowhere on t, don't throw out this knowledge; it'd
// cause a failover from DFA later.
AddDFAEdge(from, t, Error);
break;
}
// stop when we can't match any more char
// Add an edge from s to target DFA found/created for reach
target = AddDFAEdge(s, t, reach);
}
if (target.isAcceptState)
{
CaptureSimState(prevAccept, input, target);
if (t == IIntStream.Eof)
{
break;
}
}
if (t != IIntStream.Eof)
{
Consume(input);
t = input.La(1);
}
s = target;
}
// flip; current DFA target becomes new src/from state
return FailOrAccept(prevAccept, input, s.configs, t);
}
protected internal virtual int FailOrAccept(LexerATNSimulator.SimState prevAccept
, ICharStream input, ATNConfigSet reach, int t)
{
if (prevAccept.dfaState != null)
{
int ruleIndex = prevAccept.dfaState.lexerRuleIndex;
int actionIndex = prevAccept.dfaState.lexerActionIndex;
Accept(input, ruleIndex, actionIndex, prevAccept.index, prevAccept.line, prevAccept
.charPos);
return prevAccept.dfaState.prediction;
}
else
{
// if no accept and EOF is first char, return EOF
if (t == IIntStream.Eof && input.Index == startIndex)
{
return IToken.Eof;
}
throw new LexerNoViableAltException(recog, input, startIndex, reach);
}
}
/// <summary>
/// Given a starting configuration set, figure out all ATN configurations
/// we can reach upon input
/// <code>t</code>
/// . Parameter
/// <code>reach</code>
/// is a return
/// parameter.
/// </summary>
protected internal virtual void GetReachableConfigSet(ICharStream input, ATNConfigSet
closure, ATNConfigSet reach, int t)
{
// this is used to skip processing for configs which have a lower priority
// than a config that already reached an accept state for the same rule
int skipAlt = ATN.InvalidAltNumber;
foreach (ATNConfig c in closure)
{
if (c.GetAlt() == skipAlt)
{
continue;
}
int n = c.GetState().GetNumberOfOptimizedTransitions();
for (int ti = 0; ti < n; ti++)
{
// for each optimized transition
Transition trans = c.GetState().GetOptimizedTransition(ti);
ATNState target = GetReachableTarget(trans, t);
if (target != null)
{
if (Closure(input, c.Transform(target), reach, true))
{
// any remaining configs for this alt have a lower priority than
// the one that just reached an accept state.
skipAlt = c.GetAlt();
break;
}
}
}
}
}
protected internal virtual void Accept(ICharStream input, int ruleIndex, int actionIndex
, int index, int line, int charPos)
{
if (actionIndex >= 0 && recog != null)
{
recog.Action(null, ruleIndex, actionIndex);
}
// seek to after last char in token
input.Seek(index);
this.line = line;
this.charPositionInLine = charPos;
if (input.La(1) != IIntStream.Eof)
{
Consume(input);
}
}
[Nullable]
public virtual ATNState GetReachableTarget(Transition trans, int t)
{
if (trans.Matches(t, Lexer.MinCharValue, Lexer.MaxCharValue))
{
return trans.target;
}
return null;
}
[NotNull]
protected internal virtual ATNConfigSet ComputeStartState(ICharStream input, ATNState
p)
{
PredictionContext initialContext = PredictionContext.EmptyFull;
ATNConfigSet configs = new OrderedATNConfigSet();
for (int i = 0; i < p.GetNumberOfTransitions(); i++)
{
ATNState target = p.Transition(i).target;
ATNConfig c = ATNConfig.Create(target, i + 1, initialContext);
Closure(input, c, configs, false);
}
return configs;
}
/// <summary>
/// Since the alternatives within any lexer decision are ordered by
/// preference, this method stops pursuing the closure as soon as an accept
/// state is reached.
/// </summary>
/// <remarks>
/// Since the alternatives within any lexer decision are ordered by
/// preference, this method stops pursuing the closure as soon as an accept
/// state is reached. After the first accept state is reached by depth-first
/// search from
/// <code>config</code>
/// , all other (potentially reachable) states for
/// this rule would have a lower priority.
/// </remarks>
/// <returns>
///
/// <code>true</code>
/// if an accept state is reached, otherwise
/// <code>false</code>
/// .
/// </returns>
protected internal virtual bool Closure(ICharStream input, ATNConfig config, ATNConfigSet
configs, bool speculative)
{
if (config.GetState() is RuleStopState)
{
PredictionContext context = config.GetContext();
if (context.IsEmpty)
{
configs.AddItem(config);
return true;
}
else
{
if (context.HasEmpty)
{
configs.AddItem(config.Transform(config.GetState(), PredictionContext.EmptyFull));
return true;
}
}
for (int i = 0; i < context.Size; i++)
{
int returnStateNumber = context.GetReturnState(i);
if (returnStateNumber == PredictionContext.EmptyFullStateKey)
{
continue;
}
PredictionContext newContext = context.GetParent(i);
// "pop" return state
ATNState returnState = atn.states[returnStateNumber];
ATNConfig c = ATNConfig.Create(returnState, config.GetAlt(), newContext);
if (Closure(input, c, configs, speculative))
{
return true;
}
}
return false;
}
// optimization
if (!config.GetState().OnlyHasEpsilonTransitions())
{
configs.AddItem(config);
}
ATNState p = config.GetState();
for (int i_1 = 0; i_1 < p.GetNumberOfOptimizedTransitions(); i_1++)
{
Transition t = p.GetOptimizedTransition(i_1);
ATNConfig c = GetEpsilonTarget(input, config, t, configs, speculative);
if (c != null)
{
if (Closure(input, c, configs, speculative))
{
return true;
}
}
}
return false;
}
// side-effect: can alter configs.hasSemanticContext
[Nullable]
public virtual ATNConfig GetEpsilonTarget(ICharStream input, ATNConfig config, Transition
t, ATNConfigSet configs, bool speculative)
{
ATNConfig c;
switch (t.SerializationType)
{
case Transition.Rule:
{
RuleTransition ruleTransition = (RuleTransition)t;
if (optimize_tail_calls && ruleTransition.optimizedTailCall && !config.GetContext
().HasEmpty)
{
c = config.Transform(t.target);
}
else
{
PredictionContext newContext = config.GetContext().GetChild(ruleTransition.followState
.stateNumber);
c = config.Transform(t.target, newContext);
}
break;
}
case Transition.Precedence:
{
throw new NotSupportedException("Precedence predicates are not supported in lexers."
);
}
case Transition.Predicate:
{
PredicateTransition pt = (PredicateTransition)t;
configs.MarkExplicitSemanticContext();
if (EvaluatePredicate(input, pt.ruleIndex, pt.predIndex, speculative))
{
c = config.Transform(t.target);
}
else
{
c = null;
}
break;
}
case Transition.Action:
{
// ignore actions; just exec one per rule upon accept
c = config.Transform(t.target, ((ActionTransition)t).actionIndex);
break;
}
case Transition.Epsilon:
{
c = config.Transform(t.target);
break;
}
default:
{
c = null;
break;
break;
}
}
return c;
}
/// <summary>Evaluate a predicate specified in the lexer.</summary>
/// <remarks>
/// Evaluate a predicate specified in the lexer.
/// <p/>
/// If
/// <code>speculative</code>
/// is
/// <code>true</code>
/// , this method was called before
/// <see cref="Consume(Antlr4.Runtime.ICharStream)">Consume(Antlr4.Runtime.ICharStream)
/// </see>
/// for the matched character. This method should call
/// <see cref="Consume(Antlr4.Runtime.ICharStream)">Consume(Antlr4.Runtime.ICharStream)
/// </see>
/// before evaluating the predicate to ensure position
/// sensitive values, including
/// <see cref="Antlr4.Runtime.Lexer.GetText()">Antlr4.Runtime.Lexer.GetText()</see>
/// ,
/// <see cref="Antlr4.Runtime.Lexer.Line()">Antlr4.Runtime.Lexer.Line()</see>
/// ,
/// and
/// <see cref="Antlr4.Runtime.Lexer.Column()">Antlr4.Runtime.Lexer.Column()</see>
/// , properly reflect the current
/// lexer state. This method should restore
/// <code>input</code>
/// and the simulator
/// to the original state before returning (i.e. undo the actions made by the
/// call to
/// <see cref="Consume(Antlr4.Runtime.ICharStream)">Consume(Antlr4.Runtime.ICharStream)
/// </see>
/// .
/// </remarks>
/// <param name="input">The input stream.</param>
/// <param name="ruleIndex">The rule containing the predicate.</param>
/// <param name="predIndex">The index of the predicate within the rule.</param>
/// <param name="speculative">
///
/// <code>true</code>
/// if the current index in
/// <code>input</code>
/// is
/// one character before the predicate's location.
/// </param>
/// <returns>
///
/// <code>true</code>
/// if the specified predicate evaluates to
/// <code>true</code>
/// .
/// </returns>
protected internal virtual bool EvaluatePredicate(ICharStream input, int ruleIndex
, int predIndex, bool speculative)
{
// assume true if no recognizer was provided
if (recog == null)
{
return true;
}
if (!speculative)
{
return recog.Sempred(null, ruleIndex, predIndex);
}
int savedCharPositionInLine = charPositionInLine;
int savedLine = line;
int index = input.Index;
int marker = input.Mark();
try
{
Consume(input);
return recog.Sempred(null, ruleIndex, predIndex);
}
finally
{
charPositionInLine = savedCharPositionInLine;
line = savedLine;
input.Seek(index);
input.Release(marker);
}
}
protected internal virtual void CaptureSimState(LexerATNSimulator.SimState settings
, ICharStream input, DFAState dfaState)
{
settings.index = input.Index;
settings.line = line;
settings.charPos = charPositionInLine;
settings.dfaState = dfaState;
}
[NotNull]
protected internal virtual DFAState AddDFAEdge(DFAState from, int t, ATNConfigSet
q)
{
bool suppressEdge = q.HasSemanticContext();
if (suppressEdge)
{
q.ClearExplicitSemanticContext();
}
DFAState to = AddDFAState(q);
if (suppressEdge)
{
return to;
}
AddDFAEdge(from, t, to);
return to;
}
protected internal virtual void AddDFAEdge(DFAState p, int t, DFAState q)
{
if (p != null)
{
p.SetTarget(t, q);
}
}
/// <summary>
/// Add a new DFA state if there isn't one with this set of
/// configurations already.
/// </summary>
/// <remarks>
/// Add a new DFA state if there isn't one with this set of
/// configurations already. This method also detects the first
/// configuration containing an ATN rule stop state. Later, when
/// traversing the DFA, we will know which rule to accept.
/// </remarks>
[NotNull]
protected internal virtual DFAState AddDFAState(ATNConfigSet configs)
{
System.Diagnostics.Debug.Assert(!configs.HasSemanticContext());
DFAState proposed = new DFAState(configs, 0, MaxDfaEdge);
DFAState existing = atn.modeToDFA[mode].states.Get(proposed);
if (existing != null)
{
return existing;
}
configs.OptimizeConfigs(this);
DFAState newState = new DFAState(configs.Clone(true), 0, MaxDfaEdge);
ATNConfig firstConfigWithRuleStopState = null;
foreach (ATNConfig c in configs)
{
if (c.GetState() is RuleStopState)
{
firstConfigWithRuleStopState = c;
break;
}
}
if (firstConfigWithRuleStopState != null)
{
newState.isAcceptState = true;
newState.lexerRuleIndex = firstConfigWithRuleStopState.GetState().ruleIndex;
newState.lexerActionIndex = firstConfigWithRuleStopState.GetActionIndex();
newState.prediction = atn.ruleToTokenType[newState.lexerRuleIndex];
}
return atn.modeToDFA[mode].AddState(newState);
}
[NotNull]
public DFA GetDFA(int mode)
{
return atn.modeToDFA[mode];
}
/// <summary>Get the text matched so far for the current token.</summary>
/// <remarks>Get the text matched so far for the current token.</remarks>
[NotNull]
public virtual string GetText(ICharStream input)
{
// index is first lookahead char, don't include.
return input.GetText(Interval.Of(startIndex, input.Index - 1));
}
public virtual int GetLine()
{
return line;
}
public virtual void SetLine(int line)
{
this.line = line;
}
public virtual int GetCharPositionInLine()
{
return charPositionInLine;
}
public virtual void SetCharPositionInLine(int charPositionInLine)
{
this.charPositionInLine = charPositionInLine;
}
public virtual void Consume(ICharStream input)
{
int curChar = input.La(1);
if (curChar == '\n')
{
line++;
charPositionInLine = 0;
}
else
{
charPositionInLine++;
}
input.Consume();
}
[NotNull]
public virtual string GetTokenName(int t)
{
if (t == -1)
{
return "EOF";
}
//if ( atn.g!=null ) return atn.g.getTokenDisplayName(t);
return "'" + (char)t + "'";
}
}
}

View File

@ -0,0 +1,46 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>Mark the end of a * or + loop.</summary>
/// <remarks>Mark the end of a * or + loop.</remarks>
public sealed class LoopEndState : ATNState
{
public ATNState loopBackState;
public override int GetStateType()
{
return LoopEnd;
}
}
}

View File

@ -0,0 +1,61 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class NotSetTransition : SetTransition
{
public NotSetTransition(ATNState target, IntervalSet set) : base(target, set)
{
}
public override int SerializationType
{
get
{
return NotSet;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return symbol >= minVocabSymbol && symbol <= maxVocabSymbol && !base.Matches(symbol
, minVocabSymbol, maxVocabSymbol);
}
public override string ToString()
{
return '~' + base.ToString();
}
}
}

View File

@ -0,0 +1,69 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public class OrderedATNConfigSet : ATNConfigSet
{
public OrderedATNConfigSet()
{
}
protected internal OrderedATNConfigSet(ATNConfigSet set, bool @readonly) : base(set
, @readonly)
{
}
public override ATNConfigSet Clone(bool @readonly)
{
Antlr4.Runtime.Atn.OrderedATNConfigSet copy = new Antlr4.Runtime.Atn.OrderedATNConfigSet
(this, @readonly);
if (!@readonly && this.IsReadOnly())
{
Sharpen.Collections.AddAll(copy, this);
}
return copy;
}
protected internal override long GetKey(ATNConfig e)
{
return e.GetHashCode();
}
protected internal override bool CanMerge(ATNConfig left, long leftKey, ATNConfig
right)
{
return left.Equals(right);
}
}
}

View File

@ -0,0 +1,177 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public class ParserATNPathFinder
{
// public ParserATNPathFinder(@Nullable Parser<Token> parser, @NotNull ATN atn) {
// super(parser, atn);
// }
//
// /** Given an input sequence, as a subset of the input stream, trace the path through the
// * ATN starting at s. The path returned includes s and the final target of the last input
// * symbol. If there are multiple paths through the ATN to the final state, it uses the first
// * method finds. This is used to figure out how input sequence is matched in more than one
// * way between the alternatives of a decision. It's only that decision we are concerned with
// * and so if there are ambiguous decisions further along, we will ignore them for the
// * purposes of computing the path to the final state. To figure out multiple paths for
// * decision, use this method on the left edge of the alternatives of the decision in question.
// *
// * TODO: I haven't figured out what to do with nongreedy decisions yet
// * TODO: preds. unless i create rule specific ctxs, i can't eval preds. also must eval args!
// */
// public TraceTree trace(@NotNull ATNState s, @Nullable RuleContext<Token> ctx,
// TokenStream<? extends Token> input, int start, int stop)
// {
// System.out.println("REACHES "+s.stateNumber+" start state");
// List<TraceTree> leaves = new ArrayList<TraceTree>();
// @SuppressWarnings("unchecked") // safe
// HashSet<ATNState>[] busy = (HashSet<ATNState>[])new HashSet<?>[stop-start+1];
// for (int i = 0; i < busy.length; i++) {
// busy[i] = new HashSet<ATNState>();
// }
// TraceTree path = _trace(s, ctx, ctx, input, start, start, stop, leaves, busy);
// if ( path!=null ) path.leaves = leaves;
// return path;
// }
//
// /** Returns true if we found path */
// public TraceTree _trace(@NotNull ATNState s, RuleContext<Token> initialContext, RuleContext<Token> ctx,
// TokenStream<? extends Token> input, int start, int i, int stop,
// List<TraceTree> leaves, @NotNull Set<ATNState>[] busy)
// {
// TraceTree root = new TraceTree(s);
// if ( i>stop ) {
// leaves.add(root); // track final states
// System.out.println("leaves=" + leaves);
// return root;
// }
//
// if ( !busy[i-start].add(s) ) {
// System.out.println("already visited "+s.stateNumber+" at input "+i+"="+input.get(i).getText());
// return null;
// }
// busy[i-start].add(s);
//
// System.out.println("TRACE "+s.stateNumber+" at input "+input.get(i).getText());
//
// if ( s instanceof RuleStopState) {
// // We hit rule end. If we have context info, use it
// if ( ctx!=null && !ctx.isEmpty() ) {
// System.out.println("stop state "+s.stateNumber+", ctx="+ctx);
// ATNState invokingState = atn.states.get(ctx.invokingState);
// RuleTransition rt = (RuleTransition)invokingState.transition(0);
// ATNState retState = rt.followState;
// return _trace(retState, initialContext, ctx.parent, input, start, i, stop, leaves, busy);
// }
// else {
// // else if we have no context info, just chase follow links (if greedy)
// System.out.println("FALLING off rule "+getRuleName(s.ruleIndex));
// }
// }
//
// int n = s.getNumberOfTransitions();
// boolean aGoodPath = false;
// TraceTree found;
// for (int j=0; j<n; j++) {
// Transition t = s.transition(j);
// if ( t.getClass() == RuleTransition.class ) {
// RuleContext<Token> newContext = RuleContext.getChildContext(ctx, s.stateNumber);
// found = _trace(t.target, initialContext, newContext, input, start, i, stop, leaves, busy);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// continue;
// }
// if ( t instanceof PredicateTransition ) {
// found = predTransition(initialContext, ctx, input, start, i, stop, leaves, busy, root, t);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// continue;
// }
// if ( t.isEpsilon() ) {
// found = _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// continue;
// }
// if ( t.getClass() == WildcardTransition.class ) {
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// continue;
// }
// IntervalSet set = t.label();
// if ( set!=null ) {
// if ( t instanceof NotSetTransition ) {
// if ( !set.contains(input.get(i).getType()) ) {
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// }
// }
// else {
// if ( set.contains(input.get(i).getType()) ) {
// System.out.println("REACHES " + t.target.stateNumber + " matching input " + input.get(i).getText());
// found = _trace(t.target, initialContext, ctx, input, start, i+1, stop, leaves, busy);
// if ( found!=null ) {aGoodPath=true; root.addChild(found);}
// }
// }
// }
// }
// if ( aGoodPath ) return root; // found at least one transition leading to success
// return null;
// }
//
// public TraceTree predTransition(RuleContext<Token> initialContext, RuleContext<Token> ctx, TokenStream<? extends Token> input, int start,
// int i, int stop, List<TraceTree> leaves, Set<ATNState>[] busy,
// TraceTree root, Transition t)
// {
// SemanticContext.Predicate pred = ((PredicateTransition) t).getPredicate();
// boolean pass;
// if ( pred.isCtxDependent ) {
// if ( ctx instanceof ParserRuleContext && ctx==initialContext ) {
// System.out.println("eval pred "+pred+"="+pred.eval(parser, ctx));
// pass = pred.eval(parser, ctx);
// }
// else {
// pass = true; // see thru ctx dependent when out of context
// }
// }
// else {
// System.out.println("eval pred "+pred+"="+pred.eval(parser, initialContext));
// pass = pred.eval(parser, ctx);
// }
// if ( pass ) {
// return _trace(t.target, initialContext, ctx, input, start, i, stop, leaves, busy);
// }
// return null;
// }
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Start of
/// <code>(A|B|...)+</code>
/// loop. Technically a decision state, but
/// we don't use for code generation; somebody might need it, so I'm defining
/// it for completeness. In reality, the
/// <see cref="PlusLoopbackState">PlusLoopbackState</see>
/// node is the
/// real decision-making note for
/// <code>A+</code>
/// .
/// </summary>
public sealed class PlusBlockStartState : BlockStartState
{
public PlusLoopbackState loopBackState;
public override int GetStateType()
{
return PlusBlockStart;
}
}
}

View File

@ -0,0 +1,50 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Decision state for
/// <code>A+</code>
/// and
/// <code>(A|B)+</code>
/// . It has two transitions:
/// one to the loop back to start of the block and one to exit.
/// </summary>
public sealed class PlusLoopbackState : DecisionState
{
public override int GetStateType()
{
return PlusLoopBack;
}
}
}

View File

@ -0,0 +1,77 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public sealed class PrecedencePredicateTransition : AbstractPredicateTransition
{
public readonly int precedence;
public PrecedencePredicateTransition(ATNState target, int precedence) : base(target
)
{
this.precedence = precedence;
}
public override int SerializationType
{
get
{
return Precedence;
}
}
public override bool IsEpsilon
{
get
{
return true;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return false;
}
public SemanticContext.PrecedencePredicate GetPredicate()
{
return new SemanticContext.PrecedencePredicate(precedence);
}
public override string ToString()
{
return precedence + " >= _p";
}
}
}

View File

@ -0,0 +1,96 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// TODO: this is old comment:
/// A tree of semantic predicates from the grammar AST if label==SEMPRED.
/// </summary>
/// <remarks>
/// TODO: this is old comment:
/// A tree of semantic predicates from the grammar AST if label==SEMPRED.
/// In the ATN, labels will always be exactly one predicate, but the DFA
/// may have to combine a bunch of them as it collects predicates from
/// multiple ATN configurations into a single DFA state.
/// </remarks>
public sealed class PredicateTransition : AbstractPredicateTransition
{
public readonly int ruleIndex;
public readonly int predIndex;
public readonly bool isCtxDependent;
public PredicateTransition(ATNState target, int ruleIndex, int predIndex, bool isCtxDependent
) : base(target)
{
// e.g., $i ref in pred
this.ruleIndex = ruleIndex;
this.predIndex = predIndex;
this.isCtxDependent = isCtxDependent;
}
public override int SerializationType
{
get
{
return Predicate;
}
}
public override bool IsEpsilon
{
get
{
return true;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return false;
}
public SemanticContext.Predicate GetPredicate()
{
return new SemanticContext.Predicate(ruleIndex, predIndex, isCtxDependent);
}
[NotNull]
public override string ToString()
{
return "pred_" + ruleIndex + ":" + predIndex;
}
}
}

View File

@ -0,0 +1,551 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public abstract class PredictionContext
{
[NotNull]
public static readonly Antlr4.Runtime.Atn.PredictionContext EmptyLocal = EmptyPredictionContext
.LocalContext;
[NotNull]
public static readonly Antlr4.Runtime.Atn.PredictionContext EmptyFull = EmptyPredictionContext
.FullContext;
public const int EmptyLocalStateKey = int.MinValue;
public const int EmptyFullStateKey = int.MaxValue;
private const int InitialHash = 1;
private const int HashMultiplier = 31;
/// <summary>Stores the computed hash code of this PredictionContext.</summary>
/// <remarks>
/// Stores the computed hash code of this PredictionContext. The hash code is
/// computed in parts to match the following reference algorithm.
/// <pre>
/// private int referenceHashCode() {
/// int returnStateHashCode =
/// <see cref="InitialHash">INITIAL_HASH</see>
/// ;
/// for (int i = 0; i &lt; size(); i++) {
/// returnStateHashCode = returnStateHashCode *
/// <see cref="HashMultiplier">HASH_MULTIPLIER</see>
/// ^ getReturnState(i);
/// }
/// int parentHashCode = INITIAL_HASH;
/// for (int i = 0; i &lt; size(); i++) {
/// parentHashCode = parentHashCode * HASH_MULTIPLIER ^ getParent(i).hashCode();
/// }
/// int hashCode = INITIAL_HASH;
/// hashCode = hashCode * HASH_MULTIPLIER ^ parentHashCode;
/// hashCode = hashCode * HASH_MULTIPLIER ^ returnStateHashCode;
/// return hashCode;
/// }
/// </pre>
/// </remarks>
private readonly int cachedHashCode;
protected internal PredictionContext(int cachedHashCode)
{
this.cachedHashCode = cachedHashCode;
}
protected internal static int CalculateEmptyParentHashCode()
{
return InitialHash;
}
protected internal static int CalculateParentHashCode(Antlr4.Runtime.Atn.PredictionContext
parent)
{
return InitialHash * HashMultiplier ^ parent.GetHashCode();
}
protected internal static int CalculateParentHashCode(Antlr4.Runtime.Atn.PredictionContext
[] parents)
{
int hashCode = InitialHash;
foreach (Antlr4.Runtime.Atn.PredictionContext context in parents)
{
hashCode = hashCode * HashMultiplier ^ context.GetHashCode();
}
return hashCode;
}
protected internal static int CalculateEmptyReturnStateHashCode()
{
return InitialHash;
}
protected internal static int CalculateReturnStateHashCode(int returnState)
{
return InitialHash * HashMultiplier ^ returnState;
}
protected internal static int CalculateReturnStatesHashCode(int[] returnStates)
{
int hashCode = InitialHash;
foreach (int state in returnStates)
{
hashCode = hashCode * HashMultiplier ^ state;
}
return hashCode;
}
protected internal static int CalculateHashCode(int parentHashCode, int returnStateHashCode
)
{
return (InitialHash * HashMultiplier ^ parentHashCode) * HashMultiplier ^ returnStateHashCode;
}
public abstract int Size
{
get;
}
public abstract int GetReturnState(int index);
public abstract int FindReturnState(int returnState);
[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)
{
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;
}
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, IConcurrentMap<Antlr4.Runtime.Atn.PredictionContext, Antlr4.Runtime.Atn.PredictionContext
> contextCache, PredictionContext.IdentityHashMap visited)
{
if (context.IsEmpty)
{
return context;
}
Antlr4.Runtime.Atn.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;
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.PutIfAbsent(context, context);
visited.Put(context, existing != null ? existing : context);
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.PutIfAbsent(updated, updated);
visited.Put(updated, existing != null ? existing : updated);
visited.Put(context, existing != null ? existing : updated);
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
{
get;
}
public abstract bool HasEmpty
{
get;
}
public sealed override int GetHashCode()
{
return cachedHashCode;
}
public abstract override bool Equals(object o);
//@Override
//public String toString() {
// return toString(null, Integer.MAX_VALUE);
//}
public virtual string[] ToStrings<_T0>(Recognizer<_T0> recognizer, int currentState
)
{
return ToStrings(recognizer, Antlr4.Runtime.Atn.PredictionContext.EmptyFull, currentState
);
}
public virtual string[] ToStrings<_T0>(Recognizer<_T0> recognizer, Antlr4.Runtime.Atn.PredictionContext
stop, int currentState)
{
IList<string> result = new List<string>();
for (int perm = 0; ; perm++)
{
int offset = 0;
bool last = true;
Antlr4.Runtime.Atn.PredictionContext p = this;
int stateNumber = currentState;
StringBuilder localBuffer = new StringBuilder();
localBuffer.Append("[");
while (!p.IsEmpty && p != stop)
{
int index = 0;
if (p.Size > 0)
{
int bits = 1;
while ((1 << bits) < p.Size)
{
bits++;
}
int mask = (1 << bits) - 1;
index = (perm >> offset) & mask;
last &= index >= p.Size - 1;
if (index >= p.Size)
{
goto outer_continue;
}
offset += bits;
}
if (recognizer != null)
{
if (localBuffer.Length > 1)
{
// first char is '[', if more than that this isn't the first rule
localBuffer.Append(' ');
}
ATN atn = recognizer.GetATN();
ATNState s = atn.states[stateNumber];
string ruleName = recognizer.GetRuleNames()[s.ruleIndex];
localBuffer.Append(ruleName);
}
else
{
if (p.GetReturnState(index) != EmptyFullStateKey)
{
if (!p.IsEmpty)
{
if (localBuffer.Length > 1)
{
// first char is '[', if more than that this isn't the first rule
localBuffer.Append(' ');
}
localBuffer.Append(p.GetReturnState(index));
}
}
}
stateNumber = p.GetReturnState(index);
p = p.GetParent(index);
}
localBuffer.Append("]");
result.AddItem(localBuffer.ToString());
if (last)
{
break;
}
outer_continue: ;
}
outer_break: ;
return Sharpen.Collections.ToArray(result, new string[result.Count]);
}
public sealed class IdentityHashMap : FlexibleHashMap<PredictionContext, PredictionContext
>
{
public IdentityHashMap() : base(PredictionContext.IdentityEqualityComparator.Instance
)
{
}
}
public sealed class IdentityEqualityComparator : AbstractEqualityComparator<PredictionContext
>
{
public static readonly PredictionContext.IdentityEqualityComparator Instance = new
PredictionContext.IdentityEqualityComparator();
public IdentityEqualityComparator()
{
}
public override int HashCode(PredictionContext obj)
{
return obj.GetHashCode();
}
public override bool Equals(PredictionContext a, PredictionContext b)
{
return a == b;
}
}
}
}

View File

@ -0,0 +1,218 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>
/// Used to cache
/// <see cref="PredictionContext">PredictionContext</see>
/// 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);
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)
{
}
private PredictionContextCache(bool enableCache)
{
this.enableCache = enableCache;
}
public virtual PredictionContext GetAsCached(PredictionContext context)
{
if (!enableCache)
{
return context;
}
PredictionContext result = contexts.Get(context);
if (result == null)
{
result = context;
contexts.Put(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 = childContexts.Get(operands);
if (result == null)
{
result = context.GetChild(invokingState);
result = GetAsCached(result);
childContexts.Put(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 = joinContexts.Get(operands);
if (result != null)
{
return result;
}
result = PredictionContext.Join(x, y, this);
result = GetAsCached(result);
joinContexts.Put(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
{
get
{
return x;
}
}
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

@ -0,0 +1,75 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class RangeTransition : Transition
{
public readonly int from;
public readonly int to;
public RangeTransition(ATNState target, int from, int to) : base(target)
{
this.from = from;
this.to = to;
}
public override int SerializationType
{
get
{
return Range;
}
}
public override IntervalSet Label
{
get
{
return IntervalSet.Of(from, to);
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return symbol >= from && symbol <= to;
}
[NotNull]
public override string ToString()
{
return "'" + (char)from + "'..'" + (char)to + "'";
}
}
}

View File

@ -0,0 +1,48 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class RuleStartState : ATNState
{
public RuleStopState stopState;
public bool isPrecedenceRule;
public bool leftFactored;
public override int GetStateType()
{
return RuleStart;
}
}
}

View File

@ -0,0 +1,55 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>The last node in the ATN for a rule, unless that rule is the start symbol.
/// </summary>
/// <remarks>
/// The last node in the ATN for a rule, unless that rule is the start symbol.
/// In that case, there is one transition to EOF. Later, we might encode
/// references to all calls to this rule to compute FOLLOW sets for
/// error handling.
/// </remarks>
public sealed class RuleStopState : ATNState
{
public override int GetNonStopStateNumber()
{
return -1;
}
public override int GetStateType()
{
return RuleStop;
}
}
}

View File

@ -0,0 +1,81 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class RuleTransition : Transition
{
/// <summary>Ptr to the rule definition object for this rule ref</summary>
public readonly int ruleIndex;
public readonly int precedence;
/// <summary>What node to begin computations following ref to rule</summary>
[NotNull]
public ATNState followState;
public bool tailCall;
public bool optimizedTailCall;
public RuleTransition(RuleStartState ruleStart, int ruleIndex, int precedence, ATNState
followState) : base(ruleStart)
{
// no Rule object at runtime
this.ruleIndex = ruleIndex;
this.precedence = precedence;
this.followState = followState;
}
public override int SerializationType
{
get
{
return Rule;
}
}
public override bool IsEpsilon
{
get
{
return true;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return false;
}
}
}

View File

@ -0,0 +1,418 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using 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
/// <code>p1&&p2</code>
/// , or a sum of products
/// <code>p1||p2</code>
/// .
/// <p/>
/// I have scoped the
/// <see cref="AND">AND</see>
/// ,
/// <see cref="OR">OR</see>
/// , and
/// <see cref="Predicate">Predicate</see>
/// subclasses of
/// <see cref="SemanticContext">SemanticContext</see>
/// within the scope of this outer class.
/// </remarks>
public abstract class SemanticContext
{
public static readonly SemanticContext None = new SemanticContext.Predicate();
public SemanticContext parent;
/// <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.
/// </remarks>
public abstract bool Eval<_T0>(Recognizer<_T0> parser, RuleContext outerContext);
public class Predicate : SemanticContext
{
public readonly int ruleIndex;
public readonly int predIndex;
public readonly bool isCtxDependent;
public Predicate()
{
// e.g., $i ref in pred
this.ruleIndex = -1;
this.predIndex = -1;
this.isCtxDependent = false;
}
public Predicate(int ruleIndex, int predIndex, bool isCtxDependent)
{
this.ruleIndex = ruleIndex;
this.predIndex = predIndex;
this.isCtxDependent = isCtxDependent;
}
public override bool Eval<_T0>(Recognizer<_T0> parser, RuleContext outerContext)
{
RuleContext localctx = isCtxDependent ? outerContext : null;
return parser.Sempred(localctx, ruleIndex, predIndex);
}
public override int GetHashCode()
{
int hashCode = 1;
hashCode = 31 * hashCode + ruleIndex;
hashCode = 31 * hashCode + predIndex;
hashCode = 31 * hashCode + (isCtxDependent ? 1 : 0);
return hashCode;
}
public override bool Equals(object obj)
{
if (!(obj is SemanticContext.Predicate))
{
return false;
}
if (this == obj)
{
return true;
}
SemanticContext.Predicate p = (SemanticContext.Predicate)obj;
return this.ruleIndex == p.ruleIndex && this.predIndex == p.predIndex && this.isCtxDependent
== p.isCtxDependent;
}
public override string ToString()
{
return "{" + ruleIndex + ":" + predIndex + "}?";
}
}
public class PrecedencePredicate : SemanticContext, IComparable<SemanticContext.PrecedencePredicate
>
{
public readonly int precedence;
public PrecedencePredicate()
{
this.precedence = 0;
}
public PrecedencePredicate(int precedence)
{
this.precedence = precedence;
}
public override bool Eval<_T0>(Recognizer<_T0> parser, RuleContext outerContext)
{
return parser.Precpred(outerContext, precedence);
}
public virtual int CompareTo(SemanticContext.PrecedencePredicate o)
{
return precedence - o.precedence;
}
public override int GetHashCode()
{
int hashCode = 1;
hashCode = 31 * hashCode + precedence;
return hashCode;
}
public override bool Equals(object obj)
{
if (!(obj is SemanticContext.PrecedencePredicate))
{
return false;
}
if (this == obj)
{
return true;
}
SemanticContext.PrecedencePredicate other = (SemanticContext.PrecedencePredicate)
obj;
return this.precedence == other.precedence;
}
public override string ToString()
{
return base.ToString();
}
}
public class AND : SemanticContext
{
[NotNull]
public readonly SemanticContext[] opnds;
public AND(SemanticContext a, SemanticContext b)
{
ICollection<SemanticContext> operands = new HashSet<SemanticContext>();
if (a is SemanticContext.AND)
{
Sharpen.Collections.AddAll(operands, Arrays.AsList(((SemanticContext.AND)a).opnds
));
}
else
{
operands.AddItem(a);
}
if (b is SemanticContext.AND)
{
Sharpen.Collections.AddAll(operands, Arrays.AsList(((SemanticContext.AND)b).opnds
));
}
else
{
operands.AddItem(b);
}
IList<SemanticContext.PrecedencePredicate> precedencePredicates = FilterPrecedencePredicates
(operands);
if (!precedencePredicates.IsEmpty())
{
// interested in the transition with the lowest precedence
SemanticContext.PrecedencePredicate reduced = Sharpen.Collections.Min(precedencePredicates
);
operands.AddItem(reduced);
}
opnds = Sharpen.Collections.ToArray(operands, new SemanticContext[operands.Count]
);
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (!(obj is SemanticContext.AND))
{
return false;
}
SemanticContext.AND other = (SemanticContext.AND)obj;
return Arrays.Equals(this.opnds, other.opnds);
}
public override int GetHashCode()
{
return Arrays.HashCode(opnds);
}
public override bool Eval<_T0>(Recognizer<_T0> parser, RuleContext outerContext)
{
foreach (SemanticContext opnd in opnds)
{
if (!opnd.Eval(parser, outerContext))
{
return false;
}
}
return true;
}
public override string ToString()
{
return Utils.Join(opnds, "&&");
}
}
public class OR : SemanticContext
{
[NotNull]
public readonly SemanticContext[] opnds;
public OR(SemanticContext a, SemanticContext b)
{
ICollection<SemanticContext> operands = new HashSet<SemanticContext>();
if (a is SemanticContext.OR)
{
Sharpen.Collections.AddAll(operands, Arrays.AsList(((SemanticContext.OR)a).opnds)
);
}
else
{
operands.AddItem(a);
}
if (b is SemanticContext.OR)
{
Sharpen.Collections.AddAll(operands, Arrays.AsList(((SemanticContext.OR)b).opnds)
);
}
else
{
operands.AddItem(b);
}
IList<SemanticContext.PrecedencePredicate> precedencePredicates = FilterPrecedencePredicates
(operands);
if (!precedencePredicates.IsEmpty())
{
// interested in the transition with the highest precedence
SemanticContext.PrecedencePredicate reduced = Sharpen.Collections.Max(precedencePredicates
);
operands.AddItem(reduced);
}
this.opnds = Sharpen.Collections.ToArray(operands, new SemanticContext[operands.Count
]);
}
public override bool Equals(object obj)
{
if (this == obj)
{
return true;
}
if (!(obj is SemanticContext.OR))
{
return false;
}
SemanticContext.OR other = (SemanticContext.OR)obj;
return Arrays.Equals(this.opnds, other.opnds);
}
public override int GetHashCode()
{
return Arrays.HashCode(opnds) + 1;
}
// differ from AND slightly
public override bool Eval<_T0>(Recognizer<_T0> parser, RuleContext outerContext)
{
foreach (SemanticContext opnd in opnds)
{
if (opnd.Eval(parser, outerContext))
{
return true;
}
}
return false;
}
public override string ToString()
{
return Utils.Join(opnds, "||");
}
}
public static SemanticContext And(SemanticContext a, SemanticContext b)
{
if (a == null || a == None)
{
return b;
}
if (b == null || b == None)
{
return a;
}
SemanticContext.AND result = new SemanticContext.AND(a, b);
if (result.opnds.Length == 1)
{
return result.opnds[0];
}
return result;
}
/// <seealso cref="ParserATNSimulator.GetPredsForAmbigAlts(Sharpen.BitSet, ATNConfigSet, int)
/// ">ParserATNSimulator.GetPredsForAmbigAlts(Sharpen.BitSet, ATNConfigSet, int)</seealso>
public static SemanticContext Or(SemanticContext a, SemanticContext b)
{
if (a == null)
{
return b;
}
if (b == null)
{
return a;
}
if (a == None || b == None)
{
return None;
}
SemanticContext.OR result = new SemanticContext.OR(a, b);
if (result.opnds.Length == 1)
{
return result.opnds[0];
}
return result;
}
private static IList<SemanticContext.PrecedencePredicate> FilterPrecedencePredicates
<_T0>(ICollection<_T0> collection) where _T0:SemanticContext
{
List<SemanticContext.PrecedencePredicate> result = null;
for (IEnumerator<SemanticContext> iterator = collection.GetEnumerator(); iterator
.HasNext(); )
{
SemanticContext context = iterator.Next();
if (context is SemanticContext.PrecedencePredicate)
{
if (result == null)
{
result = new List<SemanticContext.PrecedencePredicate>();
}
result.AddItem((SemanticContext.PrecedencePredicate)context);
iterator.Remove();
}
}
if (result == null)
{
return Sharpen.Collections.EmptyList();
}
return result;
}
}
}

View File

@ -0,0 +1,81 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>A transition containing a set of values.</summary>
/// <remarks>A transition containing a set of values.</remarks>
public class SetTransition : Transition
{
[NotNull]
public readonly IntervalSet set;
public SetTransition(ATNState target, IntervalSet set) : base(target)
{
// TODO (sam): should we really allow null here?
if (set == null)
{
set = IntervalSet.Of(IToken.InvalidType);
}
this.set = set;
}
public override int SerializationType
{
get
{
return Set;
}
}
public override IntervalSet Label
{
get
{
return set;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return set.Contains(symbol);
}
[NotNull]
public override string ToString()
{
return set.ToString();
}
}
}

View File

@ -0,0 +1,57 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <author>Sam Harwell</author>
public class SimulatorState
{
public readonly ParserRuleContext outerContext;
public readonly DFAState s0;
public readonly bool useContext;
public readonly ParserRuleContext remainingOuterContext;
public SimulatorState(ParserRuleContext outerContext, DFAState s0, bool useContext
, ParserRuleContext remainingOuterContext)
{
this.outerContext = outerContext != null ? outerContext : ParserRuleContext.EmptyContext
();
this.s0 = s0;
this.useContext = useContext;
this.remainingOuterContext = remainingOuterContext;
}
}
}

View File

@ -0,0 +1,135 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public class SingletonPredictionContext : PredictionContext
{
[NotNull]
public readonly PredictionContext parent;
public readonly int returnState;
internal SingletonPredictionContext(PredictionContext parent, int returnState) :
base(CalculateHashCode(CalculateParentHashCode(parent), CalculateReturnStateHashCode
(returnState)))
{
System.Diagnostics.Debug.Assert(returnState != EmptyFullStateKey && returnState !=
EmptyLocalStateKey);
this.parent = parent;
this.returnState = returnState;
}
public override PredictionContext GetParent(int index)
{
System.Diagnostics.Debug.Assert(index == 0);
return parent;
}
public override int GetReturnState(int index)
{
System.Diagnostics.Debug.Assert(index == 0);
return returnState;
}
public override int FindReturnState(int returnState)
{
return this.returnState == returnState ? 0 : -1;
}
public override int Size
{
get
{
return 1;
}
}
public override bool IsEmpty
{
get
{
return false;
}
}
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)
{
return true;
}
else
{
if (!(o is Antlr4.Runtime.Atn.SingletonPredictionContext))
{
return false;
}
}
Antlr4.Runtime.Atn.SingletonPredictionContext other = (Antlr4.Runtime.Atn.SingletonPredictionContext
)o;
if (this.GetHashCode() != other.GetHashCode())
{
return false;
}
return returnState == other.returnState && parent.Equals(other.parent);
}
}
}

View File

@ -0,0 +1,44 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>The block that begins a closure loop.</summary>
/// <remarks>The block that begins a closure loop.</remarks>
public sealed class StarBlockStartState : BlockStartState
{
public override int GetStateType()
{
return StarBlockStart;
}
}
}

View File

@ -0,0 +1,44 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class StarLoopEntryState : DecisionState
{
public StarLoopbackState loopBackState;
public override int GetStateType()
{
return StarLoopEntry;
}
}
}

View File

@ -0,0 +1,47 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class StarLoopbackState : ATNState
{
public StarLoopEntryState GetLoopEntryState()
{
return (StarLoopEntryState)Transition(0).target;
}
public override int GetStateType()
{
return StarLoopBack;
}
}
}

View File

@ -0,0 +1,43 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using 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 int GetStateType()
{
return TokenStart;
}
}
}

View File

@ -0,0 +1,142 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
/// <summary>An ATN transition between any two ATN states.</summary>
/// <remarks>
/// An ATN transition between any two ATN states. Subclasses define
/// atom, set, epsilon, action, predicate, rule transitions.
/// <p/>
/// This is a one way link. It emanates from a state (usually via a list of
/// transitions) and has a target state.
/// <p/>
/// Since we never have to change the ATN transitions once we construct it,
/// we can fix these transitions as specific classes. The DFA transitions
/// on the other hand need to update the labels as it adds transitions to
/// the states. We'll use the term Edge for the DFA to distinguish them from
/// ATN transitions.
/// </remarks>
public abstract class Transition
{
public const int Epsilon = 1;
public const int Range = 2;
public const int Rule = 3;
public const int Predicate = 4;
public const int Atom = 5;
public const int Action = 6;
public const int Set = 7;
public const int NotSet = 8;
public const int Wildcard = 9;
public const int Precedence = 10;
public static readonly IList<string> serializationNames = Sharpen.Collections.UnmodifiableList
(Arrays.AsList("INVALID", "EPSILON", "RANGE", "RULE", "PREDICATE", "ATOM", "ACTION"
, "SET", "NOT_SET", "WILDCARD", "PRECEDENCE"));
private sealed class _Dictionary_86 : Dictionary<Type, int>
{
public _Dictionary_86()
{
{
// constants for serialization
// e.g., {isType(input.LT(1))}?
// ~(A|B) or ~atom, wildcard, which convert to next 2
this.Put(typeof(EpsilonTransition), Antlr4.Runtime.Atn.Transition.Epsilon);
this.Put(typeof(RangeTransition), Antlr4.Runtime.Atn.Transition.Range);
this.Put(typeof(RuleTransition), Antlr4.Runtime.Atn.Transition.Rule);
this.Put(typeof(PredicateTransition), Antlr4.Runtime.Atn.Transition.Predicate);
this.Put(typeof(AtomTransition), Antlr4.Runtime.Atn.Transition.Atom);
this.Put(typeof(ActionTransition), Antlr4.Runtime.Atn.Transition.Action);
this.Put(typeof(SetTransition), Antlr4.Runtime.Atn.Transition.Set);
this.Put(typeof(NotSetTransition), Antlr4.Runtime.Atn.Transition.NotSet);
this.Put(typeof(WildcardTransition), Antlr4.Runtime.Atn.Transition.Wildcard);
this.Put(typeof(PrecedencePredicateTransition), Antlr4.Runtime.Atn.Transition.Precedence
);
}
}
}
public static readonly IDictionary<Type, int> serializationTypes = Sharpen.Collections
.UnmodifiableMap(new _Dictionary_86());
/// <summary>The target of this transition.</summary>
/// <remarks>The target of this transition.</remarks>
[NotNull]
public ATNState target;
protected internal Transition(ATNState target)
{
if (target == null)
{
throw new ArgumentNullException("target cannot be null.");
}
this.target = target;
}
public abstract int SerializationType
{
get;
}
/// <summary>Are we epsilon, action, sempred?</summary>
public virtual bool IsEpsilon
{
get
{
return false;
}
}
public virtual IntervalSet Label
{
get
{
return null;
}
}
public abstract bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol);
}
}

View File

@ -0,0 +1,61 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Atn
{
public sealed class WildcardTransition : Transition
{
protected internal WildcardTransition(ATNState target) : base(target)
{
}
public override int SerializationType
{
get
{
return Wildcard;
}
}
public override bool Matches(int symbol, int minVocabSymbol, int maxVocabSymbol)
{
return symbol >= minVocabSymbol && symbol <= maxVocabSymbol;
}
[NotNull]
public override string ToString()
{
return ".";
}
}
}

View File

@ -0,0 +1,93 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>Bail out of parser at first syntax error.</summary>
/// <remarks>
/// Bail out of parser at first syntax error. Do this to use it:
/// <p/>
/// <code>myparser.setErrorHandler(new BailErrorStrategy<Token>());</code>
/// </remarks>
public class BailErrorStrategy : DefaultErrorStrategy
{
/// <summary>
/// Instead of recovering from exception
/// <code>e</code>
/// , re-throw it wrapped
/// in a
/// <see cref="ParseCanceledException">ParseCanceledException</see>
/// so it is not caught by the
/// rule function catches. Use
/// <see cref="System.Exception.InnerException()">System.Exception.InnerException()</see>
/// to get the
/// original
/// <see cref="RecognitionException">RecognitionException</see>
/// .
/// </summary>
public override void Recover(Parser recognizer, RecognitionException e)
{
for (ParserRuleContext context = recognizer.GetContext(); context != null; context
= ((ParserRuleContext)context.Parent))
{
context.exception = e;
}
throw new ParseCanceledException(e);
}
/// <summary>
/// Make sure we don't attempt to recover inline; if the parser
/// successfully recovers, it won't throw an exception.
/// </summary>
/// <remarks>
/// Make sure we don't attempt to recover inline; if the parser
/// successfully recovers, it won't throw an exception.
/// </remarks>
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public override IToken RecoverInline(Parser recognizer)
{
InputMismatchException e = new InputMismatchException(recognizer);
for (ParserRuleContext context = recognizer.GetContext(); context != null; context
= ((ParserRuleContext)context.Parent))
{
context.exception = e;
}
throw new ParseCanceledException(e);
}
/// <summary>Make sure we don't attempt to recover from problems in subrules.</summary>
/// <remarks>Make sure we don't attempt to recover from problems in subrules.</remarks>
public override void Sync(Parser recognizer)
{
}
}
}

View File

@ -0,0 +1,61 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime
{
/// <author>Sam Harwell</author>
public class BaseErrorListener : IParserErrorListener
{
public virtual void SyntaxError<T>(Recognizer<T, object> recognizer, T offendingSymbol
, int line, int charPositionInLine, string msg, RecognitionException e) where
T:IToken
{
}
public virtual void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int
stopIndex, BitSet ambigAlts, ATNConfigSet configs)
{
}
public virtual void ReportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex
, int stopIndex, SimulatorState initialState)
{
}
public virtual void ReportContextSensitivity(Parser recognizer, DFA dfa, int startIndex
, int stopIndex, SimulatorState acceptState)
{
}
}
}

View File

@ -0,0 +1,673 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// Buffer all input tokens but do on-demand fetching of new tokens from
/// lexer.
/// </summary>
/// <remarks>
/// Buffer all input tokens but do on-demand fetching of new tokens from
/// lexer. Useful when the parser or lexer has to set context/mode info before
/// proper lexing of future tokens. The ST template parser needs this,
/// for example, because it has to constantly flip back and forth between
/// inside/output templates. E.g.,
/// <code></code>
/// &lt;names:
/// hi, <it>}&gt;} has to parse names
/// as part of an expression but
/// <code>"hi, <it>"</code>
/// as a nested template.
/// You can't use this stream if you pass whitespace or other off-channel
/// tokens to the parser. The stream can't ignore off-channel tokens.
/// (
/// <see cref="UnbufferedTokenStream">UnbufferedTokenStream</see>
/// is the same way.) Use
/// <see cref="CommonTokenStream">CommonTokenStream</see>
/// .
/// This is not a subclass of
/// <code>UnbufferedTokenStream</code>
/// because I don't want
/// to confuse small moving window of tokens it uses for the full buffer.
/// </remarks>
public class BufferedTokenStream : ITokenStream
{
[NotNull]
protected internal ITokenSource tokenSource;
/// <summary>
/// Record every single token pulled from the source so we can reproduce
/// chunks of it later.
/// </summary>
/// <remarks>
/// Record every single token pulled from the source so we can reproduce
/// chunks of it later. This list captures everything so we can access
/// complete input text.
/// </remarks>
protected internal IList<IToken> tokens = new List<IToken>(100);
/// <summary>
/// The index into the tokens list of the current token (next token
/// to consume).
/// </summary>
/// <remarks>
/// The index into the tokens list of the current token (next token
/// to consume).
/// <code>tokens[p]</code>
/// should be
/// <code>LT(1)</code>
/// .
/// <code>p==-1</code>
/// indicates need
/// to initialize with first token. The ctor doesn't get a token.
/// First call to
/// <code>LT(1)</code>
/// or whatever gets the first token and sets
/// <code>p=0;</code>
/// .
/// </remarks>
protected internal int p = -1;
/// <summary>
/// Set to
/// <code>true</code>
/// when the EOF token is fetched. Do not continue fetching
/// tokens after that point, or multiple EOF tokens could end up in the
/// <see cref="tokens">tokens</see>
/// array.
/// </summary>
/// <seealso cref="Fetch(int)">Fetch(int)</seealso>
protected internal bool fetchedEOF;
public BufferedTokenStream(ITokenSource tokenSource)
{
if (tokenSource == null)
{
throw new ArgumentNullException("tokenSource cannot be null");
}
this.tokenSource = tokenSource;
}
public virtual ITokenSource TokenSource
{
get
{
return tokenSource;
}
}
public virtual int Index
{
get
{
return p;
}
}
// public int range() { return range; }
public virtual int Mark()
{
return 0;
}
public virtual void Release(int marker)
{
}
// no resources to release
public virtual void Reset()
{
Seek(0);
}
public virtual void Seek(int index)
{
LazyInit();
p = AdjustSeekIndex(index);
}
public virtual int Size
{
get
{
return tokens.Count;
}
}
public virtual void Consume()
{
if (La(1) == Eof)
{
throw new InvalidOperationException("cannot consume EOF");
}
if (Sync(p + 1))
{
p = AdjustSeekIndex(p + 1);
}
}
/// <summary>
/// Make sure index
/// <code>i</code>
/// in tokens has a token.
/// </summary>
/// <returns>
///
/// <code>true</code>
/// if a token is located at index
/// <code>i</code>
/// , otherwise
/// <code>false</code>
/// .
/// </returns>
/// <seealso cref="Get(int)">Get(int)</seealso>
protected internal virtual bool Sync(int i)
{
System.Diagnostics.Debug.Assert(i >= 0);
int n = i - tokens.Count + 1;
// how many more elements we need?
//System.out.println("sync("+i+") needs "+n);
if (n > 0)
{
int fetched = Fetch(n);
return fetched >= n;
}
return true;
}
/// <summary>
/// Add
/// <code>n</code>
/// elements to buffer.
/// </summary>
/// <returns>The actual number of elements added to the buffer.</returns>
protected internal virtual int Fetch(int n)
{
if (fetchedEOF)
{
return 0;
}
for (int i = 0; i < n; i++)
{
IToken t = tokenSource.NextToken();
if (t is IWritableToken)
{
((IWritableToken)t).TokenIndex = tokens.Count;
}
tokens.AddItem(t);
if (t.Type == IToken.Eof)
{
fetchedEOF = true;
return i + 1;
}
}
return n;
}
public virtual IToken Get(int i)
{
if (i < 0 || i >= tokens.Count)
{
throw new ArgumentOutOfRangeException("token index " + i + " out of range 0.." +
(tokens.Count - 1));
}
return tokens[i];
}
/// <summary>Get all tokens from start..stop inclusively.</summary>
/// <remarks>Get all tokens from start..stop inclusively.</remarks>
public virtual IList<IToken> Get(int start, int stop)
{
if (start < 0 || stop < 0)
{
return null;
}
LazyInit();
IList<IToken> subset = new List<IToken>();
if (stop >= tokens.Count)
{
stop = tokens.Count - 1;
}
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == IToken.Eof)
{
break;
}
subset.AddItem(t);
}
return subset;
}
public virtual int La(int i)
{
return Lt(i).Type;
}
protected internal virtual IToken Lb(int k)
{
if ((p - k) < 0)
{
return null;
}
return tokens[p - k];
}
public virtual IToken Lt(int k)
{
LazyInit();
if (k == 0)
{
return null;
}
if (k < 0)
{
return Lb(-k);
}
int i = p + k - 1;
Sync(i);
if (i >= tokens.Count)
{
// return EOF token
// EOF must be last token
return tokens[tokens.Count - 1];
}
// if ( i>range ) range = i;
return tokens[i];
}
/// <summary>
/// Allowed derived classes to modify the behavior of operations which change
/// the current stream position by adjusting the target token index of a seek
/// operation.
/// </summary>
/// <remarks>
/// Allowed derived classes to modify the behavior of operations which change
/// the current stream position by adjusting the target token index of a seek
/// operation. The default implementation simply returns
/// <code>i</code>
/// . If an
/// exception is thrown in this method, the current stream index should not be
/// changed.
/// <p/>
/// For example,
/// <see cref="CommonTokenStream">CommonTokenStream</see>
/// overrides this method to ensure that
/// the seek target is always an on-channel token.
/// </remarks>
/// <param name="i">The target token index.</param>
/// <returns>The adjusted target token index.</returns>
protected internal virtual int AdjustSeekIndex(int i)
{
return i;
}
protected internal void LazyInit()
{
if (p == -1)
{
Setup();
}
}
protected internal virtual void Setup()
{
Sync(0);
p = AdjustSeekIndex(0);
}
/// <summary>Reset this token stream by setting its token source.</summary>
/// <remarks>Reset this token stream by setting its token source.</remarks>
public virtual void SetTokenSource(ITokenSource tokenSource)
{
this.tokenSource = tokenSource;
tokens.Clear();
p = -1;
}
public virtual IList<IToken> GetTokens()
{
return tokens;
}
public virtual IList<IToken> GetTokens(int start, int stop)
{
return GetTokens(start, stop, null);
}
/// <summary>
/// Given a start and stop index, return a
/// <code>List</code>
/// of all tokens in
/// the token type
/// <code>BitSet</code>
/// . Return
/// <code>null</code>
/// if no tokens were found. This
/// method looks at both on and off channel tokens.
/// </summary>
public virtual IList<IToken> GetTokens(int start, int stop, BitSet types)
{
LazyInit();
if (start < 0 || stop >= tokens.Count || stop < 0 || start >= tokens.Count)
{
throw new ArgumentOutOfRangeException("start " + start + " or stop " + stop + " not in 0.."
+ (tokens.Count - 1));
}
if (start > stop)
{
return null;
}
// list = tokens[start:stop]:{T t, t.getType() in types}
IList<IToken> filteredTokens = new List<IToken>();
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (types == null || types.Get(t.Type))
{
filteredTokens.AddItem(t);
}
}
if (filteredTokens.IsEmpty())
{
filteredTokens = null;
}
return filteredTokens;
}
public virtual IList<IToken> GetTokens(int start, int stop, int ttype)
{
BitSet s = new BitSet(ttype);
s.Set(ttype);
return GetTokens(start, stop, s);
}
/// <summary>Given a starting index, return the index of the next token on channel.</summary>
/// <remarks>
/// Given a starting index, return the index of the next token on channel.
/// Return
/// <code>i</code>
/// if
/// <code>tokens[i]</code>
/// is on channel. Return
/// <code>-1</code>
/// if there are no tokens
/// on channel between
/// <code>i</code>
/// and EOF.
/// </remarks>
protected internal virtual int NextTokenOnChannel(int i, int channel)
{
Sync(i);
IToken token = tokens[i];
if (i >= Size)
{
return -1;
}
while (token.Channel != channel)
{
if (token.Type == IToken.Eof)
{
return -1;
}
i++;
Sync(i);
token = tokens[i];
}
return i;
}
/// <summary>Given a starting index, return the index of the previous token on channel.
/// </summary>
/// <remarks>
/// Given a starting index, return the index of the previous token on channel.
/// Return
/// <code>i</code>
/// if
/// <code>tokens[i]</code>
/// is on channel. Return
/// <code>-1</code>
/// if there are no tokens
/// on channel between
/// <code>i</code>
/// and
/// <code>0</code>
/// .
/// </remarks>
protected internal virtual int PreviousTokenOnChannel(int i, int channel)
{
while (i >= 0 && tokens[i].Channel != channel)
{
i--;
}
return i;
}
/// <summary>
/// Collect all tokens on specified channel to the right of
/// the current token up until we see a token on
/// <see cref="Lexer.DefaultTokenChannel">Lexer.DefaultTokenChannel</see>
/// or
/// EOF. If
/// <code>channel</code>
/// is
/// <code>-1</code>
/// , find any non default channel token.
/// </summary>
public virtual IList<IToken> GetHiddenTokensToRight(int tokenIndex, int channel)
{
LazyInit();
if (tokenIndex < 0 || tokenIndex >= tokens.Count)
{
throw new ArgumentOutOfRangeException(tokenIndex + " not in 0.." + (tokens.Count
- 1));
}
int nextOnChannel = NextTokenOnChannel(tokenIndex + 1, Lexer.DefaultTokenChannel);
int to;
int from = tokenIndex + 1;
// if none onchannel to right, nextOnChannel=-1 so set to = last token
if (nextOnChannel == -1)
{
to = Size - 1;
}
else
{
to = nextOnChannel;
}
return FilterForChannel(from, to, channel);
}
/// <summary>
/// Collect all hidden tokens (any off-default channel) to the right of
/// the current token up until we see a token on
/// <see cref="Lexer.DefaultTokenChannel">Lexer.DefaultTokenChannel</see>
/// or EOF.
/// </summary>
public virtual IList<IToken> GetHiddenTokensToRight(int tokenIndex)
{
return GetHiddenTokensToRight(tokenIndex, -1);
}
/// <summary>
/// Collect all tokens on specified channel to the left of
/// the current token up until we see a token on
/// <see cref="Lexer.DefaultTokenChannel">Lexer.DefaultTokenChannel</see>
/// .
/// If
/// <code>channel</code>
/// is
/// <code>-1</code>
/// , find any non default channel token.
/// </summary>
public virtual IList<IToken> GetHiddenTokensToLeft(int tokenIndex, int channel)
{
LazyInit();
if (tokenIndex < 0 || tokenIndex >= tokens.Count)
{
throw new ArgumentOutOfRangeException(tokenIndex + " not in 0.." + (tokens.Count
- 1));
}
int prevOnChannel = PreviousTokenOnChannel(tokenIndex - 1, Lexer.DefaultTokenChannel
);
if (prevOnChannel == tokenIndex - 1)
{
return null;
}
// if none onchannel to left, prevOnChannel=-1 then from=0
int from = prevOnChannel + 1;
int to = tokenIndex - 1;
return FilterForChannel(from, to, channel);
}
/// <summary>
/// Collect all hidden tokens (any off-default channel) to the left of
/// the current token up until we see a token on
/// <see cref="Lexer.DefaultTokenChannel">Lexer.DefaultTokenChannel</see>
/// .
/// </summary>
public virtual IList<IToken> GetHiddenTokensToLeft(int tokenIndex)
{
return GetHiddenTokensToLeft(tokenIndex, -1);
}
protected internal virtual IList<IToken> FilterForChannel(int from, int to, int channel
)
{
IList<IToken> hidden = new List<IToken>();
for (int i = from; i <= to; i++)
{
IToken t = tokens[i];
if (channel == -1)
{
if (t.Channel != Lexer.DefaultTokenChannel)
{
hidden.AddItem(t);
}
}
else
{
if (t.Channel == channel)
{
hidden.AddItem(t);
}
}
}
if (hidden.IsEmpty())
{
return null;
}
return hidden;
}
public virtual string SourceName
{
get
{
return tokenSource.SourceName;
}
}
/// <summary>Get the text of all tokens in this buffer.</summary>
/// <remarks>Get the text of all tokens in this buffer.</remarks>
[NotNull]
public virtual string GetText()
{
Fill();
return GetText(Interval.Of(0, Size - 1));
}
[NotNull]
public virtual string GetText(Interval interval)
{
int start = interval.a;
int stop = interval.b;
if (start < 0 || stop < 0)
{
return string.Empty;
}
LazyInit();
if (stop >= tokens.Count)
{
stop = tokens.Count - 1;
}
StringBuilder buf = new StringBuilder();
for (int i = start; i <= stop; i++)
{
IToken t = tokens[i];
if (t.Type == IToken.Eof)
{
break;
}
buf.Append(t.Text);
}
return buf.ToString();
}
[NotNull]
public virtual string GetText(RuleContext ctx)
{
return GetText(ctx.SourceInterval);
}
[NotNull]
public virtual string GetText(IToken start, IToken stop)
{
if (start != null && stop != null)
{
return GetText(Interval.Of(start.TokenIndex, stop.TokenIndex));
}
return string.Empty;
}
/// <summary>Get all tokens from lexer until EOF.</summary>
/// <remarks>Get all tokens from lexer until EOF.</remarks>
public virtual void Fill()
{
LazyInit();
int blockSize = 1000;
while (true)
{
int fetched = Fetch(blockSize);
if (fetched < blockSize)
{
return;
}
}
}
}
}

View File

@ -0,0 +1,285 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
[System.Serializable]
public class CommonToken : IWritableToken
{
private const long serialVersionUID = -6708843461296520577L;
protected internal int type;
protected internal int line;
protected internal int charPositionInLine = -1;
protected internal int channel = DefaultChannel;
protected internal Tuple<ITokenSource, ICharStream> source;
/// <summary>We need to be able to change the text once in a while.</summary>
/// <remarks>
/// We need to be able to change the text once in a while. If
/// this is non-null, then getText should return this. Note that
/// start/stop are not affected by changing this.
/// </remarks>
protected internal string text;
/// <summary>What token number is this from 0..n-1 tokens; &lt; 0 implies invalid index
/// </summary>
protected internal int index = -1;
/// <summary>The char position into the input buffer where this token starts</summary>
protected internal int start;
/// <summary>The char position into the input buffer where this token stops</summary>
protected internal int stop;
public CommonToken(int type)
{
// set to invalid position
// TODO: can store these in map in token stream rather than as field here
this.type = type;
}
public CommonToken(Tuple<ITokenSource, ICharStream> source, int type, int channel
, int start, int stop)
{
this.source = source;
this.type = type;
this.channel = channel;
this.start = start;
this.stop = stop;
if (source.GetItem1() != null)
{
this.line = source.GetItem1().Line;
this.charPositionInLine = source.GetItem1().Column;
}
}
public CommonToken(int type, string text)
{
this.type = type;
this.channel = DefaultChannel;
this.text = text;
}
public CommonToken(IToken oldToken)
{
text = oldToken.Text;
type = oldToken.Type;
line = oldToken.Line;
index = oldToken.TokenIndex;
charPositionInLine = oldToken.Column;
channel = oldToken.Channel;
start = oldToken.StartIndex;
stop = oldToken.StopIndex;
if (oldToken is Antlr4.Runtime.CommonToken)
{
source = ((Antlr4.Runtime.CommonToken)oldToken).source;
}
else
{
source = Tuple.Create(oldToken.TokenSource, oldToken.InputStream);
}
}
public virtual int Type
{
get
{
return type;
}
set
{
int type = value;
this.type = type;
}
}
public virtual int Line
{
get
{
return line;
}
set
{
int line = value;
this.line = line;
}
}
/// <summary>Override the text for this token.</summary>
/// <remarks>
/// Override the text for this token. getText() will return this text
/// rather than pulling from the buffer. Note that this does not mean
/// that start/stop indexes are not valid. It means that that input
/// was converted to a new string in the token object.
/// </remarks>
public virtual string Text
{
get
{
if (text != null)
{
return text;
}
ICharStream input = InputStream;
if (input == null)
{
return null;
}
int n = input.Size;
if (start < n && stop < n)
{
return input.GetText(Interval.Of(start, stop));
}
else
{
return "<EOF>";
}
}
set
{
string text = value;
this.text = text;
}
}
public virtual int Column
{
get
{
return charPositionInLine;
}
set
{
int charPositionInLine = value;
this.charPositionInLine = charPositionInLine;
}
}
public virtual int Channel
{
get
{
return channel;
}
set
{
int channel = value;
this.channel = channel;
}
}
public virtual int StartIndex
{
get
{
return start;
}
}
public virtual void SetStartIndex(int start)
{
this.start = start;
}
public virtual int StopIndex
{
get
{
return stop;
}
}
public virtual void SetStopIndex(int stop)
{
this.stop = stop;
}
public virtual int TokenIndex
{
get
{
return index;
}
set
{
int index = value;
this.index = index;
}
}
public virtual ITokenSource TokenSource
{
get
{
return source.GetItem1();
}
}
public virtual ICharStream InputStream
{
get
{
return source.GetItem2();
}
}
public override string ToString()
{
string channelStr = string.Empty;
if (channel > 0)
{
channelStr = ",channel=" + channel;
}
string txt = Text;
if (txt != null)
{
txt = txt.ReplaceAll("\n", "\\\\n");
txt = txt.ReplaceAll("\r", "\\\\r");
txt = txt.ReplaceAll("\t", "\\\\t");
}
else
{
txt = "<no text>";
}
return "[@" + TokenIndex + "," + start + ":" + stop + "='" + txt + "',<" + type +
">" + channelStr + "," + line + ":" + Column + "]";
}
}
}

View File

@ -0,0 +1,93 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
public class CommonTokenFactory : ITokenFactory
{
public static readonly ITokenFactory Default = new Antlr4.Runtime.CommonTokenFactory
();
/// <summary>Copy text for token out of input char stream.</summary>
/// <remarks>
/// Copy text for token out of input char stream. Useful when input
/// stream is unbuffered.
/// </remarks>
/// <seealso cref="UnbufferedCharStream">UnbufferedCharStream</seealso>
protected internal readonly bool copyText;
/// <summary>
/// Create factory and indicate whether or not the factory copy
/// text out of the char stream.
/// </summary>
/// <remarks>
/// Create factory and indicate whether or not the factory copy
/// text out of the char stream.
/// </remarks>
public CommonTokenFactory(bool copyText)
{
this.copyText = copyText;
}
public CommonTokenFactory() : this(false)
{
}
public virtual CommonToken Create<_T0>(Tuple<_T0> source, int type, string text,
int channel, int start, int stop, int line, int charPositionInLine) where _T0:
ITokenSource
{
CommonToken t = new CommonToken(source, type, channel, start, stop);
t.Line = line;
t.Column = charPositionInLine;
if (text != null)
{
t.Text = text;
}
else
{
if (copyText && source.GetItem2() != null)
{
t.Text = source.GetItem2().GetText(Interval.Of(start, stop));
}
}
return t;
}
public virtual CommonToken Create(int type, string text)
{
return new CommonToken(type, text);
}
}
}

View File

@ -0,0 +1,156 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// The most common stream of tokens where every token is buffered up
/// and tokens are filtered for a certain channel (the parser will only
/// see these tokens).
/// </summary>
/// <remarks>
/// The most common stream of tokens where every token is buffered up
/// and tokens are filtered for a certain channel (the parser will only
/// see these tokens).
/// Even though it buffers all of the tokens, this token stream pulls tokens
/// from the tokens source on demand. In other words, until you ask for a
/// token using consume(), LT(), etc. the stream does not pull from the lexer.
/// The only difference between this stream and
/// <see cref="BufferedTokenStream">BufferedTokenStream</see>
/// superclass
/// is that this stream knows how to ignore off channel tokens. There may be
/// a performance advantage to using the superclass if you don't pass
/// whitespace and comments etc. to the parser on a hidden channel (i.e.,
/// you set
/// <code>$channel</code>
/// instead of calling
/// <code>skip()</code>
/// in lexer rules.)
/// </remarks>
/// <seealso cref="UnbufferedTokenStream">UnbufferedTokenStream</seealso>
/// <seealso cref="BufferedTokenStream">BufferedTokenStream</seealso>
public class CommonTokenStream : BufferedTokenStream
{
/// <summary>Skip tokens on any channel but this one; this is how we skip whitespace...
/// </summary>
/// <remarks>Skip tokens on any channel but this one; this is how we skip whitespace...
/// </remarks>
protected internal int channel = IToken.DefaultChannel;
public CommonTokenStream(ITokenSource tokenSource) : base(tokenSource)
{
}
public CommonTokenStream(ITokenSource tokenSource, int channel) : this(tokenSource
)
{
this.channel = channel;
}
protected internal override int AdjustSeekIndex(int i)
{
return NextTokenOnChannel(i, channel);
}
protected internal override IToken Lb(int k)
{
if (k == 0 || (p - k) < 0)
{
return null;
}
int i = p;
int n = 1;
// find k good tokens looking backwards
while (n <= k)
{
// skip off-channel tokens
i = PreviousTokenOnChannel(i - 1, channel);
n++;
}
if (i < 0)
{
return null;
}
return tokens[i];
}
public override IToken Lt(int k)
{
//System.out.println("enter LT("+k+")");
LazyInit();
if (k == 0)
{
return null;
}
if (k < 0)
{
return Lb(-k);
}
int i = p;
int n = 1;
// we know tokens[p] is a good one
// find k good tokens
while (n < k)
{
// skip off-channel tokens, but make sure to not look past EOF
if (Sync(i + 1))
{
i = NextTokenOnChannel(i + 1, channel);
}
n++;
}
// if ( i>range ) range = i;
return tokens[i];
}
/// <summary>Count EOF just once.</summary>
/// <remarks>Count EOF just once.</remarks>
public virtual int GetNumberOfOnChannelTokens()
{
int n = 0;
Fill();
for (int i = 0; i < tokens.Count; i++)
{
IToken t = tokens[i];
if (t.Channel == channel)
{
n++;
}
if (t.Type == IToken.Eof)
{
break;
}
}
return n;
}
}
}

View File

@ -0,0 +1,47 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <author>Sam Harwell</author>
public class ConsoleErrorListener : IAntlrErrorListener<object>
{
public static readonly ConsoleErrorListener Instance = new ConsoleErrorListener();
public virtual void SyntaxError<T>(Recognizer<T, object> recognizer, T offendingSymbol
, int line, int charPositionInLine, string msg, RecognitionException e)
{
System.Console.Error.WriteLine("line " + line + ":" + charPositionInLine + " " +
msg);
}
}
}

View File

@ -0,0 +1,549 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// This is the default error handling mechanism for ANTLR parsers
/// and tree parsers.
/// </summary>
/// <remarks>
/// This is the default error handling mechanism for ANTLR parsers
/// and tree parsers.
/// </remarks>
public class DefaultErrorStrategy : IAntlrErrorStrategy
{
/// <summary>
/// This is true after we see an error and before having successfully
/// matched a token.
/// </summary>
/// <remarks>
/// This is true after we see an error and before having successfully
/// matched a token. Prevents generation of more than one error message
/// per error.
/// </remarks>
protected internal bool errorRecoveryMode = false;
/// <summary>The index into the input stream where the last error occurred.</summary>
/// <remarks>
/// The index into the input stream where the last error occurred.
/// This is used to prevent infinite loops where an error is found
/// but no token is consumed during recovery...another error is found,
/// ad nauseum. This is a failsafe mechanism to guarantee that at least
/// one token/tree node is consumed for two errors.
/// </remarks>
protected internal int lastErrorIndex = -1;
protected internal IntervalSet lastErrorStates;
public virtual void BeginErrorCondition(Parser recognizer)
{
errorRecoveryMode = true;
}
public virtual bool InErrorRecoveryMode(Parser recognizer)
{
return errorRecoveryMode;
}
public virtual void EndErrorCondition(Parser recognizer)
{
errorRecoveryMode = false;
lastErrorStates = null;
lastErrorIndex = -1;
}
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual void ReportError(Parser recognizer, RecognitionException e)
{
// if we've already reported an error and have not matched a token
// yet successfully, don't report any errors.
if (errorRecoveryMode)
{
// System.err.print("[SPURIOUS] ");
return;
}
// don't count spurious errors
recognizer._syntaxErrors++;
BeginErrorCondition(recognizer);
if (e is NoViableAltException)
{
ReportNoViableAlternative(recognizer, (NoViableAltException)e);
}
else
{
if (e is InputMismatchException)
{
ReportInputMismatch(recognizer, (InputMismatchException)e);
}
else
{
if (e is FailedPredicateException)
{
ReportFailedPredicate(recognizer, (FailedPredicateException)e);
}
else
{
System.Console.Error.WriteLine("unknown recognition error type: " + e.GetType().FullName
);
NotifyErrorListeners(recognizer, e.Message, e);
}
}
}
}
protected internal virtual void NotifyErrorListeners(Parser recognizer, string message
, RecognitionException e)
{
if (recognizer != null)
{
recognizer.NotifyErrorListeners(e.GetOffendingToken(), message, e);
}
}
/// <summary>Recover from NoViableAlt errors.</summary>
/// <remarks>
/// Recover from NoViableAlt errors. Also there could be a mismatched
/// token that the match() routine could not recover from.
/// </remarks>
public virtual void Recover(Parser recognizer, RecognitionException e)
{
// System.out.println("recover in "+recognizer.getRuleInvocationStack()+
// " index="+recognizer.getInputStream().index()+
// ", lastErrorIndex="+
// lastErrorIndex+
// ", states="+lastErrorStates);
if (lastErrorIndex == ((ITokenStream)recognizer.GetInputStream()).Index && lastErrorStates
!= null && lastErrorStates.Contains(recognizer.GetState()))
{
// uh oh, another error at same token index and previously-visited
// state in ATN; must be a case where LT(1) is in the recovery
// token set so nothing got consumed. Consume a single token
// at least to prevent an infinite loop; this is a failsafe.
// System.err.println("seen error condition before index="+
// lastErrorIndex+", states="+lastErrorStates);
// System.err.println("FAILSAFE consumes "+recognizer.getTokenNames()[recognizer.getInputStream().LA(1)]);
recognizer.Consume();
}
lastErrorIndex = ((ITokenStream)recognizer.GetInputStream()).Index;
if (lastErrorStates == null)
{
lastErrorStates = new IntervalSet();
}
lastErrorStates.Add(recognizer.GetState());
IntervalSet followSet = GetErrorRecoverySet(recognizer);
ConsumeUntil(recognizer, followSet);
}
/// <summary>
/// Make sure that the current lookahead symbol is consistent with
/// what were expecting at this point in the ATN.
/// </summary>
/// <remarks>
/// Make sure that the current lookahead symbol is consistent with
/// what were expecting at this point in the ATN.
/// At the start of a sub rule upon error, sync() performs single
/// token deletion, if possible. If it can't do that, it bails
/// on the current rule and uses the default error recovery,
/// which consumes until the resynchronization set of the current rule.
/// If the sub rule is optional, ()? or ()* or optional alternative,
/// then the expected set includes what follows the subrule.
/// During loop iteration, it consumes until it sees a token that can
/// start a sub rule or what follows loop. Yes, that is pretty aggressive.
/// We opt to stay in the loop as long as possible.
/// </remarks>
public virtual void Sync(Parser recognizer)
{
ATNState s = recognizer.GetInterpreter().atn.states[recognizer.GetState()];
// System.err.println("sync @ "+s.stateNumber+"="+s.getClass().getSimpleName());
// If already recovering, don't try to sync
if (errorRecoveryMode)
{
return;
}
ITokenStream tokens = ((ITokenStream)recognizer.GetInputStream());
int la = tokens.La(1);
// try cheaper subset first; might get lucky. seems to shave a wee bit off
if (recognizer.GetATN().NextTokens(s).Contains(la) || la == IToken.Eof)
{
return;
}
// Return but don't end recovery. only do that upon valid token match
if (recognizer.IsExpectedToken(la))
{
return;
}
switch (s.GetStateType())
{
case ATNState.BlockStart:
case ATNState.StarBlockStart:
case ATNState.PlusBlockStart:
case ATNState.StarLoopEntry:
{
// report error and recover if possible
if (SingleTokenDeletion(recognizer) != null)
{
return;
}
throw new InputMismatchException(recognizer);
}
case ATNState.PlusLoopBack:
case ATNState.StarLoopBack:
{
// System.err.println("at loop back: "+s.getClass().getSimpleName());
ReportUnwantedToken(recognizer);
IntervalSet expecting = recognizer.GetExpectedTokens();
IntervalSet whatFollowsLoopIterationOrRule = expecting.Or(GetErrorRecoverySet(recognizer
));
ConsumeUntil(recognizer, whatFollowsLoopIterationOrRule);
break;
}
default:
{
// do nothing if we can't identify the exact kind of ATN state
break;
break;
}
}
}
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual void ReportNoViableAlternative(Parser recognizer, NoViableAltException
e)
{
ITokenStream tokens = ((ITokenStream)recognizer.GetInputStream());
string input;
if (tokens != null)
{
if (e.GetStartToken().Type == IToken.Eof)
{
input = "<EOF>";
}
else
{
input = tokens.GetText(e.GetStartToken(), e.GetOffendingToken());
}
}
else
{
input = "<unknown input>";
}
string msg = "no viable alternative at input " + EscapeWSAndQuote(input);
NotifyErrorListeners(recognizer, msg, e);
}
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual void ReportInputMismatch(Parser recognizer, InputMismatchException
e)
{
string msg = "mismatched input " + GetTokenErrorDisplay(e.GetOffendingToken()) +
" expecting " + e.GetExpectedTokens().ToString(recognizer.GetTokenNames());
NotifyErrorListeners(recognizer, msg, e);
}
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual void ReportFailedPredicate(Parser recognizer, FailedPredicateException
e)
{
string ruleName = recognizer.GetRuleNames()[recognizer._ctx.GetRuleIndex()];
string msg = "rule " + ruleName + " " + e.Message;
NotifyErrorListeners(recognizer, msg, e);
}
public virtual void ReportUnwantedToken(Parser recognizer)
{
if (errorRecoveryMode)
{
return;
}
recognizer._syntaxErrors++;
BeginErrorCondition(recognizer);
IToken t = recognizer.GetCurrentToken();
string tokenName = GetTokenErrorDisplay(t);
IntervalSet expecting = GetExpectedTokens(recognizer);
string msg = "extraneous input " + tokenName + " expecting " + expecting.ToString
(recognizer.GetTokenNames());
recognizer.NotifyErrorListeners(t, msg, null);
}
public virtual void ReportMissingToken(Parser recognizer)
{
if (errorRecoveryMode)
{
return;
}
recognizer._syntaxErrors++;
BeginErrorCondition(recognizer);
IToken t = recognizer.GetCurrentToken();
IntervalSet expecting = GetExpectedTokens(recognizer);
string msg = "missing " + expecting.ToString(recognizer.GetTokenNames()) + " at "
+ GetTokenErrorDisplay(t);
recognizer.NotifyErrorListeners(t, msg, null);
}
/// <summary>Attempt to recover from a single missing or extra token.</summary>
/// <remarks>
/// Attempt to recover from a single missing or extra token.
/// EXTRA TOKEN
/// LA(1) is not what we are looking for. If LA(2) has the right token,
/// however, then assume LA(1) is some extra spurious token. Delete it
/// and LA(2) as if we were doing a normal match(), which advances the
/// input.
/// MISSING TOKEN
/// If current token is consistent with what could come after
/// ttype then it is ok to "insert" the missing token, else throw
/// exception For example, Input "i=(3;" is clearly missing the
/// ')'. When the parser returns from the nested call to expr, it
/// will have call chain:
/// stat -&gt; expr -&gt; atom
/// and it will be trying to match the ')' at this point in the
/// derivation:
/// =&gt; ID '=' '(' INT ')' ('+' atom)* ';'
/// ^
/// match() will see that ';' doesn't match ')' and report a
/// mismatched token error. To recover, it sees that LA(1)==';'
/// is in the set of tokens that can follow the ')' token
/// reference in rule atom. It can assume that you forgot the ')'.
/// </remarks>
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual IToken RecoverInline(Parser recognizer)
{
// SINGLE TOKEN DELETION
IToken matchedSymbol = SingleTokenDeletion(recognizer);
if (matchedSymbol != null)
{
// we have deleted the extra token.
// now, move past ttype token as if all were ok
recognizer.Consume();
return matchedSymbol;
}
// SINGLE TOKEN INSERTION
if (SingleTokenInsertion(recognizer))
{
return GetMissingSymbol(recognizer);
}
// even that didn't work; must throw the exception
throw new InputMismatchException(recognizer);
}
// if next token is what we are looking for then "delete" this token
public virtual bool SingleTokenInsertion(Parser recognizer)
{
int currentSymbolType = ((ITokenStream)recognizer.GetInputStream()).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.GetInterpreter().atn.states[recognizer.GetState
()];
ATNState next = currentState.Transition(0).target;
ATN atn = recognizer.GetInterpreter().atn;
IntervalSet expectingAtLL2 = atn.NextTokens(next, PredictionContext.FromRuleContext
(atn, recognizer._ctx));
// System.out.println("LT(2) set="+expectingAtLL2.toString(recognizer.getTokenNames()));
if (expectingAtLL2.Contains(currentSymbolType))
{
ReportMissingToken(recognizer);
return true;
}
return false;
}
public virtual IToken SingleTokenDeletion(Parser recognizer)
{
int nextTokenType = ((ITokenStream)recognizer.GetInputStream()).La(2);
IntervalSet expecting = GetExpectedTokens(recognizer);
if (expecting.Contains(nextTokenType))
{
ReportUnwantedToken(recognizer);
recognizer.Consume();
// simply delete extra token
// we want to return the token we're actually matching
IToken matchedSymbol = recognizer.GetCurrentToken();
EndErrorCondition(recognizer);
// we know current token is correct
return matchedSymbol;
}
return null;
}
/// <summary>Conjure up a missing token during error recovery.</summary>
/// <remarks>
/// Conjure up a missing token during error recovery.
/// The recognizer attempts to recover from single missing
/// symbols. But, actions might refer to that missing symbol.
/// For example, x=ID {f($x);}. The action clearly assumes
/// that there has been an identifier matched previously and that
/// $x points at that token. If that token is missing, but
/// the next token in the stream is what we want we assume that
/// this token is missing and we keep going. Because we
/// have to return some token to replace the missing token,
/// we have to conjure one up. This method gives the user control
/// over the tokens returned for missing tokens. Mostly,
/// you will want to create something special for identifier
/// tokens. For literals such as '{' and ',', the default
/// action in the parser or tree parser works. It simply creates
/// a CommonToken of the appropriate type. The text will be the token.
/// If you change what tokens must be created by the lexer,
/// override this method to create the appropriate tokens.
/// </remarks>
protected internal virtual IToken GetMissingSymbol(Parser recognizer)
{
IToken currentSymbol = recognizer.GetCurrentToken();
IntervalSet expecting = GetExpectedTokens(recognizer);
int expectedTokenType = expecting.GetMinElement();
// get any element
string tokenText;
if (expectedTokenType == IToken.Eof)
{
tokenText = "<missing EOF>";
}
else
{
tokenText = "<missing " + recognizer.GetTokenNames()[expectedTokenType] + ">";
}
IToken current = currentSymbol;
IToken lookback = ((ITokenStream)recognizer.GetInputStream()).Lt(-1);
if (current.Type == IToken.Eof && lookback != null)
{
current = lookback;
}
return ConstructToken(((ITokenStream)recognizer.GetInputStream()).TokenSource, expectedTokenType
, tokenText, current);
}
protected internal virtual IToken ConstructToken(ITokenSource tokenSource, int expectedTokenType
, string tokenText, IToken current)
{
ITokenFactory factory = tokenSource.TokenFactory;
return factory.Create(Tuple.Create(tokenSource, current.TokenSource.InputStream),
expectedTokenType, tokenText, IToken.DefaultChannel, -1, -1, current.Line, current
.Column);
}
public virtual IntervalSet GetExpectedTokens(Parser recognizer)
{
return recognizer.GetExpectedTokens();
}
/// <summary>
/// How should a token be displayed in an error message? The default
/// is to display just the text, but during development you might
/// want to have a lot of information spit out.
/// </summary>
/// <remarks>
/// How should a token be displayed in an error message? The default
/// is to display just the text, but during development you might
/// want to have a lot of information spit out. Override in that case
/// to use t.toString() (which, for CommonToken, dumps everything about
/// the token). This is better than forcing you to override a method in
/// your token objects because you don't have to go modify your lexer
/// so that it creates a new Java type.
/// </remarks>
public virtual string GetTokenErrorDisplay(IToken t)
{
if (t == null)
{
return "<no token>";
}
string s = GetSymbolText(t);
if (s == null)
{
if (GetSymbolType(t) == IToken.Eof)
{
s = "<EOF>";
}
else
{
s = "<" + GetSymbolType(t) + ">";
}
}
return EscapeWSAndQuote(s);
}
protected internal virtual string GetSymbolText(IToken symbol)
{
return symbol.Text;
}
protected internal virtual int GetSymbolType(IToken symbol)
{
return symbol.Type;
}
protected internal virtual string EscapeWSAndQuote(string s)
{
// if ( s==null ) return s;
s = s.ReplaceAll("\n", "\\\\n");
s = s.ReplaceAll("\r", "\\\\r");
s = s.ReplaceAll("\t", "\\\\t");
return "'" + s + "'";
}
protected internal virtual IntervalSet GetErrorRecoverySet(Parser recognizer)
{
ATN atn = recognizer.GetInterpreter().atn;
RuleContext ctx = recognizer._ctx;
IntervalSet recoverSet = new IntervalSet();
while (ctx != null && ctx.invokingState >= 0)
{
// compute what follows who invoked us
ATNState invokingState = atn.states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
IntervalSet follow = atn.NextTokens(rt.followState);
recoverSet.AddAll(follow);
ctx = ctx.parent;
}
recoverSet.Remove(IToken.Epsilon);
// System.out.println("recover set "+recoverSet.toString(recognizer.getTokenNames()));
return recoverSet;
}
/// <summary>Consume tokens until one matches the given token set</summary>
public virtual void ConsumeUntil(Parser recognizer, IntervalSet set)
{
// System.err.println("consumeUntil("+set.toString(recognizer.getTokenNames())+")");
int ttype = ((ITokenStream)recognizer.GetInputStream()).La(1);
while (ttype != IToken.Eof && !set.Contains(ttype))
{
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
// recognizer.getInputStream().consume();
recognizer.Consume();
ttype = ((ITokenStream)recognizer.GetInputStream()).La(1);
}
}
}
}

View File

@ -0,0 +1,49 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <author>Sam Harwell</author>
public enum Dependents
{
Self,
Parents,
Children,
Ancestors,
Descendants,
Siblings,
PreceedingSiblings,
FollowingSiblings,
Preceeding,
Following
}
}

View File

@ -0,0 +1,117 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections;
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <author>Sam Harwell</author>
public abstract class AbstractEdgeMap<T> : IEdgeMap<T>
{
protected internal readonly int minIndex;
protected internal readonly int maxIndex;
public AbstractEdgeMap(int minIndex, int maxIndex)
{
// the allowed range (with minIndex and maxIndex inclusive) should be less than 2^32
System.Diagnostics.Debug.Assert(maxIndex - minIndex + 1 >= 0);
this.minIndex = minIndex;
this.maxIndex = maxIndex;
}
public abstract Antlr4.Runtime.Dfa.AbstractEdgeMap<T> Put(int key, T value);
public virtual Antlr4.Runtime.Dfa.AbstractEdgeMap<T> PutAll<_T0>(IEdgeMap<_T0> m)
where _T0:T
{
Antlr4.Runtime.Dfa.AbstractEdgeMap<T> result = this;
foreach (KeyValuePair<int, T> entry in m.EntrySet())
{
result = result.Put(entry.Key, entry.Value);
}
return result;
}
public abstract Antlr4.Runtime.Dfa.AbstractEdgeMap<T> Clear();
public abstract Antlr4.Runtime.Dfa.AbstractEdgeMap<T> Remove(int key);
protected internal abstract class AbstractEntrySet : AbstractSet<KeyValuePair<int
, T>>
{
public override bool Contains(object o)
{
if (!(o is DictionaryEntry))
{
return false;
}
KeyValuePair<object, object> entry = (KeyValuePair<object, object>)o;
if (entry.Key is int)
{
int key = (int)entry.Key;
object value = entry.Value;
T existing = this._enclosing._enclosing.Get(key);
return value == existing || (existing != null && existing.Equals(value));
}
return false;
}
public override int Count
{
get
{
return this._enclosing._enclosing.Size();
}
}
internal AbstractEntrySet(AbstractEdgeMap<T> _enclosing)
{
this._enclosing = _enclosing;
}
private readonly AbstractEdgeMap<T> _enclosing;
}
public abstract bool ContainsKey(int arg1);
public abstract ICollection<KeyValuePair<int, T>> EntrySet();
public abstract T Get(int arg1);
public abstract bool IsEmpty();
public abstract int Size();
public abstract IDictionary<int, T> ToMap();
}
}

View File

@ -0,0 +1,272 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <author>sam</author>
public class ArrayEdgeMap<T> : AbstractEdgeMap<T>
{
private readonly T[] arrayData;
private int size;
public ArrayEdgeMap(int minIndex, int maxIndex) : base(minIndex, maxIndex)
{
arrayData = (T[])new object[maxIndex - minIndex + 1];
}
public override int Size()
{
return size;
}
public override bool IsEmpty()
{
return size == 0;
}
public override bool ContainsKey(int key)
{
return Get(key) != null;
}
public override T Get(int key)
{
if (key < minIndex || key > maxIndex)
{
return null;
}
return arrayData[key - minIndex];
}
public override AbstractEdgeMap<T> Put(int key, T value)
{
if (key >= minIndex && key <= maxIndex)
{
T existing = arrayData[key - minIndex];
arrayData[key - minIndex] = value;
if (existing == null && value != null)
{
size++;
}
else
{
if (existing != null && value == null)
{
size--;
}
}
}
return this;
}
public override AbstractEdgeMap<T> Remove(int key)
{
return ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)Put(key, null));
}
public override AbstractEdgeMap<T> PutAll<_T0>(IEdgeMap<_T0> m)
{
if (m.IsEmpty())
{
return this;
}
if (m is Antlr4.Runtime.Dfa.ArrayEdgeMap<object>)
{
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> other = (Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)m;
int minOverlap = Math.Max(minIndex, other.minIndex);
int maxOverlap = Math.Min(maxIndex, other.maxIndex);
for (int i = minOverlap; i <= maxOverlap; i++)
{
T target = other.arrayData[i - other.minIndex];
if (target != null)
{
T current = this.arrayData[i - this.minIndex];
this.arrayData[i - this.minIndex] = target;
size += (current != null ? 0 : 1);
}
}
return this;
}
else
{
if (m is SingletonEdgeMap<object>)
{
SingletonEdgeMap<T> other = (SingletonEdgeMap<T>)m;
System.Diagnostics.Debug.Assert(!other.IsEmpty());
return ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)Put(other.GetKey(), other.GetValue())
);
}
else
{
if (m is SparseEdgeMap<object>)
{
SparseEdgeMap<T> other = (SparseEdgeMap<T>)m;
int[] keys = other.GetKeys();
IList<T> values = other.GetValues();
Antlr4.Runtime.Dfa.ArrayEdgeMap<T> result = this;
for (int i = 0; i < values.Count; i++)
{
result = ((Antlr4.Runtime.Dfa.ArrayEdgeMap<T>)result.Put(keys[i], values[i]));
}
return result;
}
else
{
throw new NotSupportedException(string.Format("EdgeMap of type %s is supported yet."
, m.GetType().FullName));
}
}
}
}
public override AbstractEdgeMap<T> Clear()
{
Arrays.Fill(arrayData, null);
return this;
}
public override IDictionary<int, T> ToMap()
{
if (IsEmpty())
{
return Sharpen.Collections.EmptyMap();
}
IDictionary<int, T> result = new LinkedHashMap<int, T>();
for (int i = 0; i < arrayData.Length; i++)
{
if (arrayData[i] == null)
{
continue;
}
result.Put(i + minIndex, arrayData[i]);
}
return result;
}
public override ICollection<KeyValuePair<int, T>> EntrySet()
{
return new ArrayEdgeMap.EntrySet(this);
}
private class EntrySet : AbstractEdgeMap.AbstractEntrySet
{
public override IEnumerator<KeyValuePair<int, T>> GetEnumerator()
{
return new ArrayEdgeMap.EntryIterator(this);
}
internal EntrySet(ArrayEdgeMap<T> _enclosing) : base(_enclosing)
{
this._enclosing = _enclosing;
}
private readonly ArrayEdgeMap<T> _enclosing;
}
private class EntryIterator : IEnumerator<KeyValuePair<int, T>>
{
private int current;
private int currentIndex;
public override bool HasNext()
{
return this.current < this._enclosing.Size();
}
public override KeyValuePair<int, T> Next()
{
if (this.current >= this._enclosing.Size())
{
throw new NoSuchElementException();
}
while (this._enclosing.arrayData[this.currentIndex] == null)
{
this.currentIndex++;
}
this.current++;
this.currentIndex++;
return new _KeyValuePair_193(this);
}
private sealed class _KeyValuePair_193 : KeyValuePair<int, T>
{
public _KeyValuePair_193()
{
this.key = this._enclosing._enclosing.minIndex + this._enclosing.currentIndex - 1;
this.value = this._enclosing._enclosing.arrayData[this._enclosing.currentIndex -
1];
}
private readonly int key;
private readonly T value;
public int Key
{
get
{
return this.key;
}
}
public T Value
{
get
{
return this.value;
}
}
public T SetValue(T value)
{
throw new NotSupportedException("Not supported yet.");
}
}
public override void Remove()
{
throw new NotSupportedException("Not supported yet.");
}
internal EntryIterator(ArrayEdgeMap<T> _enclosing)
{
this._enclosing = _enclosing;
}
private readonly ArrayEdgeMap<T> _enclosing;
}
}
}

144
Antlr4.Runtime/Dfa/DFA.cs Normal file
View File

@ -0,0 +1,144 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
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.IDictionary{K, V}">System.Collections.IDictionary&lt;K, V&gt;
/// </see>
/// so we can get old state back
/// (
/// <see cref="Sharpen.ISet{E}">Sharpen.ISet&lt;E&gt;</see>
/// only allows you to see if it's there).
/// </remarks>
[NotNull]
public readonly IConcurrentMap<DFAState, DFAState> states = new ConcurrentHashMap
<DFAState, DFAState>();
[Nullable]
public readonly AtomicReference<DFAState> s0 = new AtomicReference<DFAState>();
[Nullable]
public readonly AtomicReference<DFAState> s0full = new AtomicReference<DFAState>(
);
public readonly int decision;
/// <summary>From which ATN state did we create this DFA?</summary>
[NotNull]
public readonly ATNState atnStartState;
private readonly AtomicInteger nextStateNumber = new AtomicInteger();
/// <summary>
/// Set of configs for a DFA state with at least one conflict? Mainly used as "return value"
/// from
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.PredictATN(DFA, Antlr4.Runtime.ITokenStream, Antlr4.Runtime.ParserRuleContext, bool)
/// ">Antlr4.Runtime.Atn.ParserATNSimulator.PredictATN(DFA, Antlr4.Runtime.ITokenStream, Antlr4.Runtime.ParserRuleContext, bool)
/// </see>
/// for retry.
/// </summary>
public DFA(ATNState atnStartState) : this(atnStartState, 0)
{
}
public DFA(ATNState atnStartState, int decision)
{
// public OrderedHashSet<ATNConfig> conflictSet;
this.atnStartState = atnStartState;
this.decision = decision;
}
public virtual bool IsEmpty()
{
return s0.Get() == null && s0full.Get() == null;
}
public virtual bool IsContextSensitive()
{
return s0full.Get() != null;
}
public virtual DFAState AddState(DFAState state)
{
state.stateNumber = nextStateNumber.GetAndIncrement();
DFAState existing = states.PutIfAbsent(state, state);
if (existing != null)
{
return existing;
}
return state;
}
public override string ToString()
{
return ToString(null);
}
public virtual string ToString(string[] tokenNames)
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new DFASerializer(this, tokenNames);
return serializer.ToString();
}
public virtual string ToString(string[] tokenNames, string[] ruleNames)
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new DFASerializer(this, tokenNames, ruleNames, atnStartState
.atn);
return serializer.ToString();
}
public virtual string ToLexerString()
{
if (s0.Get() == null)
{
return string.Empty;
}
DFASerializer serializer = new LexerDFASerializer(this);
return serializer.ToString();
}
}
}

View File

@ -0,0 +1,222 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <summary>A DFA walker that knows how to dump them to serialized strings.</summary>
/// <remarks>A DFA walker that knows how to dump them to serialized strings.</remarks>
public class DFASerializer
{
[NotNull]
internal readonly DFA dfa;
[Nullable]
internal readonly string[] tokenNames;
[Nullable]
internal readonly string[] ruleNames;
[Nullable]
internal readonly ATN atn;
public DFASerializer(DFA dfa, string[] tokenNames) : this(dfa, tokenNames, null,
null)
{
}
public DFASerializer(DFA dfa, Recognizer<object, object> parser) : this(dfa, parser
!= null ? parser.GetTokenNames() : null, parser != null ? parser.GetRuleNames
() : null, parser != null ? parser.GetATN() : null)
{
}
public DFASerializer(DFA dfa, string[] tokenNames, string[] ruleNames, ATN atn)
{
this.dfa = dfa;
this.tokenNames = tokenNames;
this.ruleNames = ruleNames;
this.atn = atn;
}
public override string ToString()
{
if (dfa.s0.Get() == null)
{
return null;
}
StringBuilder buf = new StringBuilder();
if (dfa.states != null)
{
IList<DFAState> states = new List<DFAState>(dfa.states.Values);
states.Sort(new _IComparer_85());
foreach (DFAState s in states)
{
IDictionary<int, DFAState> edges = s.EdgeMap;
IDictionary<int, DFAState> contextEdges = s.ContextEdgeMap;
foreach (KeyValuePair<int, DFAState> entry in edges.EntrySet())
{
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;
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.EntrySet())
{
buf.Append(GetStateString(s)).Append("-").Append(GetContextLabel(entry_1.Key)).Append
("->").Append(GetStateString(entry_1.Value)).Append("\n");
}
}
}
}
string output = buf.ToString();
//return Utils.sortLinesInString(output);
return output;
}
private sealed class _IComparer_85 : IComparer<DFAState>
{
public _IComparer_85()
{
}
public int Compare(DFAState o1, DFAState o2)
{
return o1.stateNumber - o2.stateNumber;
}
}
protected internal virtual string GetContextLabel(int i)
{
if (i == PredictionContext.EmptyFullStateKey)
{
return "ctx:EMPTY_FULL";
}
else
{
if (i == PredictionContext.EmptyLocalStateKey)
{
return "ctx:EMPTY_LOCAL";
}
}
if (atn != null && i > 0 && i <= atn.states.Count)
{
ATNState state = atn.states[i];
int ruleIndex = state.ruleIndex;
if (ruleNames != null && ruleIndex >= 0 && ruleIndex < ruleNames.Length)
{
return "ctx:" + i.ToString() + "(" + ruleNames[ruleIndex] + ")";
}
}
return "ctx:" + i.ToString();
}
protected internal virtual string GetEdgeLabel(int i)
{
string label;
if (i == -1)
{
return "EOF";
}
if (tokenNames != null)
{
label = tokenNames[i];
}
else
{
label = i.ToString();
}
return label;
}
internal virtual string GetStateString(DFAState s)
{
if (s == ATNSimulator.Error)
{
return "ERROR";
}
int n = s.stateNumber;
string stateStr = "s" + n;
if (s.isAcceptState)
{
if (s.predicates != null)
{
stateStr = ":s" + n + "=>" + Arrays.ToString(s.predicates);
}
else
{
stateStr = ":s" + n + "=>" + s.prediction;
}
}
if (s.IsContextSensitive)
{
stateStr += "*";
foreach (ATNConfig config in s.configs)
{
if (config.GetReachesIntoOuterContext())
{
stateStr += "*";
break;
}
}
}
return stateStr;
}
}
}

View File

@ -0,0 +1,358 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <summary>A DFA state represents a set of possible ATN configurations.</summary>
/// <remarks>
/// A DFA state represents a set of possible ATN configurations.
/// As Aho, Sethi, Ullman p. 117 says "The DFA uses its state
/// to keep track of all possible states the ATN can be in after
/// reading each input symbol. That is to say, after reading
/// input a1a2..an, the DFA is in a state that represents the
/// subset T of the states of the ATN that are reachable from the
/// ATN's start state along some path labeled a1a2..an."
/// In conventional NFA-&gt;DFA conversion, therefore, the subset T
/// would be a bitset representing the set of states the
/// ATN could be in. We need to track the alt predicted by each
/// state as well, however. More importantly, we need to maintain
/// a stack of states, tracking the closure operations as they
/// jump from rule to rule, emulating rule invocations (method calls).
/// I have to add a stack to simulate the proper lookahead sequences for
/// the underlying LL grammar from which the ATN was derived.
/// <p/>
/// I use a set of ATNConfig objects not simple states. An ATNConfig
/// is both a state (ala normal conversion) and a RuleContext describing
/// the chain of rules (if any) followed to arrive at that state.
/// <p/>
/// A DFA state may have multiple references to a particular state,
/// but with different ATN contexts (with same or different alts)
/// meaning that state was reached via a different set of rule invocations.
/// </remarks>
public class DFAState
{
public int stateNumber = -1;
[NotNull]
public readonly ATNConfigSet configs;
/// <summary>
/// <code>edges.get(symbol)</code>
/// points to target of symbol.
/// </summary>
[Nullable]
private AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> edges;
private readonly int minSymbol;
private readonly int maxSymbol;
public bool isAcceptState = false;
/// <summary>
/// if accept state, what ttype do we match or alt do we predict?
/// This is set to
/// <see cref="Antlr4.Runtime.Atn.ATN.InvalidAltNumber">Antlr4.Runtime.Atn.ATN.InvalidAltNumber
/// </see>
/// when
/// <see cref="predicates">predicates</see>
/// <code>!=null</code>
/// .
/// </summary>
public int prediction;
public int lexerRuleIndex = -1;
public int lexerActionIndex = -1;
/// <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>
[Nullable]
private AbstractEdgeMap<Antlr4.Runtime.Dfa.DFAState> contextEdges;
/// <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;
/// <summary>
/// This list is computed by
/// <see cref="Antlr4.Runtime.Atn.ParserATNSimulator.PredicateDFAState(DFAState, Antlr4.Runtime.Atn.ATNConfigSet, int)
/// ">Antlr4.Runtime.Atn.ParserATNSimulator.PredicateDFAState(DFAState, Antlr4.Runtime.Atn.ATNConfigSet, int)
/// </see>
/// .
/// </summary>
[Nullable]
public DFAState.PredPrediction[] predicates;
/// <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 int alt;
public PredPrediction(SemanticContext pred, int alt)
{
// if accept, exec action in what rule?
// if accept, exec what action?
// never null; at least SemanticContext.NONE
this.alt = alt;
this.pred = pred;
}
public override string ToString()
{
return "(" + pred + ", " + alt + ")";
}
}
public DFAState(ATNConfigSet configs, int minSymbol, int maxSymbol)
{
this.configs = configs;
this.minSymbol = minSymbol;
this.maxSymbol = maxSymbol;
}
public bool IsContextSensitive
{
get
{
return contextEdges != null;
}
}
public bool IsContextSymbol(int symbol)
{
if (!IsContextSensitive || symbol < minSymbol)
{
return false;
}
return contextSymbols.Get(symbol - minSymbol);
}
public void SetContextSymbol(int symbol)
{
System.Diagnostics.Debug.Assert(IsContextSensitive);
if (symbol < minSymbol)
{
return;
}
contextSymbols.Set(symbol - minSymbol);
}
public virtual void SetContextSensitive(ATN atn)
{
lock (this)
{
System.Diagnostics.Debug.Assert(!configs.IsOutermostConfigSet());
if (IsContextSensitive)
{
return;
}
contextSymbols = new BitSet();
contextEdges = new SingletonEdgeMap<DFAState>(-1, atn.states.Count - 1);
}
}
public virtual DFAState GetTarget(int symbol)
{
if (edges == null)
{
return null;
}
return edges.Get(symbol);
}
public virtual void SetTarget(int symbol, DFAState target)
{
lock (this)
{
if (edges == null)
{
edges = new SingletonEdgeMap<DFAState>(minSymbol, maxSymbol);
}
edges = edges.Put(symbol, target);
}
}
public virtual IDictionary<int, DFAState> EdgeMap
{
get
{
if (edges == null)
{
return Sharpen.Collections.EmptyMap();
}
return edges.ToMap();
}
}
public virtual DFAState GetContextTarget(int invokingState)
{
if (contextEdges == null)
{
return null;
}
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
return contextEdges.Get(invokingState);
}
public virtual void SetContextTarget(int invokingState, DFAState target)
{
lock (this)
{
if (contextEdges == null)
{
throw new InvalidOperationException("The state is not context sensitive.");
}
if (invokingState == PredictionContext.EmptyFullStateKey)
{
invokingState = -1;
}
contextEdges = contextEdges.Put(invokingState, target);
}
}
public virtual IDictionary<int, DFAState> ContextEdgeMap
{
get
{
if (contextEdges == null)
{
return Sharpen.Collections.EmptyMap();
}
IDictionary<int, DFAState> map = contextEdges.ToMap();
if (map.ContainsKey(-1))
{
if (map.Count == 1)
{
return Sharpen.Collections.SingletonMap(PredictionContext.EmptyFullStateKey, map.
Get(-1));
}
else
{
try
{
map.Put(PredictionContext.EmptyFullStateKey, Sharpen.Collections.Remove(map, -1));
}
catch (NotSupportedException)
{
// handles read only, non-singleton maps
map = new LinkedHashMap<int, DFAState>(map);
map.Put(PredictionContext.EmptyFullStateKey, Sharpen.Collections.Remove(map, -1));
}
}
}
return map;
}
}
public override int GetHashCode()
{
if (configs == null)
{
return 1;
}
return configs.GetHashCode();
}
/// <summary>
/// Two
/// <see cref="DFAState">DFAState</see>
/// 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/>
/// 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)
/// ">Antlr4.Runtime.Atn.ParserATNSimulator.AddDFAState(DFA, Antlr4.Runtime.Atn.ATNConfigSet, Antlr4.Runtime.Atn.PredictionContextCache)
/// </see>
/// we need to know if any other state
/// exists that has this exact set of ATN configurations. The
/// <see cref="stateNumber">stateNumber</see>
/// is irrelevant.
/// </summary>
public override bool Equals(object o)
{
// compare set of ATN configurations in this set with other
if (this == o)
{
return true;
}
if (!(o is DFAState))
{
return false;
}
DFAState other = (DFAState)o;
bool sameSet = this.configs.Equals(other.configs);
// System.out.println("DFAState.equals: "+configs+(sameSet?"==":"!=")+other.configs);
return sameSet;
}
public override string ToString()
{
StringBuilder buf = new StringBuilder();
buf.Append(stateNumber).Append(":").Append(configs);
if (isAcceptState)
{
buf.Append("=>");
if (predicates != null)
{
buf.Append(Arrays.ToString(predicates));
}
else
{
buf.Append(prediction);
}
}
return buf.ToString();
}
}
}

View File

@ -0,0 +1,67 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <author>Sam Harwell</author>
public interface IEdgeMap<T>
{
int Size();
bool IsEmpty();
bool ContainsKey(int key);
[Nullable]
T Get(int key);
[NotNull]
IEdgeMap<T> Put(int key, T value);
[NotNull]
IEdgeMap<T> Remove(int key);
[NotNull]
IEdgeMap<T> PutAll<_T0>(IEdgeMap<_T0> m) where _T0:T;
[NotNull]
IEdgeMap<T> Clear();
[NotNull]
IDictionary<int, T> ToMap();
[NotNull]
ICollection<KeyValuePair<int, T>> EntrySet();
}
}

View File

@ -0,0 +1,48 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
public class LexerDFASerializer : DFASerializer
{
public LexerDFASerializer(DFA dfa) : base(dfa, (string[])null)
{
}
[NotNull]
protected internal override string GetEdgeLabel(int i)
{
return "'" + (char)i + "'";
}
}
}

View File

@ -0,0 +1,238 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <author>Sam Harwell</author>
public class SingletonEdgeMap<T> : AbstractEdgeMap<T>
{
private readonly int key;
private readonly T value;
public SingletonEdgeMap(int minIndex, int maxIndex) : base(minIndex, maxIndex)
{
this.key = 0;
this.value = null;
}
public SingletonEdgeMap(int minIndex, int maxIndex, int key, T value) : base(minIndex
, maxIndex)
{
if (key >= minIndex && key <= maxIndex)
{
this.key = key;
this.value = value;
}
else
{
this.key = 0;
this.value = null;
}
}
public virtual int GetKey()
{
return key;
}
public virtual T GetValue()
{
return value;
}
public override int Size()
{
return value != null ? 1 : 0;
}
public override bool IsEmpty()
{
return value == null;
}
public override bool ContainsKey(int key)
{
return key == this.key && value != null;
}
public override T Get(int key)
{
if (key == this.key)
{
return value;
}
return null;
}
public override AbstractEdgeMap<T> Put(int key, T value)
{
if (key < minIndex || key > maxIndex)
{
return this;
}
if (key == this.key || this.value == null)
{
return new Antlr4.Runtime.Dfa.SingletonEdgeMap<T>(minIndex, maxIndex, key, value);
}
else
{
if (value != null)
{
AbstractEdgeMap<T> result = new SparseEdgeMap<T>(minIndex, maxIndex);
result = result.Put(this.key, this.value);
result = result.Put(key, value);
return result;
}
else
{
return this;
}
}
}
public override AbstractEdgeMap<T> Remove(int key)
{
if (key == this.key && this.value != null)
{
return new Antlr4.Runtime.Dfa.SingletonEdgeMap<T>(minIndex, maxIndex);
}
return this;
}
public override AbstractEdgeMap<T> Clear()
{
if (this.value != null)
{
return new Antlr4.Runtime.Dfa.SingletonEdgeMap<T>(minIndex, maxIndex);
}
return this;
}
public override IDictionary<int, T> ToMap()
{
if (IsEmpty())
{
return Sharpen.Collections.EmptyMap();
}
return Sharpen.Collections.SingletonMap(key, value);
}
public override ICollection<KeyValuePair<int, T>> EntrySet()
{
return new SingletonEdgeMap.EntrySet(this);
}
private class EntrySet : AbstractEdgeMap.AbstractEntrySet
{
public override IEnumerator<KeyValuePair<int, T>> GetEnumerator()
{
return new SingletonEdgeMap.EntryIterator(this);
}
internal EntrySet(SingletonEdgeMap<T> _enclosing) : base(_enclosing)
{
this._enclosing = _enclosing;
}
private readonly SingletonEdgeMap<T> _enclosing;
}
private class EntryIterator : IEnumerator<KeyValuePair<int, T>>
{
private int current;
public override bool HasNext()
{
return this.current < this._enclosing.Size();
}
public override KeyValuePair<int, T> Next()
{
if (this.current >= this._enclosing.Size())
{
throw new NoSuchElementException();
}
this.current++;
return new _KeyValuePair_166(this);
}
private sealed class _KeyValuePair_166 : KeyValuePair<int, T>
{
public _KeyValuePair_166()
{
this.key = this._enclosing._enclosing._enclosing.key;
this.value = this._enclosing._enclosing._enclosing.value;
}
private readonly int key;
private readonly T value;
public int Key
{
get
{
return this.key;
}
}
public T Value
{
get
{
return this.value;
}
}
public T SetValue(T value)
{
throw new NotSupportedException("Not supported yet.");
}
}
public override void Remove()
{
throw new NotSupportedException("Not supported yet.");
}
internal EntryIterator(SingletonEdgeMap<T> _enclosing)
{
this._enclosing = _enclosing;
}
private readonly SingletonEdgeMap<T> _enclosing;
}
}
}

View File

@ -0,0 +1,293 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime.Dfa
{
/// <author>Sam Harwell</author>
public class SparseEdgeMap<T> : AbstractEdgeMap<T>
{
private const int DefaultMaxSize = 5;
private readonly int[] keys;
private readonly IList<T> values;
public SparseEdgeMap(int minIndex, int maxIndex) : this(minIndex, maxIndex, DefaultMaxSize
)
{
}
public SparseEdgeMap(int minIndex, int maxIndex, int maxSparseSize) : base(minIndex
, maxIndex)
{
this.keys = new int[maxSparseSize];
this.values = new List<T>(maxSparseSize);
}
private SparseEdgeMap(Antlr4.Runtime.Dfa.SparseEdgeMap<T> map, int maxSparseSize)
: base(map.minIndex, map.maxIndex)
{
if (maxSparseSize < map.values.Count)
{
throw new ArgumentException();
}
keys = Arrays.CopyOf(map.keys, maxSparseSize);
values = new List<T>(maxSparseSize);
Sharpen.Collections.AddAll(values, map.values);
}
public virtual int[] GetKeys()
{
return keys;
}
public virtual IList<T> GetValues()
{
return values;
}
public virtual int GetMaxSparseSize()
{
return keys.Length;
}
public override int Size()
{
return values.Count;
}
public override bool IsEmpty()
{
return values.IsEmpty();
}
public override bool ContainsKey(int key)
{
return Get(key) != null;
}
public override T Get(int key)
{
int index = System.Array.BinarySearch(keys, 0, Size(), key);
if (index < 0)
{
return null;
}
return values[index];
}
public override AbstractEdgeMap<T> Put(int key, T value)
{
if (key < minIndex || key > maxIndex)
{
return this;
}
if (value == null)
{
return ((Antlr4.Runtime.Dfa.SparseEdgeMap<T>)Remove(key));
}
lock (values)
{
int index = System.Array.BinarySearch(keys, 0, Size(), key);
if (index >= 0)
{
// replace existing entry
values.Set(index, value);
return this;
}
System.Diagnostics.Debug.Assert(index < 0 && value != null);
int insertIndex = -index - 1;
if (Size() < GetMaxSparseSize() && insertIndex == Size())
{
// stay sparse and add new entry
keys[insertIndex] = key;
values.AddItem(value);
return this;
}
int desiredSize = Size() >= GetMaxSparseSize() ? GetMaxSparseSize() * 2 : GetMaxSparseSize
();
int space = maxIndex - minIndex + 1;
// SparseEdgeMap only uses less memory than ArrayEdgeMap up to half the size of the symbol space
if (desiredSize >= space / 2)
{
ArrayEdgeMap<T> arrayMap = new ArrayEdgeMap<T>(minIndex, maxIndex);
arrayMap = ((ArrayEdgeMap<T>)arrayMap.PutAll(this));
arrayMap.Put(key, value);
return arrayMap;
}
else
{
Antlr4.Runtime.Dfa.SparseEdgeMap<T> resized = new Antlr4.Runtime.Dfa.SparseEdgeMap
<T>(this, desiredSize);
System.Array.Copy(resized.keys, insertIndex, resized.keys, insertIndex + 1, resized
.keys.Length - insertIndex - 1);
resized.keys[insertIndex] = key;
resized.values.Add(insertIndex, value);
return resized;
}
}
}
public override AbstractEdgeMap<T> Remove(int key)
{
int index = System.Array.BinarySearch(keys, 0, Size(), key);
if (index < 0)
{
return this;
}
if (index == values.Count - 1)
{
values.Remove(index);
return this;
}
Antlr4.Runtime.Dfa.SparseEdgeMap<T> result = new Antlr4.Runtime.Dfa.SparseEdgeMap
<T>(this, GetMaxSparseSize());
System.Array.Copy(result.keys, index + 1, result.keys, index, Size() - index - 1);
result.values.Remove(index);
return result;
}
public override AbstractEdgeMap<T> Clear()
{
if (IsEmpty())
{
return this;
}
Antlr4.Runtime.Dfa.SparseEdgeMap<T> result = new Antlr4.Runtime.Dfa.SparseEdgeMap
<T>(this, GetMaxSparseSize());
result.values.Clear();
return result;
}
public override IDictionary<int, T> ToMap()
{
if (IsEmpty())
{
return Sharpen.Collections.EmptyMap();
}
IDictionary<int, T> result = new LinkedHashMap<int, T>();
for (int i = 0; i < Size(); i++)
{
result.Put(keys[i], values[i]);
}
return result;
}
public override ICollection<KeyValuePair<int, T>> EntrySet()
{
return new SparseEdgeMap.EntrySet(this);
}
private class EntrySet : AbstractEdgeMap.AbstractEntrySet
{
public override IEnumerator<KeyValuePair<int, T>> GetEnumerator()
{
return new SparseEdgeMap.EntryIterator(this);
}
internal EntrySet(SparseEdgeMap<T> _enclosing) : base(_enclosing)
{
this._enclosing = _enclosing;
}
private readonly SparseEdgeMap<T> _enclosing;
}
private class EntryIterator : IEnumerator<KeyValuePair<int, T>>
{
private int current;
public override bool HasNext()
{
return this.current < this._enclosing.Size();
}
public override KeyValuePair<int, T> Next()
{
if (this.current >= this._enclosing.Size())
{
throw new NoSuchElementException();
}
this.current++;
return new _KeyValuePair_226(this);
}
private sealed class _KeyValuePair_226 : KeyValuePair<int, T>
{
public _KeyValuePair_226()
{
this.key = this._enclosing._enclosing.keys[this._enclosing.current - 1];
this.value = this._enclosing._enclosing.values[this._enclosing.current - 1];
}
private readonly int key;
private readonly T value;
public int Key
{
get
{
return this.key;
}
}
public T Value
{
get
{
return this.value;
}
}
public T SetValue(T value)
{
throw new NotSupportedException("Not supported yet.");
}
}
public override void Remove()
{
throw new NotSupportedException("Not supported yet.");
}
internal EntryIterator(SparseEdgeMap<T> _enclosing)
{
this._enclosing = _enclosing;
}
private readonly SparseEdgeMap<T> _enclosing;
}
}
}

View File

@ -0,0 +1,73 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
public class DiagnosticErrorListener : BaseErrorListener
{
public override void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex,
int stopIndex, BitSet ambigAlts, ATNConfigSet configs)
{
string format = "reportAmbiguity d=%s: ambigAlts=%s, input='%s'";
recognizer.NotifyErrorListeners(string.Format(format, GetDecisionDescription(recognizer
, dfa.decision), ambigAlts, ((ITokenStream)recognizer.GetInputStream()).GetText
(Interval.Of(startIndex, stopIndex))));
}
public override void ReportAttemptingFullContext(Parser recognizer, DFA dfa, int
startIndex, int stopIndex, SimulatorState initialState)
{
string format = "reportAttemptingFullContext d=%s, input='%s'";
recognizer.NotifyErrorListeners(string.Format(format, GetDecisionDescription(recognizer
, dfa.decision), ((ITokenStream)recognizer.GetInputStream()).GetText(Interval
.Of(startIndex, stopIndex))));
}
public override void ReportContextSensitivity(Parser recognizer, DFA dfa, int startIndex
, int stopIndex, SimulatorState acceptState)
{
string format = "reportContextSensitivity d=%s, input='%s'";
recognizer.NotifyErrorListeners(string.Format(format, GetDecisionDescription(recognizer
, dfa.decision), ((ITokenStream)recognizer.GetInputStream()).GetText(Interval
.Of(startIndex, stopIndex))));
}
protected internal virtual string GetDecisionDescription(Parser recognizer, int decision
)
{
return Sharpen.Extensions.ToString(decision);
}
}
}

View File

@ -0,0 +1,110 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>A semantic predicate failed during validation.</summary>
/// <remarks>
/// A semantic predicate failed during validation. Validation of predicates
/// occurs when normally parsing the alternative just like matching a token.
/// Disambiguating predicate evaluation occurs when we test a predicate during
/// prediction.
/// </remarks>
[System.Serializable]
public class FailedPredicateException : RecognitionException
{
private const long serialVersionUID = 5379330841495778709L;
private readonly int ruleIndex;
private readonly int predicateIndex;
private readonly string predicate;
public FailedPredicateException(Parser recognizer) : this(recognizer, null)
{
}
public FailedPredicateException(Parser recognizer, string predicate) : this(recognizer
, predicate, null)
{
}
public FailedPredicateException(Parser recognizer, string predicate, string message
) : base(FormatMessage(predicate, message), recognizer, ((ITokenStream)recognizer
.GetInputStream()), recognizer._ctx)
{
ATNState s = recognizer.GetInterpreter().atn.states[recognizer.GetState()];
AbstractPredicateTransition trans = (AbstractPredicateTransition)s.Transition(0);
if (trans is PredicateTransition)
{
this.ruleIndex = ((PredicateTransition)trans).ruleIndex;
this.predicateIndex = ((PredicateTransition)trans).predIndex;
}
else
{
this.ruleIndex = 0;
this.predicateIndex = 0;
}
this.predicate = predicate;
this.SetOffendingToken(recognizer.GetCurrentToken());
}
public virtual int GetRuleIndex()
{
return ruleIndex;
}
public virtual int GetPredIndex()
{
return predicateIndex;
}
[Nullable]
public virtual string GetPredicate()
{
return predicate;
}
[NotNull]
private static string FormatMessage(string predicate, string message)
{
if (message != null)
{
return message;
}
return string.Format("failed predicate: {%s}?", predicate);
}
}
}

View File

@ -0,0 +1,78 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>How to emit recognition errors</summary>
public interface IAntlrErrorListener<Symbol>
{
/// <summary>Upon syntax error, notify any interested parties.</summary>
/// <remarks>
/// Upon syntax error, notify any interested parties. This is not
/// how to recover from errors or compute error messages. The
/// parser ANTLRErrorStrategy specifies how to recover from syntax
/// errors and how to compute error messages. This listener's job
/// is simply to emit a computed message, though it has enough
/// information to create its own message in many cases.
/// The RecognitionException is non-null for all syntax errors
/// except when we discover mismatched token errors that we can
/// recover from in-line, without returning from the surrounding
/// rule (via the single token insertion and deletion mechanism).
/// </remarks>
/// <param name="recognizer">
/// What parser got the error. From this
/// object, you can access the context as well
/// as the input stream.
/// </param>
/// <param name="offendingSymbol">
/// The offending token in the input token
/// stream, unless recognizer is a lexer (then it's null) If
/// no viable alternative error, e has token at which we
/// started production for the decision.
/// </param>
/// <param name="line">
/// At what line in input to the error occur? This always refers to
/// stopTokenIndex
/// </param>
/// <param name="charPositionInLine">At what character position within that line did the error occur.
/// </param>
/// <param name="msg">The message to emit</param>
/// <param name="e">
/// The exception generated by the parser that led to
/// the reporting of an error. It is null in the case where
/// the parser was able to recover in line without exiting the
/// surrounding rule.
/// </param>
void SyntaxError<T>(Recognizer<T, object> recognizer, T offendingSymbol, int line
, int charPositionInLine, string msg, RecognitionException e) where T:Symbol;
}
}

View File

@ -0,0 +1,157 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// The interface for defining strategies to deal with syntax errors
/// encountered during a parse by ANTLR-generated parsers and tree parsers.
/// </summary>
/// <remarks>
/// The interface for defining strategies to deal with syntax errors
/// encountered during a parse by ANTLR-generated parsers and tree parsers.
/// We distinguish between three different kinds of errors:
/// o The parser could not figure out which path to take in the ATN
/// (none of the available alternatives could possibly match)
/// o The current input does not match what we were looking for.
/// o A predicate evaluated to false.
/// The default implementation of this interface reports errors to any
/// error listeners of the parser. It also handles single token insertion
/// and deletion for mismatched elements.
/// We pass in the parser to each function so that the same strategy
/// can be shared between multiple parsers running at the same time.
/// This is just for flexibility, not that we need it for the default system.
/// TODO: To bail out upon first error, simply rethrow e?
/// TODO: what to do about lexers
/// </remarks>
public interface IAntlrErrorStrategy
{
/// <summary>
/// When matching elements within alternative, use this method
/// to recover.
/// </summary>
/// <remarks>
/// When matching elements within alternative, use this method
/// to recover. The default implementation uses single token
/// insertion and deletion. If you want to change the way ANTLR
/// response to mismatched element errors within an alternative,
/// implement this method.
/// From the recognizer, we can get the input stream to get
/// the current input symbol and we can get the current context.
/// That context gives us the current state within the ATN.
/// From that state, we can look at its transition to figure out
/// what was expected.
/// Because we can recover from a single token deletions by
/// "inserting" tokens, we need to specify what that implicitly created
/// token is. We use object, because it could be a tree node.
/// </remarks>
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
IToken RecoverInline(Parser recognizer);
/// <summary>
/// Resynchronize the parser by consuming tokens until we find one
/// in the resynchronization set--loosely the set of tokens that can follow
/// the current rule.
/// </summary>
/// <remarks>
/// Resynchronize the parser by consuming tokens until we find one
/// in the resynchronization set--loosely the set of tokens that can follow
/// the current rule. The exception contains info you might want to
/// use to recover better.
/// </remarks>
void Recover(Parser recognizer, RecognitionException e);
/// <summary>
/// Make sure that the current lookahead symbol is consistent with
/// what were expecting at this point in the ATN.
/// </summary>
/// <remarks>
/// Make sure that the current lookahead symbol is consistent with
/// what were expecting at this point in the ATN. You can call this
/// anytime but ANTLR only generates code to check before subrules/loops
/// and each iteration.
/// Implements Jim Idle's magic sync mechanism in closures and optional
/// subrules. E.g.,
/// a : sync ( stuff sync )* ;
/// sync : {consume to what can follow sync} ;
/// Previous versions of ANTLR did a poor job of their recovery within
/// loops. A single mismatch token or missing token would force the parser
/// to bail out of the entire rules surrounding the loop. So, for rule
/// classDef : 'class' ID '{' member* '}'
/// input with an extra token between members would force the parser to
/// consume until it found the next class definition rather than the
/// next member definition of the current class.
/// This functionality cost a little bit of effort because the parser
/// has to compare token set at the start of the loop and at each
/// iteration. If for some reason speed is suffering for you, you can
/// turn off this functionality by simply overriding this method as
/// a blank { }.
/// </remarks>
void Sync(Parser recognizer);
/// <summary>Notify handler that parser has entered an error state.</summary>
/// <remarks>
/// Notify handler that parser has entered an error state. The
/// parser currently doesn't call this--the handler itself calls this
/// in report error methods. But, for symmetry with endErrorCondition,
/// this method is in the interface.
/// </remarks>
void BeginErrorCondition(Parser recognizer);
/// <summary>
/// Is the parser in the process of recovering from an error? Upon
/// a syntax error, the parser enters recovery mode and stays there until
/// the next successful match of a token.
/// </summary>
/// <remarks>
/// Is the parser in the process of recovering from an error? Upon
/// a syntax error, the parser enters recovery mode and stays there until
/// the next successful match of a token. In this way, we can
/// avoid sending out spurious error messages. We only want one error
/// message per syntax error
/// </remarks>
bool InErrorRecoveryMode(Parser recognizer);
/// <summary>Reset the error handler.</summary>
/// <remarks>
/// Reset the error handler. Call this when the parser
/// matches a valid token (indicating no longer in recovery mode)
/// and from its own reset method.
/// </remarks>
void EndErrorCondition(Parser recognizer);
/// <summary>Report any kind of RecognitionException.</summary>
/// <remarks>Report any kind of RecognitionException.</remarks>
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
void ReportError(Parser recognizer, RecognitionException e);
}
}

View File

@ -0,0 +1,112 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>A source of characters for an ANTLR lexer.</summary>
/// <remarks>A source of characters for an ANTLR lexer.</remarks>
public abstract class ICharStream : IIntStream
{
/// <summary>
/// The minimum allowed value for a character in a
/// <code>CharStream</code>
/// .
/// </summary>
public const int MinChar = char.MinValue;
/// <summary>
/// The maximum allowed value for a character in a
/// <code>CharStream</code>
/// .
/// <p/>
/// This value is
/// <code>Character.MAX_VALUE - 1</code>
/// , which reserves the value
/// <code>Character.MAX_VALUE</code>
/// for special use within an implementing class.
/// For some implementations, the data buffers required for supporting the
/// marked ranges of
/// <see cref="IIntStream">IIntStream</see>
/// are stored as
/// <code>char[]</code>
/// instead
/// of
/// <code>int[]</code>
/// , with
/// <code>Character.MAX_VALUE</code>
/// being used instead of
/// <code>-1</code>
/// to mark the end of the stream internally.
/// </summary>
public const int MaxChar = char.MaxValue - 1;
/// <summary>
/// This method returns the text for a range of characters within this input
/// stream.
/// </summary>
/// <remarks>
/// This method returns the text for a range of characters within this input
/// stream. This method is guaranteed to not throw an exception if the
/// specified
/// <code>interval</code>
/// lies entirely within a marked range. For more
/// information about marked ranges, see
/// <see cref="IIntStream.Mark()">IIntStream.Mark()</see>
/// .
/// </remarks>
/// <param name="interval">an interval within the stream</param>
/// <returns>the text of the specified interval</returns>
/// <exception cref="System.ArgumentNullException">
/// if
/// <code>interval</code>
/// is
/// <code>null</code>
/// </exception>
/// <exception cref="System.ArgumentException">
/// if
/// <code>interval.a &lt; 0</code>
/// , or if
/// <code>interval.b &lt; interval.a - 1</code>
/// , or if
/// <code>interval.b</code>
/// lies at or
/// past the end of the stream
/// </exception>
/// <exception cref="System.NotSupportedException">
/// if the stream does not support
/// getting the text of the specified interval
/// </exception>
[NotNull]
public abstract string GetText(Interval interval);
}
}

View File

@ -0,0 +1,369 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>A simple stream of symbols whose values are represented as integers.</summary>
/// <remarks>
/// A simple stream of symbols whose values are represented as integers. This
/// interface provides <em>marked ranges</em> with support for a minimum level
/// of buffering necessary to implement arbitrary lookahead during prediction.
/// For more information on marked ranges, see
/// <see cref="Mark()">Mark()</see>
/// .
/// <p/>
/// <strong>Initializing Methods:</strong> Some methods in this interface have
/// unspecified behavior if no call to an initializing method has occurred after
/// the stream was constructed. The following is a list of initializing methods:
/// <ul>
/// <li>
/// <see cref="La(int)">La(int)</see>
/// </li>
/// <li>
/// <see cref="Consume()">Consume()</see>
/// </li>
/// <li>
/// <see cref="Size()">Size()</see>
/// </li>
/// </ul>
/// </remarks>
public abstract class IIntStream
{
/// <summary>
/// The value returned by
/// <see cref="La(int)">LA()</see>
/// when the end of the stream is
/// reached.
/// </summary>
public const int Eof = -1;
/// <summary>
/// The value returned by
/// <see cref="SourceName()">SourceName()</see>
/// when the actual name of the
/// underlying source is not known.
/// </summary>
public const string UnknownSourceName = "<unknown>";
/// <summary>Consumes the current symbol in the stream.</summary>
/// <remarks>
/// Consumes the current symbol in the stream. This method has the following
/// effects:
/// <ul>
/// <li><strong>Forward movement:</strong> The value of
/// <see cref="Index()">index()</see>
/// before calling this method is less than the value of
/// <code>index()</code>
/// after calling this method.</li>
/// <li><strong>Ordered lookahead:</strong> The value of
/// <code>LA(1)</code>
/// before
/// calling this method becomes the value of
/// <code>LA(-1)</code>
/// after calling
/// this method.</li>
/// </ul>
/// Note that calling this method does not guarantee that
/// <code>index()</code>
/// is
/// incremented by exactly 1, as that would preclude the ability to implement
/// filtering streams (e.g.
/// <see cref="CommonTokenStream">CommonTokenStream</see>
/// which distinguishes
/// between "on-channel" and "off-channel" tokens).
/// </remarks>
/// <exception cref="System.InvalidOperationException">
/// if an attempt is made to consume the the
/// end of the stream (i.e. if
/// <code>LA(1)==</code>
/// <see cref="Eof">EOF</see>
/// before calling
/// <code>consume</code>
/// ).
/// </exception>
public abstract void Consume();
/// <summary>
/// Gets the value of the symbol at offset
/// <code>i</code>
/// from the current
/// position. When
/// <code>i==1</code>
/// , this method returns the value of the current
/// symbol in the stream (which is the next symbol to be consumed). When
/// <code>i==-1</code>
/// , this method returns the value of the previously read
/// symbol in the stream. It is not valid to call this method with
/// <code>i==0</code>
/// , but the specific behavior is unspecified because this
/// method is frequently called from performance-critical code.
/// <p/>
/// This method is guaranteed to succeed if any of the following are true:
/// <ul>
/// <li>
/// <code>i&gt;0</code>
/// </li>
/// <li>
/// <code>i==-1</code>
/// and
/// <see cref="Index()">index()</see>
/// returns a value greater
/// than the value of
/// <code>index()</code>
/// after the stream was constructed
/// and
/// <code>LA(1)</code>
/// was called in that order. Specifying the current
/// <code>index()</code>
/// relative to the index after the stream was created
/// allows for filtering implementations that do not return every symbol
/// from the underlying source. Specifying the call to
/// <code>LA(1)</code>
/// allows for lazily initialized streams.</li>
/// <li>
/// <code>LA(i)</code>
/// refers to a symbol consumed within a marked region
/// that has not yet been released.</li>
/// </ul>
/// If
/// <code>i</code>
/// represents a position at or beyond the end of the stream,
/// this method returns
/// <see cref="Eof">Eof</see>
/// .
/// <p/>
/// The return value is unspecified if
/// <code>i&lt;0</code>
/// and fewer than
/// <code>-i</code>
/// calls to
/// <see cref="Consume()">consume()</see>
/// have occurred from the beginning of
/// the stream before calling this method.
/// </summary>
/// <exception cref="System.NotSupportedException">
/// if the stream does not support
/// retrieving the value of the specified symbol
/// </exception>
public abstract int La(int i);
/// <summary>
/// A mark provides a guarantee that
/// <see cref="Seek(int)">seek()</see>
/// operations will be
/// valid over a "marked range" extending from the index where
/// <code>mark()</code>
/// was called to the current
/// <see cref="Index()">index()</see>
/// . This allows the use of
/// streaming input sources by specifying the minimum buffering requirements
/// to support arbitrary lookahead during prediction.
/// <p/>
/// The returned mark is an opaque handle (type
/// <code>int</code>
/// ) which is passed
/// to
/// <see cref="Release(int)">release()</see>
/// when the guarantees provided by the marked
/// range are no longer necessary. When calls to
/// <code>mark()</code>
/// /
/// <code>release()</code>
/// are nested, the marks must be released
/// in reverse order of which they were obtained. Since marked regions are
/// used during performance-critical sections of prediction, the specific
/// behavior of invalid usage is unspecified (i.e. a mark is not released, or
/// a mark is released twice, or marks are not released in reverse order from
/// which they were created).
/// <p/>
/// The behavior of this method is unspecified if no call to an
/// <see cref="IIntStream">initializing method</see>
/// has occurred after this stream was
/// constructed.
/// <p/>
/// This method does not change the current position in the input stream.
/// <p/>
/// The following example shows the use of
/// <see cref="Mark()">mark()</see>
/// ,
/// <see cref="Release(int)">release(mark)</see>
/// ,
/// <see cref="Index()">index()</see>
/// , and
/// <see cref="Seek(int)">seek(index)</see>
/// as part of an operation to safely work within a
/// marked region, then restore the stream position to its original value and
/// release the mark.
/// <pre>
/// IntStream stream = ...;
/// int index = -1;
/// int mark = stream.mark();
/// try {
/// index = stream.index();
/// // perform work here...
/// } finally {
/// if (index != -1) {
/// stream.seek(index);
/// }
/// stream.release(mark);
/// }
/// </pre>
/// </summary>
/// <returns>
/// An opaque marker which should be passed to
/// <see cref="Release(int)">release()</see>
/// when the marked range is no longer required.
/// </returns>
public abstract int Mark();
/// <summary>
/// This method releases a marked range created by a call to
/// <see cref="Mark()">mark()</see>
/// . Calls to
/// <code>release()</code>
/// must appear in the
/// reverse order of the corresponding calls to
/// <code>mark()</code>
/// . If a mark is
/// released twice, or if marks are not released in reverse order of the
/// corresponding calls to
/// <code>mark()</code>
/// , the behavior is unspecified.
/// <p/>
/// For more information and an example, see
/// <see cref="Mark()">Mark()</see>
/// .
/// </summary>
/// <param name="marker">
/// A marker returned by a call to
/// <code>mark()</code>
/// .
/// </param>
/// <seealso cref="Mark()">Mark()</seealso>
public abstract void Release(int marker);
/// <summary>
/// Return the index into the stream of the input symbol referred to by
/// <code>LA(1)</code>
/// .
/// <p/>
/// The behavior of this method is unspecified if no call to an
/// <see cref="IIntStream">initializing method</see>
/// has occurred after this stream was
/// constructed.
/// </summary>
internal abstract int Index
{
get;
}
/// <summary>
/// Set the input cursor to the position indicated by
/// <code>index</code>
/// . If the
/// specified index lies past the end of the stream, the operation behaves as
/// though
/// <code>index</code>
/// was the index of the EOF symbol. After this method
/// returns without throwing an exception, the at least one of the following
/// will be true.
/// <ul>
/// <li>
/// <see cref="Index()">index()</see>
/// will return the index of the first symbol
/// appearing at or after the specified
/// <code>index</code>
/// . Specifically,
/// implementations which filter their sources should automatically
/// adjust
/// <code>index</code>
/// forward the minimum amount required for the
/// operation to target a non-ignored symbol.</li>
/// <li>
/// <code>LA(1)</code>
/// returns
/// <see cref="Eof">Eof</see>
/// </li>
/// </ul>
/// This operation is guaranteed to not throw an exception if
/// <code>index</code>
/// lies within a marked region. For more information on marked regions, see
/// <see cref="Mark()">Mark()</see>
/// . The behavior of this method is unspecified if no call to
/// an
/// <see cref="IIntStream">initializing method</see>
/// has occurred after this stream
/// was constructed.
/// </summary>
/// <param name="index">The absolute index to seek to.</param>
/// <exception cref="System.ArgumentException">
/// if
/// <code>index</code>
/// is less than 0
/// </exception>
/// <exception cref="System.NotSupportedException">
/// if the stream does not support
/// seeking to the specified index
/// </exception>
public abstract void Seek(int index);
/// <summary>
/// Returns the total number of symbols in the stream, including a single EOF
/// symbol.
/// </summary>
/// <remarks>
/// Returns the total number of symbols in the stream, including a single EOF
/// symbol.
/// </remarks>
/// <exception cref="System.NotSupportedException">
/// if the size of the stream is
/// unknown.
/// </exception>
internal abstract int Size
{
get;
}
/// <summary>Gets the name of the underlying symbol source.</summary>
/// <remarks>
/// Gets the name of the underlying symbol source. This method returns a
/// non-null, non-empty string. If such a name is not known, this method
/// returns
/// <see cref="UnknownSourceName">UnknownSourceName</see>
/// .
/// </remarks>
public abstract string SourceName
{
get;
}
}
}

View File

@ -0,0 +1,71 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>How to emit recognition errors</summary>
public interface IParserErrorListener : IAntlrErrorListener<IToken>
{
/// <summary>
/// Called when the parser detects a true ambiguity: an input sequence can be matched
/// literally by two or more pass through the grammar.
/// </summary>
/// <remarks>
/// Called when the parser detects a true ambiguity: an input sequence can be matched
/// literally by two or more pass through the grammar. ANTLR resolves the ambiguity in
/// favor of the alternative appearing first in the grammar. The start and stop index are
/// zero-based absolute indices into the token stream. ambigAlts is a set of alternative numbers
/// that can match the input sequence. This method is only called when we are parsing with
/// full context.
/// </remarks>
void ReportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet
ambigAlts, ATNConfigSet configs);
void ReportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int
stopIndex, SimulatorState initialState);
/// <summary>
/// Called by the parser when it find a conflict that is resolved by retrying the parse
/// with full context.
/// </summary>
/// <remarks>
/// Called by the parser when it find a conflict that is resolved by retrying the parse
/// with full context. This is not a warning; it simply notifies you that your grammar
/// is more complicated than Strong LL can handle. The parser moved up to full context
/// parsing for that input sequence.
/// </remarks>
void ReportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex
, SimulatorState acceptState);
}
}

183
Antlr4.Runtime/IToken.cs Normal file
View File

@ -0,0 +1,183 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// A token has properties: text, type, line, character position in the line
/// (so we can ignore tabs), token channel, index, and source from which
/// we obtained this token.
/// </summary>
/// <remarks>
/// A token has properties: text, type, line, character position in the line
/// (so we can ignore tabs), token channel, index, and source from which
/// we obtained this token.
/// </remarks>
public abstract class IToken
{
public const int InvalidType = 0;
/// <summary>
/// During lookahead operations, this "token" signifies we hit rule end ATN state
/// and did not follow it despite needing to.
/// </summary>
/// <remarks>
/// 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 MinUserTokenType = 1;
public const int Eof = IIntStream.Eof;
/// <summary>
/// All tokens go to the parser (unless skip() is called in that rule)
/// on a particular "channel".
/// </summary>
/// <remarks>
/// All tokens go to the parser (unless skip() is called in that rule)
/// on a particular "channel". The parser tunes to a particular channel
/// so that whitespace etc... can go to the parser on a "hidden" channel.
/// </remarks>
public const int DefaultChannel = 0;
/// <summary>
/// Anything on different channel than DEFAULT_CHANNEL is not parsed
/// by parser.
/// </summary>
/// <remarks>
/// Anything on different channel than DEFAULT_CHANNEL is not parsed
/// by parser.
/// </remarks>
public const int HiddenChannel = 1;
/// <summary>Get the text of the token.</summary>
/// <remarks>Get the text of the token.</remarks>
internal abstract string Text
{
get;
}
/// <summary>Get the token type of the token.</summary>
/// <remarks>Get the token type of the token.</remarks>
internal abstract int Type
{
get;
}
/// <summary>
/// The line number on which the 1st character of this token was matched,
/// line=1..n
/// </summary>
internal abstract int Line
{
get;
}
/// <summary>
/// The index of the first character of this token relative to the
/// beginning of the line at which it occurs, 0..n-1
/// </summary>
internal abstract int Column
{
get;
}
/// <summary>Return the channel this token.</summary>
/// <remarks>
/// Return the channel this token. Each token can arrive at the parser
/// on a different channel, but the parser only "tunes" to a single channel.
/// The parser ignores everything not on DEFAULT_CHANNEL.
/// </remarks>
internal abstract int Channel
{
get;
}
/// <summary>An index from 0..n-1 of the token object in the input stream.</summary>
/// <remarks>
/// An index from 0..n-1 of the token object in the input stream.
/// This must be valid in order to print token streams and
/// use TokenRewriteStream.
/// Return -1 to indicate that this token was conjured up since
/// it doesn't have a valid index.
/// </remarks>
internal abstract int TokenIndex
{
get;
}
/// <summary>
/// The starting character index of the token
/// This method is optional; return -1 if not implemented.
/// </summary>
/// <remarks>
/// The starting character index of the token
/// This method is optional; return -1 if not implemented.
/// </remarks>
internal abstract int StartIndex
{
get;
}
/// <summary>The last character index of the token.</summary>
/// <remarks>
/// The last character index of the token.
/// This method is optional; return -1 if not implemented.
/// </remarks>
internal abstract int StopIndex
{
get;
}
/// <summary>
/// Gets the
/// <see cref="ITokenSource">ITokenSource</see>
/// which created this token.
/// </summary>
internal abstract ITokenSource TokenSource
{
get;
}
/// <summary>
/// Gets the
/// <see cref="ICharStream">ICharStream</see>
/// from which this token was derived.
/// </summary>
internal abstract ICharStream InputStream
{
get;
}
}
}

View File

@ -0,0 +1,59 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>The default mechanism for creating tokens.</summary>
/// <remarks>
/// The default mechanism for creating tokens. It's used by default in Lexer and
/// the error handling strategy (to create missing tokens). Notifying the parser
/// of a new factory means that it notifies it's token source and error strategy.
/// </remarks>
public interface ITokenFactory
{
/// <summary>
/// This is the method used to create tokens in the lexer and in the
/// error handling strategy.
/// </summary>
/// <remarks>
/// This is the method used to create tokens in the lexer and in the
/// error handling strategy. If text!=null, than the start and stop positions
/// are wiped to -1 in the text override is set in the CommonToken.
/// </remarks>
IToken Create<_T0>(Tuple<_T0> source, int type, string text, int channel, int start
, int stop, int line, int charPositionInLine) where _T0:ITokenSource;
/// <summary>Generically useful</summary>
IToken Create(int type, string text);
}
}

View File

@ -0,0 +1,110 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// A source of tokens must provide a sequence of tokens via nextToken()
/// and also must reveal it's source of characters; CommonToken's text is
/// computed from a CharStream; it only store indices into the char stream.
/// </summary>
/// <remarks>
/// A source of tokens must provide a sequence of tokens via nextToken()
/// and also must reveal it's source of characters; CommonToken's text is
/// computed from a CharStream; it only store indices into the char stream.
/// Errors from the lexer are never passed to the parser. Either you want
/// to keep going or you do not upon token recognition error. If you do not
/// want to continue lexing then you do not want to continue parsing. Just
/// throw an exception not under RecognitionException and Java will naturally
/// toss you all the way out of the recognizers. If you want to continue
/// lexing then you should not throw an exception to the parser--it has already
/// requested a token. Keep lexing until you get a valid one. Just report
/// errors and keep going, looking for a valid token.
/// </remarks>
public interface ITokenSource
{
/// <summary>Return a Token object from your input stream (usually a CharStream).</summary>
/// <remarks>
/// Return a Token object from your input stream (usually a CharStream).
/// Do not fail/return upon lexing error; keep chewing on the characters
/// until you get a good one; errors are not passed through to the parser.
/// </remarks>
IToken NextToken();
int Line
{
get;
}
int Column
{
get;
}
/// <summary>
/// From what character stream was this token created? You don't have to
/// implement but it's nice to know where a Token comes from if you have
/// include files etc...
/// </summary>
/// <remarks>
/// From what character stream was this token created? You don't have to
/// implement but it's nice to know where a Token comes from if you have
/// include files etc... on the input.
/// </remarks>
ICharStream InputStream
{
get;
}
/// <summary>
/// Where are you getting tokens from? normally the implication will simply
/// ask lexers input stream.
/// </summary>
/// <remarks>
/// Where are you getting tokens from? normally the implication will simply
/// ask lexers input stream.
/// </remarks>
string SourceName
{
get;
}
/// <summary>Gets the factory used for constructing tokens.</summary>
/// <remarks>Gets the factory used for constructing tokens.</remarks>
/// <summary>Optional method that lets users set factory in lexer or other source</summary>
ITokenFactory TokenFactory
{
get;
set;
}
}
}

View File

@ -0,0 +1,247 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// An
/// <see cref="IIntStream">IIntStream</see>
/// whose symbols are
/// <see cref="IToken">IToken</see>
/// instances.
/// </summary>
public interface ITokenStream : IIntStream
{
/// <summary>
/// Get the
/// <see cref="IToken">IToken</see>
/// instance associated with the value returned by
/// <see cref="IIntStream.La(int)">LA(k)</see>
/// . This method has the same pre- and post-conditions as
/// <see cref="IIntStream.La(int)">IIntStream.La(int)</see>
/// . In addition, when the preconditions of this method
/// are met, the return value is non-null and the value of
/// <code>LT(k).getType()==LA(k)</code>
/// .
/// </summary>
/// <seealso cref="IIntStream.La(int)">IIntStream.La(int)</seealso>
[NotNull]
IToken Lt(int k);
/// <summary>
/// Gets the
/// <see cref="IToken">IToken</see>
/// at the specified
/// <code>index</code>
/// in the stream. When
/// the preconditions of this method are met, the return value is non-null.
/// <p/>
/// The preconditions for this method are the same as the preconditions of
/// <see cref="IIntStream.Seek(int)">IIntStream.Seek(int)</see>
/// . If the behavior of
/// <code>seek(index)</code>
/// is
/// unspecified for the current state and given
/// <code>index</code>
/// , then the
/// behavior of this method is also unspecified.
/// <p/>
/// The symbol referred to by
/// <code>index</code>
/// differs from
/// <code>seek()</code>
/// only
/// in the case of filtering streams where
/// <code>index</code>
/// lies before the end
/// of the stream. Unlike
/// <code>seek()</code>
/// , this method does not adjust
/// <code>index</code>
/// to point to a non-ignored symbol.
/// </summary>
/// <exception cref="System.ArgumentException">if {code index} is less than 0</exception>
/// <exception cref="System.NotSupportedException">
/// if the stream does not support
/// retrieving the token at the specified index
/// </exception>
[NotNull]
IToken Get(int i);
/// <summary>
/// Gets the underlying
/// <see cref="ITokenSource">ITokenSource</see>
/// which provides tokens for this
/// stream.
/// </summary>
ITokenSource TokenSource
{
get;
}
/// <summary>
/// Return the text of all tokens within the specified
/// <code>interval</code>
/// . This
/// method behaves like the following code (including potential exceptions
/// for violating preconditions of
/// <see cref="Get(int)">Get(int)</see>
/// , but may be optimized by the
/// specific implementation.
/// <pre>
/// TokenStream stream = ...;
/// String text = "";
/// for (int i = interval.a; i &lt;= interval.b; i++) {
/// text += stream.get(i).getText();
/// }
/// </pre>
/// </summary>
/// <param name="interval">
/// The interval of tokens within this stream to get text
/// for.
/// </param>
/// <returns>
/// The text of all tokens within the specified interval in this
/// stream.
/// </returns>
/// <exception cref="System.ArgumentNullException">
/// if
/// <code>interval</code>
/// is
/// <code>null</code>
/// </exception>
[NotNull]
string GetText(Interval interval);
/// <summary>Return the text of all tokens in the stream.</summary>
/// <remarks>
/// Return the text of all tokens in the stream. This method behaves like the
/// following code, including potential exceptions from the calls to
/// <see cref="IIntStream.Size()">IIntStream.Size()</see>
/// and
/// <see cref="GetText(Antlr4.Runtime.Misc.Interval)">GetText(Antlr4.Runtime.Misc.Interval)
/// </see>
/// , but may be
/// optimized by the specific implementation.
/// <pre>
/// TokenStream stream = ...;
/// String text = stream.getText(new Interval(0, stream.size()));
/// </pre>
/// </remarks>
/// <returns>The text of all tokens in the stream.</returns>
[NotNull]
string GetText();
/// <summary>
/// Return the text of all tokens in the source interval of the specified
/// context.
/// </summary>
/// <remarks>
/// Return the text of all tokens in the source interval of the specified
/// context. This method behaves like the following code, including potential
/// exceptions from the call to
/// <see cref="GetText(Antlr4.Runtime.Misc.Interval)">GetText(Antlr4.Runtime.Misc.Interval)
/// </see>
/// , but may be
/// optimized by the specific implementation.
/// </p>
/// If
/// <code>ctx.getSourceInterval()</code>
/// does not return a valid interval of
/// tokens provided by this stream, the behavior is unspecified.
/// <pre>
/// TokenStream stream = ...;
/// String text = stream.getText(ctx.getSourceInterval());
/// </pre>
/// </remarks>
/// <param name="ctx">
/// The context providing the source interval of tokens to get
/// text for.
/// </param>
/// <returns>
/// The text of all tokens within the source interval of
/// <code>ctx</code>
/// .
/// </returns>
[NotNull]
string GetText(RuleContext ctx);
/// <summary>
/// Return the text of all tokens in this stream between
/// <code>start</code>
/// and
/// <code>stop</code>
/// (inclusive).
/// <p/>
/// If the specified
/// <code>start</code>
/// or
/// <code>stop</code>
/// token was not provided by
/// this stream, or if the
/// <code>stop</code>
/// occurred before the
/// <code>start</code>
/// token, the behavior is unspecified.
/// <p/>
/// For streams which ensure that the
/// <see cref="IToken.TokenIndex()">IToken.TokenIndex()</see>
/// method is
/// accurate for all of its provided tokens, this method behaves like the
/// following code. Other streams may implement this method in other ways
/// provided the behavior is consistent with this at a high level.
/// <pre>
/// TokenStream stream = ...;
/// String text = "";
/// for (int i = start.getTokenIndex(); i &lt;= stop.getTokenIndex(); i++) {
/// text += stream.get(i).getText();
/// }
/// </pre>
/// </summary>
/// <param name="start">The first token in the interval to get text for.</param>
/// <param name="stop">The last token in the interval to get text for (inclusive).</param>
/// <returns>
/// The text of all tokens lying between the specified
/// <code>start</code>
/// and
/// <code>stop</code>
/// tokens.
/// </returns>
/// <exception cref="System.NotSupportedException">
/// if this stream does not support
/// this method for the specified tokens
/// </exception>
[NotNull]
string GetText(IToken start, IToken stop);
}
}

View File

@ -0,0 +1,67 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
public interface IWritableToken : IToken
{
string Text
{
set;
}
int Type
{
set;
}
int Line
{
set;
}
int Column
{
set;
}
int Channel
{
set;
}
int TokenIndex
{
set;
}
}
}

View File

@ -0,0 +1,54 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// This signifies any kind of mismatched input exceptions such as
/// when the current input does not match the expected token.
/// </summary>
/// <remarks>
/// This signifies any kind of mismatched input exceptions such as
/// when the current input does not match the expected token.
/// </remarks>
[System.Serializable]
public class InputMismatchException : RecognitionException
{
private const long serialVersionUID = 1532568338707443067L;
public InputMismatchException(Parser recognizer) : base(recognizer, ((ITokenStream
)recognizer.GetInputStream()), recognizer._ctx)
{
this.SetOffendingToken(recognizer.GetCurrentToken());
}
}
}

579
Antlr4.Runtime/Lexer.cs Normal file
View File

@ -0,0 +1,579 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>A lexer is recognizer that draws input symbols from a character stream.</summary>
/// <remarks>
/// A lexer is recognizer that draws input symbols from a character stream.
/// lexer grammars result in a subclass of this object. A Lexer object
/// uses simplified match() and error recovery mechanisms in the interest
/// of speed.
/// </remarks>
public abstract class Lexer : Recognizer<int, LexerATNSimulator>, ITokenSource
{
public const int DefaultMode = 0;
public const int More = -2;
public const int Skip = -3;
public const int DefaultTokenChannel = IToken.DefaultChannel;
public const int Hidden = IToken.HiddenChannel;
public const int MinCharValue = '\u0000';
public const int MaxCharValue = '\uFFFE';
public ICharStream _input;
protected internal Tuple<ITokenSource, ICharStream> _tokenFactorySourcePair;
/// <summary>How to create token objects</summary>
protected internal ITokenFactory _factory = CommonTokenFactory.Default;
/// <summary>The goal of all lexer rules/methods is to create a token object.</summary>
/// <remarks>
/// The goal of all lexer rules/methods is to create a token object.
/// This is an instance variable as multiple rules may collaborate to
/// create a single token. nextToken will return this object after
/// matching lexer rule(s). If you subclass to allow multiple token
/// emissions, then set this to the last token to be matched or
/// something nonnull so that the auto token emit mechanism will not
/// emit another token.
/// </remarks>
public IToken _token;
/// <summary>
/// What character index in the stream did the current token start at?
/// Needed, for example, to get the text for current token.
/// </summary>
/// <remarks>
/// What character index in the stream did the current token start at?
/// Needed, for example, to get the text for current token. Set at
/// the start of nextToken.
/// </remarks>
public int _tokenStartCharIndex = -1;
/// <summary>The line on which the first character of the token resides</summary>
public int _tokenStartLine;
/// <summary>The character position of first character within the line</summary>
public int _tokenStartCharPositionInLine;
/// <summary>Once we see EOF on char stream, next token will be EOF.</summary>
/// <remarks>
/// Once we see EOF on char stream, next token will be EOF.
/// If you have DONE : EOF ; then you see DONE EOF.
/// </remarks>
public bool _hitEOF;
/// <summary>The channel number for the current token</summary>
public int _channel;
/// <summary>The token type for the current token</summary>
public int _type;
public readonly IntegerStack _modeStack = new IntegerStack();
public int _mode = Antlr4.Runtime.Lexer.DefaultMode;
/// <summary>
/// You can set the text for the current token to override what is in
/// the input char buffer.
/// </summary>
/// <remarks>
/// You can set the text for the current token to override what is in
/// the input char buffer. Use setText() or can set this instance var.
/// </remarks>
public string _text;
public Lexer(ICharStream input)
{
this._input = input;
this._tokenFactorySourcePair = Tuple.Create(this, input);
}
public virtual void Reset()
{
// wack Lexer state variables
if (_input != null)
{
_input.Seek(0);
}
// rewind the input
_token = null;
_type = IToken.InvalidType;
_channel = IToken.DefaultChannel;
_tokenStartCharIndex = -1;
_tokenStartCharPositionInLine = -1;
_tokenStartLine = -1;
_text = null;
_hitEOF = false;
_mode = Antlr4.Runtime.Lexer.DefaultMode;
_modeStack.Clear();
GetInterpreter().Reset();
}
/// <summary>
/// Return a token from this source; i.e., match a token on the char
/// stream.
/// </summary>
/// <remarks>
/// Return a token from this source; i.e., match a token on the char
/// stream.
/// </remarks>
public virtual IToken NextToken()
{
if (_input == null)
{
throw new InvalidOperationException("nextToken requires a non-null input stream."
);
}
// Mark start location in char stream so unbuffered streams are
// guaranteed at least have text of current token
int tokenStartMarker = _input.Mark();
try
{
while (true)
{
if (_hitEOF)
{
EmitEOF();
return _token;
}
_token = null;
_channel = IToken.DefaultChannel;
_tokenStartCharIndex = _input.Index;
_tokenStartCharPositionInLine = GetInterpreter().GetCharPositionInLine();
_tokenStartLine = GetInterpreter().GetLine();
_text = null;
do
{
_type = IToken.InvalidType;
// System.out.println("nextToken line "+tokenStartLine+" at "+((char)input.LA(1))+
// " in mode "+mode+
// " at index "+input.index());
int ttype;
try
{
ttype = GetInterpreter().Match(_input, _mode);
}
catch (LexerNoViableAltException e)
{
NotifyListeners(e);
// report error
Recover(e);
ttype = Skip;
}
if (_input.La(1) == IIntStream.Eof)
{
_hitEOF = true;
}
if (_type == IToken.InvalidType)
{
_type = ttype;
}
if (_type == Skip)
{
goto outer_continue;
}
}
while (_type == More);
if (_token == null)
{
Emit();
}
return _token;
outer_continue: ;
}
outer_break: ;
}
finally
{
// make sure we release marker after match or
// unbuffered char stream will keep buffering
_input.Release(tokenStartMarker);
}
}
/// <summary>
/// Instruct the lexer to skip creating a token for current lexer rule
/// and look for another token.
/// </summary>
/// <remarks>
/// Instruct the lexer to skip creating a token for current lexer rule
/// and look for another token. nextToken() knows to keep looking when
/// a lexer rule finishes with token set to SKIP_TOKEN. Recall that
/// if token==null at end of any token rule, it creates one for you
/// and emits it.
/// </remarks>
public virtual void Skip()
{
_type = Skip;
}
public virtual void More()
{
_type = More;
}
public virtual void Mode(int m)
{
_mode = m;
}
public virtual void PushMode(int m)
{
_modeStack.Push(_mode);
Mode(m);
}
public virtual int PopMode()
{
if (_modeStack.IsEmpty())
{
throw new EmptyStackException();
}
Mode(_modeStack.Pop());
return _mode;
}
public virtual ITokenFactory TokenFactory
{
get
{
return _factory;
}
set
{
ITokenFactory factory = value;
this._factory = factory;
}
}
/// <summary>Set the char stream and reset the lexer</summary>
public virtual void SetInputStream(ICharStream input)
{
this._input = null;
this._tokenFactorySourcePair = Tuple.Create(this, _input);
Reset();
this._input = input;
this._tokenFactorySourcePair = Tuple.Create(this, _input);
}
public virtual string SourceName
{
get
{
return _input.SourceName;
}
}
public override IIntStream GetInputStream()
{
return _input;
}
/// <summary>
/// By default does not support multiple emits per nextToken invocation
/// for efficiency reasons.
/// </summary>
/// <remarks>
/// By default does not support multiple emits per nextToken invocation
/// for efficiency reasons. Subclass and override this method, nextToken,
/// and getToken (to push tokens into a list and pull from that list
/// rather than a single variable as this implementation does).
/// </remarks>
public virtual void Emit(IToken token)
{
//System.err.println("emit "+token);
this._token = token;
}
/// <summary>
/// The standard method called to automatically emit a token at the
/// outermost lexical rule.
/// </summary>
/// <remarks>
/// The standard method called to automatically emit a token at the
/// outermost lexical rule. The token object should point into the
/// char buffer start..stop. If there is a text override in 'text',
/// use that to set the token's text. Override this method to emit
/// custom Token objects or provide a new factory.
/// </remarks>
public virtual IToken Emit()
{
IToken t = _factory.Create(_tokenFactorySourcePair, _type, _text, _channel, _tokenStartCharIndex
, GetCharIndex() - 1, _tokenStartLine, _tokenStartCharPositionInLine);
Emit(t);
return t;
}
public virtual IToken EmitEOF()
{
int cpos = Column;
// The character position for EOF is one beyond the position of
// the previous token's last character
if (_token != null)
{
int n = _token.StopIndex - _token.StartIndex + 1;
cpos = _token.Column + n;
}
IToken eof = _factory.Create(_tokenFactorySourcePair, IToken.Eof, null, IToken.DefaultChannel
, _input.Index, _input.Index - 1, Line, cpos);
Emit(eof);
return eof;
}
public virtual int Line
{
get
{
return GetInterpreter().GetLine();
}
}
public virtual int Column
{
get
{
return GetInterpreter().GetCharPositionInLine();
}
}
public virtual void SetLine(int line)
{
GetInterpreter().SetLine(line);
}
public virtual void SetCharPositionInLine(int charPositionInLine)
{
GetInterpreter().SetCharPositionInLine(charPositionInLine);
}
/// <summary>What is the index of the current character of lookahead?</summary>
public virtual int GetCharIndex()
{
return _input.Index;
}
/// <summary>
/// Return the text matched so far for the current token or any
/// text override.
/// </summary>
/// <remarks>
/// Return the text matched so far for the current token or any
/// text override.
/// </remarks>
public virtual string GetText()
{
if (_text != null)
{
return _text;
}
return GetInterpreter().GetText(_input);
}
/// <summary>
/// Set the complete text of this token; it wipes any previous
/// changes to the text.
/// </summary>
/// <remarks>
/// Set the complete text of this token; it wipes any previous
/// changes to the text.
/// </remarks>
public virtual void SetText(string text)
{
this._text = text;
}
/// <summary>Override if emitting multiple tokens.</summary>
/// <remarks>Override if emitting multiple tokens.</remarks>
public virtual IToken GetToken()
{
return _token;
}
public virtual void SetToken(IToken _token)
{
this._token = _token;
}
public virtual void SetType(int ttype)
{
_type = ttype;
}
public virtual int GetType()
{
return _type;
}
public virtual void SetChannel(int channel)
{
_channel = channel;
}
public virtual int GetChannel()
{
return _channel;
}
public virtual string[] GetModeNames()
{
return null;
}
/// <summary>
/// Used to print out token names like ID during debugging and
/// error reporting.
/// </summary>
/// <remarks>
/// Used to print out token names like ID during debugging and
/// error reporting. The generated parsers implement a method
/// that overrides this to point to their String[] tokenNames.
/// </remarks>
public override string[] GetTokenNames()
{
return null;
}
/// <summary>Return a list of all Token objects in input char stream.</summary>
/// <remarks>
/// Return a list of all Token objects in input char stream.
/// Forces load of all tokens. Does not include EOF token.
/// </remarks>
public virtual IList<IToken> GetAllTokens()
{
IList<IToken> tokens = new List<IToken>();
IToken t = NextToken();
while (t.Type != IToken.Eof)
{
tokens.AddItem(t);
t = NextToken();
}
return tokens;
}
public virtual void Recover(LexerNoViableAltException e)
{
if (_input.La(1) != IIntStream.Eof)
{
// skip a char and try again
GetInterpreter().Consume(_input);
}
}
public virtual void NotifyListeners(LexerNoViableAltException e)
{
string text = _input.GetText(Interval.Of(_tokenStartCharIndex, _input.Index));
string msg = "token recognition error at: '" + GetErrorDisplay(text) + "'";
IAntlrErrorListener<int> listener = GetErrorListenerDispatch();
listener.SyntaxError(this, null, _tokenStartLine, _tokenStartCharPositionInLine,
msg, e);
}
public virtual string GetErrorDisplay(string s)
{
StringBuilder buf = new StringBuilder();
foreach (char c in s.ToCharArray())
{
buf.Append(GetErrorDisplay(c));
}
return buf.ToString();
}
public virtual string GetErrorDisplay(int c)
{
string s = (char)c.ToString();
switch (c)
{
case IToken.Eof:
{
s = "<EOF>";
break;
}
case '\n':
{
s = "\\n";
break;
}
case '\t':
{
s = "\\t";
break;
}
case '\r':
{
s = "\\r";
break;
}
}
return s;
}
public virtual string GetCharErrorDisplay(int c)
{
string s = GetErrorDisplay(c);
return "'" + s + "'";
}
/// <summary>
/// Lexers can normally match any char in it's vocabulary after matching
/// a token, so do the easy thing and just kill a character and hope
/// it all works out.
/// </summary>
/// <remarks>
/// Lexers can normally match any char in it's vocabulary after matching
/// a token, so do the easy thing and just kill a character and hope
/// it all works out. You can instead use the rule invocation stack
/// to do sophisticated error recovery if you are in a fragment rule.
/// </remarks>
public virtual void Recover(RecognitionException re)
{
//System.out.println("consuming char "+(char)input.LA(1)+" during recovery");
//re.printStackTrace();
// TODO: Do we lose character or line position information?
_input.Consume();
}
}
}

View File

@ -0,0 +1,86 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
[System.Serializable]
public class LexerNoViableAltException : RecognitionException
{
private const long serialVersionUID = -730999203913001726L;
/// <summary>Matching attempted at what input index?</summary>
private readonly int startIndex;
/// <summary>Which configurations did we try at input.index() that couldn't match input.LA(1)?
/// </summary>
[Nullable]
private readonly ATNConfigSet deadEndConfigs;
public LexerNoViableAltException(Lexer lexer, ICharStream input, int startIndex,
ATNConfigSet deadEndConfigs) : base(lexer, input)
{
this.startIndex = startIndex;
this.deadEndConfigs = deadEndConfigs;
}
public virtual int GetStartIndex()
{
return startIndex;
}
[Nullable]
public virtual ATNConfigSet GetDeadEndConfigs()
{
return deadEndConfigs;
}
public override IIntStream GetInputStream()
{
return (ICharStream)base.GetInputStream();
}
public override string ToString()
{
string symbol = string.Empty;
if (startIndex >= 0 && startIndex < ((ICharStream)GetInputStream()).Size)
{
symbol = ((ICharStream)GetInputStream()).GetText(Interval.Of(startIndex, startIndex
));
symbol = Utils.EscapeWhitespace(symbol, false);
}
return string.Format("%s('%s')", typeof(Antlr4.Runtime.LexerNoViableAltException)
.Name, symbol);
}
}
}

View File

@ -0,0 +1,57 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <author>Sam Harwell</author>
public sealed class Args
{
/// <exception cref="System.ArgumentNullException">
/// if
/// <code>value</code>
/// is
/// <code>null</code>
/// .
/// </exception>
public static void NotNull(string parameterName, object value)
{
if (value == null)
{
throw new ArgumentNullException(parameterName + " cannot be null.");
}
}
public Args()
{
}
}
}

View File

@ -0,0 +1,692 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>
/// <see cref="Sharpen.ISet{E}">Sharpen.ISet&lt;E&gt;</see>
/// implementation with closed hashing (open addressing).
/// </summary>
public class Array2DHashSet<T> : ICollection<T>
{
public const int InitalCapacity = 16;
public const int InitalBucketCapacity = 8;
public const double LoadFactor = 0.75;
[NotNull]
protected internal readonly AbstractEqualityComparator<T> comparator;
protected internal T[][] buckets;
/// <summary>How many elements in set</summary>
protected internal int n = 0;
protected internal int threshold = (int)(InitalCapacity * LoadFactor);
protected internal int currentPrime = 1;
protected internal int initialBucketCapacity = InitalBucketCapacity;
public Array2DHashSet() : this(null, InitalCapacity, InitalBucketCapacity)
{
}
public Array2DHashSet(AbstractEqualityComparator<T> comparator) : this(comparator
, InitalCapacity, InitalBucketCapacity)
{
}
public Array2DHashSet(AbstractEqualityComparator<T> comparator, int initialCapacity
, int initialBucketCapacity)
{
// must be power of 2
// when to expand
// jump by 4 primes each expand or whatever
if (comparator == null)
{
comparator = ObjectEqualityComparator.Instance;
}
this.comparator = comparator;
this.buckets = CreateBuckets(initialCapacity);
this.initialBucketCapacity = initialBucketCapacity;
}
/// <summary>
/// Add
/// <code>o</code>
/// to set if not there; return existing value if already
/// there. This method performs the same operation as
/// <see cref="Array2DHashSet{T}.AddItem(object)">Array2DHashSet&lt;T&gt;.AddItem(object)
/// </see>
/// aside from
/// the return value.
/// </summary>
public T GetOrAdd(T o)
{
if (n > threshold)
{
Expand();
}
return GetOrAddImpl(o);
}
protected internal virtual T GetOrAddImpl(T o)
{
int b = GetBucket(o);
T[] bucket = buckets[b];
// NEW BUCKET
if (bucket == null)
{
bucket = CreateBucket(initialBucketCapacity);
bucket[0] = o;
buckets[b] = bucket;
n++;
return o;
}
// LOOK FOR IT IN BUCKET
for (int i = 0; i < bucket.Length; i++)
{
T existing = bucket[i];
if (existing == null)
{
// empty slot; not there, add.
bucket[i] = o;
n++;
return o;
}
if (comparator.Equals(existing, o))
{
return existing;
}
}
// found existing, quit
// FULL BUCKET, expand and add to end
int oldLength = bucket.Length;
bucket = Arrays.CopyOf(bucket, bucket.Length * 2);
buckets[b] = bucket;
bucket[oldLength] = o;
// add to end
n++;
return o;
}
public virtual T Get(T o)
{
if (o == null)
{
return o;
}
int b = GetBucket(o);
T[] bucket = buckets[b];
if (bucket == null)
{
return null;
}
// no bucket
foreach (T e in bucket)
{
if (e == null)
{
return null;
}
// empty slot; not there
if (comparator.Equals(e, o))
{
return e;
}
}
return null;
}
protected internal int GetBucket(T o)
{
int hash = comparator.HashCode(o);
int b = hash & (buckets.Length - 1);
// assumes len is power of 2
return b;
}
public override int GetHashCode()
{
int h = 0;
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (T o in bucket)
{
if (o == null)
{
break;
}
h += comparator.HashCode(o);
}
}
return h;
}
public override bool Equals(object o)
{
if (o == this)
{
return true;
}
if (!(o is Antlr4.Runtime.Misc.Array2DHashSet))
{
return false;
}
Antlr4.Runtime.Misc.Array2DHashSet<object> other = (Antlr4.Runtime.Misc.Array2DHashSet
<object>)o;
if (other.Count != Count)
{
return false;
}
bool same = this.ContainsAll(other);
return same;
}
protected internal virtual void Expand()
{
T[][] old = buckets;
currentPrime += 4;
int newCapacity = buckets.Length * 2;
T[][] newTable = CreateBuckets(newCapacity);
int[] newBucketLengths = new int[newTable.Length];
buckets = newTable;
threshold = (int)(newCapacity * LoadFactor);
// System.out.println("new size="+newCapacity+", thres="+threshold);
// rehash all existing entries
int oldSize = Count;
foreach (T[] bucket in old)
{
if (bucket == null)
{
continue;
}
foreach (T o in bucket)
{
if (o == null)
{
break;
}
int b = GetBucket(o);
int bucketLength = newBucketLengths[b];
T[] newBucket;
if (bucketLength == 0)
{
// new bucket
newBucket = CreateBucket(initialBucketCapacity);
newTable[b] = newBucket;
}
else
{
newBucket = newTable[b];
if (bucketLength == newBucket.Length)
{
// expand
newBucket = Arrays.CopyOf(newBucket, newBucket.Length * 2);
newTable[b] = newBucket;
}
}
newBucket[bucketLength] = o;
newBucketLengths[b]++;
}
}
System.Diagnostics.Debug.Assert(n == oldSize);
}
public bool AddItem(T t)
{
T existing = GetOrAdd(t);
return existing == t;
}
public int Count
{
get
{
return n;
}
}
public bool IsEmpty()
{
return n == 0;
}
public bool Contains(object o)
{
return ContainsFast(AsElementType(o));
}
public virtual bool ContainsFast(T obj)
{
if (obj == null)
{
return false;
}
return Get(obj) != null;
}
public virtual IEnumerator<T> GetEnumerator()
{
return new Array2DHashSet.SetIterator(this, Sharpen.Collections.ToArray(this));
}
public virtual T[] ToArray()
{
T[] a = CreateBucket(Count);
int i = 0;
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (T o in bucket)
{
if (o == null)
{
break;
}
a[i++] = o;
}
}
return a;
}
public virtual U[] ToArray<U>(U[] a)
{
if (a.Length < Count)
{
a = Arrays.CopyOf(a, Count);
}
int i = 0;
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (T o in bucket)
{
if (o == null)
{
break;
}
U targetElement = (U)o;
// array store will check this
a[i++] = targetElement;
}
}
return a;
}
public bool Remove(object o)
{
return RemoveFast(AsElementType(o));
}
public virtual bool RemoveFast(T obj)
{
if (obj == null)
{
return false;
}
int b = GetBucket(obj);
T[] bucket = buckets[b];
if (bucket == null)
{
// no bucket
return false;
}
for (int i = 0; i < bucket.Length; i++)
{
T e = bucket[i];
if (e == null)
{
// empty slot; not there
return false;
}
if (comparator.Equals(e, obj))
{
// found it
// shift all elements to the right down one
System.Array.Copy(bucket, i + 1, bucket, i, bucket.Length - i - 1);
bucket[bucket.Length - 1] = null;
n--;
return true;
}
}
return false;
}
public virtual bool ContainsAll<_T0>(ICollection<_T0> collection)
{
if (collection is Antlr4.Runtime.Misc.Array2DHashSet)
{
Antlr4.Runtime.Misc.Array2DHashSet<object> s = (Antlr4.Runtime.Misc.Array2DHashSet
<object>)collection;
foreach (object[] bucket in s.buckets)
{
if (bucket == null)
{
continue;
}
foreach (object o in bucket)
{
if (o == null)
{
break;
}
if (!this.ContainsFast(AsElementType(o)))
{
return false;
}
}
}
}
else
{
foreach (object o in collection)
{
if (!this.ContainsFast(AsElementType(o)))
{
return false;
}
}
}
return true;
}
public virtual bool AddAll<_T0>(ICollection<_T0> c) where _T0:T
{
bool changed = false;
foreach (T o in c)
{
T existing = GetOrAdd(o);
if (existing != o)
{
changed = true;
}
}
return changed;
}
public virtual bool RetainAll<_T0>(ICollection<_T0> c)
{
int newsize = 0;
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
continue;
}
int i;
int j;
for (i = 0, j = 0; i < bucket.Length; i++)
{
if (bucket[i] == null)
{
break;
}
if (!c.Contains(bucket[i]))
{
// removed
continue;
}
// keep
if (i != j)
{
bucket[j] = bucket[i];
}
j++;
newsize++;
}
newsize += j;
while (j < i)
{
bucket[j] = null;
j++;
}
}
bool changed = newsize != n;
n = newsize;
return changed;
}
public virtual bool RemoveAll<_T0>(ICollection<_T0> c)
{
bool changed = false;
foreach (object o in c)
{
changed |= RemoveFast(AsElementType(o));
}
return changed;
}
public virtual void Clear()
{
buckets = CreateBuckets(InitalCapacity);
n = 0;
}
public override string ToString()
{
if (Count == 0)
{
return "{}";
}
StringBuilder buf = new StringBuilder();
buf.Append('{');
bool first = true;
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (T o in bucket)
{
if (o == null)
{
break;
}
if (first)
{
first = false;
}
else
{
buf.Append(", ");
}
buf.Append(o.ToString());
}
}
buf.Append('}');
return buf.ToString();
}
public virtual string ToTableString()
{
StringBuilder buf = new StringBuilder();
foreach (T[] bucket in buckets)
{
if (bucket == null)
{
buf.Append("null\n");
continue;
}
buf.Append('[');
bool first = true;
foreach (T o in bucket)
{
if (first)
{
first = false;
}
else
{
buf.Append(" ");
}
if (o == null)
{
buf.Append("_");
}
else
{
buf.Append(o.ToString());
}
}
buf.Append("]\n");
}
return buf.ToString();
}
/// <summary>
/// Return
/// <code>o</code>
/// as an instance of the element type
/// <code>T</code>
/// . If
/// <code>o</code>
/// is non-null but known to not be an instance of
/// <code>T</code>
/// , this
/// method returns
/// <code>null</code>
/// . The base implementation does not perform any
/// type checks; override this method to provide strong type checks for the
/// <see cref="Array2DHashSet{T}.Contains(object)">Array2DHashSet&lt;T&gt;.Contains(object)
/// </see>
/// and
/// <see cref="Array2DHashSet{T}.Remove(object)">Array2DHashSet&lt;T&gt;.Remove(object)
/// </see>
/// methods to ensure the arguments to
/// the
/// <see cref="IEqualityComparator{T}">IEqualityComparator&lt;T&gt;</see>
/// for the set always have the expected
/// types.
/// </summary>
/// <param name="o">the object to try and cast to the element type of the set</param>
/// <returns>
///
/// <code>o</code>
/// if it could be an instance of
/// <code>T</code>
/// , otherwise
/// <code>null</code>
/// .
/// </returns>
protected internal virtual T AsElementType(object o)
{
return (T)o;
}
/// <summary>
/// Return an array of
/// <code>T[]</code>
/// with length
/// <code>capacity</code>
/// .
/// </summary>
/// <param name="capacity">the length of the array to return</param>
/// <returns>the newly constructed array</returns>
protected internal virtual T[][] CreateBuckets(int capacity)
{
return (T[][])new object[capacity][];
}
/// <summary>
/// Return an array of
/// <code>T</code>
/// with length
/// <code>capacity</code>
/// .
/// </summary>
/// <param name="capacity">the length of the array to return</param>
/// <returns>the newly constructed array</returns>
protected internal virtual T[] CreateBucket(int capacity)
{
return (T[])new object[capacity];
}
protected internal class SetIterator : IEnumerator<T>
{
internal readonly T[] data;
internal int nextIndex = 0;
internal bool removed = true;
public SetIterator(Array2DHashSet<T> _enclosing, T[] data)
{
this._enclosing = _enclosing;
this.data = data;
}
public override bool HasNext()
{
return this.nextIndex < this.data.Length;
}
public override T Next()
{
if (!this.HasNext())
{
throw new NoSuchElementException();
}
this.removed = false;
return this.data[this.nextIndex++];
}
public override void Remove()
{
if (this.removed)
{
throw new InvalidOperationException();
}
this._enclosing._enclosing.Remove(this.data[this.nextIndex - 1]);
this.removed = true;
}
private readonly Array2DHashSet<T> _enclosing;
}
}
}

View File

@ -0,0 +1,108 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>Sometimes we need to map a key to a value but key is two pieces of data.
/// </summary>
/// <remarks>
/// Sometimes we need to map a key to a value but key is two pieces of data.
/// This nested hash table saves creating a single key each time we access
/// map; avoids mem creation.
/// </remarks>
public class DoubleKeyMap<Key1, Key2, Value>
{
internal IDictionary<Key1, IDictionary<Key2, Value>> data = new LinkedHashMap<Key1
, IDictionary<Key2, Value>>();
public virtual Value Put(Key1 k1, Key2 k2, Value v)
{
IDictionary<Key2, Value> data2 = data.Get(k1);
Value prev = null;
if (data2 == null)
{
data2 = new LinkedHashMap<Key2, Value>();
data.Put(k1, data2);
}
else
{
prev = data2.Get(k2);
}
data2.Put(k2, v);
return prev;
}
public virtual Value Get(Key1 k1, Key2 k2)
{
IDictionary<Key2, Value> data2 = data.Get(k1);
if (data2 == null)
{
return null;
}
return data2.Get(k2);
}
public virtual IDictionary<Key2, Value> Get(Key1 k1)
{
return data.Get(k1);
}
/// <summary>Get all values associated with primary key</summary>
public virtual ICollection<Value> Values(Key1 k1)
{
IDictionary<Key2, Value> data2 = data.Get(k1);
if (data2 == null)
{
return null;
}
return data2.Values;
}
/// <summary>get all primary keys</summary>
public virtual ICollection<Key1> KeySet()
{
return data.Keys;
}
/// <summary>get all secondary keys associated with a primary key</summary>
public virtual ICollection<Key2> KeySet(Key1 k1)
{
IDictionary<Key2, Value> data2 = data.Get(k1);
if (data2 == null)
{
return null;
}
return data2.Keys;
}
}
}

View File

@ -0,0 +1,397 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>
/// A limited map (many unsupported operations) that lets me use
/// varying hashCode/equals.
/// </summary>
/// <remarks>
/// A limited map (many unsupported operations) that lets me use
/// varying hashCode/equals.
/// </remarks>
public class FlexibleHashMap<K, V> : IDictionary<K, V>
{
public const int InitalCapacity = 16;
public const int InitalBucketCapacity = 8;
public const double LoadFactor = 0.75;
public class Entry<K, V>
{
public readonly K key;
public V value;
public Entry(K key, V value)
{
// must be power of 2
this.key = key;
this.value = value;
}
public override string ToString()
{
return key.ToString() + ":" + value.ToString();
}
}
[NotNull]
protected internal readonly AbstractEqualityComparator<K> comparator;
protected internal List<FlexibleHashMap.Entry<K, V>>[] buckets;
/// <summary>How many elements in set</summary>
protected internal int n = 0;
protected internal int threshold = (int)(InitalCapacity * LoadFactor);
protected internal int currentPrime = 1;
protected internal int initialBucketCapacity = InitalBucketCapacity;
public FlexibleHashMap() : this(null, InitalCapacity, InitalBucketCapacity)
{
}
public FlexibleHashMap(AbstractEqualityComparator<K> comparator) : this(comparator
, InitalCapacity, InitalBucketCapacity)
{
}
public FlexibleHashMap(AbstractEqualityComparator<K> comparator, int initialCapacity
, int initialBucketCapacity)
{
// when to expand
// jump by 4 primes each expand or whatever
if (comparator == null)
{
comparator = ObjectEqualityComparator.Instance;
}
this.comparator = comparator;
this.buckets = CreateEntryListArray(initialBucketCapacity);
this.initialBucketCapacity = initialBucketCapacity;
}
private static List<FlexibleHashMap.Entry<K, V>>[] CreateEntryListArray<K, V>(int
length)
{
List<FlexibleHashMap.Entry<K, V>>[] result = (List<FlexibleHashMap.Entry<K, V>>[]
)new List<object>[length];
return result;
}
protected internal virtual int GetBucket(K key)
{
int hash = comparator.HashCode(key);
int b = hash & (buckets.Length - 1);
// assumes len is power of 2
return b;
}
public virtual V Get(object key)
{
K typedKey = (K)key;
if (key == null)
{
return null;
}
int b = GetBucket(typedKey);
List<FlexibleHashMap.Entry<K, V>> bucket = buckets[b];
if (bucket == null)
{
return null;
}
// no bucket
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (comparator.Equals(e.key, typedKey))
{
return e.value;
}
}
return null;
}
public virtual V Put(K key, V value)
{
if (key == null)
{
return null;
}
if (n > threshold)
{
Expand();
}
int b = GetBucket(key);
List<FlexibleHashMap.Entry<K, V>> bucket = buckets[b];
if (bucket == null)
{
bucket = buckets[b] = new List<FlexibleHashMap.Entry<K, V>>();
}
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (comparator.Equals(e.key, key))
{
V prev = e.value;
e.value = value;
n++;
return prev;
}
}
// not there
bucket.AddItem(new FlexibleHashMap.Entry<K, V>(key, value));
n++;
return null;
}
public virtual V Remove(object key)
{
throw new NotSupportedException();
}
public virtual void PutAll<_T0>(IDictionary<_T0> m) where _T0:K
{
throw new NotSupportedException();
}
public virtual ICollection<K> Keys
{
get
{
throw new NotSupportedException();
}
}
public virtual ICollection<V> Values
{
get
{
IList<V> a = new List<V>(Count);
foreach (List<FlexibleHashMap.Entry<K, V>> bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
a.AddItem(e.value);
}
}
return a;
}
}
public virtual ICollection<KeyValuePair<K, V>> EntrySet()
{
throw new NotSupportedException();
}
public virtual bool ContainsKey(object key)
{
return Get(key) != null;
}
public virtual bool ContainsValue(object value)
{
throw new NotSupportedException();
}
public override int GetHashCode()
{
int h = 0;
foreach (List<FlexibleHashMap.Entry<K, V>> bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (e == null)
{
break;
}
h += comparator.HashCode(e.key);
}
}
return h;
}
public override bool Equals(object o)
{
throw new NotSupportedException();
}
protected internal virtual void Expand()
{
List<FlexibleHashMap.Entry<K, V>>[] old = buckets;
currentPrime += 4;
int newCapacity = buckets.Length * 2;
List<FlexibleHashMap.Entry<K, V>>[] newTable = CreateEntryListArray(newCapacity);
buckets = newTable;
threshold = (int)(newCapacity * LoadFactor);
// System.out.println("new size="+newCapacity+", thres="+threshold);
// rehash all existing entries
int oldSize = Count;
foreach (List<FlexibleHashMap.Entry<K, V>> bucket in old)
{
if (bucket == null)
{
continue;
}
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (e == null)
{
break;
}
Put(e.key, e.value);
}
}
n = oldSize;
}
public virtual int Count
{
get
{
return n;
}
}
public virtual bool IsEmpty()
{
return n == 0;
}
public virtual void Clear()
{
buckets = CreateEntryListArray(InitalCapacity);
n = 0;
}
public override string ToString()
{
if (Count == 0)
{
return "{}";
}
StringBuilder buf = new StringBuilder();
buf.Append('{');
bool first = true;
foreach (List<FlexibleHashMap.Entry<K, V>> bucket in buckets)
{
if (bucket == null)
{
continue;
}
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (e == null)
{
break;
}
if (first)
{
first = false;
}
else
{
buf.Append(", ");
}
buf.Append(e.ToString());
}
}
buf.Append('}');
return buf.ToString();
}
public virtual string ToTableString()
{
StringBuilder buf = new StringBuilder();
foreach (List<FlexibleHashMap.Entry<K, V>> bucket in buckets)
{
if (bucket == null)
{
buf.Append("null\n");
continue;
}
buf.Append('[');
bool first = true;
foreach (FlexibleHashMap.Entry<K, V> e in bucket)
{
if (first)
{
first = false;
}
else
{
buf.Append(" ");
}
if (e == null)
{
buf.Append("_");
}
else
{
buf.Append(e.ToString());
}
}
buf.Append("]\n");
}
return buf.ToString();
}
public static void Main(string[] args)
{
FlexibleHashMap<string, int> map = new FlexibleHashMap<string, int>();
map.Put("hi", 1);
map.Put("mom", 2);
map.Put("foo", 3);
map.Put("ach", 4);
map.Put("cbba", 5);
map.Put("d", 6);
map.Put("edf", 7);
map.Put("mom", 8);
map.Put("hi", 9);
System.Console.Out.WriteLine(map);
System.Console.Out.WriteLine(map.ToTableString());
}
}
}

View File

@ -0,0 +1,40 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <author>Sam Harwell</author>
public interface IFunc0<Result>
{
Result Eval();
}
}

View File

@ -0,0 +1,40 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <author>Sam Harwell</author>
public interface IFunc1<T1, Result>
{
Result Eval(T1 arg1);
}
}

View File

@ -0,0 +1,92 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>A generic set of ints.</summary>
/// <remarks>A generic set of ints.</remarks>
/// <seealso cref="IntervalSet">IntervalSet</seealso>
public interface IIntSet
{
/// <summary>Add an element to the set</summary>
void Add(int el);
/// <summary>Add all elements from incoming set to this set.</summary>
/// <remarks>
/// Add all elements from incoming set to this set. Can limit
/// to set of its own type. Return "this" so we can chain calls.
/// </remarks>
IIntSet AddAll(IIntSet set);
/// <summary>
/// Return the intersection of this set with the argument, creating
/// a new set.
/// </summary>
/// <remarks>
/// Return the intersection of this set with the argument, creating
/// a new set.
/// </remarks>
IIntSet And(IIntSet a);
IIntSet Complement(IIntSet elements);
IIntSet Or(IIntSet a);
IIntSet Subtract(IIntSet a);
/// <summary>
/// Return the size of this set (not the underlying implementation's
/// allocated memory size, for example).
/// </summary>
/// <remarks>
/// Return the size of this set (not the underlying implementation's
/// allocated memory size, for example).
/// </remarks>
int Size();
bool IsNil();
bool Equals(object obj);
int GetSingleElement();
bool Contains(int el);
/// <summary>remove this element from this set</summary>
void Remove(int el);
IList<int> ToList();
string ToString();
}
}

View File

@ -0,0 +1,40 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <author>Sam Harwell</author>
public interface IPredicate<T>
{
bool Eval(T arg);
}
}

View File

@ -0,0 +1,226 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>An immutable inclusive interval a..b</summary>
public class Interval
{
public const int IntervalPoolMaxValue = 1000;
public static readonly Antlr4.Runtime.Misc.Interval Invalid = new Antlr4.Runtime.Misc.Interval
(-1, -2);
private static Antlr4.Runtime.Misc.Interval[] cache = new Antlr4.Runtime.Misc.Interval
[IntervalPoolMaxValue + 1];
/// <summary>The start of the interval.</summary>
/// <remarks>The start of the interval.</remarks>
public readonly int a;
/// <summary>The end of the interval (inclusive).</summary>
/// <remarks>The end of the interval (inclusive).</remarks>
public readonly int b;
public Interval(int a, int b)
{
this.a = a;
this.b = b;
}
/// <summary>
/// Interval objects are used readonly so share all with the
/// same single value a==b up to some max size.
/// </summary>
/// <remarks>
/// Interval objects are used readonly so share all with the
/// same single value a==b up to some max size. Use an array as a perfect hash.
/// Return shared object for 0..INTERVAL_POOL_MAX_VALUE or a new
/// Interval object with a..a in it. On Java.g4, 218623 IntervalSets
/// have a..a (set with 1 element).
/// </remarks>
public static Antlr4.Runtime.Misc.Interval Of(int a, int b)
{
// cache just a..a
if (a != b || a < 0 || a > IntervalPoolMaxValue)
{
return new Antlr4.Runtime.Misc.Interval(a, b);
}
if (cache[a] == null)
{
cache[a] = new Antlr4.Runtime.Misc.Interval(a, a);
}
return cache[a];
}
/// <summary>return number of elements between a and b inclusively.</summary>
/// <remarks>
/// return number of elements between a and b inclusively. x..x is length 1.
/// if b &lt; a, then length is 0. 9..10 has length 2.
/// </remarks>
public virtual int Length()
{
if (b < a)
{
return 0;
}
return b - a + 1;
}
public override bool Equals(object o)
{
if (o == this)
{
return true;
}
else
{
if (!(o is Antlr4.Runtime.Misc.Interval))
{
return false;
}
}
Antlr4.Runtime.Misc.Interval other = (Antlr4.Runtime.Misc.Interval)o;
return this.a == other.a && this.b == other.b;
}
public override int GetHashCode()
{
int hash = 5;
hash = 37 * hash ^ this.a;
hash = 37 * hash ^ this.b;
return hash;
}
/// <summary>Does this start completely before other? Disjoint</summary>
public virtual bool StartsBeforeDisjoint(Antlr4.Runtime.Misc.Interval other)
{
return this.a < other.a && this.b < other.a;
}
/// <summary>Does this start at or before other? Nondisjoint</summary>
public virtual bool StartsBeforeNonDisjoint(Antlr4.Runtime.Misc.Interval other)
{
return this.a <= other.a && this.b >= other.a;
}
/// <summary>Does this.a start after other.b? May or may not be disjoint</summary>
public virtual bool StartsAfter(Antlr4.Runtime.Misc.Interval other)
{
return this.a > other.a;
}
/// <summary>Does this start completely after other? Disjoint</summary>
public virtual bool StartsAfterDisjoint(Antlr4.Runtime.Misc.Interval other)
{
return this.a > other.b;
}
/// <summary>Does this start after other? NonDisjoint</summary>
public virtual bool StartsAfterNonDisjoint(Antlr4.Runtime.Misc.Interval other)
{
return this.a > other.a && this.a <= other.b;
}
// this.b>=other.b implied
/// <summary>Are both ranges disjoint? I.e., no overlap?</summary>
public virtual bool Disjoint(Antlr4.Runtime.Misc.Interval other)
{
return StartsBeforeDisjoint(other) || StartsAfterDisjoint(other);
}
/// <summary>Are two intervals adjacent such as 0..41 and 42..42?</summary>
public virtual bool Adjacent(Antlr4.Runtime.Misc.Interval other)
{
return this.a == other.b + 1 || this.b == other.a - 1;
}
public virtual bool ProperlyContains(Antlr4.Runtime.Misc.Interval other)
{
return other.a >= this.a && other.b <= this.b;
}
/// <summary>Return the interval computed from combining this and other</summary>
public virtual Antlr4.Runtime.Misc.Interval Union(Antlr4.Runtime.Misc.Interval other
)
{
return Antlr4.Runtime.Misc.Interval.Of(Math.Min(a, other.a), Math.Max(b, other.b)
);
}
/// <summary>Return the interval in common between this and o</summary>
public virtual Antlr4.Runtime.Misc.Interval Intersection(Antlr4.Runtime.Misc.Interval
other)
{
return Antlr4.Runtime.Misc.Interval.Of(Math.Max(a, other.a), Math.Min(b, other.b)
);
}
/// <summary>
/// Return the interval with elements from
/// <code>this</code>
/// not in
/// <code>other</code>
/// ;
/// <code>other</code>
/// must not be totally enclosed (properly contained)
/// within
/// <code>this</code>
/// , which would result in two disjoint intervals
/// instead of the single one returned by this method.
/// </summary>
public virtual Antlr4.Runtime.Misc.Interval DifferenceNotProperlyContained(Antlr4.Runtime.Misc.Interval
other)
{
Antlr4.Runtime.Misc.Interval diff = null;
// other.a to left of this.a (or same)
if (other.StartsBeforeNonDisjoint(this))
{
diff = Antlr4.Runtime.Misc.Interval.Of(Math.Max(this.a, other.b + 1), this.b);
}
else
{
// other.a to right of this.a
if (other.StartsAfterNonDisjoint(this))
{
diff = Antlr4.Runtime.Misc.Interval.Of(this.a, other.a - 1);
}
}
return diff;
}
public override string ToString()
{
return a + ".." + b;
}
}
}

View File

@ -0,0 +1,821 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>
/// A set of integers that relies on ranges being common to do
/// "run-length-encoded" like compression (if you view an IntSet like
/// a BitSet with runs of 0s and 1s).
/// </summary>
/// <remarks>
/// A set of integers that relies on ranges being common to do
/// "run-length-encoded" like compression (if you view an IntSet like
/// a BitSet with runs of 0s and 1s). Only ranges are recorded so that
/// a few ints up near value 1000 don't cause massive bitsets, just two
/// integer intervals.
/// element values may be negative. Useful for sets of EPSILON and EOF.
/// 0..9 char range is index pair ['\u0030','\u0039'].
/// Multiple ranges are encoded with multiple index pairs. Isolated
/// elements are encoded with an index pair where both intervals are the same.
/// The ranges are ordered and disjoint so that 2..6 appears before 101..103.
/// </remarks>
public class IntervalSet : IIntSet
{
public static readonly Antlr4.Runtime.Misc.IntervalSet CompleteCharSet = Antlr4.Runtime.Misc.IntervalSet
.Of(0, Lexer.MaxCharValue);
public static readonly Antlr4.Runtime.Misc.IntervalSet EmptySet = new Antlr4.Runtime.Misc.IntervalSet
();
/// <summary>The list of sorted, disjoint intervals.</summary>
/// <remarks>The list of sorted, disjoint intervals.</remarks>
protected internal IList<Interval> intervals;
protected internal bool @readonly;
public IntervalSet(IList<Interval> intervals)
{
this.intervals = intervals;
}
public IntervalSet(Antlr4.Runtime.Misc.IntervalSet set) : this()
{
AddAll(set);
}
public IntervalSet(params int[] els)
{
if (els == null)
{
intervals = new List<Interval>(2);
}
else
{
// most sets are 1 or 2 elements
intervals = new List<Interval>(els.Length);
foreach (int e in els)
{
Add(e);
}
}
}
/// <summary>Create a set with a single element, el.</summary>
/// <remarks>Create a set with a single element, el.</remarks>
[NotNull]
public static Antlr4.Runtime.Misc.IntervalSet Of(int a)
{
Antlr4.Runtime.Misc.IntervalSet s = new Antlr4.Runtime.Misc.IntervalSet();
s.Add(a);
return s;
}
/// <summary>Create a set with all ints within range [a..b] (inclusive)</summary>
public static Antlr4.Runtime.Misc.IntervalSet Of(int a, int b)
{
Antlr4.Runtime.Misc.IntervalSet s = new Antlr4.Runtime.Misc.IntervalSet();
s.Add(a, b);
return s;
}
public virtual void Clear()
{
if (@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
intervals.Clear();
}
/// <summary>Add a single element to the set.</summary>
/// <remarks>
/// Add a single element to the set. An isolated element is stored
/// as a range el..el.
/// </remarks>
public virtual void Add(int el)
{
if (@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
Add(el, el);
}
/// <summary>Add interval; i.e., add all integers from a to b to set.</summary>
/// <remarks>
/// Add interval; i.e., add all integers from a to b to set.
/// If b&lt;a, do nothing.
/// Keep list in sorted order (by left range value).
/// If overlap, combine ranges. For example,
/// If this is {1..5, 10..20}, adding 6..7 yields
/// {1..5, 6..7, 10..20}. Adding 4..8 yields {1..8, 10..20}.
/// </remarks>
public virtual void Add(int a, int b)
{
Add(Interval.Of(a, b));
}
// copy on write so we can cache a..a intervals and sets of that
protected internal virtual void Add(Interval addition)
{
if (@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
//System.out.println("add "+addition+" to "+intervals.toString());
if (addition.b < addition.a)
{
return;
}
// find position in list
// Use iterators as we modify list in place
for (IListIterator<Interval> iter = intervals.ListIterator(); iter.HasNext(); )
{
Interval r = iter.Next();
if (addition.Equals(r))
{
return;
}
if (addition.Adjacent(r) || !addition.Disjoint(r))
{
// next to each other, make a single larger interval
Interval bigger = addition.Union(r);
iter.Set(bigger);
// make sure we didn't just create an interval that
// should be merged with next interval in list
if (iter.HasNext())
{
Interval next = iter.Next();
if (bigger.Adjacent(next) || !bigger.Disjoint(next))
{
// if we bump up against or overlap next, merge
iter.Remove();
// remove this one
iter.Previous();
// move backwards to what we just set
iter.Set(bigger.Union(next));
}
}
// set to 3 merged ones
return;
}
if (addition.StartsBeforeDisjoint(r))
{
// insert before r
iter.Previous();
iter.Add(addition);
return;
}
}
// if disjoint and after r, a future iteration will handle it
// ok, must be after last interval (and disjoint from last interval)
// just add it
intervals.AddItem(addition);
}
/// <summary>combine all sets in the array returned the or'd value</summary>
public static Antlr4.Runtime.Misc.IntervalSet Or(Antlr4.Runtime.Misc.IntervalSet[]
sets)
{
Antlr4.Runtime.Misc.IntervalSet r = new Antlr4.Runtime.Misc.IntervalSet();
foreach (Antlr4.Runtime.Misc.IntervalSet s in sets)
{
r.AddAll(s);
}
return r;
}
public virtual Antlr4.Runtime.Misc.IntervalSet AddAll(IIntSet set)
{
if (set == null)
{
return this;
}
if (!(set is Antlr4.Runtime.Misc.IntervalSet))
{
throw new ArgumentException("can't add non IntSet (" + set.GetType().FullName + ") to IntervalSet"
);
}
Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)set;
// walk set and add each interval
int n = other.intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = other.intervals[i];
this.Add(I.a, I.b);
}
return this;
}
public virtual Antlr4.Runtime.Misc.IntervalSet Complement(int minElement, int maxElement
)
{
return this.Complement(Antlr4.Runtime.Misc.IntervalSet.Of(minElement, maxElement)
);
}
/// <summary>
/// Given the set of possible values (rather than, say UNICODE or MAXINT),
/// return a new set containing all elements in vocabulary, but not in
/// this.
/// </summary>
/// <remarks>
/// Given the set of possible values (rather than, say UNICODE or MAXINT),
/// return a new set containing all elements in vocabulary, but not in
/// this. The computation is (vocabulary - this).
/// 'this' is assumed to be either a subset or equal to vocabulary.
/// </remarks>
public virtual Antlr4.Runtime.Misc.IntervalSet Complement(IIntSet vocabulary)
{
if (vocabulary == null)
{
return null;
}
// nothing in common with null set
if (!(vocabulary is Antlr4.Runtime.Misc.IntervalSet))
{
throw new ArgumentException("can't complement with non IntervalSet (" + vocabulary
.GetType().FullName + ")");
}
Antlr4.Runtime.Misc.IntervalSet vocabularyIS = ((Antlr4.Runtime.Misc.IntervalSet)
vocabulary);
int maxElement = vocabularyIS.GetMaxElement();
Antlr4.Runtime.Misc.IntervalSet compl = new Antlr4.Runtime.Misc.IntervalSet();
int n = intervals.Count;
if (n == 0)
{
return compl;
}
Interval first = intervals[0];
// add a range from 0 to first.a constrained to vocab
if (first.a > 0)
{
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(0, first.a
- 1);
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
compl.AddAll(a);
}
for (int i = 1; i < n; i++)
{
// from 2nd interval .. nth
Interval previous = intervals[i - 1];
Interval current = intervals[i];
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(previous.b
+ 1, current.a - 1);
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
compl.AddAll(a);
}
Interval last = intervals[n - 1];
// add a range from last.b to maxElement constrained to vocab
if (last.b < maxElement)
{
Antlr4.Runtime.Misc.IntervalSet s = Antlr4.Runtime.Misc.IntervalSet.Of(last.b + 1
, maxElement);
Antlr4.Runtime.Misc.IntervalSet a = s.And(vocabularyIS);
compl.AddAll(a);
}
return compl;
}
/// <summary>Compute this-other via this&~other.</summary>
/// <remarks>
/// Compute this-other via this&~other.
/// Return a new set containing all elements in this but not in other.
/// other is assumed to be a subset of this;
/// anything that is in other but not in this will be ignored.
/// </remarks>
public virtual Antlr4.Runtime.Misc.IntervalSet Subtract(IIntSet other)
{
// assume the whole unicode range here for the complement
// because it doesn't matter. Anything beyond the max of this' set
// will be ignored since we are doing this & ~other. The intersection
// will be empty. The only problem would be when this' set max value
// goes beyond MAX_CHAR_VALUE, but hopefully the constant MAX_CHAR_VALUE
// will prevent this.
return this.And(((Antlr4.Runtime.Misc.IntervalSet)other).Complement(CompleteCharSet
));
}
public virtual Antlr4.Runtime.Misc.IntervalSet Or(IIntSet a)
{
Antlr4.Runtime.Misc.IntervalSet o = new Antlr4.Runtime.Misc.IntervalSet();
o.AddAll(this);
o.AddAll(a);
return o;
}
/// <summary>Return a new set with the intersection of this set with other.</summary>
/// <remarks>
/// Return a new set with the intersection of this set with other. Because
/// the intervals are sorted, we can use an iterator for each list and
/// just walk them together. This is roughly O(min(n,m)) for interval
/// list lengths n and m.
/// </remarks>
public virtual Antlr4.Runtime.Misc.IntervalSet And(IIntSet other)
{
if (other == null)
{
//|| !(other instanceof IntervalSet) ) {
return null;
}
// nothing in common with null set
IList<Interval> myIntervals = this.intervals;
IList<Interval> theirIntervals = ((Antlr4.Runtime.Misc.IntervalSet)other).intervals;
Antlr4.Runtime.Misc.IntervalSet intersection = null;
int mySize = myIntervals.Count;
int theirSize = theirIntervals.Count;
int i = 0;
int j = 0;
// iterate down both interval lists looking for nondisjoint intervals
while (i < mySize && j < theirSize)
{
Interval mine = myIntervals[i];
Interval theirs = theirIntervals[j];
//System.out.println("mine="+mine+" and theirs="+theirs);
if (mine.StartsBeforeDisjoint(theirs))
{
// move this iterator looking for interval that might overlap
i++;
}
else
{
if (theirs.StartsBeforeDisjoint(mine))
{
// move other iterator looking for interval that might overlap
j++;
}
else
{
if (mine.ProperlyContains(theirs))
{
// overlap, add intersection, get next theirs
if (intersection == null)
{
intersection = new Antlr4.Runtime.Misc.IntervalSet();
}
intersection.Add(mine.Intersection(theirs));
j++;
}
else
{
if (theirs.ProperlyContains(mine))
{
// overlap, add intersection, get next mine
if (intersection == null)
{
intersection = new Antlr4.Runtime.Misc.IntervalSet();
}
intersection.Add(mine.Intersection(theirs));
i++;
}
else
{
if (!mine.Disjoint(theirs))
{
// overlap, add intersection
if (intersection == null)
{
intersection = new Antlr4.Runtime.Misc.IntervalSet();
}
intersection.Add(mine.Intersection(theirs));
// Move the iterator of lower range [a..b], but not
// the upper range as it may contain elements that will collide
// with the next iterator. So, if mine=[0..115] and
// theirs=[115..200], then intersection is 115 and move mine
// but not theirs as theirs may collide with the next range
// in thisIter.
// move both iterators to next ranges
if (mine.StartsAfterNonDisjoint(theirs))
{
j++;
}
else
{
if (theirs.StartsAfterNonDisjoint(mine))
{
i++;
}
}
}
}
}
}
}
}
if (intersection == null)
{
return new Antlr4.Runtime.Misc.IntervalSet();
}
return intersection;
}
/// <summary>Is el in any range of this set?</summary>
public virtual bool Contains(int el)
{
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = intervals[i];
int a = I.a;
int b = I.b;
if (el < a)
{
break;
}
// list is sorted and el is before this interval; not here
if (el >= a && el <= b)
{
return true;
}
}
// found in this interval
return false;
}
/// <summary>return true if this set has no members</summary>
public virtual bool IsNil()
{
return intervals == null || intervals.IsEmpty();
}
/// <summary>If this set is a single integer, return it otherwise Token.INVALID_TYPE</summary>
public virtual int GetSingleElement()
{
if (intervals != null && intervals.Count == 1)
{
Interval I = intervals[0];
if (I.a == I.b)
{
return I.a;
}
}
return IToken.InvalidType;
}
public virtual int GetMaxElement()
{
if (IsNil())
{
return IToken.InvalidType;
}
Interval last = intervals[intervals.Count - 1];
return last.b;
}
/// <summary>Return minimum element &gt;= 0</summary>
public virtual int GetMinElement()
{
if (IsNil())
{
return IToken.InvalidType;
}
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = intervals[i];
int a = I.a;
int b = I.b;
for (int v = a; v <= b; v++)
{
if (v >= 0)
{
return v;
}
}
}
return IToken.InvalidType;
}
/// <summary>Return a list of Interval objects.</summary>
/// <remarks>Return a list of Interval objects.</remarks>
public virtual IList<Interval> GetIntervals()
{
return intervals;
}
public override int GetHashCode()
{
if (IsNil())
{
return 0;
}
int n = 0;
// just add left edge of intervals
foreach (Interval I in intervals)
{
n += I.a;
}
return n;
}
/// <summary>
/// Are two IntervalSets equal? Because all intervals are sorted
/// and disjoint, equals is a simple linear walk over both lists
/// to make sure they are the same.
/// </summary>
/// <remarks>
/// Are two IntervalSets equal? Because all intervals are sorted
/// and disjoint, equals is a simple linear walk over both lists
/// to make sure they are the same. Interval.equals() is used
/// by the List.equals() method to check the ranges.
/// </remarks>
public override bool Equals(object obj)
{
if (obj == null || !(obj is Antlr4.Runtime.Misc.IntervalSet))
{
return false;
}
Antlr4.Runtime.Misc.IntervalSet other = (Antlr4.Runtime.Misc.IntervalSet)obj;
return this.intervals.Equals(other.intervals);
}
public override string ToString()
{
return ToString(false);
}
public virtual string ToString(bool elemAreChar)
{
StringBuilder buf = new StringBuilder();
if (this.intervals == null || this.intervals.IsEmpty())
{
return "{}";
}
if (this.Size() > 1)
{
buf.Append("{");
}
IEnumerator<Interval> iter = this.intervals.GetEnumerator();
while (iter.HasNext())
{
Interval I = iter.Next();
int a = I.a;
int b = I.b;
if (a == b)
{
if (a == -1)
{
buf.Append("<EOF>");
}
else
{
if (elemAreChar)
{
buf.Append("'").Append((char)a).Append("'");
}
else
{
buf.Append(a);
}
}
}
else
{
if (elemAreChar)
{
buf.Append("'").Append((char)a).Append("'..'").Append((char)b).Append("'");
}
else
{
buf.Append(a).Append("..").Append(b);
}
}
if (iter.HasNext())
{
buf.Append(", ");
}
}
if (this.Size() > 1)
{
buf.Append("}");
}
return buf.ToString();
}
public virtual string ToString(string[] tokenNames)
{
StringBuilder buf = new StringBuilder();
if (this.intervals == null || this.intervals.IsEmpty())
{
return "{}";
}
if (this.Size() > 1)
{
buf.Append("{");
}
IEnumerator<Interval> iter = this.intervals.GetEnumerator();
while (iter.HasNext())
{
Interval I = iter.Next();
int a = I.a;
int b = I.b;
if (a == b)
{
buf.Append(ElementName(tokenNames, a));
}
else
{
for (int i = a; i <= b; i++)
{
if (i > a)
{
buf.Append(", ");
}
buf.Append(ElementName(tokenNames, i));
}
}
if (iter.HasNext())
{
buf.Append(", ");
}
}
if (this.Size() > 1)
{
buf.Append("}");
}
return buf.ToString();
}
protected internal virtual string ElementName(string[] tokenNames, int a)
{
if (a == IToken.Eof)
{
return "<EOF>";
}
else
{
if (a == IToken.Epsilon)
{
return "<EPSILON>";
}
else
{
return tokenNames[a];
}
}
}
public virtual int Size()
{
int n = 0;
int numIntervals = intervals.Count;
if (numIntervals == 1)
{
Interval firstInterval = this.intervals[0];
return firstInterval.b - firstInterval.a + 1;
}
for (int i = 0; i < numIntervals; i++)
{
Interval I = intervals[i];
n += (I.b - I.a + 1);
}
return n;
}
public virtual IntegerList ToIntegerList()
{
IntegerList values = new IntegerList(Size());
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = intervals[i];
int a = I.a;
int b = I.b;
for (int v = a; v <= b; v++)
{
values.Add(v);
}
}
return values;
}
public virtual IList<int> ToList()
{
IList<int> values = new List<int>();
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = intervals[i];
int a = I.a;
int b = I.b;
for (int v = a; v <= b; v++)
{
values.AddItem(v);
}
}
return values;
}
public virtual ICollection<int> ToSet()
{
ICollection<int> s = new HashSet<int>();
foreach (Interval I in intervals)
{
int a = I.a;
int b = I.b;
for (int v = a; v <= b; v++)
{
s.AddItem(v);
}
}
return s;
}
public virtual int[] ToArray()
{
return ToIntegerList().ToArray();
}
public virtual void Remove(int el)
{
if (@readonly)
{
throw new InvalidOperationException("can't alter readonly IntervalSet");
}
int n = intervals.Count;
for (int i = 0; i < n; i++)
{
Interval I = intervals[i];
int a = I.a;
int b = I.b;
if (el < a)
{
break;
}
// list is sorted and el is before this interval; not here
// if whole interval x..x, rm
if (el == a && el == b)
{
intervals.Remove(i);
break;
}
// if on left edge x..b, adjust left
if (el == a)
{
intervals.Set(i, Interval.Of(I.a + 1, I.b));
break;
}
// if on right edge a..x, adjust right
if (el == b)
{
intervals.Set(i, Interval.Of(I.a, I.b - 1));
break;
}
// if in middle a..x..b, split interval
if (el > a && el < b)
{
// found in this interval
int oldb = I.b;
intervals.Set(i, Interval.Of(I.a, el - 1));
// [a..x-1]
Add(el + 1, oldb);
}
}
}
// add [x+1..b]
public virtual bool IsReadonly()
{
return @readonly;
}
public virtual void SetReadonly(bool @readonly)
{
this.@readonly = @readonly;
}
}
}

View File

@ -0,0 +1,66 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
[System.Serializable]
public class MultiMap<K, V> : LinkedHashMap<K, IList<V>>
{
private const long serialVersionUID = -4956746660057462312L;
public virtual void Map(K key, V value)
{
IList<V> elementsForKey = Get(key);
if (elementsForKey == null)
{
elementsForKey = new List<V>();
base.Put(key, elementsForKey);
}
elementsForKey.AddItem(value);
}
public virtual IList<Tuple<K, V>> GetPairs()
{
IList<Tuple<K, V>> pairs = new List<Tuple<K, V>>();
foreach (K key in Keys)
{
foreach (V value in Get(key))
{
pairs.AddItem(Tuple.Create(key, value));
}
}
return pairs;
}
}
}

View File

@ -0,0 +1,164 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>A HashMap that remembers the order that the elements were added.</summary>
/// <remarks>
/// A HashMap that remembers the order that the elements were added.
/// You can alter the ith element with set(i,value) too :) Unique list.
/// I need the replace/set-element-i functionality so I'm subclassing
/// LinkedHashSet.
/// </remarks>
[System.Serializable]
public class OrderedHashSet<T> : LinkedHashSet<T>
{
private const long serialVersionUID = 5281944403755906761L;
/// <summary>Track the elements as they are added to the set</summary>
protected internal List<T> elements = new List<T>();
public virtual T Get(int i)
{
return elements[i];
}
/// <summary>
/// Replace an existing value with a new value; updates the element
/// list and the hash table, but not the key as that has not changed.
/// </summary>
/// <remarks>
/// Replace an existing value with a new value; updates the element
/// list and the hash table, but not the key as that has not changed.
/// </remarks>
public virtual T Set(int i, T value)
{
T oldElement = elements[i];
elements.Set(i, value);
// update list
base.Remove(oldElement);
// now update the set: remove/add
base.AddItem(value);
return oldElement;
}
public virtual bool Remove(int i)
{
T o = elements.Remove(i);
return base.Remove(o);
}
/// <summary>
/// Add a value to list; keep in hashtable for consistency also;
/// Key is object itself.
/// </summary>
/// <remarks>
/// Add a value to list; keep in hashtable for consistency also;
/// Key is object itself. Good for say asking if a certain string is in
/// a list of strings.
/// </remarks>
public override bool AddItem(T value)
{
bool result = base.AddItem(value);
if (result)
{
// only track if new element not in set
elements.AddItem(value);
}
return result;
}
public override bool Remove(object o)
{
throw new NotSupportedException();
}
public override void Clear()
{
elements.Clear();
base.Clear();
}
public override int GetHashCode()
{
return elements.GetHashCode();
}
public override bool Equals(object o)
{
if (!(o is OrderedHashSet<object>))
{
return false;
}
// System.out.print("equals " + this + ", " + o+" = ");
bool same = elements != null && elements.Equals(((OrderedHashSet<object>)o).elements
);
// System.out.println(same);
return same;
}
public override IEnumerator<T> GetEnumerator()
{
return elements.GetEnumerator();
}
/// <summary>Return the List holding list of table elements.</summary>
/// <remarks>
/// Return the List holding list of table elements. Note that you are
/// NOT getting a copy so don't write to the list.
/// </remarks>
public virtual IList<T> Elements()
{
return elements;
}
public override object Clone()
{
OrderedHashSet<T> dup = (OrderedHashSet<T>)base.Clone();
// safe (result of clone)
dup.elements = new List<T>(this.elements);
return dup;
}
public override object[] ToArray()
{
return Sharpen.Collections.ToArray(elements);
}
public override string ToString()
{
return elements.ToString();
}
}
}

View File

@ -0,0 +1,71 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
/// <summary>This exception is thrown to cancel a parsing operation.</summary>
/// <remarks>
/// This exception is thrown to cancel a parsing operation. This exception does
/// not extend
/// <see cref="Antlr4.Runtime.RecognitionException">Antlr4.Runtime.RecognitionException
/// </see>
/// , allowing it to bypass the standard
/// error recovery mechanisms.
/// <see cref="Antlr4.Runtime.BailErrorStrategy">Antlr4.Runtime.BailErrorStrategy</see>
/// throws this exception in
/// response to a parse error.
/// </remarks>
/// <author>Sam Harwell</author>
[System.Serializable]
public class ParseCanceledException : OperationCanceledException
{
private const long serialVersionUID = -3529552099366979683L;
public ParseCanceledException()
{
}
public ParseCanceledException(string message) : base(message)
{
}
public ParseCanceledException(Exception cause)
{
Sharpen.Extensions.InitCause(this, cause);
}
public ParseCanceledException(string message, Exception cause) : base(message)
{
Sharpen.Extensions.InitCause(this, cause);
}
}
}

View File

@ -0,0 +1,328 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Security;
using System.Text;
using Antlr4.Runtime;
using Sharpen;
using Sharpen.Annotation;
using Sharpen.Logging;
using Sharpen.Reflect;
namespace Antlr4.Runtime.Misc
{
/// <author>Sam Harwell</author>
public class RuleDependencyChecker
{
private static readonly Logger Logger = Logger.GetLogger(typeof(Antlr4.Runtime.Misc.RuleDependencyChecker
).FullName);
private static readonly ICollection<Type> checkedTypes = new HashSet<Type>();
public static void CheckDependencies<_T0>(Type<_T0> dependentClass)
{
if (IsChecked(dependentClass))
{
return;
}
IList<Type> typesToCheck = new List<Type>();
typesToCheck.AddItem(dependentClass);
Sharpen.Collections.AddAll(typesToCheck, dependentClass.GetDeclaredClasses());
foreach (Type clazz in typesToCheck)
{
if (IsChecked(clazz))
{
continue;
}
IList<Tuple<RuleDependency, IAnnotatedElement>> dependencies = GetDependencies(clazz
);
if (dependencies.IsEmpty())
{
continue;
}
CheckDependencies(dependencies, dependencies[0].GetItem1().Recognizer());
}
}
private static bool IsChecked<_T0>(Type<_T0> clazz)
{
lock (checkedTypes)
{
return checkedTypes.Contains(clazz);
}
}
private static void MarkChecked<_T0>(Type<_T0> clazz)
{
lock (checkedTypes)
{
checkedTypes.AddItem(clazz);
}
}
private static void CheckDependencies<_T0>(IList<Tuple<RuleDependency, IAnnotatedElement
>> dependencies, Type<_T0> recognizerClass) where _T0:Recognizer<object, object
>
{
string[] ruleNames = GetRuleNames(recognizerClass);
int[] ruleVersions = GetRuleVersions(recognizerClass, ruleNames);
StringBuilder incompatible = new StringBuilder();
foreach (Tuple<RuleDependency, IAnnotatedElement> dependency in dependencies)
{
if (!recognizerClass.IsAssignableFrom(dependency.GetItem1().Recognizer()))
{
continue;
}
if (dependency.GetItem1().Rule() < 0 || dependency.GetItem1().Rule() >= ruleVersions
.Length)
{
incompatible.Append(string.Format("Element %s dependent on unknown rule %d@%d in %s\n"
, dependency.GetItem2().ToString(), dependency.GetItem1().Rule(), dependency.
GetItem1().Version(), dependency.GetItem1().Recognizer().Name));
}
else
{
if (ruleVersions[dependency.GetItem1().Rule()] != dependency.GetItem1().Version())
{
incompatible.Append(string.Format("Element %s dependent on rule %s@%d (found @%d) in %s\n"
, dependency.GetItem2().ToString(), ruleNames[dependency.GetItem1().Rule()],
dependency.GetItem1().Version(), ruleVersions[dependency.GetItem1().Rule()],
dependency.GetItem1().Recognizer().Name));
}
}
}
if (incompatible.Length != 0)
{
throw new InvalidOperationException(incompatible.ToString());
}
MarkChecked(recognizerClass);
}
private static int[] GetRuleVersions<_T0>(Type<_T0> recognizerClass, string[] ruleNames
) where _T0:Recognizer<object, object>
{
int[] versions = new int[ruleNames.Length];
FieldInfo[] fields = recognizerClass.GetFields();
foreach (FieldInfo field in fields)
{
bool isStatic = (field.GetModifiers() & Modifier.Static) != 0;
bool isInteger = field.FieldType == typeof(int);
if (isStatic && isInteger && field.Name.StartsWith("RULE_"))
{
try
{
string name = Sharpen.Runtime.Substring(field.Name, "RULE_".Length);
if (name.IsEmpty() || !System.Char.IsLower(name[0]))
{
continue;
}
int index = field.GetInt(null);
if (index < 0 || index >= versions.Length)
{
object[] @params = new object[] { index, field.Name, recognizerClass.Name };
Logger.Log(Level.Warning, "Rule index {0} for rule ''{1}'' out of bounds for recognizer {2}."
, @params);
continue;
}
MethodInfo ruleMethod = GetRuleMethod(recognizerClass, name);
if (ruleMethod == null)
{
object[] @params = new object[] { name, recognizerClass.Name };
Logger.Log(Level.Warning, "Could not find rule method for rule ''{0}'' in recognizer {1}."
, @params);
continue;
}
RuleVersion ruleVersion = ruleMethod.GetAnnotation<RuleVersion>();
int version = ruleVersion != null ? ruleVersion.Value() : 0;
versions[index] = version;
}
catch (ArgumentException ex)
{
Logger.Log(Level.Warning, null, ex);
}
catch (MemberAccessException ex)
{
Logger.Log(Level.Warning, null, ex);
}
}
}
return versions;
}
private static MethodInfo GetRuleMethod<_T0>(Type<_T0> recognizerClass, string name
) where _T0:Recognizer<object, object>
{
MethodInfo[] declaredMethods = recognizerClass.GetMethods();
foreach (MethodInfo method in declaredMethods)
{
if (method.Name.Equals(name) && method.IsAnnotationPresent(typeof(RuleVersion)))
{
return method;
}
}
return null;
}
private static string[] GetRuleNames<_T0>(Type<_T0> recognizerClass) where _T0:Recognizer
<object, object>
{
try
{
FieldInfo ruleNames = recognizerClass.GetField("ruleNames");
return (string[])ruleNames.GetValue(null);
}
catch (NoSuchFieldException ex)
{
Logger.Log(Level.Warning, null, ex);
}
catch (SecurityException ex)
{
Logger.Log(Level.Warning, null, ex);
}
catch (ArgumentException ex)
{
Logger.Log(Level.Warning, null, ex);
}
catch (MemberAccessException ex)
{
Logger.Log(Level.Warning, null, ex);
}
return new string[0];
}
public static IList<Tuple<RuleDependency, IAnnotatedElement>> GetDependencies<_T0
>(Type<_T0> clazz)
{
IList<Tuple<RuleDependency, IAnnotatedElement>> result = new List<Tuple<RuleDependency
, IAnnotatedElement>>();
IList<ElementType> supportedTarget = Arrays.AsList(typeof(RuleDependency).GetAnnotation
<Target>().Value());
foreach (ElementType target in supportedTarget)
{
switch (target)
{
case ElementType.Type:
{
if (!clazz.IsAnnotation())
{
GetElementDependencies(clazz, result);
}
break;
}
case ElementType.AnnotationType:
{
if (!clazz.IsAnnotation())
{
GetElementDependencies(clazz, result);
}
break;
}
case ElementType.Constructor:
{
foreach (Constructor<object> ctor in clazz.GetDeclaredConstructors())
{
GetElementDependencies(ctor, result);
}
break;
}
case ElementType.Field:
{
foreach (FieldInfo field in Sharpen.Runtime.GetDeclaredFields(clazz))
{
GetElementDependencies(field, result);
}
break;
}
case ElementType.LocalVariable:
{
System.Console.Error.WriteLine("Runtime rule dependency checking is not supported for local variables."
);
break;
}
case ElementType.Method:
{
foreach (MethodInfo method in Sharpen.Runtime.GetDeclaredMethods(clazz))
{
GetElementDependencies(method, result);
}
break;
}
case ElementType.Package:
{
// package is not a subset of class, so nothing to do here
break;
}
case ElementType.Parameter:
{
System.Console.Error.WriteLine("Runtime rule dependency checking is not supported for parameters."
);
break;
}
}
}
return result;
}
private static void GetElementDependencies(IAnnotatedElement annotatedElement, IList
<Tuple<RuleDependency, IAnnotatedElement>> result)
{
RuleDependency dependency = annotatedElement.GetAnnotation<RuleDependency>();
if (dependency != null)
{
result.AddItem(Tuple.Create(dependency, annotatedElement));
}
RuleDependencies dependencies = annotatedElement.GetAnnotation<RuleDependencies>(
);
if (dependencies != null)
{
foreach (RuleDependency d in dependencies.Value())
{
if (d != null)
{
result.AddItem(Tuple.Create(d, annotatedElement));
}
}
}
}
public RuleDependencyChecker()
{
}
}
}

View File

@ -0,0 +1,861 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Javax.Annotation.Processing;
using Javax.Lang.Model.Element;
using Javax.Lang.Model.Type;
using Javax.Tools;
using Sharpen;
using Sharpen.Annotation;
namespace Antlr4.Runtime.Misc
{
/// <summary>A compile-time validator for rule dependencies.</summary>
/// <remarks>A compile-time validator for rule dependencies.</remarks>
/// <seealso cref="Antlr4.Runtime.RuleDependency">Antlr4.Runtime.RuleDependency</seealso>
/// <seealso cref="Antlr4.Runtime.RuleDependencies">Antlr4.Runtime.RuleDependencies</seealso>
/// <author>Sam Harwell</author>
public class RuleDependencyProcessor : AbstractProcessor
{
public static readonly string RuleDependencyClassName = "org.antlr.v4.runtime.RuleDependency";
public static readonly string RuleDependenciesClassName = "org.antlr.v4.runtime.RuleDependencies";
public static readonly string RuleVersionClassName = "org.antlr.v4.runtime.RuleVersion";
public RuleDependencyProcessor()
{
}
public override bool Process<_T0>(ICollection<_T0> annotations, IRoundEnvironment
roundEnv)
{
if (!CheckClassNameConstants())
{
return true;
}
IList<Tuple<RuleDependency, IElement>> dependencies = GetDependencies(roundEnv);
IDictionary<ITypeMirror, IList<Tuple<RuleDependency, IElement>>> recognizerDependencies
= new Dictionary<ITypeMirror, IList<Tuple<RuleDependency, IElement>>>();
foreach (Tuple<RuleDependency, IElement> dependency in dependencies)
{
ITypeMirror recognizerType = GetRecognizerType(dependency.GetItem1());
IList<Tuple<RuleDependency, IElement>> list = recognizerDependencies.Get(recognizerType
);
if (list == null)
{
list = new List<Tuple<RuleDependency, IElement>>();
recognizerDependencies.Put(recognizerType, list);
}
list.AddItem(dependency);
}
foreach (KeyValuePair<ITypeMirror, IList<Tuple<RuleDependency, IElement>>> entry in
recognizerDependencies.EntrySet())
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Note, string.Format("ANTLR 4: Validating %d dependencies on rules in %s."
, entry.Value.Count, entry.Key.ToString()));
CheckDependencies(entry.Value, entry.Key);
}
return true;
}
private bool CheckClassNameConstants()
{
bool success = CheckClassNameConstant(RuleDependencyClassName, typeof(RuleDependency
));
success &= CheckClassNameConstant(RuleDependenciesClassName, typeof(RuleDependencies
));
success &= CheckClassNameConstant(RuleVersionClassName, typeof(RuleVersion));
return success;
}
private bool CheckClassNameConstant<_T0>(string className, System.Type<_T0> clazz
)
{
Args.NotNull("className", className);
Args.NotNull("clazz", clazz);
if (!className.Equals(clazz.GetCanonicalName()))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, string.Format("Unable to process rule dependencies due to class name mismatch: %s != %s"
, className, clazz.GetCanonicalName()));
return false;
}
return true;
}
private static ITypeMirror GetRecognizerType(RuleDependency dependency)
{
try
{
dependency.Recognizer();
string message = string.Format("Expected %s to get the %s.", typeof(MirroredTypeException
).Name, typeof(ITypeMirror).Name);
throw new NotSupportedException(message);
}
catch (MirroredTypeException ex)
{
return ex.GetTypeMirror();
}
}
private void CheckDependencies(IList<Tuple<RuleDependency, IElement>> dependencies
, ITypeMirror recognizerType)
{
string[] ruleNames = GetRuleNames(recognizerType);
int[] ruleVersions = GetRuleVersions(recognizerType, ruleNames);
RuleDependencyProcessor.RuleRelations relations = ExtractRuleRelations(recognizerType
);
foreach (Tuple<RuleDependency, IElement> dependency in dependencies)
{
try
{
if (!processingEnv.GetTypeUtils().IsAssignable(GetRecognizerType(dependency.GetItem1
()), recognizerType))
{
continue;
}
// this is the rule in the dependency set with the highest version number
int effectiveRule = dependency.GetItem1().Rule();
if (effectiveRule < 0 || effectiveRule >= ruleVersions.Length)
{
Tuple<IAnnotationMirror, IAnnotationValue> ruleReferenceElement = FindRuleDependencyProperty
(dependency, RuleDependencyProcessor.RuleDependencyProperty.Rule);
string message = string.Format("Rule dependency on unknown rule %d@%d in %s", dependency
.GetItem1().Rule(), dependency.GetItem1().Version(), GetRecognizerType(dependency
.GetItem1()).ToString());
if (ruleReferenceElement != null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2(), ruleReferenceElement.GetItem1(), ruleReferenceElement.GetItem2()
);
}
else
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2());
}
continue;
}
EnumSet<Dependents> dependents = EnumSet.Of(Dependents.Self, dependency.GetItem1(
).Dependents());
ReportUnimplementedDependents(dependency, dependents);
BitSet checked = new BitSet();
int highestRequiredDependency = CheckDependencyVersion(dependency, ruleNames, ruleVersions
, effectiveRule, null);
if (dependents.Contains(Dependents.Parents))
{
BitSet parents = relations.parents[dependency.GetItem1().Rule()];
for (int parent = parents.NextSetBit(0); parent >= 0; parent = parents.NextSetBit
(parent + 1))
{
if (parent < 0 || parent >= ruleVersions.Length || checked.Get(parent))
{
continue;
}
checked.Set(parent);
int required = CheckDependencyVersion(dependency, ruleNames, ruleVersions, parent
, "parent");
highestRequiredDependency = Math.Max(highestRequiredDependency, required);
}
}
if (dependents.Contains(Dependents.Children))
{
BitSet children = relations.children[dependency.GetItem1().Rule()];
for (int child = children.NextSetBit(0); child >= 0; child = children.NextSetBit(
child + 1))
{
if (child < 0 || child >= ruleVersions.Length || checked.Get(child))
{
continue;
}
checked.Set(child);
int required = CheckDependencyVersion(dependency, ruleNames, ruleVersions, child,
"child");
highestRequiredDependency = Math.Max(highestRequiredDependency, required);
}
}
if (dependents.Contains(Dependents.Ancestors))
{
BitSet ancestors = relations.GetAncestors(dependency.GetItem1().Rule());
for (int ancestor = ancestors.NextSetBit(0); ancestor >= 0; ancestor = ancestors.
NextSetBit(ancestor + 1))
{
if (ancestor < 0 || ancestor >= ruleVersions.Length || checked.Get(ancestor))
{
continue;
}
checked.Set(ancestor);
int required = CheckDependencyVersion(dependency, ruleNames, ruleVersions, ancestor
, "ancestor");
highestRequiredDependency = Math.Max(highestRequiredDependency, required);
}
}
if (dependents.Contains(Dependents.Descendants))
{
BitSet descendants = relations.GetDescendants(dependency.GetItem1().Rule());
for (int descendant = descendants.NextSetBit(0); descendant >= 0; descendant = descendants
.NextSetBit(descendant + 1))
{
if (descendant < 0 || descendant >= ruleVersions.Length || checked.Get(descendant
))
{
continue;
}
checked.Set(descendant);
int required = CheckDependencyVersion(dependency, ruleNames, ruleVersions, descendant
, "descendant");
highestRequiredDependency = Math.Max(highestRequiredDependency, required);
}
}
int declaredVersion = dependency.GetItem1().Version();
if (declaredVersion > highestRequiredDependency)
{
Tuple<IAnnotationMirror, IAnnotationValue> versionElement = FindRuleDependencyProperty
(dependency, RuleDependencyProcessor.RuleDependencyProperty.Version);
string message = string.Format("Rule dependency version mismatch: %s has maximum dependency version %d (expected %d) in %s"
, ruleNames[dependency.GetItem1().Rule()], highestRequiredDependency, declaredVersion
, GetRecognizerType(dependency.GetItem1()).ToString());
if (versionElement != null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2(), versionElement.GetItem1(), versionElement.GetItem2());
}
else
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2());
}
}
}
catch (AnnotationTypeMismatchException)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, string.Format("Could not validate rule dependencies for element %s"
, dependency.GetItem2().ToString()), dependency.GetItem2());
}
}
}
private static readonly ICollection<Dependents> ImplementedDependents = EnumSet.Of
(Dependents.Self, Dependents.Parents, Dependents.Children, Dependents.Ancestors
, Dependents.Descendants);
private void ReportUnimplementedDependents(Tuple<RuleDependency, IElement> dependency
, EnumSet<Dependents> dependents)
{
EnumSet<Dependents> unimplemented = dependents.Clone();
unimplemented.RemoveAll(ImplementedDependents);
if (!unimplemented.IsEmpty())
{
Tuple<IAnnotationMirror, IAnnotationValue> dependentsElement = FindRuleDependencyProperty
(dependency, RuleDependencyProcessor.RuleDependencyProperty.Dependents);
if (dependentsElement == null)
{
dependentsElement = FindRuleDependencyProperty(dependency, RuleDependencyProcessor.RuleDependencyProperty
.Rule);
}
string message = string.Format("Cannot validate the following dependents of rule %d: %s"
, dependency.GetItem1().Rule(), unimplemented);
if (dependentsElement != null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, message, dependency
.GetItem2(), dependentsElement.GetItem1(), dependentsElement.GetItem2());
}
else
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, message, dependency
.GetItem2());
}
}
}
private int CheckDependencyVersion(Tuple<RuleDependency, IElement> dependency, string
[] ruleNames, int[] ruleVersions, int relatedRule, string relation)
{
string ruleName = ruleNames[dependency.GetItem1().Rule()];
string path;
if (relation == null)
{
path = ruleName;
}
else
{
string mismatchedRuleName = ruleNames[relatedRule];
path = string.Format("rule %s (%s of %s)", mismatchedRuleName, relation, ruleName
);
}
int declaredVersion = dependency.GetItem1().Version();
int actualVersion = ruleVersions[relatedRule];
if (actualVersion > declaredVersion)
{
Tuple<IAnnotationMirror, IAnnotationValue> versionElement = FindRuleDependencyProperty
(dependency, RuleDependencyProcessor.RuleDependencyProperty.Version);
string message = string.Format("Rule dependency version mismatch: %s has version %d (expected <= %d) in %s"
, path, actualVersion, declaredVersion, GetRecognizerType(dependency.GetItem1
()).ToString());
if (versionElement != null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2(), versionElement.GetItem1(), versionElement.GetItem2());
}
else
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, dependency
.GetItem2());
}
}
return actualVersion;
}
private int[] GetRuleVersions(ITypeMirror recognizerClass, string[] ruleNames)
{
int[] versions = new int[ruleNames.Length];
IList<IElement> elements = processingEnv.GetElementUtils().GetAllMembers((ITypeElement
)processingEnv.GetTypeUtils().AsElement(recognizerClass));
foreach (IElement element in elements)
{
if (element.GetKind() != ElementKind.Field)
{
continue;
}
IVariableElement field = (IVariableElement)element;
bool isStatic = element.GetModifiers().Contains(Modifier.Static);
object constantValue = field.GetConstantValue();
bool isInteger = constantValue is int;
string name = field.GetSimpleName().ToString();
if (isStatic && isInteger && name.StartsWith("RULE_"))
{
try
{
name = Sharpen.Runtime.Substring(name, "RULE_".Length);
if (name.IsEmpty() || !System.Char.IsLower(name[0]))
{
continue;
}
int index = (int)constantValue;
if (index < 0 || index >= versions.Length)
{
string message = string.Format("Rule index %d for rule '%s' out of bounds for recognizer %s."
, index, name, recognizerClass.ToString());
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, element);
continue;
}
if (name.IndexOf(ATNSimulator.RuleVariantDelimiter) >= 0)
{
// ignore left-factored pseudo-rules
continue;
}
IExecutableElement ruleMethod = GetRuleMethod(recognizerClass, name);
if (ruleMethod == null)
{
string message = string.Format("Could not find rule method for rule '%s' in recognizer %s."
, name, recognizerClass.ToString());
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, message, element);
continue;
}
RuleVersion ruleVersion = ruleMethod.GetAnnotation<RuleVersion>();
int version = ruleVersion != null ? ruleVersion.Value() : 0;
versions[index] = version;
}
catch (ArgumentException)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, "Exception occurred while validating rule dependencies."
, element);
}
}
}
return versions;
}
private IExecutableElement GetRuleMethod(ITypeMirror recognizerClass, string name
)
{
IList<IElement> elements = processingEnv.GetElementUtils().GetAllMembers((ITypeElement
)processingEnv.GetTypeUtils().AsElement(recognizerClass));
foreach (IElement element in elements)
{
if (element.GetKind() != ElementKind.Method)
{
continue;
}
IExecutableElement method = (IExecutableElement)element;
if (method.GetSimpleName().ContentEquals(name) && HasRuleVersionAnnotation(method
))
{
return method;
}
}
return null;
}
private bool HasRuleVersionAnnotation(IExecutableElement method)
{
ITypeElement ruleVersionAnnotationElement = processingEnv.GetElementUtils().GetTypeElement
(RuleVersionClassName);
if (ruleVersionAnnotationElement == null)
{
return false;
}
foreach (IAnnotationMirror annotation in method.GetAnnotationMirrors())
{
if (processingEnv.GetTypeUtils().IsSameType(annotation.GetAnnotationType(), ruleVersionAnnotationElement
.AsType()))
{
return true;
}
}
return false;
}
private string[] GetRuleNames(ITypeMirror recognizerClass)
{
IList<string> result = new List<string>();
IList<IElement> elements = processingEnv.GetElementUtils().GetAllMembers((ITypeElement
)processingEnv.GetTypeUtils().AsElement(recognizerClass));
foreach (IElement element in elements)
{
if (element.GetKind() != ElementKind.Field)
{
continue;
}
IVariableElement field = (IVariableElement)element;
bool isStatic = element.GetModifiers().Contains(Modifier.Static);
object constantValue = field.GetConstantValue();
bool isInteger = constantValue is int;
string name = field.GetSimpleName().ToString();
if (isStatic && isInteger && name.StartsWith("RULE_"))
{
try
{
name = Sharpen.Runtime.Substring(name, "RULE_".Length);
if (name.IsEmpty() || !System.Char.IsLower(name[0]))
{
continue;
}
int index = (int)constantValue;
if (index < 0)
{
continue;
}
while (result.Count <= index)
{
result.AddItem(string.Empty);
}
result.Set(index, name);
}
catch (ArgumentException)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, "Exception occurred while validating rule dependencies."
, element);
}
}
}
return Sharpen.Collections.ToArray(result, new string[result.Count]);
}
public static IList<Tuple<RuleDependency, IElement>> GetDependencies(IRoundEnvironment
roundEnv)
{
IList<Tuple<RuleDependency, IElement>> result = new List<Tuple<RuleDependency, IElement
>>();
ICollection<IElement> elements = roundEnv.GetElementsAnnotatedWith(typeof(RuleDependency
));
foreach (IElement element in elements)
{
RuleDependency dependency = element.GetAnnotation<RuleDependency>();
if (dependency == null)
{
continue;
}
result.AddItem(Tuple.Create(dependency, element));
}
elements = roundEnv.GetElementsAnnotatedWith(typeof(RuleDependencies));
foreach (IElement element_1 in elements)
{
RuleDependencies dependencies = element_1.GetAnnotation<RuleDependencies>();
if (dependencies == null || dependencies.Value() == null)
{
continue;
}
foreach (RuleDependency dependency in dependencies.Value())
{
result.AddItem(Tuple.Create(dependency, element_1));
}
}
return result;
}
public enum RuleDependencyProperty
{
Recognizer,
Rule,
Version,
Dependents
}
[Nullable]
private Tuple<IAnnotationMirror, IAnnotationValue> FindRuleDependencyProperty(Tuple
<RuleDependency, IElement> dependency, RuleDependencyProcessor.RuleDependencyProperty
property)
{
ITypeElement ruleDependencyTypeElement = processingEnv.GetElementUtils().GetTypeElement
(RuleDependencyClassName);
ITypeElement ruleDependenciesTypeElement = processingEnv.GetElementUtils().GetTypeElement
(RuleDependenciesClassName);
IList<IAnnotationMirror> mirrors = dependency.GetItem2().GetAnnotationMirrors();
foreach (IAnnotationMirror annotationMirror in mirrors)
{
if (processingEnv.GetTypeUtils().IsSameType(ruleDependencyTypeElement.AsType(), annotationMirror
.GetAnnotationType()))
{
IAnnotationValue element = FindRuleDependencyProperty(dependency, annotationMirror
, property);
if (element != null)
{
return Tuple.Create(annotationMirror, element);
}
}
else
{
if (processingEnv.GetTypeUtils().IsSameType(ruleDependenciesTypeElement.AsType(),
annotationMirror.GetAnnotationType()))
{
IDictionary<IExecutableElement, IAnnotationValue> values = annotationMirror.GetElementValues
();
foreach (KeyValuePair<IExecutableElement, IAnnotationValue> value in values.EntrySet
())
{
if ("value()".Equals(value.Key.ToString()))
{
IAnnotationValue annotationValue = value.Value;
if (!(annotationValue.GetValue() is IList))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Expected array of RuleDependency annotations for annotation property 'value()'."
, dependency.GetItem2(), annotationMirror, annotationValue);
break;
}
IList<object> annotationValueList = (IList<object>)annotationValue.GetValue();
foreach (object obj in annotationValueList)
{
if (!(obj is IAnnotationMirror))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Expected RuleDependency annotation mirror for element of property 'value()'."
, dependency.GetItem2(), annotationMirror, annotationValue);
break;
}
IAnnotationValue element = FindRuleDependencyProperty(dependency, (IAnnotationMirror
)obj, property);
if (element != null)
{
return Tuple.Create((IAnnotationMirror)obj, element);
}
}
}
else
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, string.Format("Unexpected annotation property %s."
, value.Key.ToString()), dependency.GetItem2(), annotationMirror, value.Value
);
}
}
}
}
}
return null;
}
[Nullable]
private IAnnotationValue FindRuleDependencyProperty(Tuple<RuleDependency, IElement
> dependency, IAnnotationMirror annotationMirror, RuleDependencyProcessor.RuleDependencyProperty
property)
{
IAnnotationValue recognizerValue = null;
IAnnotationValue ruleValue = null;
IAnnotationValue versionValue = null;
IAnnotationValue dependentsValue = null;
IDictionary<IExecutableElement, IAnnotationValue> values = annotationMirror.GetElementValues
();
foreach (KeyValuePair<IExecutableElement, IAnnotationValue> value in values.EntrySet
())
{
IAnnotationValue annotationValue = value.Value;
if ("rule()".Equals(value.Key.ToString()))
{
ruleValue = annotationValue;
if (!(annotationValue.GetValue() is int))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Expected int constant for annotation property 'rule()'."
, dependency.GetItem2(), annotationMirror, annotationValue);
return null;
}
if ((int)annotationValue.GetValue() != dependency.GetItem1().Rule())
{
// this is a valid dependency annotation, but not the one we're looking for
return null;
}
}
else
{
if ("recognizer()".Equals(value.Key.ToString()))
{
recognizerValue = annotationValue;
if (!(annotationValue.GetValue() is ITypeMirror))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Expected Class constant for annotation property 'recognizer()'."
, dependency.GetItem2(), annotationMirror, annotationValue);
return null;
}
ITypeMirror annotationRecognizer = (ITypeMirror)annotationValue.GetValue();
ITypeMirror expectedRecognizer = GetRecognizerType(dependency.GetItem1());
if (!processingEnv.GetTypeUtils().IsSameType(expectedRecognizer, annotationRecognizer
))
{
// this is a valid dependency annotation, but not the one we're looking for
return null;
}
}
else
{
if ("version()".Equals(value.Key.ToString()))
{
versionValue = annotationValue;
if (!(annotationValue.GetValue() is int))
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Expected int constant for annotation property 'version()'."
, dependency.GetItem2(), annotationMirror, annotationValue);
return null;
}
if ((int)annotationValue.GetValue() != dependency.GetItem1().Version())
{
// this is a valid dependency annotation, but not the one we're looking for
return null;
}
}
}
}
}
if (recognizerValue != null)
{
if (property == RuleDependencyProcessor.RuleDependencyProperty.Recognizer)
{
return recognizerValue;
}
else
{
if (ruleValue != null)
{
if (property == RuleDependencyProcessor.RuleDependencyProperty.Rule)
{
return ruleValue;
}
else
{
if (versionValue != null)
{
if (property == RuleDependencyProcessor.RuleDependencyProperty.Version)
{
return versionValue;
}
else
{
if (property == RuleDependencyProcessor.RuleDependencyProperty.Dependents)
{
return dependentsValue;
}
}
}
}
}
}
}
if (recognizerValue == null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Could not find 'recognizer()' element in annotation."
, dependency.GetItem2(), annotationMirror);
}
if (property == RuleDependencyProcessor.RuleDependencyProperty.Recognizer)
{
return null;
}
if (ruleValue == null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Could not find 'rule()' element in annotation."
, dependency.GetItem2(), annotationMirror);
}
if (property == RuleDependencyProcessor.RuleDependencyProperty.Rule)
{
return null;
}
if (versionValue == null)
{
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Warning, "Could not find 'version()' element in annotation."
, dependency.GetItem2(), annotationMirror);
}
return null;
}
private RuleDependencyProcessor.RuleRelations ExtractRuleRelations(ITypeMirror recognizer
)
{
string serializedATN = GetSerializedATN(recognizer);
if (serializedATN == null)
{
return null;
}
ATN atn = ATNSimulator.Deserialize(serializedATN.ToCharArray());
RuleDependencyProcessor.RuleRelations relations = new RuleDependencyProcessor.RuleRelations
(atn.ruleToStartState.Length);
foreach (ATNState state in atn.states)
{
if (!state.epsilonOnlyTransitions)
{
continue;
}
foreach (Transition transition in state.GetTransitions())
{
if (transition.SerializationType != Transition.Rule)
{
continue;
}
RuleTransition ruleTransition = (RuleTransition)transition;
relations.AddRuleInvocation(state.ruleIndex, ruleTransition.target.ruleIndex);
}
}
return relations;
}
private string GetSerializedATN(ITypeMirror recognizerClass)
{
IList<IElement> elements = processingEnv.GetElementUtils().GetAllMembers((ITypeElement
)processingEnv.GetTypeUtils().AsElement(recognizerClass));
foreach (IElement element in elements)
{
if (element.GetKind() != ElementKind.Field)
{
continue;
}
IVariableElement field = (IVariableElement)element;
bool isStatic = element.GetModifiers().Contains(Modifier.Static);
object constantValue = field.GetConstantValue();
bool isString = constantValue is string;
string name = field.GetSimpleName().ToString();
if (isStatic && isString && name.Equals("_serializedATN"))
{
return (string)constantValue;
}
}
processingEnv.GetMessager().PrintMessage(Diagnostic.Kind.Error, "Could not retrieve serialized ATN from grammar."
);
return null;
}
private sealed class RuleRelations
{
private readonly BitSet[] parents;
private readonly BitSet[] children;
public RuleRelations(int ruleCount)
{
parents = new BitSet[ruleCount];
for (int i = 0; i < ruleCount; i++)
{
parents[i] = new BitSet();
}
children = new BitSet[ruleCount];
for (int i_1 = 0; i_1 < ruleCount; i_1++)
{
children[i_1] = new BitSet();
}
}
public bool AddRuleInvocation(int caller, int callee)
{
if (caller < 0)
{
// tokens rule
return false;
}
if (children[caller].Get(callee))
{
// already added
return false;
}
children[caller].Set(callee);
parents[callee].Set(caller);
return true;
}
public BitSet GetAncestors(int rule)
{
BitSet ancestors = new BitSet();
ancestors.Or(parents[rule]);
while (true)
{
int cardinality = ancestors.Cardinality();
for (int i = ancestors.NextSetBit(0); i >= 0; i = ancestors.NextSetBit(i + 1))
{
ancestors.Or(parents[i]);
}
if (ancestors.Cardinality() == cardinality)
{
// nothing changed
break;
}
}
return ancestors;
}
public BitSet GetDescendants(int rule)
{
BitSet descendants = new BitSet();
descendants.Or(children[rule]);
while (true)
{
int cardinality = descendants.Cardinality();
for (int i = descendants.NextSetBit(0); i >= 0; i = descendants.NextSetBit(i + 1))
{
descendants.Or(children[i]);
}
if (descendants.Cardinality() == cardinality)
{
// nothing changed
break;
}
}
return descendants;
}
}
}
}

View File

@ -0,0 +1,337 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Sharpen;
using Sharpen.Reflect;
namespace Antlr4.Runtime.Misc
{
/// <summary>
/// Run a lexer/parser combo, optionally printing tree string or generating
/// postscript file.
/// </summary>
/// <remarks>
/// Run a lexer/parser combo, optionally printing tree string or generating
/// postscript file. Optionally taking input file.
/// $ java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName
/// [-tree]
/// [-tokens] [-gui] [-ps file.ps]
/// [-trace]
/// [-diagnostics]
/// [-SLL]
/// [input-filename(s)]
/// </remarks>
public class TestRig
{
public static readonly string LexerStartRuleName = "tokens";
protected internal string grammarName;
protected internal string startRuleName;
protected internal readonly IList<string> inputFiles = new List<string>();
protected internal bool printTree = false;
protected internal bool gui = false;
protected internal string psFile = null;
protected internal bool showTokens = false;
protected internal bool trace = false;
protected internal bool diagnostics = false;
protected internal string encoding = null;
protected internal bool Sll = false;
/// <exception cref="System.Exception"></exception>
public TestRig(string[] args)
{
if (args.Length < 2)
{
System.Console.Error.WriteLine("java org.antlr.v4.runtime.misc.TestRig GrammarName startRuleName\n"
+ " [-tokens] [-tree] [-gui] [-ps file.ps] [-encoding encodingname]\n" + " [-trace] [-diagnostics] [-SLL]\n"
+ " [input-filename(s)]");
System.Console.Error.WriteLine("Use startRuleName='tokens' if GrammarName is a lexer grammar."
);
System.Console.Error.WriteLine("Omitting input-filename makes rig read from stdin."
);
return;
}
int i = 0;
grammarName = args[i];
i++;
startRuleName = args[i];
i++;
while (i < args.Length)
{
string arg = args[i];
i++;
if (arg[0] != '-')
{
// input file name
inputFiles.AddItem(arg);
continue;
}
if (arg.Equals("-tree"))
{
printTree = true;
}
if (arg.Equals("-gui"))
{
gui = true;
}
if (arg.Equals("-tokens"))
{
showTokens = true;
}
else
{
if (arg.Equals("-trace"))
{
trace = true;
}
else
{
if (arg.Equals("-SLL"))
{
Sll = true;
}
else
{
if (arg.Equals("-diagnostics"))
{
diagnostics = true;
}
else
{
if (arg.Equals("-encoding"))
{
if (i >= args.Length)
{
System.Console.Error.WriteLine("missing encoding on -encoding");
return;
}
encoding = args[i];
i++;
}
else
{
if (arg.Equals("-ps"))
{
if (i >= args.Length)
{
System.Console.Error.WriteLine("missing filename on -ps");
return;
}
psFile = args[i];
i++;
}
}
}
}
}
}
}
}
/// <exception cref="System.Exception"></exception>
public static void Main(string[] args)
{
Antlr4.Runtime.Misc.TestRig testRig = new Antlr4.Runtime.Misc.TestRig(args);
testRig.Process();
}
/// <exception cref="System.Exception"></exception>
public virtual void Process()
{
// System.out.println("exec "+grammarName+"."+startRuleName);
string lexerName = grammarName + "Lexer";
ClassLoader cl = Sharpen.Thread.CurrentThread().GetContextClassLoader();
Type lexerClass = null;
try
{
lexerClass = cl.LoadClass(lexerName).AsSubclass<Lexer>();
}
catch (TypeLoadException)
{
// might be pure lexer grammar; no Lexer suffix then
lexerName = grammarName;
try
{
lexerClass = cl.LoadClass(lexerName).AsSubclass<Lexer>();
}
catch (TypeLoadException)
{
System.Console.Error.WriteLine("Can't load " + lexerName + " as lexer or parser");
return;
}
}
Constructor<Lexer> lexerCtor = lexerClass.GetConstructor(typeof(ICharStream));
Lexer lexer = lexerCtor.NewInstance((ICharStream)null);
Type parserClass = null;
Parser parser = null;
if (!startRuleName.Equals(LexerStartRuleName))
{
string parserName = grammarName + "Parser";
parserClass = (Type)cl.LoadClass(parserName).AsSubclass<Parser>();
if (parserClass == null)
{
System.Console.Error.WriteLine("Can't load " + parserName);
}
Constructor<Parser> parserCtor = parserClass.GetConstructor(typeof(ITokenStream));
parser = parserCtor.NewInstance((ITokenStream)null);
}
if (inputFiles.IsEmpty())
{
InputStream @is = Sharpen.Runtime.@in;
StreamReader r;
if (encoding != null)
{
r = new InputStreamReader(@is, encoding);
}
else
{
r = new InputStreamReader(@is);
}
Process(lexer, parserClass, parser, @is, r);
return;
}
foreach (string inputFile in inputFiles)
{
InputStream @is = Sharpen.Runtime.@in;
if (inputFile != null)
{
@is = new FileInputStream(inputFile);
}
StreamReader r;
if (encoding != null)
{
r = new InputStreamReader(@is, encoding);
}
else
{
r = new InputStreamReader(@is);
}
if (inputFiles.Count > 1)
{
System.Console.Error.WriteLine(inputFile);
}
Process(lexer, parserClass, parser, @is, r);
}
}
/// <exception cref="System.IO.IOException"></exception>
/// <exception cref="System.MemberAccessException"></exception>
/// <exception cref="System.Reflection.TargetInvocationException"></exception>
/// <exception cref="Javax.Print.PrintException"></exception>
protected internal virtual void Process<_T0>(Lexer lexer, Type<_T0> parserClass,
Parser parser, InputStream @is, StreamReader r) where _T0:Parser
{
try
{
AntlrInputStream input = new AntlrInputStream(r);
lexer.SetInputStream(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
tokens.Fill();
if (showTokens)
{
foreach (object tok in tokens.GetTokens())
{
System.Console.Out.WriteLine(tok);
}
}
if (startRuleName.Equals(LexerStartRuleName))
{
return;
}
if (diagnostics)
{
parser.AddErrorListener(new DiagnosticErrorListener());
parser.GetInterpreter().SetPredictionMode(PredictionMode.LlExactAmbigDetection);
}
if (printTree || gui || psFile != null)
{
parser.SetBuildParseTree(true);
}
if (Sll)
{
// overrides diagnostics
parser.GetInterpreter().SetPredictionMode(PredictionMode.Sll);
}
parser.SetInputStream(tokens);
parser.SetTrace(trace);
try
{
MethodInfo startRule = parserClass.GetMethod(startRuleName, (Type[])null);
ParserRuleContext tree = (ParserRuleContext)startRule.Invoke(parser, (object[])null
);
if (printTree)
{
System.Console.Out.WriteLine(tree.ToStringTree(parser));
}
if (gui)
{
tree.Inspect(parser);
}
if (psFile != null)
{
tree.Save(parser, psFile);
}
}
catch (NoSuchMethodException)
{
// Generate postscript
System.Console.Error.WriteLine("No method for rule " + startRuleName + " or it has arguments"
);
}
}
finally
{
if (r != null)
{
r.Close();
}
if (@is != null)
{
@is.Close();
}
}
}
}
}

View File

@ -0,0 +1,145 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections.Generic;
using System.Text;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime.Misc
{
public class Utils
{
public static int NumNonnull(object[] data)
{
int n = 0;
if (data == null)
{
return n;
}
foreach (object o in data)
{
if (o != null)
{
n++;
}
}
return n;
}
public static void RemoveAllElements<T>(ICollection<T> data, T value)
{
if (data == null)
{
return;
}
while (data.Contains(value))
{
data.Remove(value);
}
}
public static string EscapeWhitespace(string s, bool escapeSpaces)
{
StringBuilder buf = new StringBuilder();
foreach (char c in s.ToCharArray())
{
if (c == ' ' && escapeSpaces)
{
buf.Append('\u00B7');
}
else
{
if (c == '\t')
{
buf.Append("\\t");
}
else
{
if (c == '\n')
{
buf.Append("\\n");
}
else
{
if (c == '\r')
{
buf.Append("\\r");
}
else
{
buf.Append(c);
}
}
}
}
}
return buf.ToString();
}
public static void RemoveAll<T, _T1>(IList<T> list, IPredicate<_T1> predicate)
{
int j = 0;
for (int i = 0; i < list.Count; i++)
{
T item = list[i];
if (!predicate.Eval(item))
{
if (j != i)
{
list.Set(j, item);
}
j++;
}
}
if (j < list.Count)
{
list.SubList(j, list.Count).Clear();
}
}
public static void RemoveAll<T, _T1>(IEnumerable<T> iterable, IPredicate<_T1> predicate
)
{
if (iterable is IList<object>)
{
RemoveAll((IList<T>)iterable, predicate);
return;
}
for (IEnumerator<T> iterator = iterable.GetEnumerator(); iterator.HasNext(); )
{
T item = iterator.Next();
if (predicate.Eval(item))
{
iterator.Remove();
}
}
}
}
}

View File

@ -0,0 +1,97 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Misc;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>
/// Indicates that the parser could not decide which of two or more paths
/// to take based upon the remaining input.
/// </summary>
/// <remarks>
/// Indicates that the parser could not decide which of two or more paths
/// to take based upon the remaining input. It tracks the starting token
/// of the offending input and also knows where the parser was
/// in the various paths when the error. Reported by reportNoViableAlternative()
/// </remarks>
[System.Serializable]
public class NoViableAltException : RecognitionException
{
private const long serialVersionUID = 5096000008992867052L;
/// <summary>Which configurations did we try at input.index() that couldn't match input.LT(1)?
/// </summary>
[Nullable]
private readonly ATNConfigSet deadEndConfigs;
/// <summary>
/// The token object at the start index; the input stream might
/// not be buffering tokens so get a reference to it.
/// </summary>
/// <remarks>
/// The token object at the start index; the input stream might
/// not be buffering tokens so get a reference to it. (At the
/// time the error occurred, of course the stream needs to keep a
/// buffer all of the tokens but later we might not have access to those.)
/// </remarks>
[NotNull]
private readonly IToken startToken;
public NoViableAltException(Parser recognizer) : this(recognizer, ((ITokenStream)
recognizer.GetInputStream()), recognizer.GetCurrentToken(), recognizer.GetCurrentToken
(), null, recognizer._ctx)
{
}
public NoViableAltException(Recognizer<IToken, object> recognizer, ITokenStream input
, IToken startToken, IToken offendingToken, ATNConfigSet deadEndConfigs, ParserRuleContext
ctx) : base(recognizer, input, ctx)
{
// LL(1) error
this.deadEndConfigs = deadEndConfigs;
this.startToken = startToken;
this.SetOffendingToken(offendingToken);
}
public virtual IToken GetStartToken()
{
return startToken;
}
[Nullable]
public virtual ATNConfigSet GetDeadEndConfigs()
{
return deadEndConfigs;
}
}
}

922
Antlr4.Runtime/Parser.cs Normal file
View File

@ -0,0 +1,922 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Collections;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Atn;
using Antlr4.Runtime.Dfa;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>This is all the parsing support code essentially; most of it is error recovery stuff.
/// </summary>
/// <remarks>This is all the parsing support code essentially; most of it is error recovery stuff.
/// </remarks>
public abstract class Parser : Recognizer<IToken, ParserATNSimulator>
{
public class TraceListener : IParseTreeListener
{
public virtual void EnterEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("enter " + this._enclosing.GetRuleNames()[ctx.GetRuleIndex
()] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
}
public virtual void ExitEveryRule(ParserRuleContext ctx)
{
System.Console.Out.WriteLine("exit " + this._enclosing.GetRuleNames()[ctx.GetRuleIndex
()] + ", LT(1)=" + this._enclosing._input.Lt(1).Text);
}
public virtual void VisitErrorNode(IErrorNode node)
{
}
public virtual void VisitTerminal(ITerminalNode node)
{
ParserRuleContext parent = (ParserRuleContext)((IRuleNode)node.Parent).RuleContext;
IToken token = node.Symbol;
System.Console.Out.WriteLine("consume " + token + " rule " + this._enclosing.GetRuleNames
()[parent.GetRuleIndex()] + " alt=" + parent.altNum);
}
internal TraceListener(Parser _enclosing)
{
this._enclosing = _enclosing;
}
private readonly Parser _enclosing;
}
public class TrimToSizeListener : IParseTreeListener
{
public static readonly Parser.TrimToSizeListener Instance = new Parser.TrimToSizeListener
();
public virtual void VisitTerminal(ITerminalNode node)
{
}
public virtual void VisitErrorNode(IErrorNode node)
{
}
public virtual void EnterEveryRule(ParserRuleContext ctx)
{
}
public virtual void ExitEveryRule(ParserRuleContext ctx)
{
if (ctx.children is ArrayList)
{
((List<object>)ctx.children).TrimToSize();
}
}
}
protected internal IAntlrErrorStrategy _errHandler = new DefaultErrorStrategy();
protected internal ITokenStream _input;
protected internal readonly IntegerStack _precedenceStack;
/// <summary>The RuleContext object for the currently executing rule.</summary>
/// <remarks>
/// The RuleContext object for the currently executing rule. This
/// must be non-null during parsing, but is initially null.
/// When somebody calls the start rule, this gets set to the
/// root context.
/// </remarks>
protected internal ParserRuleContext _ctx;
protected internal bool _buildParseTrees = true;
protected internal Parser.TraceListener _tracer;
/// <summary>
/// If the listener is non-null, trigger enter and exit rule events
/// *during* the parse.
/// </summary>
/// <remarks>
/// If the listener is non-null, trigger enter and exit rule events
/// *during* the parse. This is typically done only when not building
/// parse trees for later visiting. We either trigger events during
/// the parse or during tree walks later. Both could be done.
/// Not intended for average user!!! Most people should use
/// ParseTreeListener with ParseTreeWalker.
/// </remarks>
/// <seealso cref="Antlr4.Runtime.Tree.ParseTreeWalker">Antlr4.Runtime.Tree.ParseTreeWalker
/// </seealso>
protected internal IList<IParseTreeListener> _parseListeners;
/// <summary>Did the recognizer encounter a syntax error? Track how many.</summary>
/// <remarks>Did the recognizer encounter a syntax error? Track how many.</remarks>
protected internal int _syntaxErrors = 0;
public Parser(ITokenStream input)
{
{
_precedenceStack = new IntegerStack();
_precedenceStack.Push(0);
}
SetInputStream(input);
}
/// <summary>reset the parser's state</summary>
public virtual void Reset()
{
if (((ITokenStream)GetInputStream()) != null)
{
((ITokenStream)GetInputStream()).Seek(0);
}
_errHandler.EndErrorCondition(this);
_ctx = null;
_syntaxErrors = 0;
_tracer = null;
_precedenceStack.Clear();
_precedenceStack.Push(0);
ATNSimulator interpreter = GetInterpreter();
if (interpreter != null)
{
interpreter.Reset();
}
}
/// <summary>Match current input symbol against ttype.</summary>
/// <remarks>
/// Match current input symbol against ttype. Attempt
/// single token insertion or deletion error recovery. If
/// that fails, throw MismatchedTokenException.
/// </remarks>
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual IToken Match(int ttype)
{
IToken t = GetCurrentToken();
if (t.Type == ttype)
{
_errHandler.EndErrorCondition(this);
Consume();
}
else
{
t = _errHandler.RecoverInline(this);
if (_buildParseTrees && t.TokenIndex == -1)
{
// we must have conjured up a new token during single token insertion
// if it's not the current symbol
_ctx.AddErrorNode(t);
}
}
return t;
}
/// <exception cref="Antlr4.Runtime.RecognitionException"></exception>
public virtual IToken MatchWildcard()
{
IToken t = GetCurrentToken();
if (t.Type > 0)
{
_errHandler.EndErrorCondition(this);
Consume();
}
else
{
t = _errHandler.RecoverInline(this);
if (_buildParseTrees && t.TokenIndex == -1)
{
// we must have conjured up a new token during single token insertion
// if it's not the current symbol
_ctx.AddErrorNode(t);
}
}
return t;
}
/// <summary>
/// Track the RuleContext objects during the parse and hook them up
/// using the children list so that it forms a parse tree.
/// </summary>
/// <remarks>
/// Track the RuleContext objects during the parse and hook them up
/// using the children list so that it forms a parse tree.
/// The RuleContext returned from the start rule represents the root
/// of the parse tree.
/// To built parse trees, all we have to do is put a hook in setState()
/// and enterRule(). In setState(), we add tokens to the current context
/// as children. By the time we get to enterRule(), we are already
/// in an invoked rule so we add this context as a child of the parent
/// (invoking) context. Simple and effective.
/// Note that if we are not building parse trees, rule contexts
/// only point upwards. When a rule exits, it returns the context
/// but that gets garbage collected if nobody holds a reference.
/// It points upwards but nobody points at it.
/// When we build parse trees, we are adding all of these contexts to
/// somebody's children list. Contexts are then not candidates
/// for garbage collection.
/// </remarks>
public virtual void SetBuildParseTree(bool buildParseTrees)
{
this._buildParseTrees = buildParseTrees;
}
public virtual bool GetBuildParseTree()
{
return _buildParseTrees;
}
/// <summary>Trim the internal lists of the parse tree during parsing to conserve memory.
/// </summary>
/// <remarks>
/// Trim the internal lists of the parse tree during parsing to conserve memory.
/// This property is set to
/// <code>false</code>
/// by default for a newly constructed parser.
/// </remarks>
/// <param name="trimParseTrees">
///
/// <code>true</code>
/// to trim the capacity of the
/// <see cref="ParserRuleContext.children">ParserRuleContext.children</see>
/// list to its size after a rule is parsed.
/// </param>
public virtual void SetTrimParseTree(bool trimParseTrees)
{
if (trimParseTrees)
{
if (GetTrimParseTree())
{
return;
}
AddParseListener(Parser.TrimToSizeListener.Instance);
}
else
{
RemoveParseListener(Parser.TrimToSizeListener.Instance);
}
}
/// <returns>
///
/// <code>true</code>
/// if the
/// <see cref="ParserRuleContext.children">ParserRuleContext.children</see>
/// list is trimmed
/// using the default
/// <see cref="TrimToSizeListener">TrimToSizeListener</see>
/// during the parse process.
/// </returns>
public virtual bool GetTrimParseTree()
{
if (_parseListeners == null)
{
return false;
}
return _parseListeners.Contains(Parser.TrimToSizeListener.Instance);
}
// public void setTraceATNStates(boolean traceATNStates) {
// this.traceATNStates = traceATNStates;
// }
//
// public boolean getTraceATNStates() {
// return traceATNStates;
// }
public virtual IList<IParseTreeListener> GetParseListeners()
{
return _parseListeners;
}
/// <summary>
/// Provide a listener that gets notified about token matches,
/// and rule entry/exit events DURING the parse.
/// </summary>
/// <remarks>
/// Provide a listener that gets notified about token matches,
/// and rule entry/exit events DURING the parse. It's a little bit
/// weird for left recursive rule entry events but it's
/// deterministic.
/// THIS IS ONLY FOR ADVANCED USERS. Please give your
/// ParseTreeListener to a ParseTreeWalker instead of giving it to
/// the parser!!!!
/// </remarks>
public virtual void AddParseListener(IParseTreeListener listener)
{
if (listener == null)
{
return;
}
if (_parseListeners == null)
{
_parseListeners = new List<IParseTreeListener>();
}
this._parseListeners.AddItem(listener);
}
public virtual void RemoveParseListener(IParseTreeListener l)
{
if (l == null)
{
return;
}
if (_parseListeners != null)
{
_parseListeners.Remove(l);
if (_parseListeners.IsEmpty())
{
_parseListeners = null;
}
}
}
public virtual void RemoveParseListeners()
{
_parseListeners = null;
}
/// <summary>
/// Notify any parse listeners (implemented as ParseTreeListener's)
/// of an enter rule event.
/// </summary>
/// <remarks>
/// Notify any parse listeners (implemented as ParseTreeListener's)
/// of an enter rule event. This is not involved with
/// parse tree walking in any way; it's just reusing the
/// ParseTreeListener interface. This is not for the average user.
/// </remarks>
public virtual void TriggerEnterRuleEvent()
{
foreach (IParseTreeListener l in _parseListeners)
{
l.EnterEveryRule(_ctx);
_ctx.EnterRule(l);
}
}
/// <summary>
/// Notify any parse listeners (implemented as ParseTreeListener's)
/// of an exit rule event.
/// </summary>
/// <remarks>
/// Notify any parse listeners (implemented as ParseTreeListener's)
/// of an exit rule event. This is not involved with
/// parse tree walking in any way; it's just reusing the
/// ParseTreeListener interface. This is not for the average user.
/// </remarks>
public virtual void TriggerExitRuleEvent()
{
// reverse order walk of listeners
for (int i = _parseListeners.Count - 1; i >= 0; i--)
{
IParseTreeListener l = _parseListeners[i];
_ctx.ExitRule(l);
l.ExitEveryRule(_ctx);
}
}
/// <summary>Get number of recognition errors (lexer, parser, tree parser).</summary>
/// <remarks>
/// Get number of recognition errors (lexer, parser, tree parser). Each
/// recognizer tracks its own number. So parser and lexer each have
/// separate count. Does not count the spurious errors found between
/// an error and next valid token match
/// See also reportError()
/// </remarks>
public virtual int GetNumberOfSyntaxErrors()
{
return _syntaxErrors;
}
public virtual IAntlrErrorStrategy GetErrorHandler()
{
return _errHandler;
}
public virtual void SetErrorHandler(IAntlrErrorStrategy handler)
{
this._errHandler = handler;
}
public override IIntStream GetInputStream()
{
return _input;
}
/// <summary>Set the token stream and reset the parser</summary>
public virtual void SetInputStream(ITokenStream input)
{
this._input = null;
Reset();
this._input = input;
}
/// <summary>
/// Match needs to return the current input symbol, which gets put
/// into the label for the associated token ref; e.g., x=ID.
/// </summary>
/// <remarks>
/// Match needs to return the current input symbol, which gets put
/// into the label for the associated token ref; e.g., x=ID.
/// </remarks>
public virtual IToken GetCurrentToken()
{
return _input.Lt(1);
}
public virtual void NotifyErrorListeners(string msg)
{
NotifyErrorListeners(GetCurrentToken(), msg, null);
}
public virtual void NotifyErrorListeners(IToken offendingToken, string msg, RecognitionException
e)
{
int line = -1;
int charPositionInLine = -1;
if (offendingToken != null)
{
line = offendingToken.Line;
charPositionInLine = offendingToken.Column;
}
IAntlrErrorListener<IToken> listener = ((IParserErrorListener)GetErrorListenerDispatch
());
listener.SyntaxError(this, offendingToken, line, charPositionInLine, msg, e);
}
/// <summary>Consume the current symbol and return it.</summary>
/// <remarks>
/// Consume the current symbol and return it. E.g., given the following
/// input with A being the current lookahead symbol:
/// A B
/// ^
/// this function moves the cursor to B and returns A.
/// If the parser is creating parse trees, the current symbol
/// would also be added as a child to the current context (node).
/// Trigger listener events if there's a listener.
/// </remarks>
public virtual IToken Consume()
{
IToken o = GetCurrentToken();
if (o.Type != Eof)
{
((ITokenStream)GetInputStream()).Consume();
}
bool hasListener = _parseListeners != null && !_parseListeners.IsEmpty();
if (_buildParseTrees || hasListener)
{
if (_errHandler.InErrorRecoveryMode(this))
{
IErrorNode node = _ctx.AddErrorNode(o);
if (_parseListeners != null)
{
foreach (IParseTreeListener listener in _parseListeners)
{
listener.VisitErrorNode(node);
}
}
}
else
{
ITerminalNode node = _ctx.AddChild(o);
if (_parseListeners != null)
{
foreach (IParseTreeListener listener in _parseListeners)
{
listener.VisitTerminal(node);
}
}
}
}
return o;
}
protected internal virtual void AddContextToParseTree()
{
ParserRuleContext parent = (ParserRuleContext)_ctx.parent;
// add current context to parent if we have a parent
if (parent != null)
{
parent.AddChild(_ctx);
}
}
/// <summary>Always called by generated parsers upon entry to a rule.</summary>
/// <remarks>
/// Always called by generated parsers upon entry to a rule.
/// This occurs after the new context has been pushed. Access field
/// _ctx get the current context.
/// This is flexible because users do not have to regenerate parsers
/// to get trace facilities.
/// </remarks>
public virtual void EnterRule(ParserRuleContext localctx, int state, int ruleIndex
)
{
SetState(state);
_ctx = localctx;
_ctx.start = _input.Lt(1);
if (_buildParseTrees)
{
AddContextToParseTree();
}
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
}
}
public virtual void EnterLeftFactoredRule(ParserRuleContext localctx, int state,
int ruleIndex)
{
SetState(state);
if (_buildParseTrees)
{
ParserRuleContext factoredContext = (ParserRuleContext)_ctx.GetChild(_ctx.ChildCount
- 1);
_ctx.RemoveLastChild();
factoredContext.parent = localctx;
localctx.AddChild(factoredContext);
}
_ctx = localctx;
_ctx.start = _input.Lt(1);
if (_buildParseTrees)
{
AddContextToParseTree();
}
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
}
}
public virtual void ExitRule()
{
_ctx.stop = _input.Lt(-1);
// trigger event on _ctx, before it reverts to parent
if (_parseListeners != null)
{
TriggerExitRuleEvent();
}
SetState(_ctx.invokingState);
_ctx = (ParserRuleContext)_ctx.parent;
}
public virtual void EnterOuterAlt(ParserRuleContext localctx, int altNum)
{
// if we have new localctx, make sure we replace existing ctx
// that is previous child of parse tree
if (_buildParseTrees && _ctx != localctx)
{
ParserRuleContext parent = (ParserRuleContext)_ctx.parent;
if (parent != null)
{
parent.RemoveLastChild();
parent.AddChild(localctx);
}
}
_ctx = localctx;
_ctx.altNum = altNum;
}
public virtual void EnterRecursionRule(ParserRuleContext localctx, int ruleIndex,
int precedence)
{
_precedenceStack.Push(precedence);
_ctx = localctx;
_ctx.start = _input.Lt(1);
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
}
}
// simulates rule entry for left-recursive rules
public virtual void PushNewRecursionContext(ParserRuleContext localctx, int state
, int ruleIndex)
{
ParserRuleContext previous = _ctx;
previous.parent = localctx;
previous.invokingState = state;
previous.stop = _input.Lt(-1);
_ctx = localctx;
_ctx.start = previous.start;
if (_buildParseTrees)
{
_ctx.AddChild(previous);
}
if (_parseListeners != null)
{
TriggerEnterRuleEvent();
}
}
// simulates rule entry for left-recursive rules
public virtual void UnrollRecursionContexts(ParserRuleContext _parentctx)
{
_precedenceStack.Pop();
_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
if (_parseListeners != null)
{
while (_ctx != _parentctx)
{
TriggerExitRuleEvent();
_ctx = (ParserRuleContext)_ctx.parent;
}
}
else
{
_ctx = _parentctx;
}
// hook into tree
retctx.parent = _parentctx;
if (_buildParseTrees)
{
_parentctx.AddChild(retctx);
}
}
// add return ctx into invoking rule's tree
public virtual ParserRuleContext GetInvokingContext(int ruleIndex)
{
ParserRuleContext p = _ctx;
while (p != null)
{
if (p.GetRuleIndex() == ruleIndex)
{
return p;
}
p = (ParserRuleContext)p.parent;
}
return null;
}
public virtual ParserRuleContext GetContext()
{
return _ctx;
}
public override bool Precpred(RuleContext localctx, int precedence)
{
return precedence >= _precedenceStack.Peek();
}
public override IAntlrErrorListener<IToken> GetErrorListenerDispatch()
{
return new ProxyParserErrorListener(GetErrorListeners());
}
public virtual bool InContext(string context)
{
// TODO: useful in parser?
return false;
}
public virtual bool IsExpectedToken(int symbol)
{
// return getInterpreter().atn.nextTokens(_ctx);
ATN atn = GetInterpreter().atn;
ParserRuleContext ctx = _ctx;
ATNState s = atn.states[GetState()];
IntervalSet following = atn.NextTokens(s);
if (following.Contains(symbol))
{
return true;
}
// System.out.println("following "+s+"="+following);
if (!following.Contains(IToken.Epsilon))
{
return false;
}
while (ctx != null && ctx.invokingState >= 0 && following.Contains(IToken.Epsilon
))
{
ATNState invokingState = atn.states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
following = atn.NextTokens(rt.followState);
if (following.Contains(symbol))
{
return true;
}
ctx = (ParserRuleContext)ctx.parent;
}
if (following.Contains(IToken.Epsilon) && symbol == IToken.Eof)
{
return true;
}
return false;
}
/// <summary>
/// Compute the set of valid tokens reachable from the current
/// position in the parse.
/// </summary>
/// <remarks>
/// Compute the set of valid tokens reachable from the current
/// position in the parse.
/// </remarks>
public virtual IntervalSet GetExpectedTokens()
{
ATN atn = GetInterpreter().atn;
ParserRuleContext ctx = _ctx;
ATNState s = atn.states[GetState()];
IntervalSet following = atn.NextTokens(s);
// System.out.println("following "+s+"="+following);
if (!following.Contains(IToken.Epsilon))
{
return following;
}
IntervalSet expected = new IntervalSet();
expected.AddAll(following);
expected.Remove(IToken.Epsilon);
while (ctx != null && ctx.invokingState >= 0 && following.Contains(IToken.Epsilon
))
{
ATNState invokingState = atn.states[ctx.invokingState];
RuleTransition rt = (RuleTransition)invokingState.Transition(0);
following = atn.NextTokens(rt.followState);
expected.AddAll(following);
expected.Remove(IToken.Epsilon);
ctx = (ParserRuleContext)ctx.parent;
}
if (following.Contains(IToken.Epsilon))
{
expected.Add(IToken.Eof);
}
return expected;
}
public virtual IntervalSet GetExpectedTokensWithinCurrentRule()
{
ATN atn = GetInterpreter().atn;
ATNState s = atn.states[GetState()];
return atn.NextTokens(s);
}
// /** Compute the set of valid tokens reachable from the current
// * position in the parse.
// */
// public IntervalSet nextTokens(@NotNull RuleContext ctx) {
// ATN atn = getInterpreter().atn;
// ATNState s = atn.states.get(ctx.s);
// if ( s == null ) return null;
// return atn.nextTokens(s, ctx);
// }
public virtual ParserRuleContext GetRuleContext()
{
return _ctx;
}
/// <summary>
/// Return List<String> of the rule names in your parser instance
/// leading up to a call to the current rule.
/// </summary>
/// <remarks>
/// Return List<String> of the rule names in your parser instance
/// leading up to a call to the current rule. You could override if
/// you want more details such as the file/line info of where
/// in the ATN a rule is invoked.
/// This is very useful for error messages.
/// </remarks>
public virtual IList<string> GetRuleInvocationStack()
{
return GetRuleInvocationStack(_ctx);
}
public virtual IList<string> GetRuleInvocationStack(RuleContext p)
{
string[] ruleNames = GetRuleNames();
IList<string> stack = new List<string>();
while (p != null)
{
// compute what follows who invoked us
int ruleIndex = p.GetRuleIndex();
if (ruleIndex < 0)
{
stack.AddItem("n/a");
}
else
{
stack.AddItem(ruleNames[ruleIndex]);
}
p = p.parent;
}
return stack;
}
/// <summary>For debugging and other purposes</summary>
public virtual IList<string> GetDFAStrings()
{
IList<string> s = new List<string>();
for (int d = 0; d < _interp.atn.decisionToDFA.Length; d++)
{
DFA dfa = _interp.atn.decisionToDFA[d];
s.AddItem(dfa.ToString(GetTokenNames(), GetRuleNames()));
}
return s;
}
/// <summary>For debugging and other purposes</summary>
public virtual void DumpDFA()
{
bool seenOne = false;
for (int d = 0; d < _interp.atn.decisionToDFA.Length; d++)
{
DFA dfa = _interp.atn.decisionToDFA[d];
if (!dfa.IsEmpty())
{
if (seenOne)
{
System.Console.Out.WriteLine();
}
System.Console.Out.WriteLine("Decision " + dfa.decision + ":");
System.Console.Out.Write(dfa.ToString(GetTokenNames(), GetRuleNames()));
seenOne = true;
}
}
}
public virtual string GetSourceName()
{
return _input.SourceName;
}
/// <summary>A convenience method for use most often with template rewrites.</summary>
/// <remarks>
/// A convenience method for use most often with template rewrites.
/// Convert a List<Token> to List<String>
/// </remarks>
public virtual IList<string> ToStrings<_T0>(IList<_T0> tokens) where _T0:IToken
{
if (tokens == null)
{
return null;
}
IList<string> strings = new List<string>(tokens.Count);
for (int i = 0; i < tokens.Count; i++)
{
strings.AddItem(tokens[i].Text);
}
return strings;
}
/// <summary>
/// During a parse is sometimes useful to listen in on the rule entry and exit
/// events as well as token matches.
/// </summary>
/// <remarks>
/// During a parse is sometimes useful to listen in on the rule entry and exit
/// events as well as token matches. This is for quick and dirty debugging.
/// </remarks>
public virtual void SetTrace(bool trace)
{
if (!trace)
{
RemoveParseListener(_tracer);
_tracer = null;
}
else
{
if (_tracer != null)
{
RemoveParseListener(_tracer);
}
else
{
_tracer = new Parser.TraceListener(this);
}
AddParseListener(_tracer);
}
}
}
}

View File

@ -0,0 +1,391 @@
/*
* [The "BSD license"]
* Copyright (c) 2013 Terence Parr
* Copyright (c) 2013 Sam Harwell
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using Antlr4.Runtime;
using Antlr4.Runtime.Misc;
using Antlr4.Runtime.Tree;
using Sharpen;
namespace Antlr4.Runtime
{
/// <summary>A rule invocation record for parsing.</summary>
/// <remarks>
/// A rule invocation record for parsing.
/// Contains all of the information about the current rule not stored in the
/// RuleContext. It handles parse tree children list, Any ATN state
/// tracing, and the default values available for rule indications:
/// start, stop, rule index, current alt number, current
/// ATN state.
/// Subclasses made for each rule and grammar track the parameters,
/// return values, locals, and labels specific to that rule. These
/// are the objects that are returned from rules.
/// Note text is not an actual field of a rule return value; it is computed
/// from start and stop using the input stream's toString() method. I
/// could add a ctor to this so that we can pass in and store the input
/// stream, but I'm not sure we want to do that. It would seem to be undefined
/// to get the .text property anyway if the rule matches tokens from multiple
/// input streams.
/// I do not use getters for fields of objects that are used simply to
/// group values such as this aggregate. The getters/setters are there to
/// satisfy the superclass interface.
/// </remarks>
public class ParserRuleContext : RuleContext
{
private static readonly Antlr4.Runtime.ParserRuleContext Empty = new Antlr4.Runtime.ParserRuleContext
();
/// <summary>
/// If we are debugging or building a parse tree for a visitor,
/// we need to track all of the tokens and rule invocations associated
/// with this rule's context.
/// </summary>
/// <remarks>
/// If we are debugging or building a parse tree for a visitor,
/// we need to track all of the tokens and rule invocations associated
/// with this rule's context. This is empty for parsing w/o tree constr.
/// operation because we don't the need to track the details about
/// how we parse this rule.
/// </remarks>
public IList<IParseTree> children;
/// <summary>
/// For debugging/tracing purposes, we want to track all of the nodes in
/// the ATN traversed by the parser for a particular rule.
/// </summary>
/// <remarks>
/// For debugging/tracing purposes, we want to track all of the nodes in
/// the ATN traversed by the parser for a particular rule.
/// This list indicates the sequence of ATN nodes used to match
/// the elements of the children list. This list does not include
/// ATN nodes and other rules used to match rule invocations. It
/// traces the rule invocation node itself but nothing inside that
/// other rule's ATN submachine.
/// There is NOT a one-to-one correspondence between the children and
/// states list. There are typically many nodes in the ATN traversed
/// for each element in the children list. For example, for a rule
/// invocation there is the invoking state and the following state.
/// The parser setState() method updates field s and adds it to this list
/// if we are debugging/tracing.
/// This does not trace states visited during prediction.
/// </remarks>
public IToken start;
/// <summary>
/// For debugging/tracing purposes, we want to track all of the nodes in
/// the ATN traversed by the parser for a particular rule.
/// </summary>
/// <remarks>
/// For debugging/tracing purposes, we want to track all of the nodes in
/// the ATN traversed by the parser for a particular rule.
/// This list indicates the sequence of ATN nodes used to match
/// the elements of the children list. This list does not include
/// ATN nodes and other rules used to match rule invocations. It
/// traces the rule invocation node itself but nothing inside that
/// other rule's ATN submachine.
/// There is NOT a one-to-one correspondence between the children and
/// states list. There are typically many nodes in the ATN traversed
/// for each element in the children list. For example, for a rule
/// invocation there is the invoking state and the following state.
/// The parser setState() method updates field s and adds it to this list
/// if we are debugging/tracing.
/// This does not trace states visited during prediction.
/// </remarks>
public IToken stop;
/// <summary>Set during parsing to identify which alt of rule parser is in.</summary>
/// <remarks>Set during parsing to identify which alt of rule parser is in.</remarks>
public int altNum;
/// <summary>The exception which forced this rule to return.</summary>
/// <remarks>
/// The exception which forced this rule to return. If the rule successfully
/// completed, this is
/// <code>null</code>
/// .
/// </remarks>
public RecognitionException exception;
public ParserRuleContext()
{
}
// public List<Integer> states;
public static Antlr4.Runtime.ParserRuleContext EmptyContext()
{
return Empty;
}
/// <summary>COPY a ctx (I'm deliberately not using copy constructor)</summary>
public virtual void CopyFrom(Antlr4.Runtime.ParserRuleContext ctx)
{
// from RuleContext
this.parent = ctx.parent;
this.invokingState = ctx.invokingState;
this.start = ctx.start;
this.stop = ctx.stop;
}
public ParserRuleContext(Antlr4.Runtime.ParserRuleContext parent, int invokingStateNumber
) : base(parent, invokingStateNumber)
{
}
// Double dispatch methods for listeners
public virtual void EnterRule(IParseTreeListener listener)
{
}
public virtual void ExitRule(IParseTreeListener listener)
{
}
/// <summary>Does not set parent link; other add methods do that</summary>
public virtual void AddChild(ITerminalNode t)
{
if (children == null)
{
children = new List<IParseTree>();
}
children.AddItem(t);
}
public virtual void AddChild(RuleContext ruleInvocation)
{
if (children == null)
{
children = new List<IParseTree>();
}
children.AddItem(ruleInvocation);
}
/// <summary>
/// Used by enterOuterAlt to toss out a RuleContext previously added as
/// we entered a rule.
/// </summary>
/// <remarks>
/// Used by enterOuterAlt to toss out a RuleContext previously added as
/// we entered a rule. If we have # label, we will need to remove
/// generic ruleContext object.
/// </remarks>
public virtual void RemoveLastChild()
{
if (children != null)
{
children.Remove(children.Count - 1);
}
}
// public void trace(int s) {
// if ( states==null ) states = new ArrayList<Integer>();
// states.add(s);
// }
public virtual ITerminalNode AddChild(IToken matchedToken)
{
TerminalNodeImpl t = new TerminalNodeImpl(matchedToken);
AddChild(t);
t.parent = this;
return t;
}
public virtual IErrorNode AddErrorNode(IToken badToken)
{
ErrorNodeImpl t = new ErrorNodeImpl(badToken);
AddChild(t);
t.parent = this;
return t;
}
public override RuleContext Parent
{
get
{
return (Antlr4.Runtime.ParserRuleContext)base.Parent;
}
}
public override IParseTree GetChild(int i)
{
return children != null && i >= 0 && i < children.Count ? children[i] : null;
}
public virtual T GetChild<T, _T1>(Type<_T1> ctxType, int i) where T:IParseTree where
_T1:T
{
if (children == null || i < 0 || i >= children.Count)
{
return null;
}
int j = -1;
// what element have we found with ctxType?
foreach (IParseTree o in children)
{
if (ctxType.IsInstanceOfType(o))
{
j++;
if (j == i)
{
return ctxType.Cast(o);
}
}
}
return null;
}
public virtual ITerminalNode GetToken(int ttype, int i)
{
if (children == null || i < 0 || i >= children.Count)
{
return null;
}
int j = -1;
// what token with ttype have we found?
foreach (IParseTree o in children)
{
if (o is ITerminalNode)
{
ITerminalNode tnode = (ITerminalNode)o;
IToken symbol = tnode.Symbol;
if (symbol.Type == ttype)
{
j++;
if (j == i)
{
return tnode;
}
}
}
}
return null;
}
public virtual IList<ITerminalNode> GetTokens(int ttype)
{
if (children == null)
{
return Sharpen.Collections.EmptyList();
}
IList<ITerminalNode> tokens = null;
foreach (IParseTree o in children)
{
if (o is ITerminalNode)
{
ITerminalNode tnode = (ITerminalNode)o;
IToken symbol = tnode.Symbol;
if (symbol.Type == ttype)
{
if (tokens == null)
{
tokens = new List<ITerminalNode>();
}
tokens.AddItem(tnode);
}
}
}
if (tokens == null)
{
return Sharpen.Collections.EmptyList();
}
return tokens;
}
public virtual T GetRuleContext<T, _T1>(Type<_T1> ctxType, int i) where T:Antlr4.Runtime.ParserRuleContext
where _T1:T
{
return GetChild(ctxType, i);
}
public virtual IList<T> GetRuleContexts<T, _T1>(Type<_T1> ctxType) where T:Antlr4.Runtime.ParserRuleContext
where _T1:T
{
if (children == null)
{
return Sharpen.Collections.EmptyList();
}
IList<T> contexts = null;
foreach (IParseTree o in children)
{
if (ctxType.IsInstanceOfType(o))
{
if (contexts == null)
{
contexts = new List<T>();
}
contexts.AddItem(ctxType.Cast(o));
}
}
if (contexts == null)
{
return Sharpen.Collections.EmptyList();
}
return contexts;
}
public override int ChildCount
{
get
{
return children != null ? children.Count : 0;
}
}
public override Interval SourceInterval
{
get
{
if (start == null || stop == null)
{
return Interval.Invalid;
}
return Interval.Of(start.TokenIndex, stop.TokenIndex);
}
}
public virtual IToken GetStart()
{
return start;
}
public virtual IToken GetStop()
{
return stop;
}
/// <summary>Used for rule context info debugging during parse-time, not so much for ATN debugging
/// </summary>
public virtual string ToInfoString(Parser recognizer)
{
IList<string> rules = recognizer.GetRuleInvocationStack(this);
Sharpen.Collections.Reverse(rules);
return "ParserRuleContext" + rules + "{" + "altNum=" + altNum + ", start=" + start
+ ", stop=" + stop + '}';
}
}
}

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