slcom/slangc/parser/Parse.sauce

2400 lines
89 KiB
Plaintext

package slangc.parser;
public class Parse {
private int maxRecursion = 1000;
public String nodeTypesAsString(NodeType[] types) {
if (types.length == 0) {
return "Nothing?";
} else if (types.length == 1) {
return types[0].name();
} else {
String result = "";
for (int i = 0; i < types.length; i++) {
if (i != 0) {
if (i == types.length - 1) {
result += " or ";
} else {
result += ", ";
}
}
result += types[i].name();
}
return result;
}
}
public Node expectAny(ScanWalker walker, int recursion, NodeType... types) {
return expectAnyArray(walker, recursion, types);
}
public Node expectAnyArray(ScanWalker walker, int recursion, NodeType[] types) {
Node result = parseAnyArray(walker, recursion + 1, types);
if (result == null) {
result = new Branch(NodeType.ERROR_ONLY).annotate(ErrorType.EXPECTING, "Expecting " + nodeTypesAsString(types) + " (got " + walker.peek().getType().name() + ")");
}
return result;
}
public Node parseAny(ScanWalker walker, int recursion, NodeType... types) {
return parseAnyArray(walker, recursion, types);
}
public Node parseAnyArray(ScanWalker walker, int recursion, NodeType[] types) {
for (int i = 0; i < types.length; i++) {
ScanWalker w = walker.clone();
Node result = parseInner(w, recursion + 1, types[i]);
if (result != null) {
walker.reset(w);
ScanWalker.recycle(w);
return result;
}
ScanWalker.recycle(w);
}
return null;
}
public Node parseList(ScanWalker walker, int recursion, NodeType listType, NodeType separator, boolean consumeTailSeparator, NodeType... types) {
return parseListArray(walker, recursion, listType, separator, consumeTailSeparator, types);
}
public Node parseListArray(ScanWalker walker, int recursion, NodeType listType, NodeType separator, boolean consumeTailSeparator, NodeType[] types) {
checkRecursion(walker, recursion);
Branch result = new Branch(listType);
Node n;
boolean first = true;
do {
ScanWalker w = walker.clone();
if (first || separator == null) {
n = parseAnyArray(w, recursion + 1, types);
first = false;
} else {
ScanWalker w2 = w.clone();
Node sep = parseInner(w2, recursion + 1, separator);
if (sep == null) {
n = null;
} else {
n = parseAnyArray(w2, recursion + 1, types);
//System.out.println("Got a "+ n);
if (n != null || consumeTailSeparator) {
result.append(sep);
w.reset(w2);
}
}
ScanWalker.recycle(w2);
}
if (n != null) {
result.append(n);
walker.reset(w);
} else if (consumeTailSeparator) {
walker.reset(w);
}
ScanWalker.recycle(w);
} while (n != null);
return result;
}
public Node parseGenericOnlyList(ScanWalker walker, int recursion, NodeType listType, NodeType separator, boolean consumeTailSeparator, NodeType gentype, NodeType middletype) {
checkRecursion(walker, recursion);
Branch result = new Branch(listType);
Node n;
boolean first = true;
Node lastGenType = null;
ScanWalker lastGenWalker = null;
ScanWalker ogWalker = walker.clone();
int iter = 0;
do {
//System.out.println("XXXXXX" + iter); iter++;
ScanWalker w = walker.clone();
if (first || separator == null) {
n = parseAny(w, recursion + 1, gentype, middletype);
if (n != null && n.getNodeType() == gentype) {
lastGenType = n;
lastGenWalker = w.clone();
}
first = false;
} else {
ScanWalker w2 = w.clone();
Node sep = parseInner(w2, recursion + 1, separator);
if (sep == null) {
n = null;
} else {
n = parseAny(w2, recursion + 1, gentype, middletype);
if (n != null && n.getNodeType() == gentype) {
lastGenType = n;
lastGenWalker = w2.clone();
}
//System.out.println("Got a "+ n);
if (n != null || consumeTailSeparator) {
result.append(sep);
w.reset(w2);
}
}
ScanWalker.recycle(w2);
}
if (n != null) {
result.append(n);
walker.reset(w);
} else if (consumeTailSeparator) {
walker.reset(w);
}
ScanWalker.recycle(w);
} while (n != null);
if (lastGenWalker == null) {
walker.reset(ogWalker);
return null;
} else {
walker.reset(lastGenWalker);
Branch realResult = new Branch(listType);
for (int i = 0; i < result.countSubnodes(); i++) {
realResult.append(result.getSubnode(i));
if (result.getSubnode(i) == lastGenType) {
return realResult;
}
}
throw new Error("Internal error (this should be unreachable)");
}
}
public Token parseToken(ScanWalker walker, int recursion, TokenType type) {
//checkRecursion(walker, recursion);
if (walker.isAtEnd()) {
//System.out.println("AT END");
return null;
}
if (walker.peek().is(type)) {
//System.out.println("Got a match to " + type);
Token result = walker.peek();
walker.advance();
return result;
} else {
//System.out.println("Not a " + type + " but a " + walker.peek());
return null;
}
}
public Token parseToken(ScanWalker walker, int recursion, TokenType type, String value) {
//checkRecursion(walker, recursion);
if (walker.isAtEnd()) {
return null;
}
if (walker.peek().is(type, value)) {
Token result = walker.peek();
walker.advance();
return result;
} else {
return null;
}
}
public Token parseToken(ScanWalker walker, int recursion, Language.Key key) {
//checkRecursion(walker, recursion);
if (walker.isAtEnd()) {
return null;
}
String val = walker.peek().getSnippet().getSource();
if (walker.peek().is(TokenType.KEYWORD) && walker.getScan().getLanguage().matches(key, val)) {
Token result = walker.peek();
walker.advance();
return result;
} else {
return null;
}
}
public Token parseToken(ScanWalker walker, int recursion, String value) {
// Can skip recursion check since we know we won't recurse from here! checkRecursion(walker, recursion);
if (walker.isAtEnd()) {
return null;
}
if (walker.peek().is(value)) {
Token result = walker.peek();
walker.advance();
return result;
} else {
return null;
}
}
public Branch parseTokenBranch(ScanWalker walker, int recursion, NodeType n, TokenType type) {
Token t = parseToken(walker, recursion, type);
//System.out.println("Got " + t);
if (t == null) {
return null;
} else {
return new Branch(n, t);
}
}
public Branch parseTokenBranch(ScanWalker walker, int recursion, NodeType n, Language.Key key) {
Token t = parseToken(walker, recursion, key);
//System.out.println("Got " + t);
if (t == null) {
return null;
} else {
return new Branch(n, t);
}
}
public Branch parseTokenBranch(ScanWalker walker, int recursion, NodeType n, TokenType type, String value) {
Token t = parseToken(walker, recursion, type, value);
if (t == null) {
return null;
} else {
return new Branch(n, t);
}
}
/** This one is used for the special >> and >>> operators (which are actually parsed as a sequence of > operators, to avoid
* conflict with nested template sizeExpression (e.g. Map<String,List<String>>). */
public Branch parseSpecialTokenBranch(ScanWalker walker, int recursion, NodeType n, TokenType type, String value, int number) {
ScanWalker pos = walker.clone();
switch (number) { case 2: case 3: break; default: throw new Error("Internal error: Bad number " + number); }
Token t = parseToken(walker, recursion, type, value);
if (t == null) {
walker.reset(pos);
ScanWalker.recycle(pos);
return null;
} else {
Token t2 = parseToken(walker, recursion, type, value);
if (t2 == null) {
walker.reset(pos);
ScanWalker.recycle(pos);
return null;
} else if (number == 2) {
ScanWalker.recycle(pos);
return new Branch(n, t, t2);
} else { // number == 3
Token t3 = parseToken(walker, recursion, type, value);
if (t3 == null) {
walker.reset(pos);
ScanWalker.recycle(pos);
return null;
} else {
ScanWalker.recycle(pos);
return new Branch(n, t, t2, t3);
}
}
}
}
public Branch parseTokenBranch(ScanWalker walker, int recursion, NodeType n, String value) {
Token t = parseToken(walker, recursion, value);
if (t == null) {
return null;
} else {
return new Branch(n, t);
}
}
public Node parseSimpleBinop(ScanWalker walker, int recursion, NodeType result, NodeType operator, NodeType inner) {
Node lhs = parseInner(walker, recursion + 1, inner);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseInner(walker, recursion, operator);
if (op == null) {
done = true;
} else {
lhs = new Branch(result,
lhs,
op,
expectAny(walker, recursion + 1, inner));
}
}
return lhs;
}
public Node parseInner(ScanWalker walker, int recursion, NodeType type) {
checkRecursion(walker, recursion);
if (walker.isAtEnd()) {
return null;
}
switch (type) {
case NodeType.EOF:
return parseTokenBranch(walker, recursion + 1, NodeType.EOF, TokenType.END_OF_FILE);
case NodeType.TOKEN:
if (walker.isAtEnd()) {
return null;
} else {
Token t = walker.peek();
walker.advance();
return t;
}
case NodeType.NAME:
//System.out.println("Parsing name...");
return parseTokenBranch(walker, recursion + 1, NodeType.NAME, TokenType.NAME);
case NodeType.INDEXED_NAME: {
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
Node o = parseInner(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE);
if (o == null) {
return n;
} else {
while (o != null) {
Node c = expectAny(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE);
n = new Branch(NodeType.INDEXED_NAME, n, o, c);
// Check for next set of braces
o = parseInner(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE);
}
return n;
}
}
}
case NodeType.GENERIC_NAME: {
Node n = parseTokenBranch(walker, recursion + 1, NodeType.NAME, TokenType.NAME);
if (n != null) {
if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "<")) {
Node genargs = parseAny(walker, recursion + 1, NodeType.GENERIC_ARGUMENTS);
if (genargs == null) {
return null;
}
return new Branch(NodeType.GENERIC_NAME, n, genargs);
} else {
return null;
}
}
return null;
}
case NodeType.DOT:
return parseTokenBranch(walker, recursion + 1, NodeType.DOT, TokenType.OPERATOR, ".");
case NodeType.WILDCARD:
return parseTokenBranch(walker, recursion + 1, NodeType.WILDCARD, TokenType.OPERATOR, "*");
case NodeType.COMMA:
return parseTokenBranch(walker, recursion + 1, NodeType.COMMA, TokenType.OPERATOR, ",");
case NodeType.SEMICOLON:
return parseTokenBranch(walker, recursion + 1, NodeType.SEMICOLON, TokenType.OPERATOR, ";");
case NodeType.COLON:
return parseTokenBranch(walker, recursion + 1, NodeType.COLON, TokenType.OPERATOR, ":");
case NodeType.DOUBLECOLON:
return parseTokenBranch(walker, recursion + 1, NodeType.DOUBLECOLON, TokenType.OPERATOR, "::");
case NodeType.QUESTIONMARK:
return parseTokenBranch(walker, recursion + 1, NodeType.QUESTIONMARK, TokenType.OPERATOR, "?");
case NodeType.OPEN_ROUND_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE, TokenType.OPERATOR, "(");
case NodeType.CLOSE_ROUND_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE, TokenType.OPERATOR, ")");
case NodeType.OPEN_CURLY_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE, TokenType.OPERATOR, "{");
case NodeType.CLOSE_CURLY_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE, TokenType.OPERATOR, "}");
case NodeType.OPEN_SQUARE_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE, TokenType.OPERATOR, "[");
case NodeType.CLOSE_SQUARE_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE, TokenType.OPERATOR, "]");
case NodeType.OPEN_ANGLE_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.OPEN_ANGLE_BRACE, TokenType.OPERATOR, "<");
case NodeType.CLOSE_ANGLE_BRACE:
return parseTokenBranch(walker, recursion + 1, NodeType.CLOSE_ANGLE_BRACE, TokenType.OPERATOR, ">");
case NodeType.PACKAGE_NAME:
return parseList(walker, recursion + 1, NodeType.PACKAGE_NAME, NodeType.DOT, false, NodeType.NAME);
case NodeType.PACKAGE_DECLARATION: {
Token t = parseToken(walker, recursion + 1, Language.Key.MODULE); //TokenType.KEYWORD, "package");
if (t == null) {
return null;
} else {
return new Branch(NodeType.PACKAGE_DECLARATION,
t,
expectAny(walker, recursion + 1, NodeType.PACKAGE_NAME),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
}
case NodeType.IMPORTED_PACKAGE: {
Node n = parseInner(walker, recursion + 1, NodeType.PACKAGE_NAME);
if (n != null) {
Node dot = parseInner(walker, recursion + 1, NodeType.DOT);
if (dot != null) {
return new Branch(NodeType.IMPORTED_PACKAGE,
n,
dot,
expectAny(walker, recursion + 1, NodeType.WILDCARD));
}
}
return null;
}
case NodeType.IMPORTED_TYPE:
return parseList(walker, recursion + 1, NodeType.IMPORTED_TYPE, NodeType.DOT, false, NodeType.NAME);
case NodeType.IMPORT_DECLARATION: {
Token t = parseToken(walker, recursion + 1, Language.Key.IMPORT); //TokenType.KEYWORD, "import");
if (t == null) {
return null;
} else {
Token stat = parseToken(walker, recursion + 1, Language.Key.STATIC); //TokenType.KEYWORD, "static");
if (stat == null) {
return new Branch(NodeType.IMPORT_DECLARATION,
t,
expectAny(walker, recursion + 1, NodeType.IMPORTED_PACKAGE, NodeType.IMPORTED_TYPE),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
} else {
return new Branch(NodeType.IMPORT_STATIC_DECLARATION,
t,
stat,
expectAny(walker, recursion + 1, NodeType.IMPORTED_PACKAGE, NodeType.IMPORTED_TYPE),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
}
}
case NodeType.TYPE_DECLARATIONS:
return parseList(walker, recursion + 1, NodeType.TYPE_DECLARATIONS, null, false,
NodeType.CLASS_DECLARATION,
NodeType.INTERFACE_DECLARATION,
NodeType.ENUM_DECLARATION,
NodeType.ATTRIBUTE_DECLARATION,
NodeType.SEMICOLON);
case NodeType.INTERFACE_BASES: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.EXTENDS); //TokenType.KEYWORD, "extends");
if (keyword == null) {
return new Branch(NodeType.NO_INTERFACE_BASES);
} else {
return new Branch(NodeType.INTERFACE_BASES, keyword, parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCES));
}
}
case NodeType.CLASS_BASE: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.EXTENDS); //TokenType.KEYWORD, "extends");
if (keyword == null) {
return new Branch(NodeType.NO_CLASS_BASE);
} else {
return new Branch(NodeType.CLASS_BASE, keyword, expectAny(walker, recursion + 1, NodeType.TYPE_REFERENCE));
}
}
case NodeType.CLASS_IMPLEMENTS: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.IMPLEMENTS); //TokenType.KEYWORD, "implements");
if (keyword == null) {
return new Branch(NodeType.NO_CLASS_IMPLEMENTS);
} else {
return new Branch(NodeType.CLASS_IMPLEMENTS, keyword, parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCES));
}
}
case NodeType.TYPE_REFERENCES:
return parseList(walker, recursion + 1, NodeType.TYPE_REFERENCES, NodeType.COMMA, false, NodeType.TYPE_REFERENCE);
case NodeType.TYPE_REFERENCE:
if (!walker.isAtEnd() && walker.peek().is(TokenType.NAME)) {
return parseList(walker, recursion + 1, NodeType.TYPE_REFERENCE, NodeType.DOT, false, NodeType.GENERIC_NAME, NodeType.NAME);
} else {
return null;
}
case NodeType.GENERIC_ONLY_TYPE_REFERENCE:
if (!walker.isAtEnd() && walker.peek().is(TokenType.NAME)) {
return parseGenericOnlyList(walker, recursion + 1, NodeType.TYPE_REFERENCE, NodeType.DOT, false, NodeType.GENERIC_NAME, NodeType.NAME);
} else {
return null;
}
case NodeType.TYPE: {
Node result = null;
result = result != null ? result : parseInner(walker, recursion + 1, NodeType.SIMPLE_TYPE);
result = result != null ? result : parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCE);
while (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "[") && walker.peekOffset(1) != null && walker.peekOffset(1).is(TokenType.OPERATOR, "]")) {
result = new Branch(NodeType.ARRAY_TYPE,
result,
parseInner(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE),
parseInner(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE));
}
if (result == null) {
return null;
} else {
return new Branch(NodeType.TYPE, result);
}
}
case NodeType.RETURN_TYPE: {
Node voidToken = parseToken(walker, recursion + 1, Language.Key.VOID); //TokenType.KEYWORD, "void");
if (voidToken == null) {
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
} else {
return new Branch(NodeType.RETURN_TYPE, t);
}
} else {
return new Branch(NodeType.NO_RETURN_TYPE, voidToken);
}
}
case NodeType.ENUM_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node keyword = parseToken(walker, recursion + 1, Language.Key.ENUM); //TokenType.KEYWORD, "enum");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.ENUM_DECLARATION,
mods,
keyword,
expectAny(walker, recursion + 1, NodeType.NAME),
parseInner(walker, recursion + 1, NodeType.GENERIC_DECLARATIONS),
parseInner(walker, recursion + 1, NodeType.CLASS_BASE),
parseInner(walker, recursion + 1, NodeType.CLASS_IMPLEMENTS),
expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE),
parseInner(walker, recursion + 1, NodeType.ENUM_MEMBERS),
parseInner(walker, recursion + 1, NodeType.ENUM_CLASS_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.INTERFACE_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node keyword = parseToken(walker, recursion + 1, Language.Key.INTERFACE); //TokenType.KEYWORD, "interface");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.INTERFACE_DECLARATION,
mods,
keyword,
expectAny(walker, recursion + 1, NodeType.NAME),
parseInner(walker, recursion + 1, NodeType.GENERIC_DECLARATIONS),
parseInner(walker, recursion + 1, NodeType.INTERFACE_BASES),
expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE),
parseInner(walker, recursion + 1, NodeType.INTERFACE_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.CLASS_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node keyword = parseToken(walker, recursion + 1, Language.Key.CLASS);//parseToken(walker, recursion + 1, TokenType.KEYWORD, "class");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.CLASS_DECLARATION,
mods,
keyword,
expectAny(walker, recursion + 1, NodeType.NAME),
parseInner(walker, recursion + 1, NodeType.GENERIC_DECLARATIONS),
parseInner(walker, recursion + 1, NodeType.CLASS_BASE),
parseInner(walker, recursion + 1, NodeType.CLASS_IMPLEMENTS),
expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE),
parseInner(walker, recursion + 1, NodeType.CLASS_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.ATTRIBUTE_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node at = parseToken(walker, recursion + 1, TokenType.OPERATOR, "@");
if (at == null) {
return null;
}
Node keyword = parseToken(walker, recursion + 1, Language.Key.INTERFACE); //TokenType.KEYWORD, "interface");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.ATTRIBUTE_DECLARATION,
mods,
at,
keyword,
expectAny(walker, recursion + 1, NodeType.NAME),
parseInner(walker, recursion + 1, NodeType.GENERIC_DECLARATIONS),
parseInner(walker, recursion + 1, NodeType.INTERFACE_BASES),
expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE),
parseInner(walker, recursion + 1, NodeType.INTERFACE_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.ENUM_MEMBERS:
return parseList(walker, recursion + 1, NodeType.ENUM_MEMBERS, NodeType.COMMA, true, NodeType.SPECIALISED_ENUM_SUBTYPE, NodeType.SPECIALISED_ENUM_MEMBER, NodeType.ENUM_MEMBER);
case NodeType.ENUM_MEMBER: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node name = parseToken(walker, recursion + 1, TokenType.NAME);
if (name == null) {
return null;
} else {
return new Branch(NodeType.ENUM_MEMBER, mods, name);
}
}
case NodeType.SPECIALISED_ENUM_MEMBER: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node name = parseToken(walker, recursion + 1, TokenType.NAME);
if (name == null) {
return null;
}
Node args = parseAny(walker, recursion + 1, NodeType.ARGUMENTS);
if (args == null) {
return null;
}
return new Branch(NodeType.SPECIALISED_ENUM_MEMBER, mods, name, args);
}
case NodeType.SPECIALISED_ENUM_SUBTYPE: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node name = parseToken(walker, recursion + 1, TokenType.NAME);
if (name == null) {
return null;
}
Node args = parseAny(walker, recursion + 1, NodeType.ARGUMENTS);
//if (args == null) {
// return null;
//}
Node open = parseAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE);
if (open == null) {
return null;
}
Node members = expectAny(walker, recursion + 1, NodeType.CLASS_MEMBERS);
Node close = expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE);
if (args == null) {
return new Branch(NodeType.SPECIALISED_ENUM_SUBTYPE, mods, name, open, members, close);
} else {
return new Branch(NodeType.SPECIALISED_ENUM_SUBTYPE_WITH_ARGS, mods, name, args, open, members, close);
}
}
case NodeType.ENUM_CLASS_MEMBERS: {
//System.out.println("Looking for semicolon got " + walker.peek());
Node semi = parseInner(walker, recursion + 1, NodeType.SEMICOLON);
if (semi == null) {
return new Branch(NodeType.NO_ENUM_CLASS_MEMBERS);
} else {
return new Branch(NodeType.ENUM_CLASS_MEMBERS, semi, parseInner(walker, recursion + 1, NodeType.CLASS_MEMBERS));
}
}
case NodeType.CLASS_MEMBERS: {
// Workaround because empty {...} seems to cause issues
//ScanWalker pos = walker.clone();
//Node emptyEnd = parseAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE);
//if (emptyEnd != null) {
// walker.reset(pos);
// return new Branch(NodeType.CLASS_MEMBERS);
//}
return parseList(walker, recursion + 1, NodeType.CLASS_MEMBERS, null, false,
NodeType.CONSTRUCTOR_DECLARATION,
NodeType.STATIC_CONSTRUCTOR_DECLARATION,
NodeType.METHOD_DECLARATION,
NodeType.FIELD_DECLARATION,
NodeType.CLASS_DECLARATION,
NodeType.INTERFACE_DECLARATION,
NodeType.ENUM_DECLARATION,
NodeType.ATTRIBUTE_DECLARATION,
NodeType.SEMICOLON);
}
case NodeType.INTERFACE_MEMBERS: {
return parseList(walker, recursion + 1, NodeType.INTERFACE_MEMBERS, null, false,
NodeType.STATIC_CONSTRUCTOR_DECLARATION,
NodeType.METHOD_DECLARATION,
NodeType.FIELD_DECLARATION,
NodeType.CLASS_DECLARATION,
NodeType.INTERFACE_DECLARATION,
NodeType.ENUM_DECLARATION,
NodeType.ATTRIBUTE_DECLARATION,
NodeType.SEMICOLON);
}
case NodeType.MODIFIER_LIST:
return parseList(walker, recursion + 1, NodeType.MODIFIER_LIST, null, false, NodeType.SIMPLE_MODIFIER, NodeType.COMPLEX_TAGGED_MODIFIER);
case NodeType.SIMPLE_MODIFIER: {
Node mod = null;
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.PUBLIC);//parseToken(walker, recursion + 1, TokenType.KEYWORD, "public");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.PROTECTED);//TokenType.KEYWORD, "protected");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.PRIVATE);//TokenType.KEYWORD, "private");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.STATIC);//TokenType.KEYWORD, "static");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.FINAL);//TokenType.KEYWORD, "final");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.ABSTRACT);//TokenType.KEYWORD, "abstract");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.SYNCHRONISED);//TokenType.KEYWORD, "synchronized");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.NATIVE);//TokenType.KEYWORD, "native");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.TRANSIENT);//TokenType.KEYWORD, "transient");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.VOLATILE);//TokenType.KEYWORD, "volatile");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.COMPAT_STRICTFP);//TokenType.KEYWORD, "strictfp");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.VOLATILE);//TokenType.KEYWORD, "volatile");
mod = mod != null ? mod : parseToken(walker, recursion + 1, Language.Key.DEFAULT);//TokenType.KEYWORD, "default");
return mod == null ? null : new Branch(NodeType.SIMPLE_MODIFIER, mod);
}
case NodeType.BREAK_STATEMENT: {
Node br = parseToken(walker, recursion + 1, Language.Key.BREAK); //TokenType.KEYWORD, "break");
if (br == null) {
return null;
} else {
Node label = parseAny(walker, recursion + 1, NodeType.NAME);
Node semicolon = expectAny(walker, recursion + 1, NodeType.SEMICOLON);
if (label == null) {
return new Branch(NodeType.BREAK_STATEMENT, br, semicolon);
} else {
return new Branch(NodeType.BREAK_TO_STATEMENT, br, label, semicolon);
}
}
}
case NodeType.CONTINUE_STATEMENT: {
Node br = parseToken(walker, recursion + 1, Language.Key.CONTINUE); //TokenType.KEYWORD, "continue");
if (br == null) {
return null;
} else {
Node label = parseAny(walker, recursion + 1, NodeType.NAME);
Node semicolon = expectAny(walker, recursion + 1, NodeType.SEMICOLON);
if (label == null) {
return new Branch(NodeType.CONTINUE_STATEMENT, br, semicolon);
} else {
return new Branch(NodeType.CONTINUE_TO_STATEMENT, br, label, semicolon);
}
}
}
case NodeType.LABEL_STATEMENT: {
Node n = parseAny(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
}
Node s = parseAny(walker, recursion + 1, NodeType.COLON);
if (s == null) {
return null;
} else {
return new Branch(NodeType.LABEL_STATEMENT, n, s);
}
}
case NodeType.COMPLEX_TAGGED_MODIFIER: {
Node tagsymbol = parseToken(walker, recursion + 1, TokenType.OPERATOR, "@");
boolean noAt = (tagsymbol == null);
if (noAt) {
tagsymbol = tagsymbol != null ? tagsymbol : parseToken(walker, recursion + 1, TokenType.OPERATOR, "#");
tagsymbol = tagsymbol != null ? tagsymbol : parseToken(walker, recursion + 1, TokenType.OPERATOR, "##");
}
if (tagsymbol == null) {
return null;
}
Node tagname;
if (noAt) {
tagname = parseAny(walker, recursion + 1, NodeType.NAME, NodeType.STRING_LITERAL_EXPRESSION, NodeType.INTEGER_LITERAL_EXPRESSION);
} else {
tagname = parseAny(walker, recursion + 1, NodeType.TYPE_REFERENCE);
}
if (tagname == null) {
return null;
}
if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "(")) {
return new Branch(NodeType.COMPLEX_TAGGED_MODIFIER, tagsymbol, tagname, expectAny(walker, recursion + 1, NodeType.MODIFIER_ARGUMENTS));
} else if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, ":")) {
Node sep = parseToken(walker, recursion + 1, TokenType.OPERATOR, ":");
return new Branch(NodeType.NAME_TAGGED_MODIFIER, tagsymbol, tagname, sep, expectAny(walker, recursion + 1, NodeType.NAME, NodeType.STRING_LITERAL_EXPRESSION, NodeType.INTEGER_LITERAL_EXPRESSION));
} else {
return new Branch(NodeType.SIMPLE_TAGGED_MODIFIER, tagsymbol, tagname);
}
}
case NodeType.MODIFIER_ARGUMENTS: {
Node open = parseAny(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (open == null) {
return null;
}
Node inner = parseAny(walker, recursion + 1, NodeType.MODIFIER_EXPRESSIONS);
Node close = expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE);
return new Branch(NodeType.MODIFIER_ARGUMENTS, open, inner, close);
}
case NodeType.SIMPLE_TYPE: {
Node result = null;
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.BIT); //TokenType.KEYWORD, "boolean");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.BYTE); //TokenType.KEYWORD, "byte");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.SHORT); //TokenType.KEYWORD, "short");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.COMPAT_CHAR); //TokenType.KEYWORD, "char");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.INT); //TokenType.KEYWORD, "int");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.LONG); //TokenType.KEYWORD, "long");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.FLOAT); //TokenType.KEYWORD, "float");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.DOUBLE); //TokenType.KEYWORD, "double");
//result = result != null ? result : parseToken(walker, recursion + 1, TokenType.KEYWORD, "cpuword");
result = result != null ? result : parseToken(walker, recursion + 1, Language.Key.DUCK); //TokenType.KEYWORD, "duck");
return result;
}
case NodeType.ARGUMENT_DECLARATIONS: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (start == null) {
return null;
} else {
return new Branch(NodeType.ARGUMENT_DECLARATIONS,
start,
parseList(walker, recursion + 1, NodeType.ARGUMENT_DECLARATION_LIST, NodeType.COMMA, false, NodeType.LAZY_ARGUMENT_DECLARATION, NodeType.VARIABLE_ARGUMENT_DECLARATION, NodeType.SIMPLE_ARGUMENT_DECLARATION),
expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE));
}
}
case NodeType.GENERIC_DECLARATIONS: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_ANGLE_BRACE);
if (start == null) {
return new Branch(NodeType.NO_GENERIC_DECLARATIONS);
} else {
return new Branch(NodeType.GENERIC_DECLARATIONS,
start,
parseList(walker, recursion + 1, NodeType.GENERIC_DECLARATION_LIST, NodeType.COMMA, false,
NodeType.VARIABLE_TYPED_GENERIC_DECLARATION,
NodeType.VARIABLE_GENERIC_DECLARATION,
NodeType.SIMPLE_TYPED_GENERIC_DECLARATION,
NodeType.SIMPLE_EXTENDED_GENERIC_DECLARATION,
NodeType.SIMPLE_GENERIC_DECLARATION),
expectAny(walker, recursion + 1, NodeType.CLOSE_ANGLE_BRACE));
}
}
case NodeType.METHOD_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node gentype = parseInner(walker, recursion + 1, NodeType.GENERIC_DECLARATIONS);
Node t = parseInner(walker, recursion + 1, NodeType.RETURN_TYPE);
if (t == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
Node args = parseInner(walker, recursion + 1, NodeType.ARGUMENT_DECLARATIONS);
if (args == null) {
return null;
} else {
return new Branch(NodeType.METHOD_DECLARATION,
mods,
gentype,
t,
n,
args,
parseAny(walker, recursion + 1, NodeType.ARRAY_TYPE_TAIL),
parseInner(walker, recursion + 1, NodeType.THROWS),
expectAny(walker, recursion + 1, NodeType.METHOD_BODY));
}
}
}
}
case NodeType.CONSTRUCTOR_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
Node args = parseInner(walker, recursion + 1, NodeType.ARGUMENT_DECLARATIONS);
if (args == null) {
return null;
} else {
return new Branch(NodeType.CONSTRUCTOR_DECLARATION,
mods,
n,
args,
parseInner(walker, recursion + 1, NodeType.THROWS),
expectAny(walker, recursion + 1, NodeType.METHOD_BODY));
}
}
}
case NodeType.STATIC_CONSTRUCTOR_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
if (walker.peek().is(TokenType.OPERATOR, "{")) {
Node body = parseInner(walker, recursion + 1, NodeType.METHOD_BODY);
return new Branch(NodeType.STATIC_CONSTRUCTOR_DECLARATION, mods, body);
} else {
return null;
}
}
case NodeType.THROWS: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.THROWS); //TokenType.KEYWORD, "throws");
if (keyword == null) {
return new Branch(NodeType.NO_THROWS);
} else {
return new Branch(NodeType.THROWS, parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCES));
}
}
case NodeType.METHOD_BODY: {
Node semi = parseInner(walker, recursion + 1, NodeType.SEMICOLON);
if (semi == null) {
Node def = parseToken(walker, recursion + 1, Language.Key.DEFAULT); //TokenType.KEYWORD, "default");
if (def != null) {
return new Branch(NodeType.DEFAULT_METHOD_BODY,
def,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
return new Branch(NodeType.METHOD_BODY, expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT));
} else {
return new Branch(NodeType.NO_METHOD_BODY, semi);
}
}
case NodeType.BLOCK_STATEMENT: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE);
if (start == null) {
return null;
} else {
return new Branch(NodeType.BLOCK_STATEMENT,
start,
parseInner(walker, recursion + 1, NodeType.STATEMENTS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.SWITCH_STATEMENT: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.SWITCH); //TokenType.KEYWORD, "switch");
if (keyword == null) {
return null;
}
Node cond = expectAny(walker, recursion + 1, NodeType.BRACED_EXPRESSION);
Node start = expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE);
return new Branch(NodeType.SWITCH_STATEMENT,
keyword,
cond,
start,
parseInner(walker, recursion + 1, NodeType.SWITCH_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
case NodeType.ASSERT_STATEMENT: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.ASSERT); //TokenType.KEYWORD, "assert");
if (keyword == null) {
return null;
} else {
Node expr = expectAny(walker, recursion + 1, NodeType.EXPRESSION);
Node colon = parseAny(walker, recursion + 1, NodeType.COLON);
if (colon == null) {
return new Branch(NodeType.ASSERT_STATEMENT,
keyword,
expr,
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
} else {
return new Branch(NodeType.ASSERT_DEBUG_STATEMENT,
keyword,
expr,
colon,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
}
}
case NodeType.THROW_STATEMENT: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.THROW); //TokenType.KEYWORD, "throw");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.THROW_STATEMENT,
keyword,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
}
case NodeType.RETURN_EXPRESSION_STATEMENT: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.RETURN); //TokenType.KEYWORD, "return");
if (keyword == null) {
return null;
} else {
Node next = expectAny(walker, recursion + 1, NodeType.EXPRESSION, NodeType.SEMICOLON);
if (next.getNodeType() == NodeType.SEMICOLON) {
return new Branch(NodeType.RETURN_NOTHING_STATEMENT, keyword, next);
} else {
return new Branch(NodeType.RETURN_EXPRESSION_STATEMENT,
keyword,
next,
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
}
}
}
case NodeType.VARIABLE_STATEMENT: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t != null &&!walker.isAtEnd() && walker.peek().is(TokenType.NAME)) {
return new Branch(NodeType.VARIABLE_STATEMENT,
mods,
t,
parseInner(walker, recursion + 1, NodeType.SLOTS),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
} else {
return null;
}
}
case NodeType.FOR_VARIABLES: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t != null &&!walker.isAtEnd() && walker.peek().is(TokenType.NAME)) {
return new Branch(NodeType.FOR_VARIABLES,
mods,
t,
parseInner(walker, recursion + 1, NodeType.SLOTS));
} else {
return null;
}
}
case NodeType.IF_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.IF); //TokenType.KEYWORD, "if");
if (keyword == null) {
return null;
} else {
Node cond = expectAny(walker, recursion + 1, NodeType.BRACED_EXPRESSION); // TODO: Change to only bracketed expression
Node cons = expectAny(walker, recursion + 1, NodeType.STATEMENT);
Node els = parseInner(walker, recursion + 1, NodeType.ELSE_CLAUSE);
return new Branch(NodeType.IF_STATEMENT, keyword, cond, cons, els);
}
}
case NodeType.SYNCHRONIZED_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.SYNCHRONISED); //TokenType.KEYWORD, "synchronized");
if (keyword == null) {
return null;
} else {
Node cond = expectAny(walker, recursion + 1, NodeType.BRACED_EXPRESSION); // TODO: Change to only bracketed expression
Node cons = expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT);
return new Branch(NodeType.SYNCHRONIZED_STATEMENT, keyword, cond, cons);
}
}
case NodeType.ELSE_CLAUSE: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.ELSE); //TokenType.KEYWORD, "else");
if (keyword == null) {
return new Branch(NodeType.NO_ELSE_CLAUSE);
} else {
return new Branch(NodeType.ELSE_CLAUSE, keyword,
expectAny(walker, recursion + 1, NodeType.STATEMENT));
}
}
case NodeType.WHILE_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.WHILE); //TokenType.KEYWORD, "while");
if (keyword == null) {
return null;
} else {
Node cond = expectAny(walker, recursion + 1, NodeType.BRACED_EXPRESSION);
Node cons = expectAny(walker, recursion + 1, NodeType.STATEMENT, NodeType.SEMICOLON);
return new Branch(NodeType.WHILE_STATEMENT, keyword, cond, cons);
}
}
case NodeType.FOR_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.FOR); //TokenType.KEYWORD, "for");
if (keyword == null) {
return null;
} else {
Node obr = expectAny(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
Node st1 = expectAny(walker, recursion + 1, NodeType.FOR_VARIABLES, NodeType.EXPRESSIONS);
Node firstsep = expectAny(walker, recursion + 1, NodeType.SEMICOLON, NodeType.COLON);
if (firstsep.getNodeType() == NodeType.COLON) {
// Handle for-each variant
Node rangeexpr = parseAny(walker, recursion + 1, NodeType.EXPRESSIONS);
Node cbr = expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE);
Node cons = expectAny(walker, recursion + 1, NodeType.STATEMENT, NodeType.SEMICOLON);
return new Branch(NodeType.FOR_EACH_STATEMENT, keyword, obr, st1, firstsep, rangeexpr, cbr, cons);
} else {
Node st2 = expectAny(walker, recursion + 1, NodeType.EXPRESSIONS);
Node lastsep = expectAny(walker, recursion + 1, NodeType.SEMICOLON);
Node st3 = parseAny(walker, recursion + 1, NodeType.EXPRESSIONS);
Node cbr = expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE);
Node cons = expectAny(walker, recursion + 1, NodeType.STATEMENT, NodeType.SEMICOLON);
return new Branch(NodeType.FOR_STATEMENT, keyword, obr, st1, firstsep, st2, lastsep, st3, cbr, cons);
}
}
}
case NodeType.DO_WHILE_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.DO); //TokenType.KEYWORD, "do");
if (keyword == null) {
return null;
} else {
Node cons = expectAny(walker, recursion + 1, NodeType.STATEMENT);
Node kw2 = parseToken(walker, recursion + 1, Language.Key.WHILE); //TokenType.KEYWORD, "while");
Node cond = expectAny(walker, recursion + 1, NodeType.BRACED_EXPRESSION);
Node end = expectAny(walker, recursion + 1, NodeType.SEMICOLON);
return new Branch(NodeType.DO_WHILE_STATEMENT, keyword, cons, kw2, cond, end);
}
}
case NodeType.TRY_STATEMENT: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.TRY); //TokenType.KEYWORD, "try");
if (keyword == null) {
return null;
} else {
Node vars = parseAny(walker, recursion + 1, NodeType.TRY_RESOURCES);
Node tries = expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT);
Node catches = parseList(walker, recursion + 1, NodeType.CATCH_CLAUSES, null, false, NodeType.CATCH_CLAUSE);
Node fin = parseInner(walker, recursion + 1, NodeType.FINALLY_CLAUSE);
return new Branch(NodeType.TRY_STATEMENT, keyword, vars, tries, catches, fin);
}
}
case NodeType.TRY_RESOURCES: {
Node open = parseAny(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (open == null) {
return new Branch(NodeType.NO_TRY_RESOURCES);
}
return new Branch(NodeType.TRY_RESOURCES,
open,
parseList(walker, recursion + 1, NodeType.TRY_RESOURCE_LIST, NodeType.SEMICOLON, false, NodeType.FOR_VARIABLES),
expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE));
}
case NodeType.CATCH_CLAUSE: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.CATCH); //TokenType.KEYWORD, "catch");
if (keyword == null) {
return null;
} else {
Node cond = expectAny(walker, recursion + 1, NodeType.ARGUMENT_DECLARATIONS);
Node cons = expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT);
return new Branch(NodeType.CATCH_CLAUSE, keyword, cond, cons);
}
}
case NodeType.FINALLY_CLAUSE: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.FINALLY); //TokenType.KEYWORD, "finally");
if (keyword == null) {
return new Branch(NodeType.NO_FINALLY_CLAUSE);
} else {
Node cons = expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT);
return new Branch(NodeType.FINALLY_CLAUSE, keyword, cons);
}
}
case NodeType.EXPRESSION_STATEMENT: {
Node expr = parseAny(walker, recursion + 1, NodeType.EXPRESSION);
if (expr != null) {
/*switch (expr.getNodeType()) {
case NodeType.ASSIGNMENT_EXPRESSION:
case NodeType.COUNT_EXPRESSION:
case NodeType.AUTOMATIC_METHOD_CALL_EXPRESSION:
case NodeType.NORMAL_METHOD_CALL_EXPRESSION:
case NodeType.SUPER_CONSTRUCTOR_CALL_EXPRESSION:
case NodeType.SUPER_METHOD_CALL_EXPRESSION:
case NodeType.THIS_CONSTRUCTOR_CALL_EXPRESSION:
return new Branch(NodeType.EXPRESSION_STATEMENT,
expr,
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
default:
return null;
}*/
return new Branch(NodeType.EXPRESSION_STATEMENT,
expr,
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
} else {
return null;
}
}
case NodeType.STATEMENTS:
return parseList(walker, recursion + 1, NodeType.STATEMENTS, null, false, NodeType.STATEMENT);
case NodeType.SWITCH_MEMBERS:
return parseList(walker, recursion + 1, NodeType.SWITCH_MEMBERS, null, false, NodeType.CASE_LABEL, NodeType.DEFAULT_LABEL, NodeType.STATEMENT);
case NodeType.CASE_LABEL: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.CASE); //TokenType.KEYWORD, "case");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.CASE_LABEL,
keyword,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.COLON));
}
}
case NodeType.DEFAULT_LABEL: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.DEFAULT); //TokenType.KEYWORD, "default");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.DEFAULT_LABEL,
keyword,
expectAny(walker, recursion + 1, NodeType.COLON));
}
}
case NodeType.STATEMENT:
return parseAny(walker, recursion + 1,
NodeType.LABEL_STATEMENT,
NodeType.IF_STATEMENT,
NodeType.WHILE_STATEMENT,
NodeType.DO_WHILE_STATEMENT,
NodeType.FOR_STATEMENT,
NodeType.SWITCH_STATEMENT,
NodeType.ASSERT_STATEMENT,
NodeType.THROW_STATEMENT,
NodeType.RETURN_EXPRESSION_STATEMENT,
NodeType.TRY_STATEMENT,
NodeType.VARIABLE_STATEMENT,
NodeType.BLOCK_STATEMENT,
NodeType.EXPRESSION_STATEMENT,
NodeType.SYNCHRONIZED_STATEMENT,
NodeType.BREAK_STATEMENT,
NodeType.CONTINUE_STATEMENT,
NodeType.CLASS_DECLARATION,
NodeType.INTERFACE_DECLARATION,
NodeType.ENUM_DECLARATION,
NodeType.ATTRIBUTE_DECLARATION,
NodeType.SEMICOLON);
case NodeType.FIELD_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t != null &&!walker.isAtEnd() && walker.peek().is(TokenType.NAME)) {
return new Branch(NodeType.FIELD_DECLARATION,
mods,
t,
parseInner(walker, recursion + 1, NodeType.SLOTS),
expectAny(walker, recursion + 1, NodeType.SEMICOLON));
} else {
return null;
}
}
case NodeType.NULL_LITERAL_EXPRESSION: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.NULL); //TokenType.KEYWORD, "null");
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.NULL_LITERAL_EXPRESSION, keyword);
}
}
case NodeType.BOOLEAN_LITERAL_EXPRESSION: {
Token keyword = parseToken(walker, recursion + 1, Language.Key.FALSE); //TokenType.KEYWORD, "false");
if (keyword == null) {
keyword = parseToken(walker, recursion + 1, Language.Key.TRUE); //TokenType.KEYWORD, "true");
}
if (keyword == null) {
return null;
} else {
return new Branch(NodeType.BOOLEAN_LITERAL_EXPRESSION, keyword);
}
}
case NodeType.INTEGER_LITERAL_EXPRESSION: {
Token num = parseToken(walker, recursion + 1, TokenType.DEC_INTEGER);
if (num == null) {
num = parseToken(walker, recursion + 1, TokenType.HEX_INTEGER);
}
if (num == null) {
num = parseToken(walker, recursion + 1, TokenType.BIN_INTEGER);
}
if (num == null) {
return null;
} else {
return new Branch(NodeType.INTEGER_LITERAL_EXPRESSION, num);
}
}
case NodeType.FLOAT_LITERAL_EXPRESSION: {
Token num = parseToken(walker, recursion + 1, TokenType.DEC_FLOAT);
if (num == null) {
num = parseToken(walker, recursion + 1, TokenType.HEX_FLOAT);
}
if (num == null) {
num = parseToken(walker, recursion + 1, TokenType.BIN_FLOAT);
}
if (num == null) {
return null;
} else {
return new Branch(NodeType.FLOAT_LITERAL_EXPRESSION, num);
}
}
case NodeType.STRING_LITERAL_EXPRESSION: {
Token str = parseToken(walker, recursion + 1, TokenType.STRING);
if (str == null) {
return null;
} else {
return new Branch(NodeType.STRING_LITERAL_EXPRESSION, str);
}
}
case NodeType.CHAR_LITERAL_EXPRESSION: {
Token chr = parseToken(walker, recursion + 1, TokenType.CHAR);
if (chr == null) {
return null;
} else {
return new Branch(NodeType.CHAR_LITERAL_EXPRESSION, chr);
}
}
case NodeType.LITERAL_EXPRESSION:
return parseAny(walker, recursion + 1,
NodeType.NULL_LITERAL_EXPRESSION,
NodeType.BOOLEAN_LITERAL_EXPRESSION,
NodeType.INTEGER_LITERAL_EXPRESSION,
NodeType.FLOAT_LITERAL_EXPRESSION,
NodeType.CHAR_LITERAL_EXPRESSION,
NodeType.STRING_LITERAL_EXPRESSION);
case NodeType.REFERENCE_EXPRESSION:
return parseTokenBranch(walker, recursion + 1, NodeType.REFERENCE_EXPRESSION, TokenType.NAME);
case NodeType.GENERIC_REFERENCE_EXPRESSION: {
Node n = parseAny(walker, recursion + 1, NodeType.GENERIC_ONLY_TYPE_REFERENCE);
if (n == null) {
return null;
}
return new Branch(NodeType.GENERIC_REFERENCE_EXPRESSION, n);
}
case NodeType.GENERIC_REFERENCE_NAME: {
Node args = parseAny(walker, recursion + 1, NodeType.GENERIC_ARGUMENTS);
if (args == null) {
return null;
}
Node nam = parseAny(walker, recursion + 1, NodeType.NAME);
if (nam == null) {
return null;
}
return new Branch(NodeType.GENERIC_NAME, args, nam);
}
case NodeType.SUPER:
return parseTokenBranch(walker, recursion + 1, NodeType.SUPER, Language.Key.SUPER); //TokenType.KEYWORD, "super");
case NodeType.THIS_EXPRESSION: {
// TODO: Why'd I put this here?
// Node t = parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCE);
return parseTokenBranch(walker, recursion + 1, NodeType.THIS_EXPRESSION, Language.Key.THIS); //TokenType.KEYWORD, "this");
}
case NodeType.OUTER_THIS_EXPRESSION: {
Node t = parseInner(walker, recursion + 1, NodeType.TYPE_REFERENCE);
if (t == null) {
return null;
}
Node dot = parseInner(walker, recursion + 1, NodeType.DOT);
if (dot == null) {
return null;
}
Node thi = parseTokenBranch(walker, recursion + 1, NodeType.THIS_EXPRESSION, Language.Key.THIS); //TokenType.KEYWORD, "this");
if (thi == null) {
return null;
} else {
return new Branch(NodeType.OUTER_THIS_EXPRESSION, t, dot, thi);
}
}
case NodeType.OUTER_SUPER_CONSTRUCTOR_CALL_EXPRESSION: {
Node outerThis = parseAny(walker, recursion + 1, NodeType.OUTER_THIS_EXPRESSION, NodeType.TYPE);
if (outerThis == null) {
return null;
}
Node dot = parseInner(walker, recursion + 1, NodeType.DOT);
if (dot == null) {
return null;
}
Node sup = parseToken(walker, recursion + 1, Language.Key.SUPER); //TokenType.KEYWORD, "super");
if (sup == null) {
return null;
}
Node argsOrDot = parseAny(walker, recursion + 1, NodeType.DOT, NodeType.ARGUMENTS);
if (argsOrDot == null) {
return null;
}
if (argsOrDot.getNodeType() == NodeType.DOT) {
Node nam = expectAny(walker, recursion + 1, NodeType.NAME);
Node realargs = expectAny(walker, recursion + 1, NodeType.ARGUMENTS);
return new Branch(NodeType.OUTER_SUPER_METHOD_CALL_EXPRESSION, outerThis, dot, sup, argsOrDot, nam, realargs);
}
return new Branch(NodeType.OUTER_THIS_EXPRESSION, outerThis, dot, sup, argsOrDot);
}
case NodeType.TYPE_EXPRESSION: {
Node t = parseAny(walker, recursion + 1, NodeType.TYPE, NodeType.RETURN_TYPE); // RETURN_TYPE handles special case NodeType.of void
if (t == null) {
return null;
}
Node dot = parseInner(walker, recursion + 1, NodeType.DOT);
if (dot == null) {
return null;
}
Node thi = parseToken(walker, recursion + 1, Language.Key.CLASS);//parseToken(walker, recursion + 1, TokenType.KEYWORD, "class");
if (thi == null) {
return null;
} else {
return new Branch(NodeType.TYPE_EXPRESSION, t, dot, thi);
}
}
/*case NodeType.NAMED_LAMBDA_EXPRESSION: {
Node t = parseAny(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
}
Node dcol = parseAny(walker, recursion + 1, NodeType.DOUBLECOLON);
if (dcol == null) {
return null;
}
Node name = parseToken(walker, recursion + 1, Language.Key.NEW); //TokenType.KEYWORD, "new");
if (name == null) {
name = expectAny(walker, recursion + 1, TokenType.NAME);
}
return new Branch(NodeType.NAMED_LAMBDA_EXPRESSION, t, dcol, name);
}*/
case NodeType.LAMBDA_ARGS: {
Node open = parseAny(walker, recursion + 1, NodeType.NAME, NodeType.OPEN_ROUND_BRACE);
if (open == null) {
return null;
}
if (open.getNodeType() == NodeType.NAME) {
return new Branch(NodeType.LAMBDA_ARGS, open);
}
Node inner = parseList(walker, recursion + 1, NodeType.ARGUMENT_DECLARATION_LIST, NodeType.COMMA, false, NodeType.LAZY_ARGUMENT_DECLARATION, NodeType.VARIABLE_ARGUMENT_DECLARATION, NodeType.SIMPLE_ARGUMENT_DECLARATION, NodeType.NAME);
Node close = parseAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE);
if (close == null) {
return null;
}
return new Branch(NodeType.LAMBDA_ARGS, open, inner, close);
}
case NodeType.LAMBDA_EXPRESSION: {
Node args = parseAny(walker, recursion + 1, NodeType.LAMBDA_ARGS);
if (args == null) {
return null;
}
Node op = parseToken(walker, recursion + 1, TokenType.OPERATOR, "->");
if (op == null) {
return null;
}
Node rhs = expectAny(walker, recursion + 1, NodeType.BLOCK_STATEMENT, NodeType.EXPRESSION);
return new Branch(NodeType.LAMBDA_EXPRESSION, args, op, rhs);
}
case NodeType.SIMPLE_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1,
NodeType.TYPE_NAMED_LAMBDA_EXPRESSION,
NodeType.SUPER,
NodeType.THIS_EXPRESSION,
NodeType.OUTER_SUPER_CONSTRUCTOR_CALL_EXPRESSION, // A weird edge-case
NodeType.OUTER_THIS_EXPRESSION,
NodeType.TYPE_EXPRESSION,
NodeType.LITERAL_EXPRESSION,
NodeType.BRACED_EXPRESSION,
NodeType.GENERIC_REFERENCE_EXPRESSION,
NodeType.REFERENCE_EXPRESSION,
NodeType.NEW_EXPRESSION);
boolean done = false;
while (lhs != null && !done && !walker.isAtEnd() &&
(walker.peek().is(TokenType.OPERATOR, "[")
|| walker.peek().is(TokenType.OPERATOR, ".")
|| walker.peek().is(TokenType.OPERATOR, "::")
|| walker.peek().is(TokenType.OPERATOR, "("))) {
if ((lhs.getNodeType() == NodeType.REFERENCE_EXPRESSION || lhs.getNodeType() == NodeType.GENERIC_REFERENCE_EXPRESSION) && walker.peek().is(TokenType.OPERATOR, "(")) {
lhs = new Branch(NodeType.AUTOMATIC_METHOD_CALL_EXPRESSION,
lhs,
parseInner(walker, recursion + 1, NodeType.ARGUMENTS));
} else if (lhs.getNodeType() == NodeType.SUPER && walker.peek().is(TokenType.OPERATOR, "(")) {
lhs = new Branch(NodeType.SUPER_CONSTRUCTOR_CALL_EXPRESSION,
lhs,
parseInner(walker, recursion + 1, NodeType.ARGUMENTS));
} else if (lhs.getNodeType() == NodeType.THIS_EXPRESSION && walker.peek().is(TokenType.OPERATOR, "(")) {
lhs = new Branch(NodeType.THIS_CONSTRUCTOR_CALL_EXPRESSION,
lhs,
parseInner(walker, recursion + 1, NodeType.ARGUMENTS));
} else if (walker.peek().is(TokenType.OPERATOR, "::")) {
Node dcol = parseInner(walker, recursion + 1, NodeType.DOUBLECOLON);
Node nam = parseToken(walker, recursion + 1, Language.Key.NEW); //TokenType.KEYWORD, "new");
if (nam == null) {
nam = expectAny(walker, recursion + 1, NodeType.NAME);
}
lhs = new Branch(NodeType.NAMED_LAMBDA_EXPRESSION,
lhs,
dcol,
nam);
} else if (walker.peek().is(TokenType.OPERATOR, ".")) {
boolean isThis = lhs.getNodeType() == NodeType.THIS_EXPRESSION;
boolean isSuper = lhs.getNodeType() == NodeType.SUPER;
Node dot = parseInner(walker, recursion + 1, NodeType.DOT);
Node specialNew = parseAny(walker, recursion + 1, NodeType.NEW_EXPRESSION);
if (specialNew != null) {
lhs = new Branch(NodeType.SPECIAL_NEW_EXPRESSION,
lhs,
dot,
specialNew);
} else {
Node nam = expectAny(walker, recursion + 1, NodeType.NAME, NodeType.THIS_EXPRESSION, NodeType.GENERIC_REFERENCE_NAME);
if (walker.peek().is(TokenType.OPERATOR, "(")) {
lhs = new Branch(isThis ? NodeType.THIS_METHOD_CALL_EXPRESSION : (isSuper ? NodeType.SUPER_METHOD_CALL_EXPRESSION : NodeType.NORMAL_METHOD_CALL_EXPRESSION),
lhs,
dot,
nam,
parseInner(walker, recursion + 1, NodeType.ARGUMENTS));
} else {
lhs = new Branch(/*isThis ? NodeType.THIS_REFERENCE_EXPRESSION : (isSuper ? NodeType.SUPER_REFERENCE_EXPRESSION : */ (NodeType.SUBREFERENCE_EXPRESSION),
lhs,
dot,
nam);
}
}
} else if (lhs.getNodeType() != NodeType.SUPER && lhs.getNodeType() != NodeType.THIS_EXPRESSION && walker.peek().is(TokenType.OPERATOR, "[")) {
Node open = parseInner(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE);
/*if (walker.peek().is(TokenType.OPERATOR, "]")) {
//ScanWalker pos = walker.clone();
Node close = parseInner(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE);
lhs = new Branch(NodeType.SPECIAL_ARRAY_TYPE_EXPRESSION, open, close);
} else {*/
lhs = new Branch(NodeType.ARRAY_INDEX_EXPRESSION,
lhs,
open,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE));
//}
} else {
done = true;
}
}
return lhs;
}
case NodeType.TYPE_NAMED_LAMBDA_EXPRESSION: {
Node typ = parseAny(walker, recursion + 1, NodeType.TYPE);
if (typ == null) {
return null;
}
Node dcol = parseAny(walker, recursion + 1, NodeType.DOUBLECOLON);
if (dcol == null) {
return null;
}
Node nam = parseToken(walker, recursion + 1, Language.Key.NEW); //TokenType.KEYWORD, "new");
if (nam == null) {
nam = expectAny(walker, recursion + 1, NodeType.NAME);
}
return new Branch(NodeType.TYPE_NAMED_LAMBDA_EXPRESSION, typ, dcol, nam);
}
case NodeType.NEW_EXPRESSION: {
Node keyword = parseToken(walker, recursion + 1, Language.Key.NEW); //TokenType.KEYWORD, "new");
if (keyword == null) {
return null;
} else {
Node typ = expectAny(walker, recursion + 1, NodeType.TYPE);
if (typ.getNodeType() == NodeType.TYPE && ((Branch)typ).getSubnode(0).getNodeType() == NodeType.ARRAY_TYPE) {
return new Branch(NodeType.NEW_INITIALISED_ARRAY_EXPRESSION,
keyword,
typ,
expectAny(walker, recursion + 1, NodeType.ARRAY_INITIALISER));
}
if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "[")) {
Node opener = parseAny(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE);
/*if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "]")) {
Node closer = parseAny(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE);
return new Branch(NodeType.NEW_INITIALISED_ARRAY_EXPRESSION,
keyword,
typ,
opener,
closer,
expectAny(walker, recursion + 1, NodeType.ARRAY_INITIALISER));
} else*/ {
return new Branch(NodeType.NEW_CLEARED_ARRAY_EXPRESSION,
keyword,
typ,
opener,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE),
expectAny(walker, recursion + 1, NodeType.ARRAY_TYPE_TAIL));
}
} else {
Node args = expectAny(walker, recursion + 1, NodeType.ARGUMENTS);
if (!walker.isAtEnd() && walker.peek().is(TokenType.OPERATOR, "{")) {
return new Branch(NodeType.NEW_CLASS_EXPRESSION,
keyword,
typ,
args,
expectAny(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE),
parseInner(walker, recursion + 1, NodeType.CLASS_MEMBERS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
} else {
return new Branch(NodeType.NEW_OBJECT_EXPRESSION,
keyword,
typ,
args);
}
/*
return new Branch(NodeType.NEW_OBJECT_EXPRESSION,
keyword,
typ,
expectAny(walker, recursion + 1, NodeType.ARGUMENTS));*/
}
}
}
case NodeType.ARRAY_TYPE_TAIL: {
Node tmp;
Branch result = new Branch(NodeType.ARRAY_TYPE_TAIL);
while ((tmp = parseAny(walker, recursion + 1, NodeType.ARRAY_TYPE_PART)) != null) {
result.append(tmp);
}
return result;
}
case NodeType.ARRAY_TYPE_PART: {
Node open = parseAny(walker, recursion + 1, NodeType.OPEN_SQUARE_BRACE);
if (open == null) {
return null;
}
Node close = parseAny(walker, recursion + 1, NodeType.CLOSE_SQUARE_BRACE);
if (close == null) {
return null;
}
return new Branch(NodeType.ARRAY_TYPE_PART, open, close);
}
case NodeType.UNARY_EXPRESSION: {
Node op = parseInner(walker, recursion + 1, NodeType.UNARY_OPERATOR);
if (op == null) {
Node open = parseInner(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (open == null) {
return null;
} else {
Node typ = parseInner(walker, recursion + 1, NodeType.ANDABLE_TYPE);
if (typ == null) {
return null;
} else {
Node close = parseInner(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE);
if (close == null) {
return null;
} else {
// TODO: Should parsing EXPRESSION here really work?
Node expr = parseAny(walker, recursion + 1, NodeType.UNARY_EXPRESSION, NodeType.SIMPLE_EXPRESSION);
if (expr == null) {
return null;
} else {
return new Branch(NodeType.CAST_EXPRESSION, open, typ, close, expr);
}
}
}
}
} else {
Node rhs = parseAny(walker, recursion + 1, NodeType.UNARY_EXPRESSION, NodeType.SIMPLE_EXPRESSION);
if (rhs.getNodeType() == NodeType.STRING_LITERAL_EXPRESSION) {
return null; // XXX This is a bit of a hack to prevent (x) + "str" evaluating as a cast
}
return new Branch(NodeType.UNARY_EXPRESSION,
op,
rhs);
}
}
case NodeType.MULTIPLICATIVE_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.UNARY_EXPRESSION, NodeType.COUNT_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.MULTIPLICATIVE_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.MULTIPLICATIVE_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.UNARY_EXPRESSION, NodeType.SIMPLE_EXPRESSION));
}
}
return lhs;
}
case NodeType.ADDITIVE_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.MULTIPLICATIVE_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.ADDITIVE_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.ADDITIVE_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.MULTIPLICATIVE_EXPRESSION));
}
}
return lhs;
}
case NodeType.SHIFT_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.ADDITIVE_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.SHIFT_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.SHIFT_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.ADDITIVE_EXPRESSION));
}
}
return lhs;
}
case NodeType.COMPARISON_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.SHIFT_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.COMPARISON_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.COMPARISON_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.SHIFT_EXPRESSION));
}
}
return lhs;
}
case NodeType.INSTANCEOF_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.COMPARISON_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseToken(walker, recursion + 1, Language.Key.INSTANCEOF); //TokenType.KEYWORD, "instanceof");
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.INSTANCEOF_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.TYPE));
}
}
return lhs;
}
case NodeType.EQUALITY_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.INSTANCEOF_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.EQUALITY_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.EQUALITY_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.INSTANCEOF_EXPRESSION));
}
}
return lhs;
}
/*case NodeType.LOGICAL_EXPRESSION: {
Node lhs = parseAny(walker, recursion + 1, NodeType.EQUALITY_EXPRESSION);
boolean done = false;
while (lhs != null && !walker.isAtEnd() && !done) {
Node op = parseAny(walker, recursion, NodeType.LOGICAL_OPERATOR);
if (op == null) {
done = true;
} else {
lhs = new Branch(NodeType.LOGICAL_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.EQUALITY_EXPRESSION));
}
}
return lhs;
}*/
case NodeType.BITWISE_AND_EXPRESSION:
return parseSimpleBinop(walker, recursion,
NodeType.BITWISE_AND_EXPRESSION,
NodeType.BITWISE_AND_OPERATOR,
NodeType.EQUALITY_EXPRESSION);
case NodeType.BITWISE_XOR_EXPRESSION:
return parseSimpleBinop(walker, recursion,
NodeType.BITWISE_XOR_EXPRESSION,
NodeType.BITWISE_XOR_OPERATOR,
NodeType.BITWISE_AND_EXPRESSION);
case NodeType.BITWISE_OR_EXPRESSION:
return parseSimpleBinop(walker, recursion,
NodeType.BITWISE_OR_EXPRESSION,
NodeType.BITWISE_OR_OPERATOR,
NodeType.BITWISE_XOR_EXPRESSION);
case NodeType.LOGICAL_AND_EXPRESSION:
return parseSimpleBinop(walker, recursion,
NodeType.LOGICAL_AND_EXPRESSION,
NodeType.LOGICAL_AND_OPERATOR,
NodeType.BITWISE_OR_EXPRESSION);
case NodeType.LOGICAL_OR_EXPRESSION:
return parseSimpleBinop(walker, recursion,
NodeType.LOGICAL_OR_EXPRESSION,
NodeType.LOGICAL_OR_OPERATOR,
NodeType.LOGICAL_AND_EXPRESSION);
case NodeType.CONDITIONAL_EXPRESSION: {
Node cond = parseAny(walker, recursion + 1, NodeType.LOGICAL_OR_EXPRESSION /*NodeType.LOGICAL_EXPRESSION*/); // TODO: Change to only bracketed expression
if (cond == null) {
return null;
}
Node q = parseToken(walker, recursion + 1, TokenType.OPERATOR, "?");
if (q == null) {
return cond;
}
Node opt1 = parseAny(walker, recursion + 1, NodeType.LAMBDA_EXPRESSION, NodeType.CONDITIONAL_EXPRESSION, NodeType.LOGICAL_OR_EXPRESSION);
Node c = parseToken(walker, recursion + 1, TokenType.OPERATOR, ":"); // TODO: Expect
Node opt2 = parseAny(walker, recursion + 1, NodeType.LAMBDA_EXPRESSION, NodeType.CONDITIONAL_EXPRESSION, NodeType.LOGICAL_OR_EXPRESSION);
return new Branch(NodeType.CONDITIONAL_EXPRESSION, cond, q, opt1, c, opt2);
}
case NodeType.ASSIGNMENT_EXPRESSION: {
Node lhs = parseInner(walker, recursion + 1, NodeType.SIMPLE_EXPRESSION);
if (lhs != null && !walker.isAtEnd() && (lhs.getNodeType() == NodeType.REFERENCE_EXPRESSION || lhs.getNodeType() == NodeType.SUBREFERENCE_EXPRESSION || lhs.getNodeType() == NodeType.ARRAY_INDEX_EXPRESSION)) {
Node op = parseInner(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR);
if (op == null) {
//op = parseInner(walker, recursion + 1, NodeType.COUNT_OPERATOR);
//if (op == null) {
return null;
//} else {
//return new Branch(NodeType.COUNT_EXPRESSION, lhs, op);
//}
} else {
return new Branch(NodeType.ASSIGNMENT_EXPRESSION,
lhs,
op,
expectAny(walker, recursion + 1, NodeType.EXPRESSION));
}
} else {
return null;
}
}
case NodeType.COUNT_EXPRESSION: {
Node lhs = parseInner(walker, recursion + 1, NodeType.SIMPLE_EXPRESSION);
if (lhs != null && !walker.isAtEnd()/* && (lhs.getNodeType() == NodeType.REFERENCE_EXPRESSION || lhs.getNodeType() == NodeType.SUBREFERENCE_EXPRESSION || lhs.getNodeType() == NodeType.ARRAY_INDEX_EXPRESSION)*/) {
Node op = parseInner(walker, recursion + 1, NodeType.COUNT_OPERATOR);
if (op == null) {
return lhs;
} else {
return new Branch(NodeType.COUNT_EXPRESSION, lhs, op);
}
} else {
return lhs;
}
}
case NodeType.ASSIGNMENT_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "+=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "-=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "*=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "/=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "%=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "&=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "|=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "^=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, "<<=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, ">>>=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ASSIGNMENT_OPERATOR, TokenType.OPERATOR, ">>=");
return result;
}
case NodeType.COUNT_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COUNT_OPERATOR, TokenType.OPERATOR, "--");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COUNT_OPERATOR, TokenType.OPERATOR, "++");
return result;
}
case NodeType.UNARY_OPERATOR: {
Node result = parseInner(walker, recursion + 1, NodeType.COUNT_OPERATOR);
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.UNARY_OPERATOR, TokenType.OPERATOR, "-");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.UNARY_OPERATOR, TokenType.OPERATOR, "+");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.UNARY_OPERATOR, TokenType.OPERATOR, "!");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.UNARY_OPERATOR, TokenType.OPERATOR, "~");
return result;
}
case NodeType.MULTIPLICATIVE_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "*");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "/");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "%");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "&");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "|");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.MULTIPLICATIVE_OPERATOR, TokenType.OPERATOR, "^");
return result;
}
case NodeType.ADDITIVE_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ADDITIVE_OPERATOR, TokenType.OPERATOR, "+");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ADDITIVE_OPERATOR, TokenType.OPERATOR, "-");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ADDITIVE_OPERATOR, TokenType.OPERATOR, "&");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.ADDITIVE_OPERATOR, TokenType.OPERATOR, "|");
return result;
}
case NodeType.SHIFT_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.SHIFT_OPERATOR, TokenType.OPERATOR, "<<");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.SHIFT_OPERATOR, TokenType.OPERATOR, ">>");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.SHIFT_OPERATOR, TokenType.OPERATOR, ">>>");
// Special handling of combined ">" characters is required for generics
result = result != null ? result : parseSpecialTokenBranch(walker, recursion + 1, NodeType.SHIFT_OPERATOR, TokenType.OPERATOR, ">", 3);
result = result != null ? result : parseSpecialTokenBranch(walker, recursion + 1, NodeType.SHIFT_OPERATOR, TokenType.OPERATOR, ">", 2);
return result;
}
case NodeType.COMPARISON_OPERATOR: {
Node result = null;
// Specifically fail if we can parse (especially muliple ">" characters) as a shift operator instead
Node shiftop = parseAny(walker, recursion + 1, NodeType.SHIFT_OPERATOR);
if (shiftop != null) {
return null;
}
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, "==");
//result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, "!=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, "<");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, "<=");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, ">");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.COMPARISON_OPERATOR, TokenType.OPERATOR, ">=");
return result;
}
case NodeType.EQUALITY_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.EQUALITY_OPERATOR, TokenType.OPERATOR, "==");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.EQUALITY_OPERATOR, TokenType.OPERATOR, "!=");
return result;
}
case NodeType.BITWISE_AND_OPERATOR:
return parseTokenBranch(walker, recursion + 1,
NodeType.BITWISE_AND_OPERATOR, "&");
case NodeType.BITWISE_XOR_OPERATOR:
return parseTokenBranch(walker, recursion + 1,
NodeType.BITWISE_XOR_OPERATOR, "^");
case NodeType.BITWISE_OR_OPERATOR:
return parseTokenBranch(walker, recursion + 1,
NodeType.BITWISE_AND_OPERATOR, "|");
case NodeType.LOGICAL_AND_OPERATOR:
return parseTokenBranch(walker, recursion + 1,
NodeType.LOGICAL_AND_OPERATOR, "&&");
case NodeType.LOGICAL_OR_OPERATOR:
return parseTokenBranch(walker, recursion + 1,
NodeType.LOGICAL_OR_OPERATOR, "||");
case NodeType.LOGICAL_OPERATOR: {
Node result = null;
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.LOGICAL_OPERATOR, TokenType.OPERATOR, "&&");
result = result != null ? result : parseTokenBranch(walker, recursion + 1, NodeType.LOGICAL_OPERATOR, TokenType.OPERATOR, "||");
return result;
}
case NodeType.EXPRESSION:
return parseAny(walker, recursion + 1,
NodeType.LAMBDA_EXPRESSION,
NodeType.ASSIGNMENT_EXPRESSION,
NodeType.CONDITIONAL_EXPRESSION,
NodeType.LOGICAL_OR_EXPRESSION);
case NodeType.EXPRESSIONS:
return parseList(walker, recursion + 1, NodeType.EXPRESSIONS, NodeType.COMMA, false, NodeType.EXPRESSION);
case NodeType.ARRAY_EXPRESSIONS:
return parseList(walker, recursion + 1, NodeType.ARRAY_EXPRESSIONS, NodeType.COMMA, true, NodeType.ARRAY_INITIALISER, NodeType.EXPRESSION);
case NodeType.MODIFIER_EXPRESSIONS:
return parseList(walker, recursion + 1, NodeType.MODIFIER_EXPRESSIONS, NodeType.COMMA, true, NodeType.ARRAY_INITIALISER, NodeType.SIMPLE_ASSIGN, NodeType.EXPRESSION);
case NodeType.SIMPLE_ASSIGN: {
Node nam = parseAny(walker, recursion + 1, NodeType.NAME);
if (nam == null) {
return null;
}
Node eq = parseToken(walker, recursion + 1, TokenType.OPERATOR, "=");
if (eq == null) {
return null;
}
return new Branch(NodeType.SIMPLE_ASSIGN,
nam,
eq,
expectAny(walker, recursion + 1, NodeType.ARRAY_INITIALISER, NodeType.EXPRESSION));
}
case NodeType.SIMPLE_GENERIC_WILDCARD:
return parseTokenBranch(walker, recursion + 1, NodeType.SIMPLE_GENERIC_WILDCARD, TokenType.OPERATOR, "?");
case NodeType.EXTENDED_GENERIC_WILDCARD: {
Node start = parseTokenBranch(walker, recursion + 1, NodeType.QUESTIONMARK, TokenType.OPERATOR, "?");
if (start == null) {
return null;
}
Node ext = parseToken(walker, recursion + 1, Language.Key.EXTENDS); //TokenType.KEYWORD, "extends");
if (ext == null) {
return null;
}
Node typ = expectAny(walker, recursion + 1, NodeType.ANDABLE_TYPE);
return new Branch(NodeType.EXTENDED_GENERIC_WILDCARD, start, ext, typ);
}
case NodeType.ANDABLE_TYPE: {
ScanWalker pos = walker.clone();
Node firstType = parseAny(walker, recursion + 1, NodeType.TYPE);
if (firstType == null) {
return null;
}
walker.reset(pos);
ScanWalker.recycle(pos);
return parseList(walker, recursion + 1, NodeType.ANDABLE_TYPE, NodeType.SINGLE_AND, false, NodeType.TYPE);
}
case NodeType.SINGLE_AND: {
return parseTokenBranch(walker, recursion + 1, NodeType.SINGLE_AND, TokenType.OPERATOR, "&");
}
case NodeType.SUPER_GENERIC_WILDCARD: {
Node start = parseTokenBranch(walker, recursion + 1, NodeType.QUESTIONMARK, TokenType.OPERATOR, "?");
if (start == null) {
return null;
}
Node sup = parseToken(walker, recursion + 1, Language.Key.SUPER); //TokenType.KEYWORD, "super");
if (sup == null) {
return null;
}
Node typ = expectAny(walker, recursion + 1, NodeType.TYPE);
return new Branch(NodeType.SUPER_GENERIC_WILDCARD, start, sup, typ);
}
case NodeType.GENERIC_VALUE:
//return new Branch(NodeType.GENERIC_VALUE,
return parseAny(walker, recursion + 1,
NodeType.TYPE,
NodeType.EXTENDED_GENERIC_WILDCARD,
NodeType.SUPER_GENERIC_WILDCARD,
NodeType.SIMPLE_GENERIC_WILDCARD);//);
case NodeType.GENERIC_EXPRESSIONS:
return parseList(walker, recursion + 1, NodeType.GENERIC_EXPRESSIONS, NodeType.COMMA, false, NodeType.GENERIC_VALUE);
case NodeType.BRACED_EXPRESSION: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (start == null) {
return null;
} else {
return new Branch(NodeType.BRACED_EXPRESSION,
start,
expectAny(walker, recursion + 1, NodeType.EXPRESSION),
expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE));
}
}
case NodeType.ARGUMENTS: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_ROUND_BRACE);
if (start == null) {
return null;
} else {
return new Branch(NodeType.ARGUMENTS,
start,
parseInner(walker, recursion + 1, NodeType.EXPRESSIONS),
expectAny(walker, recursion + 1, NodeType.CLOSE_ROUND_BRACE));
}
}
case NodeType.ARRAY_INITIALISER: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_CURLY_BRACE);
if (start == null) {
return null;
} else {
return new Branch(NodeType.ARRAY_INITIALISER,
start,
parseInner(walker, recursion + 1, NodeType.ARRAY_EXPRESSIONS),
expectAny(walker, recursion + 1, NodeType.CLOSE_CURLY_BRACE));
}
}
case NodeType.GENERIC_ARGUMENTS: {
Node start = parseInner(walker, recursion + 1, NodeType.OPEN_ANGLE_BRACE);
if (start == null) {
return null;
} else {
Node middle = parseAny(walker, recursion + 1, NodeType.GENERIC_EXPRESSIONS);
if (middle == null) {
return null;
}
Node end = parseAny(walker, recursion + 1, NodeType.CLOSE_ANGLE_BRACE);
if (end == null) {
return null;
}
return new Branch(NodeType.GENERIC_ARGUMENTS,
start,
middle,
end);
}
}
case NodeType.SLOTS:
return parseList(walker, recursion + 1, NodeType.SLOTS, NodeType.COMMA, false, NodeType.INITIALISED_SLOT);
case NodeType.INITIALISED_SLOT: {
Node n = parseInner(walker, recursion + 1, NodeType.INDEXED_NAME);
if (n == null) {
return null;
} else {
Token eq = parseToken(walker, recursion + 1, TokenType.OPERATOR, "=");
if (eq == null) {
return new Branch(NodeType.UNINITIALISED_SLOT, n);
} else {
return new Branch(NodeType.INITIALISED_SLOT, n, eq, expectAny(walker, recursion + 1, NodeType.EXPRESSION, NodeType.ARRAY_INITIALISER));
}
}
}
case NodeType.SIMPLE_ARGUMENT_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.INDEXED_NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.SIMPLE_ARGUMENT_DECLARATION, mods, t, n);
}
}
}
case NodeType.LAZY_ARGUMENT_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.LAZY_TYPE);
if (t == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.INDEXED_NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.SIMPLE_ARGUMENT_DECLARATION, mods, t, n);
}
}
}
case NodeType.LAZY_TYPE: {
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
}
Node bar = null;
Branch result = null;
while ((bar = parseToken(walker, recursion + 1, TokenType.OPERATOR, "|")) != null) {
Node nextt = parseInner(walker, recursion + 1, NodeType.TYPE);
if (nextt == null) {
return null;
}
if (result == null) {
result = new Branch(NodeType.LAZY_TYPE);
result.append(t);
}
result.append(bar);
result.append(nextt);
}
return result; // Will be null unless one or more "|" followed by another type was found
}
case NodeType.VARIABLE_ARGUMENT_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
} else {
Node dots = parseToken(walker, recursion + 1, TokenType.OPERATOR, "...");
if (dots == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.INDEXED_NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.VARIABLE_ARGUMENT_DECLARATION, mods, t, dots, n);
}
}
}
}
case NodeType.SIMPLE_GENERIC_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.SIMPLE_GENERIC_DECLARATION, mods, n);
}
}
case NodeType.SIMPLE_EXTENDED_GENERIC_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
}
Node ext = parseToken(walker, recursion + 1, Language.Key.EXTENDS); //TokenType.KEYWORD, "extends");
if (ext == null) {
return null;
}
Node typ = expectAny(walker, recursion + 1, NodeType.ANDABLE_TYPE);
return new Branch(NodeType.SIMPLE_EXTENDED_GENERIC_DECLARATION, mods, n, ext, typ);
}
case NodeType.SIMPLE_TYPED_GENERIC_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.SIMPLE_TYPED_GENERIC_DECLARATION, mods, t, n);
}
}
}
case NodeType.VARIABLE_GENERIC_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node dots = parseToken(walker, recursion + 1, TokenType.OPERATOR, "...");
if (dots == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.VARIABLE_GENERIC_DECLARATION, mods, dots, n);
}
}
}
case NodeType.VARIABLE_TYPED_GENERIC_DECLARATION: {
Node mods = parseInner(walker, recursion + 1, NodeType.MODIFIER_LIST);
Node t = parseInner(walker, recursion + 1, NodeType.TYPE);
if (t == null) {
return null;
} else {
Node dots = parseToken(walker, recursion + 1, TokenType.OPERATOR, "...");
if (dots == null) {
return null;
} else {
Node n = parseInner(walker, recursion + 1, NodeType.NAME);
if (n == null) {
return null;
} else {
return new Branch(NodeType.VARIABLE_TYPED_GENERIC_DECLARATION, mods, t, dots, n);
}
}
}
}
case NodeType.UNIT:
return new Branch(NodeType.UNIT,
parseInner(walker, recursion + 1, NodeType.PACKAGE_DECLARATION),
parseList(walker, recursion + 1, NodeType.IMPORT_DECLARATIONS, null, false,
NodeType.IMPORT_DECLARATION),
parseInner(walker, recursion + 1, NodeType.TYPE_DECLARATIONS),
expectAny(walker, recursion + 1, NodeType.EOF));
default:
//System.out.println("TODO: Parsing of " + type);
//return new Branch(NodeType.ERROR_ONLY).annotate(ErrorType.INTERNAL_ERROR, "TODO: Parsing of " + type);
return null;
}
}
public Node parseSafely(ScanWalker walker, int recursion, NodeType type) {
checkRecursion(walker, recursion);
ScanWalker w = walker.clone();
Node r = parseInner(walker, recursion + 1, type);
if (r != null) {
walker.reset(w);
}
ScanWalker.recycle(w);
return r;
}
public Node parseUnit(Scan scan) {
ScanWalker w = new ScanWalker(scan);
return parseSafely(w, 0, NodeType.UNIT);
}
public void checkRecursion(ScanWalker walker, int recursion) {
if (recursion >= maxRecursion) {
throw new Error("Recursion got too deep around " + walker.peek());
}
}
}