2362N/A * Copyright (c) 1994, 2004, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * This class is used to parse Java statements and expressions. 0N/A * The result is a parse tree.<p> 0N/A * This class implements an operator precedence parser. Errors are 0N/A * reported to the Environment object, if the error can't be 0N/A * resolved immediately, a SyntaxError exception is thrown.<p> 0N/A * Error recovery is implemented by catching SyntaxError exceptions 0N/A * and discarding input tokens until an input token is reached that 0N/A * is possibly a legal continuation.<p> 0N/A * The parse tree that is constructed represents the input 0N/A * exactly (no rewrites to simpler forms). This is important 0N/A * if the resulting tree is to be used for code formatting in 0N/A * a programming environment. Currently only documentation comments 0N/A * The parsing algorithm does NOT use any type information. Changes 0N/A * in the type system do not affect the structure of the parse tree. 0N/A * This restriction does introduce an ambiguity an expression of the 0N/A * form: (e1) e2 is assumed to be a cast if e2 does not start with 0N/A * an operator. That means that (a) - b is interpreted as subtract 0N/A * b from a and not cast negative b to type a. However, if a is a 0N/A * simple type (byte, int, ...) then it is assumed to be a cast.<p> 0N/A * WARNING: The contents of this source file are not part of any 0N/A * supported API. Code that depends on them does so at its own risk: 0N/A * they are subject to change or removal without notice. 0N/A * @author Arthur van Hoff 0N/A * Create a parser, given a scanner. 0N/A * Create a parser, given a scanner and the semantic callback. 0N/A * Usually <code>this.actions == (ParserActions)this</code>. 0N/A * However, a delegate scanner can produce tokens for this parser, 0N/A * in which case <code>(Scanner)this</code> is unused, 0N/A * except for <code>this.token</code> and <code>this.pos</code> 0N/A * instance variables which are filled from the real scanner 0N/A * by <code>this.scan()</code> and the constructor. 0N/A // Note: The duplication of methods allows pre-1.1 classes to 0N/A // be binary compatible with the new version of the parser, 0N/A // which now passes IdentifierTokens to the semantics phase, 0N/A // rather than just Identifiers. This change is necessary, 0N/A // since the parser is no longer responsible for managing the 0N/A // resolution of type names. (That caused the "Vector" bug.) 0N/A // In a future release, the old "plain-Identifier" methods will 0N/A // go away, and the corresponding "IdentifierToken" methods 0N/A // may become abstract. 0N/A * package declaration 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the packageDeclaration methods. 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the packageDeclaration methods. 0N/A * @deprecated Use the version with the IdentifierToken arguments. 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the importPackage methods. 0N/A * @deprecated Use the version with the IdentifierToken arguments. 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the beginClass methods. 0N/A * @deprecated Use the version with the IdentifierToken arguments. 0N/A * Report the current class under construction. 0N/A * By default, it's a no-op which returns null. 0N/A * It may only be called before the corresponding endClass(). 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the beginClass methods. 0N/A * @deprecated Use the version with the IdentifierToken arguments. 0N/A // By default, call the deprecated version. 0N/A // Any application must override one of the defineField methods. 0N/A * @deprecated Use the version with the IdentifierToken arguments. 0N/A * A growable array of nodes. It is used as a growable 0N/A * buffer to hold argument lists and expression lists. 0N/A * I'm not using Vector to make it more efficient. 0N/A * Expect a token, return its value, scan the next token or 0N/A * throw an exception. 0N/A * Parse a type expression. Does not parse the []'s. 0N/A * Parse a method invocation. Should be called when the current 0N/A * then is the '(' of the argument list. 0N/A * Parse a new instance expression. Should be called when the current 0N/A * token is the '(' of the argument list. 0N/A // x = new Type(arg) { subclass body ... } 0N/A * Parse a primary expression. 0N/A // bracketed-expr: (expr) 0N/A // cast-expr: (simple-type) expr 0N/A // We handle INC and DEC specially. 0N/A // See the discussion in JLS section 15.14.1. 0N/A // (Part of fix for 4044502.) 0N/A // We know this must be a postfix increment. 0N/A // We know this must be a postfix decrement. 0N/A // cast-expr: (expr) expr 0N/A // array initializer: {expr1, expr2, ... exprn} 0N/A // System.err.println("NEAR: " + opNames[token]); 0N/A * Parse an expression. 0N/A // this return is bogus 0N/A * Given a left-hand term, parse an operator and right-hand term. 0N/A // index: expr1[expr2] 0N/A // class C { class N { ... C.this ... } } 0N/A // class C { class N { N(C c){ ... c.this() ... } } } 0N/A // class D extends C.N { D(C.N n) { n.super(); } } 0N/A // Also, 'C.super', as in: 0N/A // class C extends CS { class N { ... C.super.foo ... } } 0N/A // class C extends CS { class N { ... C.super.foo() ... } } 0N/A // We must check elsewhere that this expression 0N/A // does not stand alone, but qualifies a member name. 0N/A // just class literals, really 0N/A // Class c = C.class; 0N/A // The grammar in the JLS does not allow assignment 0N/A // expressions as the third part of a ?: expression. 0N/A // Even though javac has no trouble parsing this, 0N/A // check for this case and signal an error. 0N/A // (fix for bug 4092958) 0N/A return null;
// mark end of binary expressions 0N/A return e;
// return more binary expression stuff 0N/A * Recover after a syntax error in a statement. This involves 0N/A * discarding tokens until EOF or a possible continuation is 0N/A // begin of a statement, return 0N/A // begin of something outside a statement, panic some more 0N/A // don't know what to do, skip 0N/A * Parse declaration, called after the type expression 0N/A * has been parsed and the current token is IDENT. 0N/A * Check if an expression is a legal toplevel expression. 0N/A * Only method, inc, dec, and new expression are allowed. 0N/A * Parse a statement. 0N/A // if-statement: if (expr) stat 0N/A // if-statement: if (expr) stat else stat 0N/A // else-statement: else stat 0N/A // for-statement: for (decl-expr? ; expr? ; expr?) stat 0N/A // while-statement: while (expr) stat 0N/A // do-statement: do stat while (expr) 0N/A // break-statement: break ; 0N/A // continue-statement: continue ; 0N/A // return-statement: return ; 0N/A // return-statement: return expr ; 0N/A // switch statement: switch ( expr ) stat 0N/A // case-statement: case expr: 0N/A // default-statement: default: 0N/A // case-statement: case expr : stat 0N/A // default-statement: default : stat 0N/A // try-statement: try stat catch (type-expr ident) stat finally stat 0N/A // leave check for try (T x, y) for semantic phase 0N/A // s = new FinallyStatement(p, init, s, 0); 0N/A // We only catch Throwable's, so this is no longer required 0N/A // while (token == LSQBRACKET) { 0N/A // t = new ArrayAccessExpression(scan(), t, null); 0N/A // expect(RSQBRACKET); 0N/A // catch-statement: catch (expr ident) stat finally stat 0N/A // finally-statement: finally stat 0N/A // throw-statement: throw expr; 0N/A // synchronized-statement: synchronized (expr) stat 0N/A // a declaration of some sort 0N/A // A class which is local to a block is not a member, and so 0N/A // cannot be public, private, protected, or static. It is in 0N/A // effect private to the block, since it cannot be used outside 0N/A // However, any class (if it has a name) can be declared final, 0N/A // abstract, or strictfp. 0N/A // declaration: final expr expr 0N/A // This is the start of something outside a statement 0N/A // declaration: expr expr 0N/A // it was just an expression... 0N/A // compound statement: { stat1 stat2 ... statn } 0N/A // We're expecting a block statement. But we'll probably do the 0N/A // least damage if we try to parse a normal statement instead. 0N/A * Parse an identifier. ie: a.b.c returns "a.b.c" 0N/A * If star is true then "a.b.*" is allowed. 0N/A * The return value encodes both the identifier and its location. 0N/A * Parse a type expression, this results in a Type. 0N/A * The parse includes trailing array brackets. 0N/A * Parse the tail of a type expression, which might be array brackets. 0N/A * Return the given type, as possibly modified by the suffix. 0N/A * Dealing with argument lists, I'm not using 0N/A * Vector for efficiency. 0N/A * Parse a possibly-empty sequence of modifier keywords. 0N/A * Return the resulting bitmask. 0N/A * Diagnose repeated modifiers, but make no other checks. 0N/A * Only modifiers mentioned in the given bitmask are scanned; 0N/A * an unmatched modifier must be handled by the caller. 0N/A // const isn't in java, but handle a common C++ usage gently 0N/A // Empty fields are not allowed by the JLS but are accepted by 0N/A // the compiler, and much code has come to rely on this. It has 0N/A // been decided that the language will be extended to legitimize them. 0N/A // Optional doc comment 0N/A // The start of the field 0N/A // Parse the modifiers 0N/A // Check for static initializer 0N/A // ie: static { ... } 0N/A // or an instance initializer (w/o the static). 0N/A // static initializer 0N/A // Check for inner class 0N/A // Check that the type is followed by an Identifier 0N/A // (the name of the method or the first variable), 0N/A // otherwise it is a constructor. 0N/A // It is a constructor 0N/A // If the next token is a left-bracket then we 0N/A // are dealing with a method or constructor, otherwise it is 0N/A // a list of variables 0N/A // It is a method or constructor declaration 0N/A // Parse argument type and identifier 0N/A // (arguments (like locals) are allowed to be final) 0N/A // Parse optional array specifier, ie: a[][] 0N/A // If the next token is a comma then there are 0N/A // Parse argument type and identifier 0N/A // Parse optional array specifier, ie: a[][] 0N/A // Parse optional array sepecifier, ie: foo()[][] 0N/A // Construct the type signature 0N/A // Parse and ignore throws clause 0N/A // Check if it is a method definition or a method declaration 0N/A // ie: foo() {...} or foo(); 0N/A // Set the state of FP strictness for the body of the method 0N/A // really expected a statement body here 0N/A // It is a list of instance variables 0N/A p =
pos;
// get the current position 0N/A // parse the array brackets (if any) 0N/A // Parse the optional initializer 0N/A // Define the variable 0N/A // If the next token is a comma, then there is more 0N/A // The next token must be an identifier 0N/A * Recover after a syntax error in a field. This involves 0N/A * discarding tokens until an EOF or a possible legal 0N/A * continuation is encountered. 0N/A // possible begin of a field, continue 0N/A // begin of something outside a class, panic more 0N/A // don't know what to do, skip 0N/A * Parse a top-level class or interface declaration. 0N/A // Parse the modifiers. 0N/A // set and reset with a stack discipline around methods and named 0N/A // classes. Only M_STRICTFP may be set in this word. try... 0N/A // finally is not needed to protect setting and resetting because 0N/A // there are no error messages based on FPstate. 0N/A * Parse a block-local class or interface declaration. 0N/A * Parse a named class or interface declaration, 0N/A * starting at "class" or "interface". 0N/A * @arg ctx Syntactic context of the class, one of {PACKAGE CLASS STAT EXPR}. 0N/A // The & (...) isn't really necessary here because we do maintain 0N/A // the invariant that FPstate has no extra bits set. 0N/A // Parse the class name 0N/A // Parse extends clause 0N/A // Parse implements clause 0N/A * Parse the body of a class or interface declaration, 0N/A * starting at the left brace. 0N/A // Decide which is the super class 0N/A "multiple.inherit");
0N/A // Begin a new class 0N/A * Recover after a syntax error in the file. 0N/A * This involves discarding tokens until an EOF 0N/A * or a possible legal continuation is encountered. 0N/A // Start of a new source file statement, continue 0N/A // Don't know what to do, skip 0N/A * Parse an Java file. 0N/A // Package statement 0N/A // According to the JLS (7.6,19.6), a TypeDeclaration 0N/A // may consist of a single semicolon, however, this 0N/A // usage is discouraged (JLS 7.6). In contrast, 0N/A // a FieldDeclaration may not be empty, and is flagged 0N/A // as an error. See parseField above. 0N/A * Usually <code>this.scanner == (Scanner)this</code>. 0N/A * However, a delegate scanner can produce tokens for this parser, 0N/A * in which case <code>(Scanner)this</code> is unused, 0N/A * except for <code>this.token</code> and <code>this.pos</code> 0N/A * instance variables which are filled from the real scanner 0N/A * by <code>this.scan()</code> and the constructor. 0N/A // Design Note: We ought to disinherit Parser from Scanner. 0N/A // We also should split out the interface ParserActions from 0N/A // Parser, and make BatchParser implement ParserActions, 0N/A // not extend Parser. This would split scanning, parsing, 0N/A // and class building into distinct responsibility areas. 0N/A // (Perhaps tree building could be virtualized too.)