Re: multiple super types for generics
On Mar 26, 2:56 pm, Tom Hawtin <use...@tackline.plus.com> wrote:
Aryeh M. Friedman wrote:
now the question is how can I make it so sym[...] is T or State<T> the
only thing I can think of is something like the following syntex
(which I know is illegal):
public class State<T extends (T || State<T>)>
I'm not sure what you would do with such a thing. How would you do
anything to a reference to T, other than what you could do with an
Object? I think you want a little type hierarchy here so that you can
treat things uniformly:
class Terminal<T> extends State<T> {
Terminal(T t) {
...
class NonTerminal<T> extends State<T> {
NonTerminal(List<State<T>> symbols) {
...
You might also want to consider introducing a Builder.
Tom Hawtin
Thanks will look into using a Builder.... you almost nailed it but
something more like
public abstract class State<T>
{
public State()
{
symbols=new ArrayList<T>();
}
public void addSymbol(T sym) // this is = to State(T... syms)
I used in the orginal post but this is the actual implementation
{
states.add(t);
}
public abstract consume(List<T> in)
{
Queue<T> q=new
ArrayBackedBlockingQueue<T>(in.size(),true,in);
consume(q);
}
public void consume(T sym, Queue<T> q)
{
// this where I need to detect if it is T or State<T>
// psedo code
if symbols.get(sym) instanceof State<T>
symbols.get(sym).consume(q)
else
q.poll()
}
}
public class SingleState<T> extends State<T>
{
public void consume(Queue<T> q)
{
if(symbols.contains(q.peek())
consume(q.peek(),q);
}
}
I also subclass State to be RepeatState (consume until a symbol not in
symbols is encountered), SequenceState (consume N symbols only if they
are in a certain order... for example if we do:
SequenceState<Character> state=new SequenceState<Character>();
state.addSymbol('a')
state.addSymbol('b')
will accept input *ONLY* if the next two chars in the input is
"ab" (but not "ba" unlike RepeatState would))
and the final subclass is TerminalState where if the input is one of
the symbols then it returns the output state (i.e. the ctor is
TerminalState(State<T> outState) and if the next input
sym is in th alphabet then getState() returns outState else it returns
null).
Side question as far I can tell this plus some form output sink (which
the real code does have) is enough to parse any formal grammer (if a
state needs memory then it done by pushing back onto the input queue)
[i.e. I think this is all that is needed to make a UTM]
--Aryeh