static class ComputeArg extends Status {
@Override
<T> Response<T> process(Request<T> req) {
Token token = req.tokenizer.peek();
Response<T> response = new Response<T>();
if (token == null) {
response.add(new Event.Stop.Done(req.tokenizer.getIndex()));
} else if (token instanceof Token.Whitespace) {
response.add(new Event.Separator((Token.Whitespace) token));
req.tokenizer.next();
} else {
//
List<? extends ArgumentDescriptor> arguments = req.command.getArguments();
// Count the number ok remaining non whitespace;
int tokenCount = 0;
int wordCount = 0;
do {
Token t = req.tokenizer.next();
if (t instanceof Token.Literal) {
wordCount++;
}
tokenCount++;
}
while (req.tokenizer.hasNext());
req.tokenizer.pushBack(tokenCount);
//
int oneCount = 0;
int zeroOrOneCount = 0;
int index = 0;
for (ArgumentDescriptor argument : arguments) {
Multiplicity multiplicity = argument.getMultiplicity();
if (multiplicity == Multiplicity.SINGLE) {
if (argument.isRequired()) {
if (oneCount + 1 > wordCount) {
break;
}
oneCount++;
} else {
zeroOrOneCount++;
}
}
index++;
}
// This the number of arguments we can satisfy
arguments = arguments.subList(0, index);
// How many words we can consume for zeroOrOne and zeroOrMore
int toConsume = wordCount - oneCount;
// Correct the zeroOrOneCount and adjust toConsume
zeroOrOneCount = Math.min(zeroOrOneCount, toConsume);
toConsume -= zeroOrOneCount;
// The remaining
LinkedList<Event> events = new LinkedList<Event>();
for (ArgumentDescriptor argument : arguments) {
int size;
switch (argument.getMultiplicity()) {
case SINGLE:
if (argument.isRequired()) {
size = 1;
} else {
if (zeroOrOneCount > 0) {
zeroOrOneCount--;
size = 1;
} else {
size = 0;
}
}
break;
case MULTI:
// We consume the remaining
size = toConsume;
toConsume = 0;
break;
default:
throw new AssertionError();
}
// Now take care of the argument
if (size > 0) {
List<Token.Literal> values = new ArrayList<Token.Literal>(size);
while (size > 0) {
Token t = req.tokenizer.next();
if (t instanceof Token.Literal) {
values.add(((Token.Literal)t));
size--;
}
}