org.snapscript.common.command.CommandParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of snap-all Show documentation
Show all versions of snap-all Show documentation
Dynamic scripting for the JVM
package org.snapscript.common.command;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
public class CommandParser implements Iterable {
private List tokens;
private StringBuilder token;
private char[] source;
private int count;
private int off;
public CommandParser(String command) {
this.tokens = new ArrayList();
this.token = new StringBuilder();
this.source = command.toCharArray();
this.count = source.length;
}
public List command() {
if (tokens.isEmpty()) {
parse();
}
return Collections.unmodifiableList(tokens);
}
@Override
public Iterator iterator() {
return command().iterator();
}
private void parse() {
seek();
tokens();
}
private void tokens() {
while (off < count) {
char next = source[off];
if (quote(next)) {
literal();
} else {
value();
}
insert();
seek();
}
}
private void insert() {
String value = token.toString();
if (!value.isEmpty()) {
tokens.add(value);
}
reset();
}
private void reset() {
token.setLength(0);
}
private void seek() {
while (off < count) {
if (!space(source[off])) {
break;
}
off++;
}
}
private void value() {
while (off < count) {
char next = source[off++];
if (space(next)) {
break;
}
token.append(next);
}
}
private void literal() {
char open = source[off];
int start = off + 1;
int length = 0;
if (quote(open)) {
off++;
while (off < count) {
if (open == source[off++]) {
break;
}
}
length = (off - start) - 1;
}
if (length > 0) {
token.append(source, start, length);
}
}
private boolean quote(char value) {
switch (value) {
case '\'':
case '\"':
return true;
default:
return false;
}
}
private boolean space(char value) {
switch (value) {
case ' ':
case '\t':
case '\n':
case '\r':
return true;
default:
return false;
}
}
}