Source Code Cross Referenced for Parser.java in  » Byte-Code » Javassist » javassist » compiler » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Byte Code » Javassist » javassist.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Javassist, a Java-bytecode translator toolkit.
0003:         * Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.
0004:         *
0005:         * The contents of this file are subject to the Mozilla Public License Version
0006:         * 1.1 (the "License"); you may not use this file except in compliance with
0007:         * the License.  Alternatively, the contents of this file may be used under
0008:         * the terms of the GNU Lesser General Public License Version 2.1 or later.
0009:         *
0010:         * Software distributed under the License is distributed on an "AS IS" basis,
0011:         * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0012:         * for the specific language governing rights and limitations under the
0013:         * License.
0014:         */
0015:
0016:        package javassist.compiler;
0017:
0018:        import javassist.compiler.ast.*;
0019:
0020:        public final class Parser implements  TokenId {
0021:            private Lex lex;
0022:
0023:            public Parser(Lex lex) {
0024:                this .lex = lex;
0025:            }
0026:
0027:            public boolean hasMore() {
0028:                return lex.lookAhead() >= 0;
0029:            }
0030:
0031:            /* member.declaration
0032:             * : method.declaration | field.declaration
0033:             */
0034:            public ASTList parseMember(SymbolTable tbl) throws CompileError {
0035:                ASTList mem = parseMember1(tbl);
0036:                if (mem instanceof  MethodDecl)
0037:                    return parseMethod2(tbl, (MethodDecl) mem);
0038:                else
0039:                    return mem;
0040:            }
0041:
0042:            /* A method body is not parsed.
0043:             */
0044:            public ASTList parseMember1(SymbolTable tbl) throws CompileError {
0045:                ASTList mods = parseMemberMods();
0046:                Declarator d;
0047:                boolean isConstructor = false;
0048:                if (lex.lookAhead() == Identifier && lex.lookAhead(1) == '(') {
0049:                    d = new Declarator(VOID, 0);
0050:                    isConstructor = true;
0051:                } else
0052:                    d = parseFormalType(tbl);
0053:
0054:                if (lex.get() != Identifier)
0055:                    throw new SyntaxError(lex);
0056:
0057:                String name;
0058:                if (isConstructor)
0059:                    name = MethodDecl.initName;
0060:                else
0061:                    name = lex.getString();
0062:
0063:                d.setVariable(new Symbol(name));
0064:                if (isConstructor || lex.lookAhead() == '(')
0065:                    return parseMethod1(tbl, isConstructor, mods, d);
0066:                else
0067:                    return parseField(tbl, mods, d);
0068:            }
0069:
0070:            /* field.declaration
0071:             *  : member.modifiers
0072:             *    formal.type Identifier
0073:             *    [ "=" expression ] ";"
0074:             */
0075:            private FieldDecl parseField(SymbolTable tbl, ASTList mods,
0076:                    Declarator d) throws CompileError {
0077:                ASTree expr = null;
0078:                if (lex.lookAhead() == '=') {
0079:                    lex.get();
0080:                    expr = parseExpression(tbl);
0081:                }
0082:
0083:                int c = lex.get();
0084:                if (c == ';')
0085:                    return new FieldDecl(mods,
0086:                            new ASTList(d, new ASTList(expr)));
0087:                else if (c == ',')
0088:                    throw new CompileError(
0089:                            "only one field can be declared in one declaration",
0090:                            lex);
0091:                else
0092:                    throw new SyntaxError(lex);
0093:            }
0094:
0095:            /* method.declaration
0096:             *  : member.modifiers
0097:             *    [ formal.type ]
0098:             *    Identifier "(" [ formal.parameter ( "," formal.parameter )* ] ")"
0099:             *    array.dimension
0100:             *    [ THROWS class.type ( "," class.type ) ]
0101:             *    ( block.statement | ";" )
0102:             *
0103:             * Note that a method body is not parsed.
0104:             */
0105:            private MethodDecl parseMethod1(SymbolTable tbl,
0106:                    boolean isConstructor, ASTList mods, Declarator d)
0107:                    throws CompileError {
0108:                if (lex.get() != '(')
0109:                    throw new SyntaxError(lex);
0110:
0111:                ASTList parms = null;
0112:                if (lex.lookAhead() != ')')
0113:                    while (true) {
0114:                        parms = ASTList.append(parms, parseFormalParam(tbl));
0115:                        int t = lex.lookAhead();
0116:                        if (t == ',')
0117:                            lex.get();
0118:                        else if (t == ')')
0119:                            break;
0120:                    }
0121:
0122:                lex.get(); // ')'
0123:                d.addArrayDim(parseArrayDimension());
0124:                if (isConstructor && d.getArrayDim() > 0)
0125:                    throw new SyntaxError(lex);
0126:
0127:                ASTList throwsList = null;
0128:                if (lex.lookAhead() == THROWS) {
0129:                    lex.get();
0130:                    while (true) {
0131:                        throwsList = ASTList.append(throwsList,
0132:                                parseClassType(tbl));
0133:                        if (lex.lookAhead() == ',')
0134:                            lex.get();
0135:                        else
0136:                            break;
0137:                    }
0138:                }
0139:
0140:                return new MethodDecl(mods, new ASTList(d, ASTList.make(parms,
0141:                        throwsList, null)));
0142:            }
0143:
0144:            /* Parses a method body.
0145:             */
0146:            public MethodDecl parseMethod2(SymbolTable tbl, MethodDecl md)
0147:                    throws CompileError {
0148:                Stmnt body = null;
0149:                if (lex.lookAhead() == ';')
0150:                    lex.get();
0151:                else {
0152:                    body = parseBlock(tbl);
0153:                    if (body == null)
0154:                        body = new Stmnt(BLOCK);
0155:                }
0156:
0157:                md.sublist(4).setHead(body);
0158:                return md;
0159:            }
0160:
0161:            /* member.modifiers
0162:             *  : ( FINAL | SYNCHRONIZED | ABSTRACT
0163:             *    | PUBLIC | PROTECTED | PRIVATE | STATIC
0164:             *    | VOLATILE | TRANSIENT | STRICT )*
0165:             */
0166:            private ASTList parseMemberMods() {
0167:                int t;
0168:                ASTList list = null;
0169:                while (true) {
0170:                    t = lex.lookAhead();
0171:                    if (t == ABSTRACT || t == FINAL || t == PUBLIC
0172:                            || t == PROTECTED || t == PRIVATE
0173:                            || t == SYNCHRONIZED || t == STATIC
0174:                            || t == VOLATILE || t == TRANSIENT || t == STRICT)
0175:                        list = new ASTList(new Keyword(lex.get()), list);
0176:                    else
0177:                        break;
0178:                }
0179:
0180:                return list;
0181:            }
0182:
0183:            /* formal.type : ( build-in-type | class.type ) array.dimension
0184:             */
0185:            private Declarator parseFormalType(SymbolTable tbl)
0186:                    throws CompileError {
0187:                int t = lex.lookAhead();
0188:                if (isBuiltinType(t) || t == VOID) {
0189:                    lex.get(); // primitive type
0190:                    int dim = parseArrayDimension();
0191:                    return new Declarator(t, dim);
0192:                } else {
0193:                    ASTList name = parseClassType(tbl);
0194:                    int dim = parseArrayDimension();
0195:                    return new Declarator(name, dim);
0196:                }
0197:            }
0198:
0199:            private static boolean isBuiltinType(int t) {
0200:                return (t == BOOLEAN || t == BYTE || t == CHAR || t == SHORT
0201:                        || t == INT || t == LONG || t == FLOAT || t == DOUBLE);
0202:            }
0203:
0204:            /* formal.parameter : formal.type Identifier array.dimension
0205:             */
0206:            private Declarator parseFormalParam(SymbolTable tbl)
0207:                    throws CompileError {
0208:                Declarator d = parseFormalType(tbl);
0209:                if (lex.get() != Identifier)
0210:                    throw new SyntaxError(lex);
0211:
0212:                String name = lex.getString();
0213:                d.setVariable(new Symbol(name));
0214:                d.addArrayDim(parseArrayDimension());
0215:                tbl.append(name, d);
0216:                return d;
0217:            }
0218:
0219:            /* statement : [ label ":" ]* labeled.statement
0220:             *
0221:             * labeled.statement
0222:             *          : block.statement
0223:             *          | if.statement
0224:             *          | while.statement
0225:             *          | do.statement
0226:             *          | for.statement
0227:             *          | switch.statement
0228:             *          | try.statement
0229:             *          | return.statement
0230:             *          | thorw.statement
0231:             *          | break.statement
0232:             *          | continue.statement
0233:             *          | declaration.or.expression
0234:             *          | ";"
0235:             *
0236:             * This method may return null (empty statement).
0237:             */
0238:            public Stmnt parseStatement(SymbolTable tbl) throws CompileError {
0239:                int t = lex.lookAhead();
0240:                if (t == '{')
0241:                    return parseBlock(tbl);
0242:                else if (t == ';') {
0243:                    lex.get();
0244:                    return new Stmnt(BLOCK); // empty statement
0245:                } else if (t == Identifier && lex.lookAhead(1) == ':') {
0246:                    lex.get(); // Identifier
0247:                    String label = lex.getString();
0248:                    lex.get(); // ':'
0249:                    return Stmnt.make(LABEL, new Symbol(label),
0250:                            parseStatement(tbl));
0251:                } else if (t == IF)
0252:                    return parseIf(tbl);
0253:                else if (t == WHILE)
0254:                    return parseWhile(tbl);
0255:                else if (t == DO)
0256:                    return parseDo(tbl);
0257:                else if (t == FOR)
0258:                    return parseFor(tbl);
0259:                else if (t == TRY)
0260:                    return parseTry(tbl);
0261:                else if (t == SWITCH)
0262:                    return parseSwitch(tbl);
0263:                else if (t == SYNCHRONIZED)
0264:                    return parseSynchronized(tbl);
0265:                else if (t == RETURN)
0266:                    return parseReturn(tbl);
0267:                else if (t == THROW)
0268:                    return parseThrow(tbl);
0269:                else if (t == BREAK)
0270:                    return parseBreak(tbl);
0271:                else if (t == CONTINUE)
0272:                    return parseContinue(tbl);
0273:                else
0274:                    return parseDeclarationOrExpression(tbl, false);
0275:            }
0276:
0277:            /* block.statement : "{" statement* "}"
0278:             */
0279:            private Stmnt parseBlock(SymbolTable tbl) throws CompileError {
0280:                if (lex.get() != '{')
0281:                    throw new SyntaxError(lex);
0282:
0283:                Stmnt body = null;
0284:                SymbolTable tbl2 = new SymbolTable(tbl);
0285:                while (lex.lookAhead() != '}') {
0286:                    Stmnt s = parseStatement(tbl2);
0287:                    if (s != null)
0288:                        body = (Stmnt) ASTList
0289:                                .concat(body, new Stmnt(BLOCK, s));
0290:                }
0291:
0292:                lex.get(); // '}'
0293:                if (body == null)
0294:                    return new Stmnt(BLOCK); // empty block
0295:                else
0296:                    return body;
0297:            }
0298:
0299:            /* if.statement : IF "(" expression ")" statement
0300:             *                [ ELSE statement ]
0301:             */
0302:            private Stmnt parseIf(SymbolTable tbl) throws CompileError {
0303:                int t = lex.get(); // IF
0304:                ASTree expr = parseParExpression(tbl);
0305:                Stmnt thenp = parseStatement(tbl);
0306:                Stmnt elsep;
0307:                if (lex.lookAhead() == ELSE) {
0308:                    lex.get();
0309:                    elsep = parseStatement(tbl);
0310:                } else
0311:                    elsep = null;
0312:
0313:                return new Stmnt(t, expr,
0314:                        new ASTList(thenp, new ASTList(elsep)));
0315:            }
0316:
0317:            /* while.statement : WHILE "(" expression ")" statement
0318:             */
0319:            private Stmnt parseWhile(SymbolTable tbl) throws CompileError {
0320:                int t = lex.get(); // WHILE
0321:                ASTree expr = parseParExpression(tbl);
0322:                Stmnt body = parseStatement(tbl);
0323:                return new Stmnt(t, expr, body);
0324:            }
0325:
0326:            /* do.statement : DO statement WHILE "(" expression ")" ";"
0327:             */
0328:            private Stmnt parseDo(SymbolTable tbl) throws CompileError {
0329:                int t = lex.get(); // DO
0330:                Stmnt body = parseStatement(tbl);
0331:                if (lex.get() != WHILE || lex.get() != '(')
0332:                    throw new SyntaxError(lex);
0333:
0334:                ASTree expr = parseExpression(tbl);
0335:                if (lex.get() != ')' || lex.get() != ';')
0336:                    throw new SyntaxError(lex);
0337:
0338:                return new Stmnt(t, expr, body);
0339:            }
0340:
0341:            /* for.statement : FOR "(" decl.or.expr expression ";" expression ")"
0342:             *                 statement
0343:             */
0344:            private Stmnt parseFor(SymbolTable tbl) throws CompileError {
0345:                Stmnt expr1, expr3;
0346:                ASTree expr2;
0347:                int t = lex.get(); // FOR
0348:
0349:                SymbolTable tbl2 = new SymbolTable(tbl);
0350:
0351:                if (lex.get() != '(')
0352:                    throw new SyntaxError(lex);
0353:
0354:                if (lex.lookAhead() == ';') {
0355:                    lex.get();
0356:                    expr1 = null;
0357:                } else
0358:                    expr1 = parseDeclarationOrExpression(tbl2, true);
0359:
0360:                if (lex.lookAhead() == ';')
0361:                    expr2 = null;
0362:                else
0363:                    expr2 = parseExpression(tbl2);
0364:
0365:                if (lex.get() != ';')
0366:                    throw new CompileError("; is missing", lex);
0367:
0368:                if (lex.lookAhead() == ')')
0369:                    expr3 = null;
0370:                else
0371:                    expr3 = parseExprList(tbl2);
0372:
0373:                if (lex.get() != ')')
0374:                    throw new CompileError(") is missing", lex);
0375:
0376:                Stmnt body = parseStatement(tbl2);
0377:                return new Stmnt(t, expr1, new ASTList(expr2, new ASTList(
0378:                        expr3, body)));
0379:            }
0380:
0381:            /* switch.statement : SWITCH "(" expression ")" "{" switch.block "}"
0382:             *
0383:             * swtich.block : ( switch.label statement* )*
0384:             *
0385:             * swtich.label : DEFAULT ":"
0386:             *              | CASE const.expression ":"
0387:             */
0388:            private Stmnt parseSwitch(SymbolTable tbl) throws CompileError {
0389:                int t = lex.get(); // SWITCH
0390:                ASTree expr = parseParExpression(tbl);
0391:                Stmnt body = parseSwitchBlock(tbl);
0392:                return new Stmnt(t, expr, body);
0393:            }
0394:
0395:            private Stmnt parseSwitchBlock(SymbolTable tbl) throws CompileError {
0396:                if (lex.get() != '{')
0397:                    throw new SyntaxError(lex);
0398:
0399:                SymbolTable tbl2 = new SymbolTable(tbl);
0400:                Stmnt s = parseStmntOrCase(tbl2);
0401:                if (s == null)
0402:                    throw new CompileError("empty switch block", lex);
0403:
0404:                int op = s.getOperator();
0405:                if (op != CASE && op != DEFAULT)
0406:                    throw new CompileError(
0407:                            "no case or default in a switch block", lex);
0408:
0409:                Stmnt body = new Stmnt(BLOCK, s);
0410:                while (lex.lookAhead() != '}') {
0411:                    Stmnt s2 = parseStmntOrCase(tbl2);
0412:                    if (s2 != null) {
0413:                        int op2 = s2.getOperator();
0414:                        if (op2 == CASE || op2 == DEFAULT) {
0415:                            body = (Stmnt) ASTList.concat(body, new Stmnt(
0416:                                    BLOCK, s2));
0417:                            s = s2;
0418:                        } else
0419:                            s = (Stmnt) ASTList.concat(s, new Stmnt(BLOCK, s2));
0420:                    }
0421:                }
0422:
0423:                lex.get(); // '}'
0424:                return body;
0425:            }
0426:
0427:            private Stmnt parseStmntOrCase(SymbolTable tbl) throws CompileError {
0428:                int t = lex.lookAhead();
0429:                if (t != CASE && t != DEFAULT)
0430:                    return parseStatement(tbl);
0431:
0432:                lex.get();
0433:                Stmnt s;
0434:                if (t == CASE)
0435:                    s = new Stmnt(t, parseExpression(tbl));
0436:                else
0437:                    s = new Stmnt(DEFAULT);
0438:
0439:                if (lex.get() != ':')
0440:                    throw new CompileError(": is missing", lex);
0441:
0442:                return s;
0443:            }
0444:
0445:            /* synchronized.statement :
0446:             *     SYNCHRONIZED "(" expression ")" block.statement
0447:             */
0448:            private Stmnt parseSynchronized(SymbolTable tbl)
0449:                    throws CompileError {
0450:                int t = lex.get(); // SYNCHRONIZED
0451:                if (lex.get() != '(')
0452:                    throw new SyntaxError(lex);
0453:
0454:                ASTree expr = parseExpression(tbl);
0455:                if (lex.get() != ')')
0456:                    throw new SyntaxError(lex);
0457:
0458:                Stmnt body = parseBlock(tbl);
0459:                return new Stmnt(t, expr, body);
0460:            }
0461:
0462:            /* try.statement
0463:             * : TRY block.statement
0464:             *   [ CATCH "(" class.type Identifier ")" block.statement ]*
0465:             *   [ FINALLY block.statement ]*
0466:             */
0467:            private Stmnt parseTry(SymbolTable tbl) throws CompileError {
0468:                lex.get(); // TRY
0469:                Stmnt block = parseBlock(tbl);
0470:                ASTList catchList = null;
0471:                while (lex.lookAhead() == CATCH) {
0472:                    lex.get(); // CATCH
0473:                    if (lex.get() != '(')
0474:                        throw new SyntaxError(lex);
0475:
0476:                    SymbolTable tbl2 = new SymbolTable(tbl);
0477:                    Declarator d = parseFormalParam(tbl2);
0478:                    if (d.getArrayDim() > 0 || d.getType() != CLASS)
0479:                        throw new SyntaxError(lex);
0480:
0481:                    if (lex.get() != ')')
0482:                        throw new SyntaxError(lex);
0483:
0484:                    Stmnt b = parseBlock(tbl2);
0485:                    catchList = ASTList.append(catchList, new Pair(d, b));
0486:                }
0487:
0488:                Stmnt finallyBlock = null;
0489:                if (lex.lookAhead() == FINALLY) {
0490:                    lex.get(); // FINALLY
0491:                    finallyBlock = parseBlock(tbl);
0492:                }
0493:
0494:                return Stmnt.make(TRY, block, catchList, finallyBlock);
0495:            }
0496:
0497:            /* return.statement : RETURN [ expression ] ";"
0498:             */
0499:            private Stmnt parseReturn(SymbolTable tbl) throws CompileError {
0500:                int t = lex.get(); // RETURN
0501:                Stmnt s = new Stmnt(t);
0502:                if (lex.lookAhead() != ';')
0503:                    s.setLeft(parseExpression(tbl));
0504:
0505:                if (lex.get() != ';')
0506:                    throw new CompileError("; is missing", lex);
0507:
0508:                return s;
0509:            }
0510:
0511:            /* throw.statement : THROW expression ";"
0512:             */
0513:            private Stmnt parseThrow(SymbolTable tbl) throws CompileError {
0514:                int t = lex.get(); // THROW
0515:                ASTree expr = parseExpression(tbl);
0516:                if (lex.get() != ';')
0517:                    throw new CompileError("; is missing", lex);
0518:
0519:                return new Stmnt(t, expr);
0520:            }
0521:
0522:            /* break.statement : BREAK [ Identifier ] ";"
0523:             */
0524:            private Stmnt parseBreak(SymbolTable tbl) throws CompileError {
0525:                return parseContinue(tbl);
0526:            }
0527:
0528:            /* continue.statement : CONTINUE [ Identifier ] ";"
0529:             */
0530:            private Stmnt parseContinue(SymbolTable tbl) throws CompileError {
0531:                int t = lex.get(); // CONTINUE
0532:                Stmnt s = new Stmnt(t);
0533:                int t2 = lex.get();
0534:                if (t2 == Identifier) {
0535:                    s.setLeft(new Symbol(lex.getString()));
0536:                    t2 = lex.get();
0537:                }
0538:
0539:                if (t2 != ';')
0540:                    throw new CompileError("; is missing", lex);
0541:
0542:                return s;
0543:            }
0544:
0545:            /* declaration.or.expression
0546:             *      : [ FINAL ] built-in-type array.dimension declarators
0547:             *      | [ FINAL ] class.type array.dimension declarators
0548:             *      | expression ';'
0549:             *      | expr.list ';'             if exprList is true
0550:             *
0551:             * Note: FINAL is currently ignored.  This must be fixed
0552:             * in future.
0553:             */
0554:            private Stmnt parseDeclarationOrExpression(SymbolTable tbl,
0555:                    boolean exprList) throws CompileError {
0556:                int t = lex.lookAhead();
0557:                while (t == FINAL) {
0558:                    lex.get();
0559:                    t = lex.lookAhead();
0560:                }
0561:
0562:                if (isBuiltinType(t)) {
0563:                    t = lex.get();
0564:                    int dim = parseArrayDimension();
0565:                    return parseDeclarators(tbl, new Declarator(t, dim));
0566:                } else if (t == Identifier) {
0567:                    int i = nextIsClassType(0);
0568:                    if (i >= 0)
0569:                        if (lex.lookAhead(i) == Identifier) {
0570:                            ASTList name = parseClassType(tbl);
0571:                            int dim = parseArrayDimension();
0572:                            return parseDeclarators(tbl, new Declarator(name,
0573:                                    dim));
0574:                        }
0575:                }
0576:
0577:                Stmnt expr;
0578:                if (exprList)
0579:                    expr = parseExprList(tbl);
0580:                else
0581:                    expr = new Stmnt(EXPR, parseExpression(tbl));
0582:
0583:                if (lex.get() != ';')
0584:                    throw new CompileError("; is missing", lex);
0585:
0586:                return expr;
0587:            }
0588:
0589:            /* expr.list : ( expression ',')* expression
0590:             */
0591:            private Stmnt parseExprList(SymbolTable tbl) throws CompileError {
0592:                Stmnt expr = null;
0593:                for (;;) {
0594:                    Stmnt e = new Stmnt(EXPR, parseExpression(tbl));
0595:                    expr = (Stmnt) ASTList.concat(expr, new Stmnt(BLOCK, e));
0596:                    if (lex.lookAhead() == ',')
0597:                        lex.get();
0598:                    else
0599:                        return expr;
0600:                }
0601:            }
0602:
0603:            /* declarators : declarator [ ',' declarator ]* ';'
0604:             */
0605:            private Stmnt parseDeclarators(SymbolTable tbl, Declarator d)
0606:                    throws CompileError {
0607:                Stmnt decl = null;
0608:                for (;;) {
0609:                    decl = (Stmnt) ASTList.concat(decl, new Stmnt(DECL,
0610:                            parseDeclarator(tbl, d)));
0611:                    int t = lex.get();
0612:                    if (t == ';')
0613:                        return decl;
0614:                    else if (t != ',')
0615:                        throw new CompileError("; is missing", lex);
0616:                }
0617:            }
0618:
0619:            /* declarator : Identifier array.dimension [ '=' initializer ]
0620:             */
0621:            private Declarator parseDeclarator(SymbolTable tbl, Declarator d)
0622:                    throws CompileError {
0623:                if (lex.get() != Identifier || d.getType() == VOID)
0624:                    throw new SyntaxError(lex);
0625:
0626:                String name = lex.getString();
0627:                Symbol symbol = new Symbol(name);
0628:                int dim = parseArrayDimension();
0629:                ASTree init = null;
0630:                if (lex.lookAhead() == '=') {
0631:                    lex.get();
0632:                    init = parseInitializer(tbl);
0633:                }
0634:
0635:                Declarator decl = d.make(symbol, dim, init);
0636:                tbl.append(name, decl);
0637:                return decl;
0638:            }
0639:
0640:            /* initializer : expression | array.initializer
0641:             */
0642:            private ASTree parseInitializer(SymbolTable tbl)
0643:                    throws CompileError {
0644:                if (lex.lookAhead() == '{')
0645:                    return parseArrayInitializer(tbl);
0646:                else
0647:                    return parseExpression(tbl);
0648:            }
0649:
0650:            /* array.initializer :
0651:             *  '{' (( array.initializer | expression ) ',')* '}'
0652:             */
0653:            private ArrayInit parseArrayInitializer(SymbolTable tbl)
0654:                    throws CompileError {
0655:                lex.get(); // '{'
0656:                ASTree expr = parseExpression(tbl);
0657:                ArrayInit init = new ArrayInit(expr);
0658:                while (lex.lookAhead() == ',') {
0659:                    lex.get();
0660:                    expr = parseExpression(tbl);
0661:                    ASTList.append(init, expr);
0662:                }
0663:
0664:                if (lex.get() != '}')
0665:                    throw new SyntaxError(lex);
0666:
0667:                return init;
0668:            }
0669:
0670:            /* par.expression : '(' expression ')'
0671:             */
0672:            private ASTree parseParExpression(SymbolTable tbl)
0673:                    throws CompileError {
0674:                if (lex.get() != '(')
0675:                    throw new SyntaxError(lex);
0676:
0677:                ASTree expr = parseExpression(tbl);
0678:                if (lex.get() != ')')
0679:                    throw new SyntaxError(lex);
0680:
0681:                return expr;
0682:            }
0683:
0684:            /* expression : conditional.expr
0685:             *            | conditional.expr assign.op expression (right-to-left)
0686:             */
0687:            public ASTree parseExpression(SymbolTable tbl) throws CompileError {
0688:                ASTree left = parseConditionalExpr(tbl);
0689:                if (!isAssignOp(lex.lookAhead()))
0690:                    return left;
0691:
0692:                int t = lex.get();
0693:                ASTree right = parseExpression(tbl);
0694:                return AssignExpr.makeAssign(t, left, right);
0695:            }
0696:
0697:            private static boolean isAssignOp(int t) {
0698:                return t == '=' || t == MOD_E || t == AND_E || t == MUL_E
0699:                        || t == PLUS_E || t == MINUS_E || t == DIV_E
0700:                        || t == EXOR_E || t == OR_E || t == LSHIFT_E
0701:                        || t == RSHIFT_E || t == ARSHIFT_E;
0702:            }
0703:
0704:            /* conditional.expr                 (right-to-left)
0705:             *     : logical.or.expr [ '?' expression ':' conditional.expr ]
0706:             */
0707:            private ASTree parseConditionalExpr(SymbolTable tbl)
0708:                    throws CompileError {
0709:                ASTree cond = parseBinaryExpr(tbl);
0710:                if (lex.lookAhead() == '?') {
0711:                    lex.get();
0712:                    ASTree thenExpr = parseExpression(tbl);
0713:                    if (lex.get() != ':')
0714:                        throw new CompileError(": is missing", lex);
0715:
0716:                    ASTree elseExpr = parseExpression(tbl);
0717:                    return new CondExpr(cond, thenExpr, elseExpr);
0718:                } else
0719:                    return cond;
0720:            }
0721:
0722:            /* logical.or.expr          10 (operator precedence)
0723:             * : logical.and.expr
0724:             * | logical.or.expr OROR logical.and.expr          left-to-right
0725:             *
0726:             * logical.and.expr         9
0727:             * : inclusive.or.expr
0728:             * | logical.and.expr ANDAND inclusive.or.expr
0729:             *
0730:             * inclusive.or.expr        8
0731:             * : exclusive.or.expr
0732:             * | inclusive.or.expr "|" exclusive.or.expr
0733:             *
0734:             * exclusive.or.expr        7
0735:             *  : and.expr
0736:             * | exclusive.or.expr "^" and.expr
0737:             *
0738:             * and.expr                 6
0739:             * : equality.expr
0740:             * | and.expr "&" equality.expr
0741:             *
0742:             * equality.expr            5
0743:             * : relational.expr
0744:             * | equality.expr (EQ | NEQ) relational.expr
0745:             *
0746:             * relational.expr          4
0747:             * : shift.expr
0748:             * | relational.expr (LE | GE | "<" | ">") shift.expr
0749:             * | relational.expr INSTANCEOF class.type ("[" "]")*
0750:             *
0751:             * shift.expr               3
0752:             * : additive.expr
0753:             * | shift.expr (LSHIFT | RSHIFT | ARSHIFT) additive.expr
0754:             *
0755:             * additive.expr            2
0756:             * : multiply.expr
0757:             * | additive.expr ("+" | "-") multiply.expr
0758:             *
0759:             * multiply.expr            1
0760:             * : unary.expr
0761:             * | multiply.expr ("*" | "/" | "%") unary.expr
0762:             */
0763:            private ASTree parseBinaryExpr(SymbolTable tbl) throws CompileError {
0764:                ASTree expr = parseUnaryExpr(tbl);
0765:                for (;;) {
0766:                    int t = lex.lookAhead();
0767:                    int p = getOpPrecedence(t);
0768:                    if (p == 0)
0769:                        return expr;
0770:                    else
0771:                        expr = binaryExpr2(tbl, expr, p);
0772:                }
0773:            }
0774:
0775:            private ASTree parseInstanceOf(SymbolTable tbl, ASTree expr)
0776:                    throws CompileError {
0777:                int t = lex.lookAhead();
0778:                if (isBuiltinType(t)) {
0779:                    lex.get(); // primitive type
0780:                    int dim = parseArrayDimension();
0781:                    return new InstanceOfExpr(t, dim, expr);
0782:                } else {
0783:                    ASTList name = parseClassType(tbl);
0784:                    int dim = parseArrayDimension();
0785:                    return new InstanceOfExpr(name, dim, expr);
0786:                }
0787:            }
0788:
0789:            private ASTree binaryExpr2(SymbolTable tbl, ASTree expr, int prec)
0790:                    throws CompileError {
0791:                int t = lex.get();
0792:                if (t == INSTANCEOF)
0793:                    return parseInstanceOf(tbl, expr);
0794:
0795:                ASTree expr2 = parseUnaryExpr(tbl);
0796:                for (;;) {
0797:                    int t2 = lex.lookAhead();
0798:                    int p2 = getOpPrecedence(t2);
0799:                    if (p2 != 0 && prec > p2)
0800:                        expr2 = binaryExpr2(tbl, expr2, p2);
0801:                    else
0802:                        return BinExpr.makeBin(t, expr, expr2);
0803:                }
0804:            }
0805:
0806:            // !"#$%&'(    )*+,-./0    12345678    9:;<=>?
0807:            private static final int[] binaryOpPrecedence = { 0, 0, 0, 0, 1, 6,
0808:                    0, 0, 0, 1, 2, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0809:                    0, 4, 0, 4, 0 };
0810:
0811:            private int getOpPrecedence(int c) {
0812:                if ('!' <= c && c <= '?')
0813:                    return binaryOpPrecedence[c - '!'];
0814:                else if (c == '^')
0815:                    return 7;
0816:                else if (c == '|')
0817:                    return 8;
0818:                else if (c == ANDAND)
0819:                    return 9;
0820:                else if (c == OROR)
0821:                    return 10;
0822:                else if (c == EQ || c == NEQ)
0823:                    return 5;
0824:                else if (c == LE || c == GE || c == INSTANCEOF)
0825:                    return 4;
0826:                else if (c == LSHIFT || c == RSHIFT || c == ARSHIFT)
0827:                    return 3;
0828:                else
0829:                    return 0; // not a binary operator
0830:            }
0831:
0832:            /* unary.expr : "++"|"--" unary.expr
0833:                          | "+"|"-" unary.expr
0834:                          | "!"|"~" unary.expr
0835:                          | cast.expr
0836:                          | postfix.expr
0837:
0838:               unary.expr.not.plus.minus is a unary expression starting without
0839:               "+", "-", "++", or "--".
0840:             */
0841:            private ASTree parseUnaryExpr(SymbolTable tbl) throws CompileError {
0842:                int t;
0843:                switch (lex.lookAhead()) {
0844:                case '+':
0845:                case '-':
0846:                case PLUSPLUS:
0847:                case MINUSMINUS:
0848:                case '!':
0849:                case '~':
0850:                    t = lex.get();
0851:                    if (t == '-') {
0852:                        int t2 = lex.lookAhead();
0853:                        switch (t2) {
0854:                        case LongConstant:
0855:                        case IntConstant:
0856:                        case CharConstant:
0857:                            lex.get();
0858:                            return new IntConst(-lex.getLong(), t2);
0859:                        case DoubleConstant:
0860:                        case FloatConstant:
0861:                            lex.get();
0862:                            return new DoubleConst(-lex.getDouble(), t2);
0863:                        default:
0864:                            break;
0865:                        }
0866:                    }
0867:
0868:                    return Expr.make(t, parseUnaryExpr(tbl));
0869:                case '(':
0870:                    return parseCast(tbl);
0871:                default:
0872:                    return parsePostfix(tbl);
0873:                }
0874:            }
0875:
0876:            /* cast.expr : "(" builtin.type ("[" "]")* ")" unary.expr
0877:                         | "(" class.type ("[" "]")* ")" unary.expr2
0878:
0879:               unary.expr2 is a unary.expr begining with "(", NULL, StringL,
0880:               Identifier, THIS, SUPER, or NEW.
0881:
0882:               Either "(int.class)" or "(String[].class)" is a not cast expression.
0883:             */
0884:            private ASTree parseCast(SymbolTable tbl) throws CompileError {
0885:                int t = lex.lookAhead(1);
0886:                if (isBuiltinType(t) && nextIsBuiltinCast()) {
0887:                    lex.get(); // '('
0888:                    lex.get(); // primitive type
0889:                    int dim = parseArrayDimension();
0890:                    if (lex.get() != ')')
0891:                        throw new CompileError(") is missing", lex);
0892:
0893:                    return new CastExpr(t, dim, parseUnaryExpr(tbl));
0894:                } else if (t == Identifier && nextIsClassCast()) {
0895:                    lex.get(); // '('
0896:                    ASTList name = parseClassType(tbl);
0897:                    int dim = parseArrayDimension();
0898:                    if (lex.get() != ')')
0899:                        throw new CompileError(") is missing", lex);
0900:
0901:                    return new CastExpr(name, dim, parseUnaryExpr(tbl));
0902:                } else
0903:                    return parsePostfix(tbl);
0904:            }
0905:
0906:            private boolean nextIsBuiltinCast() {
0907:                int t;
0908:                int i = 2;
0909:                while ((t = lex.lookAhead(i++)) == '[')
0910:                    if (lex.lookAhead(i++) != ']')
0911:                        return false;
0912:
0913:                return lex.lookAhead(i - 1) == ')';
0914:            }
0915:
0916:            private boolean nextIsClassCast() {
0917:                int i = nextIsClassType(1);
0918:                if (i < 0)
0919:                    return false;
0920:
0921:                int t = lex.lookAhead(i);
0922:                if (t != ')')
0923:                    return false;
0924:
0925:                t = lex.lookAhead(i + 1);
0926:                return t == '(' || t == NULL || t == StringL || t == Identifier
0927:                        || t == THIS || t == SUPER || t == NEW || t == TRUE
0928:                        || t == FALSE || t == LongConstant || t == IntConstant
0929:                        || t == CharConstant || t == DoubleConstant
0930:                        || t == FloatConstant;
0931:            }
0932:
0933:            private int nextIsClassType(int i) {
0934:                int t;
0935:                while (lex.lookAhead(++i) == '.')
0936:                    if (lex.lookAhead(++i) != Identifier)
0937:                        return -1;
0938:
0939:                while ((t = lex.lookAhead(i++)) == '[')
0940:                    if (lex.lookAhead(i++) != ']')
0941:                        return -1;
0942:
0943:                return i - 1;
0944:            }
0945:
0946:            /* array.dimension : [ "[" "]" ]*
0947:             */
0948:            private int parseArrayDimension() throws CompileError {
0949:                int arrayDim = 0;
0950:                while (lex.lookAhead() == '[') {
0951:                    ++arrayDim;
0952:                    lex.get();
0953:                    if (lex.get() != ']')
0954:                        throw new CompileError("] is missing", lex);
0955:                }
0956:
0957:                return arrayDim;
0958:            }
0959:
0960:            /* class.type : Identifier ( "." Identifier )*
0961:             */
0962:            private ASTList parseClassType(SymbolTable tbl) throws CompileError {
0963:                ASTList list = null;
0964:                for (;;) {
0965:                    if (lex.get() != Identifier)
0966:                        throw new SyntaxError(lex);
0967:
0968:                    list = ASTList.append(list, new Symbol(lex.getString()));
0969:                    if (lex.lookAhead() == '.')
0970:                        lex.get();
0971:                    else
0972:                        break;
0973:                }
0974:
0975:                return list;
0976:            }
0977:
0978:            /* postfix.expr : number.literal
0979:             *              | primary.expr
0980:             *              | method.expr
0981:             *              | postfix.expr "++" | "--"
0982:             *              | postfix.expr "[" array.size "]"
0983:             *              | postfix.expr "." Identifier
0984:             *              | postfix.expr ( "[" "]" )* "." CLASS
0985:             *              | postfix.expr "#" Identifier
0986:             *
0987:             * "#" is not an operator of regular Java.  It separates
0988:             * a class name and a member name in an expression for static member
0989:             * access.  For example,
0990:             *     java.lang.Integer.toString(3)        in regular Java
0991:             * can be written like this:
0992:             *     java.lang.Integer#toString(3)        for this compiler.
0993:             */
0994:            private ASTree parsePostfix(SymbolTable tbl) throws CompileError {
0995:                int token = lex.lookAhead();
0996:                switch (token) { // see also parseUnaryExpr()
0997:                case LongConstant:
0998:                case IntConstant:
0999:                case CharConstant:
1000:                    lex.get();
1001:                    return new IntConst(lex.getLong(), token);
1002:                case DoubleConstant:
1003:                case FloatConstant:
1004:                    lex.get();
1005:                    return new DoubleConst(lex.getDouble(), token);
1006:                default:
1007:                    break;
1008:                }
1009:
1010:                String str;
1011:                ASTree index;
1012:                ASTree expr = parsePrimaryExpr(tbl);
1013:                int t;
1014:                while (true) {
1015:                    switch (lex.lookAhead()) {
1016:                    case '(':
1017:                        expr = parseMethodCall(tbl, expr);
1018:                        break;
1019:                    case '[':
1020:                        if (lex.lookAhead(1) == ']') {
1021:                            int dim = parseArrayDimension();
1022:                            if (lex.get() != '.' || lex.get() != CLASS)
1023:                                throw new SyntaxError(lex);
1024:
1025:                            expr = parseDotClass(expr, dim);
1026:                        } else {
1027:                            index = parseArrayIndex(tbl);
1028:                            if (index == null)
1029:                                throw new SyntaxError(lex);
1030:
1031:                            expr = Expr.make(ARRAY, expr, index);
1032:                        }
1033:                        break;
1034:                    case PLUSPLUS:
1035:                    case MINUSMINUS:
1036:                        t = lex.get();
1037:                        expr = Expr.make(t, null, expr);
1038:                        break;
1039:                    case '.':
1040:                        lex.get();
1041:                        t = lex.get();
1042:                        if (t == CLASS) {
1043:                            expr = parseDotClass(expr, 0);
1044:                        } else if (t == Identifier) {
1045:                            str = lex.getString();
1046:                            expr = Expr.make('.', expr, new Member(str));
1047:                        } else
1048:                            throw new CompileError("missing member name", lex);
1049:                        break;
1050:                    case '#':
1051:                        lex.get();
1052:                        t = lex.get();
1053:                        if (t != Identifier)
1054:                            throw new CompileError(
1055:                                    "missing static member name", lex);
1056:
1057:                        str = lex.getString();
1058:                        expr = Expr.make(MEMBER, new Symbol(toClassName(expr)),
1059:                                new Member(str));
1060:                        break;
1061:                    default:
1062:                        return expr;
1063:                    }
1064:                }
1065:            }
1066:
1067:            /* Parse a .class expression on a class type.  For example,
1068:             * String.class   => ('.' "String" "class")
1069:             * String[].class => ('.' "[LString;" "class")
1070:             */
1071:            private ASTree parseDotClass(ASTree className, int dim)
1072:                    throws CompileError {
1073:                String cname = toClassName(className);
1074:                if (dim > 0) {
1075:                    StringBuffer sbuf = new StringBuffer();
1076:                    while (dim-- > 0)
1077:                        sbuf.append('[');
1078:
1079:                    sbuf.append('L').append(cname.replace('.', '/'))
1080:                            .append(';');
1081:                    cname = sbuf.toString();
1082:                }
1083:
1084:                return Expr.make('.', new Symbol(cname), new Member("class"));
1085:            }
1086:
1087:            /* Parses a .class expression on a built-in type.  For example,
1088:             * int.class   => ('#' "java.lang.Integer" "TYPE")
1089:             * int[].class => ('.' "[I", "class")
1090:             */
1091:            private ASTree parseDotClass(int builtinType, int dim)
1092:                    throws CompileError {
1093:                if (dim > 0) {
1094:                    String cname = CodeGen.toJvmTypeName(builtinType, dim);
1095:                    return Expr.make('.', new Symbol(cname),
1096:                            new Member("class"));
1097:                } else {
1098:                    String cname;
1099:                    switch (builtinType) {
1100:                    case BOOLEAN:
1101:                        cname = "java.lang.Boolean";
1102:                        break;
1103:                    case BYTE:
1104:                        cname = "java.lang.Byte";
1105:                        break;
1106:                    case CHAR:
1107:                        cname = "java.lang.Character";
1108:                        break;
1109:                    case SHORT:
1110:                        cname = "java.lang.Short";
1111:                        break;
1112:                    case INT:
1113:                        cname = "java.lang.Integer";
1114:                        break;
1115:                    case LONG:
1116:                        cname = "java.lang.Long";
1117:                        break;
1118:                    case FLOAT:
1119:                        cname = "java.lang.Float";
1120:                        break;
1121:                    case DOUBLE:
1122:                        cname = "java.lang.Double";
1123:                        break;
1124:                    case VOID:
1125:                        cname = "java.lang.Void";
1126:                        break;
1127:                    default:
1128:                        throw new CompileError("invalid builtin type: "
1129:                                + builtinType);
1130:                    }
1131:
1132:                    return Expr.make(MEMBER, new Symbol(cname), new Member(
1133:                            "TYPE"));
1134:                }
1135:            }
1136:
1137:            /* method.call : method.expr "(" argument.list ")"
1138:             * method.expr : THIS | SUPER | Identifier
1139:             *             | postfix.expr "." Identifier
1140:             *             | postfix.expr "#" Identifier
1141:             */
1142:            private ASTree parseMethodCall(SymbolTable tbl, ASTree expr)
1143:                    throws CompileError {
1144:                if (expr instanceof  Keyword) {
1145:                    int token = ((Keyword) expr).get();
1146:                    if (token != THIS && token != SUPER)
1147:                        throw new SyntaxError(lex);
1148:                } else if (expr instanceof  Symbol) // Identifier
1149:                    ;
1150:                else if (expr instanceof  Expr) {
1151:                    int op = ((Expr) expr).getOperator();
1152:                    if (op != '.' && op != MEMBER)
1153:                        throw new SyntaxError(lex);
1154:                }
1155:
1156:                return CallExpr.makeCall(expr, parseArgumentList(tbl));
1157:            }
1158:
1159:            private String toClassName(ASTree name) throws CompileError {
1160:                StringBuffer sbuf = new StringBuffer();
1161:                toClassName(name, sbuf);
1162:                return sbuf.toString();
1163:            }
1164:
1165:            private void toClassName(ASTree name, StringBuffer sbuf)
1166:                    throws CompileError {
1167:                if (name instanceof  Symbol) {
1168:                    sbuf.append(((Symbol) name).get());
1169:                    return;
1170:                } else if (name instanceof  Expr) {
1171:                    Expr expr = (Expr) name;
1172:                    if (expr.getOperator() == '.') {
1173:                        toClassName(expr.oprand1(), sbuf);
1174:                        sbuf.append('.');
1175:                        toClassName(expr.oprand2(), sbuf);
1176:                        return;
1177:                    }
1178:                }
1179:
1180:                throw new CompileError("bad static member access", lex);
1181:            }
1182:
1183:            /* primary.expr : THIS | SUPER | TRUE | FALSE | NULL
1184:             *              | StringL
1185:             *              | Identifier
1186:             *              | NEW new.expr
1187:             *              | "(" expression ")"
1188:             *              | builtin.type ( "[" "]" )* "." CLASS
1189:             *
1190:             * Identifier represents either a local variable name, a member name,
1191:             * or a class name.
1192:             */
1193:            private ASTree parsePrimaryExpr(SymbolTable tbl)
1194:                    throws CompileError {
1195:                int t;
1196:                String name;
1197:                Declarator decl;
1198:                ASTree expr;
1199:
1200:                switch (t = lex.get()) {
1201:                case THIS:
1202:                case SUPER:
1203:                case TRUE:
1204:                case FALSE:
1205:                case NULL:
1206:                    return new Keyword(t);
1207:                case Identifier:
1208:                    name = lex.getString();
1209:                    decl = tbl.lookup(name);
1210:                    if (decl == null)
1211:                        return new Member(name); // this or static member
1212:                    else
1213:                        return new Variable(name, decl); // local variable
1214:                case StringL:
1215:                    return new StringL(lex.getString());
1216:                case NEW:
1217:                    return parseNew(tbl);
1218:                case '(':
1219:                    expr = parseExpression(tbl);
1220:                    if (lex.get() == ')')
1221:                        return expr;
1222:                    else
1223:                        throw new CompileError(") is missing", lex);
1224:                default:
1225:                    if (isBuiltinType(t) || t == VOID) {
1226:                        int dim = parseArrayDimension();
1227:                        if (lex.get() == '.' && lex.get() == CLASS)
1228:                            return parseDotClass(t, dim);
1229:                    }
1230:
1231:                    throw new SyntaxError(lex);
1232:                }
1233:            }
1234:
1235:            /* new.expr : class.type "(" argument.list ")"
1236:             *          | class.type     array.size [ array.initializer ]
1237:             *          | primitive.type array.size [ array.initializer ]
1238:             */
1239:            private NewExpr parseNew(SymbolTable tbl) throws CompileError {
1240:                ArrayInit init = null;
1241:                int t = lex.lookAhead();
1242:                if (isBuiltinType(t)) {
1243:                    lex.get();
1244:                    ASTList size = parseArraySize(tbl);
1245:                    if (lex.lookAhead() == '{')
1246:                        init = parseArrayInitializer(tbl);
1247:
1248:                    return new NewExpr(t, size, init);
1249:                } else if (t == Identifier) {
1250:                    ASTList name = parseClassType(tbl);
1251:                    t = lex.lookAhead();
1252:                    if (t == '(') {
1253:                        ASTList args = parseArgumentList(tbl);
1254:                        return new NewExpr(name, args);
1255:                    } else if (t == '[') {
1256:                        ASTList size = parseArraySize(tbl);
1257:                        if (lex.lookAhead() == '{')
1258:                            init = parseArrayInitializer(tbl);
1259:
1260:                        return NewExpr.makeObjectArray(name, size, init);
1261:                    }
1262:                }
1263:
1264:                throw new SyntaxError(lex);
1265:            }
1266:
1267:            /* array.size : [ array.index ]*
1268:             */
1269:            private ASTList parseArraySize(SymbolTable tbl) throws CompileError {
1270:                ASTList list = null;
1271:                while (lex.lookAhead() == '[')
1272:                    list = ASTList.append(list, parseArrayIndex(tbl));
1273:
1274:                return list;
1275:            }
1276:
1277:            /* array.index : "[" [ expression ] "]"
1278:             */
1279:            private ASTree parseArrayIndex(SymbolTable tbl) throws CompileError {
1280:                lex.get(); // '['
1281:                if (lex.lookAhead() == ']') {
1282:                    lex.get();
1283:                    return null;
1284:                } else {
1285:                    ASTree index = parseExpression(tbl);
1286:                    if (lex.get() != ']')
1287:                        throw new CompileError("] is missing", lex);
1288:
1289:                    return index;
1290:                }
1291:            }
1292:
1293:            /* argument.list : "(" [ expression [ "," expression ]* ] ")"
1294:             */
1295:            private ASTList parseArgumentList(SymbolTable tbl)
1296:                    throws CompileError {
1297:                if (lex.get() != '(')
1298:                    throw new CompileError("( is missing", lex);
1299:
1300:                ASTList list = null;
1301:                if (lex.lookAhead() != ')')
1302:                    for (;;) {
1303:                        list = ASTList.append(list, parseExpression(tbl));
1304:                        if (lex.lookAhead() == ',')
1305:                            lex.get();
1306:                        else
1307:                            break;
1308:                    }
1309:
1310:                if (lex.get() != ')')
1311:                    throw new CompileError(") is missing", lex);
1312:
1313:                return list;
1314:            }
1315:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.