using System;
using HashtableSystem.Collections.Hashtable;
using StackSystem.Collections.Stack;
namespace Spring.Expressions.Parser.antlr{
/*ANTLR Translator Generator
* Project led by Terence Parr at http://www.jGuru.com
* Software rights: http://www.antlr.org/license.html
*
* $Id:$
*/
//
// ANTLR C# Code Generator by Micheal Jordan
// Kunle Odutola : kunle UNDERSCORE odutola AT hotmail DOT com
// Anthony Oguntimehin
//
// With many thanks to Eric V. Smith from the ANTLR list.
//
/*A token stream MUX (multiplexor) knows about n token streams
* and can multiplex them onto the same channel for use by token
* stream consumer like a parser. This is a way to have multiple
* lexers break up the same input stream for a single parser.
* Or, you can have multiple instances of the same lexer handle
* multiple input streams; this works great for includes.
*/
public class TokenStreamSelector : TokenStream
{
/*The set of inputs to the MUX */
protected internal Hashtable inputStreamNames;
/*The currently-selected token stream input */
protected internal TokenStream input;
/*Used to track stack of input streams */
protected internal Stack streamStack = new Stack();
public TokenStreamSelector() : base()
{
inputStreamNames = new Hashtable();
}
public virtual void addInputStream(TokenStream stream, string key)
{
inputStreamNames[key] = stream;
}
/*Return the stream from tokens are being pulled at
* the moment.
*/
public virtual TokenStream getCurrentStream()
{
return input;
}
public virtual TokenStream getStream(string sname)
{
TokenStream stream = (TokenStream) inputStreamNames[sname];
if (stream == null)
{
throw new System.ArgumentException("TokenStream " + sname + " not found");
}
return stream;
}
public virtual IToken nextToken()
{
// return input.nextToken();
// keep looking for a token until you don't
// get a retry exception.
for (; ; )
{
try
{
return input.nextToken();
}
catch (TokenStreamRetryException)
{
// just retry "forever"
}
}
}
public virtual TokenStream pop()
{
TokenStream stream = (TokenStream) streamStack.Pop();
select(stream);
return stream;
}
public virtual void push(TokenStream stream)
{
streamStack.Push(input); // save current stream
select(stream);
}
public virtual void push(string sname)
{
streamStack.Push(input);
select(sname);
}
/*Abort recognition of current Token and try again.
* A stream can push a new stream (for include files
* for example, and then retry(), which will cause
* the current stream to abort back to this.nextToken().
* this.nextToken() then asks for a token from the
* current stream, which is the new "substream."
*/
public virtual void retry()
{
throw new TokenStreamRetryException();
}
/*Set the stream without pushing old stream */
public virtual void select(TokenStream stream)
{
input = stream;
if (input is CharScanner)
{
((CharScanner) input).refresh();
}
}
public virtual void select(string sname)
{
input = getStream(sname);
if (input is CharScanner)
{
((CharScanner) input).refresh();
}
}
}
}
|