📄 quercusparser.java
字号:
break; case FOREACH: statementList.add(parseForeach()); break; case PHP_END: return statementList; case RETURN: statementList.add(parseReturn()); break; case THROW: statementList.add(parseThrow()); break; case BREAK: statementList.add(parseBreak()); break; case CONTINUE: statementList.add(parseContinue()); break; case GLOBAL: statementList.add(parseGlobal()); break; case STATIC: statementList.add(parseStatic()); break; case TRY: statementList.add(parseTry()); break; case '{': { ArrayList<Statement> enclosedStatementList = parseStatementList(); expect('}'); statementList.addAll(enclosedStatementList); } break; case '}': case CASE: case DEFAULT: case ELSE: case ELSEIF: case ENDIF: case ENDWHILE: case ENDFOR: case ENDFOREACH: case ENDSWITCH: _peekToken = token; return statementList; case TEXT: if (_lexeme.length() > 0) { statementList.add(_factory.createText(location, _lexeme)); } break; case TEXT_PHP: if (_lexeme.length() > 0) { statementList.add(_factory.createText(location, _lexeme)); } _peekToken = parseToken(); if (_peekToken == IDENTIFIER && _lexeme.equalsIgnoreCase("php")) { _peekToken = -1; } break; case TEXT_ECHO: if (_lexeme.length() > 0) statementList.add(_factory.createText(location, _lexeme)); parseEcho(statementList); break; default: _peekToken = token; statementList.add(parseExprStatement()); break; } } } private Statement parseStatement() throws IOException { Location location = getLocation(); int token = parseToken(); switch (token) { case ';': return _factory.createNullStatement(); case '{': location = getLocation(); ArrayList<Statement> statementList = parseStatementList(); expect('}'); return _factory.createBlock(location, statementList); case IF: return parseIf(); case SWITCH: return parseSwitch(); case WHILE: return parseWhile(); case DO: return parseDo(); case FOR: return parseFor(); case FOREACH: return parseForeach(); case TRY: return parseTry(); case TEXT: if (_lexeme.length() > 0) { return _factory.createText(location, _lexeme); } else return parseStatement(); case TEXT_PHP: { Statement stmt = null; if (_lexeme.length() > 0) { stmt = _factory.createText(location, _lexeme); } _peekToken = parseToken(); if (_peekToken == IDENTIFIER && _lexeme.equalsIgnoreCase("php")) { _peekToken = -1; } if (stmt == null) stmt = parseStatement(); return stmt; } default: Statement stmt = parseStatementImpl(token); token = parseToken(); if (token != ';') _peekToken = token; return stmt; } } /** * Parses statements that expect to be terminated by ';'. */ private Statement parseStatementImpl(int token) throws IOException { switch (token) { case ECHO: { Location location = getLocation(); ArrayList<Statement> statementList = new ArrayList<Statement>(); parseEcho(statementList); return _factory.createBlock(location, statementList); } case PRINT: return parsePrint(); case UNSET: return parseUnset(); case GLOBAL: return parseGlobal(); case STATIC: return parseStatic(); case BREAK: return parseBreak(); case CONTINUE: return parseContinue(); case RETURN: return parseReturn(); case THROW: return parseThrow(); case TRY: return parseTry(); default: _peekToken = token; return parseExprStatement(); /* default: throw error(L.l("unexpected token {0}.", tokenName(token))); */ } } /** * Parses the echo statement. */ private void parseEcho(ArrayList<Statement> statements) throws IOException { Location location = getLocation(); while (true) { Expr expr = parseTopExpr(); createEchoStatements(location, statements, expr); int token = parseToken(); if (token != ',') { _peekToken = token; return; } } } /** * Creates echo statements from an expression. */ private void createEchoStatements(Location location, ArrayList<Statement> statements, Expr expr) { if (expr == null) { // since AppendExpr.getNext() can be null. } else if (expr instanceof AppendExpr) { AppendExpr append = (AppendExpr) expr; // XXX: children of append print differently? createEchoStatements(location, statements, append.getValue()); createEchoStatements(location, statements, append.getNext()); } else if (expr instanceof StringLiteralExpr) { StringLiteralExpr string = (StringLiteralExpr) expr; Statement statement = _factory.createText(location, string.evalConstant().toString()); statements.add(statement); } else { Statement statement = _factory.createEcho(location, expr); statements.add(statement); } } /** * Parses the print statement. */ private Statement parsePrint() throws IOException { return _factory.createExpr(getLocation(), parsePrintExpr()); } /** * Parses the print statement. */ private Expr parsePrintExpr() throws IOException { ArrayList<Expr> args = new ArrayList<Expr>(); args.add(parseTopExpr()); return _factory.createFunction(getLocation(), "print", args); } /** * Parses the global statement. */ private Statement parseGlobal() throws IOException { ArrayList<Statement> statementList = new ArrayList<Statement>(); Location location = getLocation(); while (true) { Expr expr = parseTopExpr(); if (expr instanceof VarExpr) { VarExpr var = (VarExpr) expr; // php/3a6g, php/3a58 var.getVarInfo().setGlobal(); statementList.add(_factory.createGlobal(location, var)); } else if (expr instanceof VarVarExpr) { VarVarExpr var = (VarVarExpr) expr; statementList.add(_factory.createVarGlobal(location, var)); } else throw error(L.l("unknown expr {0} to global", expr)); // statementList.add(new ExprStatement(expr)); int token = parseToken(); if (token != ',') { _peekToken = token; return _factory.createBlock(location, statementList); } } } /** * Parses the static statement. */ private Statement parseStatic() throws IOException { ArrayList<Statement> statementList = new ArrayList<Statement>(); Location location = getLocation(); while (true) { expect('$'); String name = parseIdentifier(); VarExpr var = _factory.createVar(_function.createVar(name)); Expr init = null; int token = parseToken(); if (token == '=') { init = parseExpr(); token = parseToken(); } // var.getVarInfo().setReference(); statementList.add(_factory.createStatic(location, var, init)); if (token != ',') { _peekToken = token; return _factory.createBlock(location, statementList); } } } /** * Parses the unset statement. */ private Statement parseUnset() throws IOException { Location location = getLocation(); ArrayList<Statement> statementList = new ArrayList<Statement>(); parseUnset(statementList); return _factory.createBlock(location, statementList); } /** * Parses the unset statement. */ private void parseUnset(ArrayList<Statement> statementList) throws IOException { Location location = getLocation(); int token = parseToken(); if (token != '(') { _peekToken = token; statementList.add(parseTopExpr().createUnset(_factory, location)); return; } do { // XXX: statementList.add(parseTopExpr().createUnset(_factory, getLocation())); Expr topExpr = parseTopExpr(); statementList.add(topExpr.createUnset(_factory, getLocation())); } while ((token = parseToken()) == ','); _peekToken = token; expect(')'); } /** * Parses the if statement */ private Statement parseIf() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); expect('('); _isIfTest = true; Expr test = parseExpr(); _isIfTest = false; expect(')'); int token = parseToken(); if (token == ':') return parseAlternateIf(test, location); else _peekToken = token; Statement trueBlock = parseStatement(); Statement falseBlock = null; token = parseToken(); if (token == ELSEIF) { falseBlock = parseIf(); } else if (token == ELSE) { falseBlock = parseStatement(); } else _peekToken = token; return _factory.createIf(location, test, trueBlock, falseBlock); } finally { _isTop = oldTop; } } /** * Parses the if statement */ private Statement parseAlternateIf(Expr test, Location location) throws IOException { Statement trueBlock = _factory.createBlock(location, parseStatementList()); Statement falseBlock = null; int token = parseToken(); if (token == ELSEIF) { Location subLocation = getLocation(); Expr subTest = parseExpr(); expect(':'); falseBlock = parseAlternateIf(subTest, subLocation); } else if (token == ELSE) { expect(':'); falseBlock = _factory.createBlock(getLocation(), parseStatementList()); expect(ENDIF); } else { _peekToken = token; expect(ENDIF); } return _factory.createIf(location, test, trueBlock, falseBlock); } /** * Parses the switch statement */ private Statement parseSwitch() throws IOException { Location location = getLocation(); boolean oldTop = _isTop; _isTop = false; try { expect('('); Expr test = parseExpr(); expect(')'); boolean isAlternate = false; int token = parseToken(); if (token == ':') isAlternate = true; else if (token == '{') isAlternate = false; else { _peekToken = token; expect('{'); } ArrayList<Expr[]> caseList = new ArrayList<Expr[]>(); ArrayList<BlockStatement> blockList = new ArrayList<BlockStatement>(); ArrayList<Integer> fallThroughList = new ArrayList<Integer>(); BlockStatement defaultBlock = null; while ((token = parseToken()) == CASE || token == DEFAULT) { Location caseLocation = getLocation(); ArrayList<Expr> valueList = new ArrayList<Expr>(); boolean isDefault = false; while (token == CASE || token == DEFAULT) { if (token == CASE) { Expr value = parseExpr(); valueList.add(value); } else isDefault = true; token = parseToken(); if (token == ':') { } else if (token == ';') { // XXX: warning? } else throw error("expected ':' at " + tokenName(token)); token = parseToken(); } _peekToken = token; Expr []values = new Expr[valueList.size()]; valueList.toArray(values); ArrayList<Statement> newBlockList = parseStatementList(); for (int fallThrough : fallThroughList) { BlockStatement block = blockList.get(fallThrough); boolean isDefaultBlock = block == defaultBlock; block = block.append(newBlockList); blockList.set(fallThrough, block); if (isDefaultBlock) defaultBlock = block; } BlockStatement block = _factory.createBlockImpl(caseLocation, newBlockList); if (values.length > 0) { caseList.add(values); blockList.add(block); } if (isDefault) defaultBlock = block; if (blockList.size() > 0 && ! fallThroughList.contains(blockList.size() - 1)) { fallThroughList.add(blockList.size() - 1); } if (block.fallThrough() != Statement.FALL_THROUGH) fallThroughList.clear(); } _peekToken = token; if (isAlternate) expect(ENDSWITCH);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -