Reformat JS parser for conformance with project's style settings

This commit is contained in:
Alexey Andreev
2017-05-17 12:38:46 +03:00
parent 41ad637bad
commit 3a3720db8d
@@ -44,7 +44,7 @@ import java.util.Observable;
/** /**
* This class implements the JavaScript parser. * This class implements the JavaScript parser.
* * <p>
* It is based on the C source files jsparse.c and jsparse.h in the jsref * It is based on the C source files jsparse.c and jsparse.h in the jsref
* package. * package.
* *
@@ -57,8 +57,7 @@ public class Parser extends Observable {
this.insideFunction = insideFunction; this.insideFunction = insideFunction;
} }
private void mustMatchToken(TokenStream ts, int toMatch, String messageId) private void mustMatchToken(TokenStream ts, int toMatch, String messageId) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
int tt; int tt;
if ((tt = ts.getToken()) != toMatch) { if ((tt = ts.getToken()) != toMatch) {
reportError(ts, messageId); reportError(ts, messageId);
@@ -66,8 +65,7 @@ public class Parser extends Observable {
} }
} }
private void reportError(TokenStream ts, String messageId) private void reportError(TokenStream ts, String messageId) throws JavaScriptException {
throws JavaScriptException {
this.ok = false; this.ok = false;
ts.reportSyntaxError(messageId, null); ts.reportSyntaxError(messageId, null);
@@ -114,11 +112,13 @@ public class Parser extends Observable {
if (tt == TokenStream.FUNCTION) { if (tt == TokenStream.FUNCTION) {
try { try {
nf.addChildToBack(tempBlock, function(ts, false)); nf.addChildToBack(tempBlock, function(ts, false));
} catch (JavaScriptException e) { }
catch (JavaScriptException e) {
this.ok = false; this.ok = false;
break; break;
} }
} else { }
else {
ts.ungetToken(tt); ts.ungetToken(tt);
nf.addChildToBack(tempBlock, statement(ts)); nf.addChildToBack(tempBlock, statement(ts));
} }
@@ -129,8 +129,7 @@ public class Parser extends Observable {
return null; return null;
} }
Object pn = nf.createScript(tempBlock, ts.getSourceName(), baseLineno, ts Object pn = nf.createScript(tempBlock, ts.getSourceName(), baseLineno, ts.getLineno(), null);
.getLineno(), null);
((Node) pn).setIsSyntheticBlock(true); ((Node) pn).setIsSyntheticBlock(true);
return pn; return pn;
} }
@@ -152,13 +151,16 @@ public class Parser extends Observable {
if (tt == TokenStream.FUNCTION) { if (tt == TokenStream.FUNCTION) {
ts.getToken(); ts.getToken();
nf.addChildToBack(pn, function(ts, false)); nf.addChildToBack(pn, function(ts, false));
} else { }
else {
nf.addChildToBack(pn, statement(ts)); nf.addChildToBack(pn, statement(ts));
} }
} }
} catch (JavaScriptException e) { }
catch (JavaScriptException e) {
this.ok = false; this.ok = false;
} finally { }
finally {
// also in finally block: // also in finally block:
// flushNewLines, clearPushback. // flushNewLines, clearPushback.
@@ -177,8 +179,7 @@ public class Parser extends Observable {
if (ts.matchToken(TokenStream.NAME)) { if (ts.matchToken(TokenStream.NAME)) {
name = ts.getString(); name = ts.getString();
if (!ts.matchToken(TokenStream.LP)) { if (!ts.matchToken(TokenStream.LP)) {
if (Context.getContext().hasFeature( if (Context.getContext().hasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)) {
Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)) {
// Extension to ECMA: if 'function <name>' does not follow // Extension to ECMA: if 'function <name>' does not follow
// by '(', assume <name> starts memberExpr // by '(', assume <name> starts memberExpr
Object memberExprHead = nf.createName(name); Object memberExprHead = nf.createName(name);
@@ -187,13 +188,14 @@ public class Parser extends Observable {
} }
mustMatchToken(ts, TokenStream.LP, "msg.no.paren.parms"); mustMatchToken(ts, TokenStream.LP, "msg.no.paren.parms");
} }
} else if (ts.matchToken(TokenStream.LP)) { }
else if (ts.matchToken(TokenStream.LP)) {
// Anonymous function // Anonymous function
name = null; name = null;
} else { }
else {
name = null; name = null;
if (Context.getContext().hasFeature( if (Context.getContext().hasFeature(Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)) {
Context.FEATURE_MEMBER_EXPR_AS_FUNCTION_NAME)) {
// Note that memberExpr can not start with '(' like // Note that memberExpr can not start with '(' like
// in (1+2).toString, because 'function (' already // in (1+2).toString, because 'function (' already
// processed as anonymous function // processed as anonymous function
@@ -219,8 +221,8 @@ public class Parser extends Observable {
mustMatchToken(ts, TokenStream.NAME, "msg.no.parm"); mustMatchToken(ts, TokenStream.NAME, "msg.no.parm");
String s = ts.getString(); String s = ts.getString();
nf.addChildToBack(args, nf.createName(s)); nf.addChildToBack(args, nf.createName(s));
}
} while (ts.matchToken(TokenStream.COMMA)); while (ts.matchToken(TokenStream.COMMA));
mustMatchToken(ts, TokenStream.GWT, "msg.no.paren.after.parms"); mustMatchToken(ts, TokenStream.GWT, "msg.no.paren.after.parms");
} }
@@ -229,7 +231,8 @@ public class Parser extends Observable {
body = parseFunctionBody(ts); body = parseFunctionBody(ts);
mustMatchToken(ts, TokenStream.RC, "msg.no.brace.after.body"); mustMatchToken(ts, TokenStream.RC, "msg.no.brace.after.body");
// skip the last EOL so nested functions work... // skip the last EOL so nested functions work...
} finally { }
finally {
sourceTop = savedSourceTop; sourceTop = savedSourceTop;
functionNumber = savedFunctionNumber; functionNumber = savedFunctionNumber;
} }
@@ -261,8 +264,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object condition(TokenStream ts) throws IOException, private Object condition(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
Object pn; Object pn;
mustMatchToken(ts, TokenStream.LP, "msg.no.paren.cond"); mustMatchToken(ts, TokenStream.LP, "msg.no.paren.cond");
pn = expr(ts, false); pn = expr(ts, false);
@@ -273,8 +275,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private void wellTerminated(TokenStream ts, int lastExprType) private void wellTerminated(TokenStream ts, int lastExprType) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
int tt = ts.peekTokenSameLine(); int tt = ts.peekTokenSameLine();
if (tt == TokenStream.ERROR) { if (tt == TokenStream.ERROR) {
return; return;
@@ -282,22 +283,21 @@ public class Parser extends Observable {
if (tt != TokenStream.EOF && tt != TokenStream.EOL && tt != TokenStream.SEMI && tt != TokenStream.RC) { if (tt != TokenStream.EOF && tt != TokenStream.EOL && tt != TokenStream.SEMI && tt != TokenStream.RC) {
int version = Context.getContext().getLanguageVersion(); int version = Context.getContext().getLanguageVersion();
if ((tt == TokenStream.FUNCTION || lastExprType == TokenStream.FUNCTION) if ((tt == TokenStream.FUNCTION || lastExprType == TokenStream.FUNCTION) && (version < Context.VERSION_1_2)) {
&& (version < Context.VERSION_1_2)) {
/* /*
* Checking against version < 1.2 and version >= 1.0 in the above line * Checking against version < 1.2 and version >= 1.0 in the above line
* breaks old javascript, so we keep it this way for now... XXX warning * breaks old javascript, so we keep it this way for now... XXX warning
* needed? * needed?
*/ */
} else { }
else {
reportError(ts, "msg.no.semi.stmt"); reportError(ts, "msg.no.semi.stmt");
} }
} }
} }
// match a NAME; return null if no match. // match a NAME; return null if no match.
private String matchLabel(TokenStream ts) throws IOException, private String matchLabel(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
int lineno = ts.getLineno(); int lineno = ts.getLineno();
String label = null; String label = null;
@@ -308,8 +308,9 @@ public class Parser extends Observable {
label = ts.getString(); label = ts.getString();
} }
if (lineno == ts.getLineno()) if (lineno == ts.getLineno()) {
wellTerminated(ts, TokenStream.ERROR); wellTerminated(ts, TokenStream.ERROR);
}
return label; return label;
} }
@@ -317,13 +318,15 @@ public class Parser extends Observable {
private Object statement(TokenStream ts) throws IOException { private Object statement(TokenStream ts) throws IOException {
try { try {
return statementHelper(ts); return statementHelper(ts);
} catch (JavaScriptException e) { }
catch (JavaScriptException e) {
// skip to end of statement // skip to end of statement
int lineno = ts.getLineno(); int lineno = ts.getLineno();
int t; int t;
do { do {
t = ts.getToken(); t = ts.getToken();
} while (t != TokenStream.SEMI && t != TokenStream.EOL }
while (t != TokenStream.SEMI && t != TokenStream.EOL
&& t != TokenStream.EOF && t != TokenStream.ERROR); && t != TokenStream.EOF && t != TokenStream.ERROR);
return nf.createExprStatement(nf.createName("error"), lineno); return nf.createExprStatement(nf.createName("error"), lineno);
} }
@@ -334,8 +337,7 @@ public class Parser extends Observable {
* implemented. * implemented.
*/ */
private Object statementHelper(TokenStream ts) throws IOException, private Object statementHelper(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
Object pn; Object pn;
int tt; int tt;
@@ -407,7 +409,6 @@ public class Parser extends Observable {
pn = nf.createWhile(cond, body, lineno); pn = nf.createWhile(cond, body, lineno);
break; break;
} }
case TokenStream.DO: { case TokenStream.DO: {
@@ -434,12 +435,14 @@ public class Parser extends Observable {
tt = ts.peekToken(); tt = ts.peekToken();
if (tt == TokenStream.SEMI) { if (tt == TokenStream.SEMI) {
init = nf.createLeaf(TokenStream.VOID); init = nf.createLeaf(TokenStream.VOID);
} else { }
else {
if (tt == TokenStream.VAR) { if (tt == TokenStream.VAR) {
// set init to a var list or initial // set init to a var list or initial
ts.getToken(); // throw away the 'var' token ts.getToken(); // throw away the 'var' token
init = variables(ts, true); init = variables(ts, true);
} else { }
else {
init = expr(ts, true); init = expr(ts, true);
} }
} }
@@ -449,19 +452,22 @@ public class Parser extends Observable {
ts.matchToken(TokenStream.RELOP); ts.matchToken(TokenStream.RELOP);
// 'cond' is the object over which we're iterating // 'cond' is the object over which we're iterating
cond = expr(ts, false); cond = expr(ts, false);
} else { // ordinary for loop }
else { // ordinary for loop
mustMatchToken(ts, TokenStream.SEMI, "msg.no.semi.for"); mustMatchToken(ts, TokenStream.SEMI, "msg.no.semi.for");
if (ts.peekToken() == TokenStream.SEMI) { if (ts.peekToken() == TokenStream.SEMI) {
// no loop condition // no loop condition
cond = nf.createLeaf(TokenStream.VOID); cond = nf.createLeaf(TokenStream.VOID);
} else { }
else {
cond = expr(ts, false); cond = expr(ts, false);
} }
mustMatchToken(ts, TokenStream.SEMI, "msg.no.semi.for.cond"); mustMatchToken(ts, TokenStream.SEMI, "msg.no.semi.for.cond");
if (ts.peekToken() == TokenStream.GWT) { if (ts.peekToken() == TokenStream.GWT) {
incr = nf.createLeaf(TokenStream.VOID); incr = nf.createLeaf(TokenStream.VOID);
} else { }
else {
incr = expr(ts, false); incr = expr(ts, false);
} }
} }
@@ -472,7 +478,8 @@ public class Parser extends Observable {
if (incr == null) { if (incr == null) {
// cond could be null if 'in obj' got eaten by the init node. // cond could be null if 'in obj' got eaten by the init node.
pn = nf.createForIn(init, cond, body, lineno); pn = nf.createForIn(init, cond, body, lineno);
} else { }
else {
pn = nf.createFor(init, cond, incr, body, lineno); pn = nf.createFor(init, cond, incr, body, lineno);
} }
break; break;
@@ -504,19 +511,20 @@ public class Parser extends Observable {
Object catchCond = null; Object catchCond = null;
if (ts.matchToken(TokenStream.IF)) { if (ts.matchToken(TokenStream.IF)) {
catchCond = expr(ts, false); catchCond = expr(ts, false);
} else { }
else {
sawDefaultCatch = true; sawDefaultCatch = true;
} }
mustMatchToken(ts, TokenStream.GWT, "msg.bad.catchcond"); mustMatchToken(ts, TokenStream.GWT, "msg.bad.catchcond");
mustMatchToken(ts, TokenStream.LC, "msg.no.brace.catchblock"); mustMatchToken(ts, TokenStream.LC, "msg.no.brace.catchblock");
nf.addChildToBack(catchblocks, nf.createCatch(varName, catchCond, nf.addChildToBack(catchblocks, nf.createCatch(varName, catchCond, statements(ts), ts.getLineno()));
statements(ts), ts.getLineno()));
mustMatchToken(ts, TokenStream.RC, "msg.no.brace.after.body"); mustMatchToken(ts, TokenStream.RC, "msg.no.brace.after.body");
} }
} else if (peek != TokenStream.FINALLY) { }
else if (peek != TokenStream.FINALLY) {
mustMatchToken(ts, TokenStream.FINALLY, "msg.try.no.catchfinally"); mustMatchToken(ts, TokenStream.FINALLY, "msg.try.no.catchfinally");
} }
@@ -524,16 +532,16 @@ public class Parser extends Observable {
finallyblock = statement(ts); finallyblock = statement(ts);
} }
pn = nf.createTryCatchFinally(tryblock, catchblocks, finallyblock, pn = nf.createTryCatchFinally(tryblock, catchblocks, finallyblock, lineno);
lineno);
break; break;
} }
case TokenStream.THROW: { case TokenStream.THROW: {
int lineno = ts.getLineno(); int lineno = ts.getLineno();
pn = nf.createThrow(expr(ts, false), lineno); pn = nf.createThrow(expr(ts, false), lineno);
if (lineno == ts.getLineno()) if (lineno == ts.getLineno()) {
wellTerminated(ts, TokenStream.ERROR); wellTerminated(ts, TokenStream.ERROR);
}
break; break;
} }
case TokenStream.BREAK: { case TokenStream.BREAK: {
@@ -575,8 +583,9 @@ public class Parser extends Observable {
case TokenStream.VAR: { case TokenStream.VAR: {
int lineno = ts.getLineno(); int lineno = ts.getLineno();
pn = variables(ts, false); pn = variables(ts, false);
if (ts.getLineno() == lineno) if (ts.getLineno() == lineno) {
wellTerminated(ts, TokenStream.ERROR); wellTerminated(ts, TokenStream.ERROR);
}
break; break;
} }
case TokenStream.RETURN: { case TokenStream.RETURN: {
@@ -595,10 +604,12 @@ public class Parser extends Observable {
if (tt != TokenStream.EOF && tt != TokenStream.EOL && tt != TokenStream.SEMI && tt != TokenStream.RC) { if (tt != TokenStream.EOF && tt != TokenStream.EOL && tt != TokenStream.SEMI && tt != TokenStream.RC) {
lineno = ts.getLineno(); lineno = ts.getLineno();
retExpr = expr(ts, false); retExpr = expr(ts, false);
if (ts.getLineno() == lineno) if (ts.getLineno() == lineno) {
wellTerminated(ts, TokenStream.ERROR); wellTerminated(ts, TokenStream.ERROR);
}
ts.flags |= TokenStream.TSF_RETURN_EXPR; ts.flags |= TokenStream.TSF_RETURN_EXPR;
} else { }
else {
ts.flags |= TokenStream.TSF_RETURN_VOID; ts.flags |= TokenStream.TSF_RETURN_VOID;
} }
@@ -631,8 +642,9 @@ public class Parser extends Observable {
* check that the last thing the tokenizer returned was a NAME and * check that the last thing the tokenizer returned was a NAME and
* that only one token was consumed. * that only one token was consumed.
*/ */
if (lastExprType != TokenStream.NAME || (ts.getTokenno() != tokenno)) if (lastExprType != TokenStream.NAME || (ts.getTokenno() != tokenno)) {
reportError(ts, "msg.bad.label"); reportError(ts, "msg.bad.label");
}
ts.getToken(); // eat the COLON ts.getToken(); // eat the COLON
@@ -670,8 +682,7 @@ public class Parser extends Observable {
* was on a new line, because speculative getToken calls advanced the * was on a new line, because speculative getToken calls advanced the
* line number even when they didn't succeed. * line number even when they didn't succeed.
*/ */
if (ts.getLineno() == lineno if (ts.getLineno() == lineno || (lastExprType == TokenStream.FUNCTION && ts.getLineno() == lastExprEndLine)) {
|| (lastExprType == TokenStream.FUNCTION && ts.getLineno() == lastExprEndLine)) {
wellTerminated(ts, lastExprType); wellTerminated(ts, lastExprType);
} }
break; break;
@@ -682,8 +693,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object variables(TokenStream ts, boolean inForInit) private Object variables(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object pn = nf.createVariables(ts.getLineno()); Object pn = nf.createVariables(ts.getLineno());
while (true) { while (true) {
@@ -711,8 +721,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object expr(TokenStream ts, boolean inForInit) throws IOException, private Object expr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = assignExpr(ts, inForInit); Object pn = assignExpr(ts, inForInit);
while (ts.matchToken(TokenStream.COMMA)) { while (ts.matchToken(TokenStream.COMMA)) {
pn = nf.createBinary(TokenStream.COMMA, pn, assignExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.COMMA, pn, assignExpr(ts, inForInit));
@@ -720,21 +729,18 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object assignExpr(TokenStream ts, boolean inForInit) private Object assignExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object pn = condExpr(ts, inForInit); Object pn = condExpr(ts, inForInit);
if (ts.matchToken(TokenStream.ASSIGN)) { if (ts.matchToken(TokenStream.ASSIGN)) {
// omitted: "invalid assignment left-hand side" check. // omitted: "invalid assignment left-hand side" check.
pn = nf pn = nf.createBinary(TokenStream.ASSIGN, ts.getOp(), pn, assignExpr(ts, inForInit));
.createBinary(TokenStream.ASSIGN, ts.getOp(), pn, assignExpr(ts, inForInit));
} }
return pn; return pn;
} }
private Object condExpr(TokenStream ts, boolean inForInit) private Object condExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object ifTrue; Object ifTrue;
Object ifFalse; Object ifFalse;
@@ -750,8 +756,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object orExpr(TokenStream ts, boolean inForInit) throws IOException, private Object orExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = andExpr(ts, inForInit); Object pn = andExpr(ts, inForInit);
if (ts.matchToken(TokenStream.OR)) { if (ts.matchToken(TokenStream.OR)) {
pn = nf.createBinary(TokenStream.OR, pn, orExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.OR, pn, orExpr(ts, inForInit));
@@ -760,8 +765,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object andExpr(TokenStream ts, boolean inForInit) throws IOException, private Object andExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = bitOrExpr(ts, inForInit); Object pn = bitOrExpr(ts, inForInit);
if (ts.matchToken(TokenStream.AND)) { if (ts.matchToken(TokenStream.AND)) {
pn = nf.createBinary(TokenStream.AND, pn, andExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.AND, pn, andExpr(ts, inForInit));
@@ -770,8 +774,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object bitOrExpr(TokenStream ts, boolean inForInit) private Object bitOrExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object pn = bitXorExpr(ts, inForInit); Object pn = bitXorExpr(ts, inForInit);
while (ts.matchToken(TokenStream.BITOR)) { while (ts.matchToken(TokenStream.BITOR)) {
pn = nf.createBinary(TokenStream.BITOR, pn, bitXorExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.BITOR, pn, bitXorExpr(ts, inForInit));
@@ -779,8 +782,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object bitXorExpr(TokenStream ts, boolean inForInit) private Object bitXorExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object pn = bitAndExpr(ts, inForInit); Object pn = bitAndExpr(ts, inForInit);
while (ts.matchToken(TokenStream.BITXOR)) { while (ts.matchToken(TokenStream.BITXOR)) {
pn = nf.createBinary(TokenStream.BITXOR, pn, bitAndExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.BITXOR, pn, bitAndExpr(ts, inForInit));
@@ -788,8 +790,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object bitAndExpr(TokenStream ts, boolean inForInit) private Object bitAndExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
Object pn = eqExpr(ts, inForInit); Object pn = eqExpr(ts, inForInit);
while (ts.matchToken(TokenStream.BITAND)) { while (ts.matchToken(TokenStream.BITAND)) {
pn = nf.createBinary(TokenStream.BITAND, pn, eqExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.BITAND, pn, eqExpr(ts, inForInit));
@@ -797,8 +798,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object eqExpr(TokenStream ts, boolean inForInit) throws IOException, private Object eqExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = relExpr(ts, inForInit); Object pn = relExpr(ts, inForInit);
while (ts.matchToken(TokenStream.EQOP)) { while (ts.matchToken(TokenStream.EQOP)) {
pn = nf.createBinary(TokenStream.EQOP, ts.getOp(), pn, relExpr(ts, inForInit)); pn = nf.createBinary(TokenStream.EQOP, ts.getOp(), pn, relExpr(ts, inForInit));
@@ -806,8 +806,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object relExpr(TokenStream ts, boolean inForInit) throws IOException, private Object relExpr(TokenStream ts, boolean inForInit) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = shiftExpr(ts); Object pn = shiftExpr(ts);
while (ts.matchToken(TokenStream.RELOP)) { while (ts.matchToken(TokenStream.RELOP)) {
int op = ts.getOp(); int op = ts.getOp();
@@ -821,8 +820,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object shiftExpr(TokenStream ts) throws IOException, private Object shiftExpr(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
Object pn = addExpr(ts); Object pn = addExpr(ts);
while (ts.matchToken(TokenStream.SHOP)) { while (ts.matchToken(TokenStream.SHOP)) {
pn = nf.createBinary(TokenStream.SHOP, ts.getOp(), pn, addExpr(ts)); pn = nf.createBinary(TokenStream.SHOP, ts.getOp(), pn, addExpr(ts));
@@ -830,8 +828,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object addExpr(TokenStream ts) throws IOException, private Object addExpr(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
int tt; int tt;
Object pn = mulExpr(ts); Object pn = mulExpr(ts);
@@ -844,8 +841,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object mulExpr(TokenStream ts) throws IOException, private Object mulExpr(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
int tt; int tt;
Object pn = unaryExpr(ts); Object pn = unaryExpr(ts);
@@ -858,8 +854,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
private Object unaryExpr(TokenStream ts) throws IOException, private Object unaryExpr(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
int tt; int tt;
ts.flags |= TokenStream.TSF_REGEXP; ts.flags |= TokenStream.TSF_REGEXP;
@@ -907,11 +902,9 @@ public class Parser extends Observable {
return pn; return pn;
} }
return nf.createName("err"); // Only reached on error. Try to continue. return nf.createName("err"); // Only reached on error. Try to continue.
} }
private Object argumentList(TokenStream ts, Object listNode) private Object argumentList(TokenStream ts, Object listNode) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
boolean matched; boolean matched;
ts.flags |= TokenStream.TSF_REGEXP; ts.flags |= TokenStream.TSF_REGEXP;
matched = ts.matchToken(TokenStream.GWT); matched = ts.matchToken(TokenStream.GWT);
@@ -919,15 +912,15 @@ public class Parser extends Observable {
if (!matched) { if (!matched) {
do { do {
nf.addChildToBack(listNode, assignExpr(ts, false)); nf.addChildToBack(listNode, assignExpr(ts, false));
} while (ts.matchToken(TokenStream.COMMA)); }
while (ts.matchToken(TokenStream.COMMA));
mustMatchToken(ts, TokenStream.GWT, "msg.no.paren.arg"); mustMatchToken(ts, TokenStream.GWT, "msg.no.paren.arg");
} }
return listNode; return listNode;
} }
private Object memberExpr(TokenStream ts, boolean allowCallSyntax) private Object memberExpr(TokenStream ts, boolean allowCallSyntax) throws IOException, JavaScriptException {
throws IOException, JavaScriptException {
int tt; int tt;
Object pn; Object pn;
@@ -964,15 +957,18 @@ public class Parser extends Observable {
if (tt == TokenStream.LC) { if (tt == TokenStream.LC) {
nf.addChildToBack(pn, primaryExpr(ts)); nf.addChildToBack(pn, primaryExpr(ts));
} }
} else { }
else {
pn = primaryExpr(ts); pn = primaryExpr(ts);
} }
return memberExprTail(ts, allowCallSyntax, pn); return memberExprTail(ts, allowCallSyntax, pn);
} }
private Object memberExprTail(TokenStream ts, boolean allowCallSyntax, private Object memberExprTail(
Object pn) throws IOException, JavaScriptException { TokenStream ts, boolean allowCallSyntax,
Object pn
) throws IOException, JavaScriptException {
lastExprEndLine = ts.getLineno(); lastExprEndLine = ts.getLineno();
int tt; int tt;
while ((tt = ts.getToken()) > TokenStream.EOF) { while ((tt = ts.getToken()) > TokenStream.EOF) {
@@ -987,19 +983,22 @@ public class Parser extends Observable {
* operator syntax he mentioned? * operator syntax he mentioned?
*/ */
lastExprEndLine = ts.getLineno(); lastExprEndLine = ts.getLineno();
} else if (tt == TokenStream.LB) { }
else if (tt == TokenStream.LB) {
pn = nf.createBinary(TokenStream.LB, pn, expr(ts, false)); pn = nf.createBinary(TokenStream.LB, pn, expr(ts, false));
mustMatchToken(ts, TokenStream.RB, "msg.no.bracket.index"); mustMatchToken(ts, TokenStream.RB, "msg.no.bracket.index");
lastExprEndLine = ts.getLineno(); lastExprEndLine = ts.getLineno();
} else if (allowCallSyntax && tt == TokenStream.LP) { }
else if (allowCallSyntax && tt == TokenStream.LP) {
/* make a call node */ /* make a call node */
pn = nf.createUnary(TokenStream.CALL, pn); pn = nf.createUnary(TokenStream.CALL, pn);
/* Add the arguments to pn, if any are supplied. */ /* Add the arguments to pn, if any are supplied. */
pn = argumentList(ts, pn); pn = argumentList(ts, pn);
lastExprEndLine = ts.getLineno(); lastExprEndLine = ts.getLineno();
} else { }
else {
ts.ungetToken(tt); ts.ungetToken(tt);
break; break;
@@ -1008,8 +1007,7 @@ public class Parser extends Observable {
return pn; return pn;
} }
public Object primaryExpr(TokenStream ts) throws IOException, public Object primaryExpr(TokenStream ts) throws IOException, JavaScriptException {
JavaScriptException {
int tt; int tt;
Object pn; Object pn;
@@ -1042,11 +1040,12 @@ public class Parser extends Observable {
if (tt == TokenStream.COMMA) { if (tt == TokenStream.COMMA) {
nf.addChildToBack(pn, nf.createLeaf(TokenStream.PRIMARY, TokenStream.UNDEFINED)); nf.addChildToBack(pn, nf.createLeaf(TokenStream.PRIMARY, TokenStream.UNDEFINED));
} else { }
else {
nf.addChildToBack(pn, assignExpr(ts, false)); nf.addChildToBack(pn, assignExpr(ts, false));
} }
}
} while (ts.matchToken(TokenStream.COMMA)); while (ts.matchToken(TokenStream.COMMA));
mustMatchToken(ts, TokenStream.RB, "msg.no.bracket.arg"); mustMatchToken(ts, TokenStream.RB, "msg.no.bracket.arg");
} }
@@ -1058,7 +1057,8 @@ public class Parser extends Observable {
if (!ts.matchToken(TokenStream.RC)) { if (!ts.matchToken(TokenStream.RC)) {
commaloop : do { commaloop:
do {
Object property; Object property;
tt = ts.getToken(); tt = ts.getToken();
@@ -1090,8 +1090,8 @@ public class Parser extends Observable {
// decompilation to solve spacing ambiguity. // decompilation to solve spacing ambiguity.
nf.addChildToBack(pn, property); nf.addChildToBack(pn, property);
nf.addChildToBack(pn, assignExpr(ts, false)); nf.addChildToBack(pn, assignExpr(ts, false));
}
} while (ts.matchToken(TokenStream.COMMA)); while (ts.matchToken(TokenStream.COMMA));
mustMatchToken(ts, TokenStream.RC, "msg.no.brace.prop"); mustMatchToken(ts, TokenStream.RC, "msg.no.brace.prop");
} }
@@ -1143,7 +1143,6 @@ public class Parser extends Observable {
default: default:
reportError(ts, "msg.syntax"); reportError(ts, "msg.syntax");
break; break;
} }
return null; // should never reach here return null; // should never reach here
} }