📄 quercusparser.java
字号:
else expect('}'); return _factory.createSwitch(location, test, caseList, blockList, defaultBlock); } finally { _isTop = oldTop; } } /** * Parses the 'while' statement */ private Statement parseWhile() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); expect('('); _isIfTest = true; Expr test = parseExpr(); _isIfTest = false; expect(')'); Statement block; int token = parseToken(); if (token == ':') { block = _factory.createBlock(getLocation(), parseStatementList()); expect(ENDWHILE); } else { _peekToken = token; block = parseStatement(); } return _factory.createWhile(location, test, block); } finally { _isTop = oldTop; } } /** * Parses the 'do' statement */ private Statement parseDo() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); Statement block = parseStatement(); expect(WHILE); expect('('); _isIfTest = true; Expr test = parseExpr(); _isIfTest = false; expect(')'); return _factory.createDo(location, test, block); } finally { _isTop = oldTop; } } /** * Parses the 'for' statement */ private Statement parseFor() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); expect('('); Expr init = null; int token = parseToken(); if (token != ';') { _peekToken = token; init = parseTopCommaExpr(); expect(';'); } Expr test = null; token = parseToken(); if (token != ';') { _peekToken = token; _isIfTest = true; test = parseTopCommaExpr(); _isIfTest = false; expect(';'); } Expr incr = null; token = parseToken(); if (token != ')') { _peekToken = token; incr = parseTopCommaExpr(); expect(')'); } Statement block; token = parseToken(); if (token == ':') { block = _factory.createBlock(getLocation(), parseStatementList()); expect(ENDFOR); } else { _peekToken = token; block = parseStatement(); } return _factory.createFor(location, init, test, incr, block); } finally { _isTop = oldTop; } } /** * Parses the 'foreach' statement */ private Statement parseForeach() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); expect('('); Expr objExpr = parseTopExpr(); expect(AS); boolean isRef = false; int token = parseToken(); if (token == '&') isRef = true; else _peekToken = token; AbstractVarExpr valueExpr = (AbstractVarExpr) parseLeftHandSide(); AbstractVarExpr keyVar = null; AbstractVarExpr valueVar; token = parseToken(); if (token == ARRAY_RIGHT) { if (isRef) throw error(L.l("key reference is forbidden in foreach")); keyVar = valueExpr; token = parseToken(); if (token == '&') isRef = true; else _peekToken = token; valueVar = (AbstractVarExpr) parseLeftHandSide(); token = parseToken(); } else valueVar = valueExpr; if (token != ')') throw error(L.l("expected ')' in foreach")); Statement block; token = parseToken(); if (token == ':') { block = _factory.createBlock(getLocation(), parseStatementList()); expect(ENDFOREACH); } else { _peekToken = token; block = parseStatement(); } return _factory.createForeach(location, objExpr, keyVar, valueVar, isRef, block); } finally { _isTop = oldTop; } } /** * Parses the try statement */ private Statement parseTry() throws IOException { boolean oldTop = _isTop; _isTop = false; try { Location location = getLocation(); Statement block = parseStatement(); TryStatement stmt = _factory.createTry(location, block); int token = parseToken(); while (token == CATCH) { expect('('); String id = parseIdentifier(); AbstractVarExpr lhs = parseLeftHandSide(); expect(')'); block = parseStatement(); stmt.addCatch(id, lhs, block); token = parseToken(); } _peekToken = token; return stmt; } finally { _isTop = oldTop; } } /** * Parses a function definition */ private Function parseFunctionDefinition(int modifiers) throws IOException { boolean oldTop = _isTop; _isTop = false; boolean oldReturnsReference = _returnsReference; FunctionInfo oldFunction = _function; boolean isAbstract = (modifiers & M_ABSTRACT) != 0; if (_classDef != null && _classDef.isInterface()) isAbstract = true; try { _returnsReference = false; int token = parseToken(); if (token == '&') _returnsReference = true; else _peekToken = token; String name = parseIdentifier(); if (isAbstract && ! _scope.isAbstract()) { if (_classDef != null) throw error(L.l("'{0}' may not be abstract because class {1} is not abstract.", name, _classDef.getName())); else throw error(L.l("'{0}' may not be abstract. Abstract functions are only allowed in abstract classes.", name)); } _function = getFactory().createFunctionInfo(_quercus, name); _function.setDeclaringClass(_classDef); _function.setPageStatic(oldTop); _function.setReturnsReference(_returnsReference); Location location = getLocation(); expect('('); Arg []args = parseFunctionArgDefinition(); expect(')'); if (_classDef != null && "__call".equals(name) && args.length != 2) { throw error(L.l("{0}::{1} must have exactly two arguments defined", _classDef.getName(), name)); } Function function; if (isAbstract) { expect(';'); function = _factory.createMethodDeclaration(location, _classDef, name, _function, args); } else { expect('{'); Statement []statements = parseStatements(); expect('}'); if (_classDef != null) function = _factory.createObjectMethod(location, _classDef, name, _function, args, statements); else function = _factory.createFunction(location, name, _function, args, statements); } function.setGlobal(oldTop); function.setStatic((modifiers & M_STATIC) != 0); function.setFinal((modifiers & M_FINAL) != 0); if ((modifiers & M_PROTECTED) != 0) function.setVisibility(Visibility.PROTECTED); else if ((modifiers & M_PRIVATE) != 0) function.setVisibility(Visibility.PRIVATE); _scope.addFunction(name, function); /* com.caucho.vfs.WriteStream out = com.caucho.vfs.Vfs.lookup("stdout:").openWrite(); out.setFlushOnNewline(true); function.debug(new JavaWriter(out)); */ return function; } finally { _returnsReference = oldReturnsReference; _function = oldFunction; _isTop = oldTop; } } private Arg []parseFunctionArgDefinition() throws IOException { LinkedHashMap<String, Arg> argMap = new LinkedHashMap<String, Arg>(); while (true) { int token = parseToken(); boolean isReference = false; // php/076b, php/1c02 // XXX: save arg type for type checking upon function call String expectedClass = null; if (token != ')' && token != '&' && token != '$' && token != -1) { _peekToken = token; expectedClass = parseIdentifier(); token = parseToken(); } if (token == '&') { isReference = true; token = parseToken(); } if (token != '$') { _peekToken = token; break; } String argName = parseIdentifier(); Expr defaultExpr = _factory.createRequired(); token = parseToken(); if (token == '=') { // XXX: actually needs to be primitive defaultExpr = parseTerm(); token = parseToken(); } Arg arg = new Arg(argName, defaultExpr, isReference); if (argMap.get(argName) != null && _quercus.isStrict()) { throw error(L.l("aliasing of function argument '{0}'", argName)); } argMap.put(argName, arg); VarInfo var = _function.createVar(argName); if (token != ',') { _peekToken = token; break; } } Arg [] args = new Arg[argMap.size()]; argMap.values().toArray(args); return args; } /** * Parses the 'return' statement */ private Statement parseBreak() throws IOException { Location location = getLocation(); int token = parseToken(); switch (token) { case ';': _peekToken = token; return _factory.createBreak(location, null); default: _peekToken = token; Expr expr = parseTopExpr(); return _factory.createBreak(location, expr); } } /** * Parses the 'return' statement */ private Statement parseContinue() throws IOException { Location location = getLocation(); int token = parseToken(); switch (token) { case ';': _peekToken = token; return _factory.createContinue(location, null); default: _peekToken = token; Expr expr = parseTopExpr(); return _factory.createContinue(location, expr); } } /** * Parses the 'return' statement */ private Statement parseReturn() throws IOException { Location location = getLocation(); int token = parseToken(); switch (token) { case ';': _peekToken = token; return _factory.createReturn(location, _factory.createNull()); default: _peekToken = token; Expr expr = parseTopExpr(); /* if (_returnsReference) expr = expr.createRef(); else expr = expr.createCopy(); */ if (_returnsReference) return _factory.createReturnRef(location, expr); else return _factory.createReturn(location, expr); } } /** * Parses the 'throw' statement */ private Statement parseThrow() throws IOException { Location location = getLocation(); Expr expr = parseExpr(); return _factory.createThrow(location, expr); } /** * Parses a class definition */ private Statement parseClassDefinition(int modifiers) throws IOException { String name = parseIdentifier(); String parentName = null; ArrayList<String> ifaceList = new ArrayList<String>(); int token = parseToken(); if (token == EXTENDS) { if ((modifiers & M_INTERFACE)!= 0) { do { ifaceList.add(parseIdentifier()); token = parseToken(); } while (token == ','); } else { parentName = parseIdentifier(); token = parseToken(); } } if ((modifiers & M_INTERFACE) == 0 && token == IMPLEMENTS) { do { ifaceList.add(parseIdentifier()); token = parseToken(); } while (token == ','); } _peekToken = token; InterpretedClassDef oldClass = _classDef; Scope oldScope = _scope; try { _classDef = oldScope.addClass(getLocation(), name, parentName, ifaceList); if ((modifiers & M_ABSTRACT) != 0) _classDef.setAbstract(true); if ((modifiers & M_INTERFACE) != 0) _classDef.setInterface(true); if ((modifiers & M_FINAL) != 0) _classDef.setFinal(true); _scope = new ClassScope(_classDef); expect('{'); parseClassContents(); expect('}'); return _factory.createClassDef(getLocation(), _classDef); } finally { _classDef = oldClass; _scope = oldScope; } } /** * Parses a statement list. */ private void parseClassContents() throws IOException { while (true) { int token = parseToken(); switch (token) { case ';': break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -