📄 quercusparser.java
字号:
{ Expr expr = parseTerm(); while (true) { int token = parseToken(); switch (token) { case '=': token = parseToken(); try { if (token == '&') { // php/03d6 expr = expr.createAssignRef(this, parseBitOrExpr()); } else { _peekToken = token; if (_isIfTest && _quercus.isStrict()) { throw error("assignment without parentheses inside If/While/For test statement; please make sure whether equality was intended instead"); } expr = expr.createAssign(this, parseConditionalExpr()); } } catch (QuercusParseException e) { throw e; } catch (IOException e) { throw error(e.getMessage()); } break; case PLUS_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createAdd(expr, parseConditionalExpr())); else // php/03d4 expr = expr.createAssign(this, parseConditionalExpr()); break; case MINUS_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createSub(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case APPEND_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createAppend(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case MUL_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createMul(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case DIV_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createDiv(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case MOD_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createMod(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case LSHIFT_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createLeftShift(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case RSHIFT_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createRightShift(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case AND_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createBitAnd(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case OR_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createBitOr(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; case XOR_ASSIGN: if (expr.canRead()) expr = expr.createAssign(this, _factory.createBitXor(expr, parseConditionalExpr())); else expr = expr.createAssign(this, parseConditionalExpr()); break; default: _peekToken = token; return expr; } } } /** * Parses a basic term. * * <pre> * term ::= termBase * ::= term '[' index ']' * ::= term '{' index '}' * ::= term '(' index ')' * </pre> */ private Expr parseTerm() throws IOException { Expr term = parseTermBase(); while (true) { int token = parseToken(); switch (token) { case '[': { token = parseToken(); if (token == ']') { term = _factory.createArrayTail(getLocation(), term); } else { _peekToken = token; Expr index = parseExpr(); token = parseToken(); term = _factory.createArrayGet(getLocation(), term, index); } if (token != ']') throw expect("']'", token); } break; case '{': { Expr index = parseExpr(); expect('}'); term = _factory.createCharAt(term, index); } break; case INCR: term = _factory.createPostIncrement(term, 1); break; case DECR: term = _factory.createPostIncrement(term, -1); break; case DEREF: term = parseDeref(term); break; case '(': _peek = token; term = parseFunction(term); break; default: _peekToken = token; return term; } } } /** * Parses a basic term. * * <pre> * term ::= termBase * ::= term '[' index ']' * ::= term '{' index '}' * ::= term '->' field; * </pre> * * No function, though. */ private Expr parseTermDeref() throws IOException { Expr term = parseTermBase(); while (true) { int token = parseToken(); switch (token) { case '[': { token = parseToken(); if (token == ']') { term = _factory.createArrayTail(getLocation(), term); } else { _peekToken = token; Expr index = parseExpr(); token = parseToken(); term = _factory.createArrayGet(getLocation(), term, index); } if (token != ']') throw expect("']'", token); } break; case '{': { Expr index = parseExpr(); expect('}'); term = _factory.createCharAt(term, index); } break; case INCR: term = _factory.createPostIncrement(term, 1); break; case DECR: term = _factory.createPostIncrement(term, -1); break; case DEREF: term = parseDeref(term); break; default: _peekToken = token; return term; } } } /** * Parses a deref * * <pre> * deref ::= term -> IDENTIFIER * ::= term -> IDENTIFIER '(' args ')' * </pre> */ private Expr parseDeref(Expr term) throws IOException { String name = null; Expr nameExpr = null; int token = parseToken(); if (token == '$') { _peekToken = token; nameExpr = parseTermBase(); // php/09e0 token = parseToken(); switch (token) { case '[': Expr index = parseExpr(); token = parseToken(); if (token != ']') throw expect("']'", token); nameExpr = _factory.createArrayGet(getLocation(), nameExpr, index); break; default: _peekToken = token; break; } } else if (token == '{') { nameExpr = parseExpr(); expect('}'); } else { _peekToken = token; name = parseIdentifier(); } token = parseToken(); if (token == '(') { if (_isNewExpr) { //php/09fj _peekToken = token; return term.createFieldGet(_factory, getLocation(), createStringValue(name)); } ArrayList<Expr> args = new ArrayList<Expr>(); parseFunctionArgs(args); if (nameExpr != null) return _factory.createVarMethodCall(getLocation(), term, nameExpr, args); else return _factory.createMethodCall(getLocation(), term, name, args); } else if (nameExpr != null) { _peekToken = token; return term.createFieldGet(_factory, getLocation(), nameExpr); } else { _peekToken = token; return term.createFieldGet(_factory, getLocation(), createStringValue(name)); } } /** * Parses a basic term. * * <pre> * term ::= STRING * ::= LONG * ::= DOUBLE * </pre> */ private Expr parseTermBase() throws IOException { int token = parseToken(); switch (token) { case STRING: return createString(_lexeme); case SYSTEM_STRING: { ArrayList<Expr> args = new ArrayList<Expr>(); args.add(createString(_lexeme)); return _factory.createFunction(getLocation(), "shell_exec", args); } case SIMPLE_SYSTEM_STRING: { ArrayList<Expr> args = new ArrayList<Expr>(); args.add(parseEscapedString(_lexeme, SIMPLE_STRING_ESCAPE, true)); return _factory.createFunction(getLocation(), "shell_exec", args); } case COMPLEX_SYSTEM_STRING: { ArrayList<Expr> args = new ArrayList<Expr>(); args.add(parseEscapedString(_lexeme, COMPLEX_STRING_ESCAPE, true)); return _factory.createFunction(getLocation(), "shell_exec", args); } case SIMPLE_STRING_ESCAPE: case COMPLEX_STRING_ESCAPE: return parseEscapedString(_lexeme, token, false); case BINARY: return createBinary(_lexeme.getBytes()); case SIMPLE_BINARY_ESCAPE: case COMPLEX_BINARY_ESCAPE: return parseEscapedString(_lexeme, token, false, false); case LONG: return _factory.createLiteral(LongValue.create(Long.parseLong(_lexeme))); case DOUBLE: return _factory.createLiteral(new DoubleValue(Double.parseDouble(_lexeme))); case NULL: return _factory.createNull(); case TRUE: return _factory.createLiteral(BooleanValue.TRUE); case FALSE: return _factory.createLiteral(BooleanValue.FALSE); case '$': return parseVariable(); /* quercus/0211 case '&': { Expr expr = parseTerm(); return expr.createRef(); } */ case '-': { Expr expr = parseTerm(); token = parseToken(); if (token == '=') { token = parseToken(); if (token == '&') { return _factory.createMinus(expr.createAssignRef(this, parseBitOrExpr())); } else { _peekToken = token; return _factory.createMinus(expr.createAssign(this, parseConditionalExpr())); } } else { _peekToken = token; return _factory.createMinus(expr); } } case '+': { Expr expr = parseTerm(); token = parseToken(); if (token == '=') { token = parseToken(); if (token == '&') { return _factory.createPlus(expr.createAssignRef(this, parseBitOrExpr())); } else { _peekToken = token; return _factory.createPlus(expr.createAssign(this, parseConditionalExpr())); } } else { _peekToken = token; return _factory.createPlus(expr); } } case '!': { // XXX: quercus/03i3 vs quercus/03i4 Expr expr = parseTerm(); token = parseToken(); if (token == '=') { token = parseToken(); // php/03i6 if (token == '&') { return _factory.createNot(expr.createAssignRef(this, parseBitOrExpr())); } else { _peekToken = token; return _factory.createNot(expr.createAssign(this, parseConditionalExpr())); } } else if (token == INSTANCEOF) { // php/03p1 return _factory.createNot(_factory.createInstanceOf(expr, parseIdentifier())); } else { _peekToken = token; return _factory.createNot(expr); } } case '~': { Expr expr = parseTerm(); return _factory.createBitNot(expr); } case '@': { Expr expr = parseTerm(); return _factory.createSuppress(expr); } case CLONE: { Expr expr = parseTerm(); return _factory.createClone(expr); } case INCR: { Expr expr = parseTerm(); return _factory.createPreIncrement(expr, 1); } case DECR: { Expr expr = parseTerm(); return _factory.createPreIncrement(expr, -1); } case NEW: return parseNew(); case INCLUDE: return _factory.createInclude(getLocation(), _sourceFile, parseExpr()); case REQUIRE: return _factory.createRequire(getLocation(), _sourceFile, parseExpr()); case INCLUDE_ONCE: return _factory.createIncludeOnce(getLocation(), _sourceFile, parseExpr()); case REQUIRE_ONCE: return _factory.createRequireOnce(getLocation(), _sourceFile, parseExpr()); case LIST: return parseList(); case PRINT: return parsePrintExpr(); case EXIT: return parseExit(); case DIE: return parseDie(); case IDENTIFIER: { if (_lexeme.equals("new")) return parseNew(); String className = null; String name = _lexeme; token = parseToken(); _peekToken = token; boolean isInstantiated = false; boolean isLateStaticBinding = false; if (token == SCOPE) { _peekToken = -1; className = name; if (className.equals("self")) { isInstantiated = true; className = _classDef.getName(); if (className == null) throw error(L.l("cannot access self when not in object scope")); } else if (className.equals("parent")) { isInstantiated = true; className = _classDef.getParentName(); if (className == null) throw error(L.l("object does not have a parent class")); } else if (className.e
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -