Source Code Cross Referenced for Parser.java in  » Template-Engine » Tea » com » go » tea » 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 » Template Engine » Tea » com.go.tea.compiler 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /* ====================================================================
0002:         * Tea - Copyright (c) 1997-2000 Walt Disney Internet Group
0003:         * ====================================================================
0004:         * The Tea Software License, Version 1.1
0005:         *
0006:         * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
0007:         *
0008:         * Redistribution and use in source and binary forms, with or without
0009:         * modification, are permitted provided that the following conditions
0010:         * are met:
0011:         *
0012:         * 1. Redistributions of source code must retain the above copyright
0013:         *    notice, this list of conditions and the following disclaimer.
0014:         *
0015:         * 2. Redistributions in binary form must reproduce the above copyright
0016:         *    notice, this list of conditions and the following disclaimer in
0017:         *    the documentation and/or other materials provided with the
0018:         *    distribution.
0019:         *
0020:         * 3. The end-user documentation included with the redistribution,
0021:         *    if any, must include the following acknowledgment:
0022:         *       "This product includes software developed by the
0023:         *        Walt Disney Internet Group (http://opensource.go.com/)."
0024:         *    Alternately, this acknowledgment may appear in the software itself,
0025:         *    if and wherever such third-party acknowledgments normally appear.
0026:         *
0027:         * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
0028:         *    not be used to endorse or promote products derived from this
0029:         *    software without prior written permission. For written
0030:         *    permission, please contact opensource@dig.com.
0031:         *
0032:         * 5. Products derived from this software may not be called "Tea",
0033:         *    "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
0034:         *    "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
0035:         *    written permission of the Walt Disney Internet Group.
0036:         *
0037:         * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
0038:         * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
0039:         * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
0040:         * DISCLAIMED.  IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
0041:         * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0042:         * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0043:         * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
0044:         * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0045:         * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
0046:         * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0047:         * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0048:         * ====================================================================
0049:         *
0050:         * For more information about Tea, please see http://opensource.go.com/.
0051:         */
0052:
0053:        package com.go.tea.compiler;
0054:
0055:        import java.io.*;
0056:        import java.util.Vector;
0057:        import com.go.tea.parsetree.*;
0058:        import com.go.trove.io.SourceReader;
0059:
0060:        /******************************************************************************
0061:         * A Parser creates the parse tree for a template by reading tokens emitted by
0062:         * a {@link Scanner}. The parse tree represents the entire template as a
0063:         * data structure composed of specialized nodes. Add an {@link ErrorListener}
0064:         * to capture any syntax errors detected by the Parser.
0065:         *
0066:         * @author Brian S O'Neill
0067:         * @version
0068:         * <!--$$Revision:--> 64 <!-- $-->, <!--$$JustDate:-->  5/31/01 <!-- $-->
0069:         */
0070:        public class Parser {
0071:            private Scanner mScanner;
0072:            private CompilationUnit mUnit;
0073:
0074:            private Vector mListeners = new Vector(1);
0075:            private int mErrorCount = 0;
0076:            private int mEOFErrorCount = 0;
0077:
0078:            private MessageFormatter mFormatter;
0079:
0080:            public Parser(Scanner scanner) {
0081:                this (scanner, null);
0082:            }
0083:
0084:            public Parser(Scanner scanner, CompilationUnit unit) {
0085:                mScanner = scanner;
0086:                mUnit = unit;
0087:                mFormatter = MessageFormatter.lookup(this );
0088:            }
0089:
0090:            public void addErrorListener(ErrorListener listener) {
0091:                mListeners.addElement(listener);
0092:            }
0093:
0094:            public void removeErrorListener(ErrorListener listener) {
0095:                mListeners.removeElement(listener);
0096:            }
0097:
0098:            private void dispatchParseError(ErrorEvent e) {
0099:                mErrorCount++;
0100:
0101:                synchronized (mListeners) {
0102:                    for (int i = 0; i < mListeners.size(); i++) {
0103:                        ((ErrorListener) mListeners.elementAt(i))
0104:                                .compileError(e);
0105:                    }
0106:                }
0107:            }
0108:
0109:            private void error(String str, Token culprit) {
0110:                str = mFormatter.format(str);
0111:
0112:                if (culprit.getID() == Token.EOF) {
0113:                    if (mEOFErrorCount++ == 0) {
0114:                        str = mFormatter.format("error.at.end", str);
0115:                    } else {
0116:                        return;
0117:                    }
0118:                }
0119:
0120:                dispatchParseError(new ErrorEvent(this , str, culprit, mUnit));
0121:            }
0122:
0123:            private void error(String str, String arg, Token culprit) {
0124:                str = mFormatter.format(str, arg);
0125:
0126:                if (culprit.getID() == Token.EOF) {
0127:                    if (mEOFErrorCount++ == 0) {
0128:                        str = mFormatter.format("error.at.end", str);
0129:                    } else {
0130:                        return;
0131:                    }
0132:                }
0133:
0134:                dispatchParseError(new ErrorEvent(this , str, culprit, mUnit));
0135:            }
0136:
0137:            private void error(String str, SourceInfo info) {
0138:                str = mFormatter.format(str);
0139:                dispatchParseError(new ErrorEvent(this , str, info, mUnit));
0140:            }
0141:
0142:            /**
0143:             * Returns a parse tree by its root node. The parse tree is generated
0144:             * from tokens read from the scanner. Any errors encountered while
0145:             * parsing are delivered by dispatching an event. Add an error listener
0146:             * in order to capture parse errors.
0147:             *
0148:             * @return Non-null template node, even if there were errors during 
0149:             * parsing.
0150:             * @see Parser#addErrorListener
0151:             */
0152:            public Template parse() throws IOException {
0153:                Template t = parseTemplate();
0154:
0155:                if (t != null) {
0156:                    return t;
0157:                }
0158:
0159:                return new Template(new SourceInfo(0, 0, 0), null, null, false,
0160:                        null);
0161:            }
0162:
0163:            public int getErrorCount() {
0164:                return mErrorCount;
0165:            }
0166:
0167:            private Token read() throws IOException {
0168:                return mScanner.readToken();
0169:            }
0170:
0171:            private Token peek() throws IOException {
0172:                return mScanner.peekToken();
0173:            }
0174:
0175:            private void unread(Token token) throws IOException {
0176:                mScanner.unreadToken(token);
0177:            }
0178:
0179:            private Template parseTemplate() throws IOException {
0180:                Name name;
0181:                Variable[] params = null;
0182:                StatementList statementList;
0183:
0184:                Token token = read();
0185:                SourceInfo templateInfo = token.getSourceInfo();
0186:
0187:                if (token.getID() != Token.TEMPLATE) {
0188:                    if (token.getID() == Token.STRING
0189:                            && peek().getID() == Token.TEMPLATE) {
0190:
0191:                        error("template.start", token);
0192:                        token = read();
0193:                    } else {
0194:                        error("template.declaration", token);
0195:                    }
0196:                }
0197:
0198:                SourceInfo nameInfo = peek().getSourceInfo();
0199:                name = new Name(nameInfo, parseIdentifier());
0200:
0201:                params = parseFormalParameters();
0202:
0203:                // Check if a block is accepted as a parameter. Pattern is { ... }
0204:                boolean subParam = false;
0205:                token = peek();
0206:                if (token.getID() == Token.LBRACE
0207:                        || token.getID() == Token.ELLIPSIS) {
0208:                    if (token.getID() == Token.ELLIPSIS) {
0209:                        error("template.substitution.lbrace", token);
0210:                    } else {
0211:                        read();
0212:                        token = peek();
0213:                    }
0214:
0215:                    if (token.getID() == Token.ELLIPSIS) {
0216:                        read();
0217:                        token = peek();
0218:                        if (token.getID() == Token.RBRACE) {
0219:                            read();
0220:                            subParam = true;
0221:                        } else {
0222:                            error("template.substitution.rbrace", token);
0223:                        }
0224:                    } else {
0225:                        error("template.substitution.ellipsis", token);
0226:                        if (token.getID() == Token.RBRACE) {
0227:                            read();
0228:                            subParam = true;
0229:                        }
0230:                    }
0231:                }
0232:
0233:                // Parse statements until end of file is reached.
0234:                Vector v = new Vector(10, 0);
0235:
0236:                SourceInfo info = peek().getSourceInfo();
0237:
0238:                Statement statement = null;
0239:                while (peek().getID() != Token.EOF) {
0240:                    statement = parseStatement();
0241:                    v.addElement(statement);
0242:                }
0243:
0244:                if (statement != null) {
0245:                    info = info.setEndPosition(statement.getSourceInfo());
0246:                }
0247:
0248:                Statement[] statements = new Statement[v.size()];
0249:                v.copyInto(statements);
0250:
0251:                statementList = new StatementList(info, statements);
0252:
0253:                templateInfo = templateInfo.setEndPosition(statementList
0254:                        .getSourceInfo());
0255:
0256:                return new Template(templateInfo, name, params, subParam,
0257:                        statementList);
0258:            }
0259:
0260:            private String parseIdentifier() throws IOException {
0261:                Token token = read();
0262:                if (token.getID() != Token.IDENT) {
0263:                    if (token.isReservedWord()) {
0264:                        error("identifier.reserved.word", token.getImage(),
0265:                                token);
0266:                        return token.getImage();
0267:                    } else {
0268:                        error("identifier.expected", token);
0269:                        return "";
0270:                    }
0271:                }
0272:
0273:                return token.getStringValue();
0274:            }
0275:
0276:            private Name parseName() throws IOException {
0277:                SourceInfo info = null;
0278:                StringBuffer name = new StringBuffer(20);
0279:
0280:                while (true) {
0281:                    Token token = read();
0282:                    if (token.getID() != Token.IDENT) {
0283:                        if (info == null) {
0284:                            info = token.getSourceInfo();
0285:                        } else {
0286:                            info = info.setEndPosition(token.getSourceInfo());
0287:                        }
0288:
0289:                        if (token.isReservedWord()) {
0290:                            error("name.reserved.word", token.getImage(), token);
0291:                            name.append(token.getImage());
0292:                        } else {
0293:                            error("name.identifier.expected", token);
0294:                            break;
0295:                        }
0296:                    } else {
0297:                        name.append(token.getStringValue());
0298:                        if (info == null) {
0299:                            info = token.getSourceInfo();
0300:                        } else {
0301:                            info = info.setEndPosition(token.getSourceInfo());
0302:                        }
0303:                    }
0304:
0305:                    token = peek();
0306:                    if (token.getID() != Token.DOT) {
0307:                        break;
0308:                    } else {
0309:                        token = read();
0310:                        name.append('.');
0311:                        info = info.setEndPosition(token.getSourceInfo());
0312:                    }
0313:                }
0314:
0315:                return new Name(info, name.toString());
0316:            }
0317:
0318:            private TypeName parseTypeName() throws IOException {
0319:                Name name = parseName();
0320:
0321:                SourceInfo info = name.getSourceInfo();
0322:                int dim = 0;
0323:
0324:                while (peek().getID() == Token.LBRACK) {
0325:                    dim++;
0326:                    Token token = read(); // read the left bracket
0327:                    if (peek().getID() == Token.RBRACK) {
0328:                        token = read(); // read the right bracket
0329:                    } else {
0330:                        error("name.rbracket", peek());
0331:                    }
0332:                    info = info.setEndPosition(token.getSourceInfo());
0333:                }
0334:
0335:                return new TypeName(info, name, dim);
0336:            }
0337:
0338:            private Variable parseVariableDeclaration() throws IOException {
0339:                TypeName typeName = parseTypeName();
0340:
0341:                SourceInfo info = peek().getSourceInfo();
0342:                String varName = parseIdentifier();
0343:
0344:                return new Variable(info, varName, typeName);
0345:            }
0346:
0347:            private Variable[] parseFormalParameters() throws IOException {
0348:                Token token = peek();
0349:
0350:                if (token.getID() == Token.LPAREN) {
0351:                    read(); // read the left paren
0352:                    token = peek();
0353:                } else {
0354:                    error("params.lparen", token);
0355:                }
0356:
0357:                Vector vars = new Vector(10, 0);
0358:
0359:                if (token.getID() == Token.RPAREN) {
0360:                    // Empty list detected.
0361:                } else {
0362:                    Expression expr = null;
0363:                    while (true) {
0364:                        if ((token = peek()).getID() == Token.RPAREN) {
0365:                            error("params.premature.end", token);
0366:                            break;
0367:                        }
0368:
0369:                        vars.addElement(parseVariableDeclaration());
0370:
0371:                        if ((token = peek()).getID() != Token.COMMA) {
0372:                            break;
0373:                        } else {
0374:                            read(); // read the comma
0375:                        }
0376:                    }
0377:                }
0378:
0379:                if (token.getID() == Token.RPAREN) {
0380:                    read(); // read the right paren
0381:                } else {
0382:                    error("params.rparen.expected", token);
0383:                }
0384:
0385:                Variable[] variables = new Variable[vars.size()];
0386:                vars.copyInto(variables);
0387:
0388:                return variables;
0389:            }
0390:
0391:            private VariableRef parseLValue() throws IOException {
0392:                return parseLValue(read());
0393:            }
0394:
0395:            private VariableRef parseLValue(Token token) throws IOException {
0396:                String loopVarName;
0397:                if (token.getID() != Token.IDENT) {
0398:                    if (token.isReservedWord()) {
0399:                        error("lvalue.reserved.word", token.getImage(), token);
0400:                        loopVarName = token.getImage();
0401:                    } else {
0402:                        error("lvalue.identifier.expected", token);
0403:                        loopVarName = "";
0404:                    }
0405:                } else {
0406:                    loopVarName = token.getStringValue();
0407:                }
0408:
0409:                return new VariableRef(token.getSourceInfo(), loopVarName);
0410:            }
0411:
0412:            private Block parseBlock() throws IOException {
0413:                Token token = peek();
0414:                SourceInfo info = token.getSourceInfo();
0415:
0416:                if (token.getID() != Token.LBRACE) {
0417:                    error("block.lbrace.expected", token);
0418:                    if (token.getID() == Token.SEMI) {
0419:                        read();
0420:                        return new Block(info, new Statement[0]);
0421:                    }
0422:                } else {
0423:                    token = read(); // read the left brace
0424:                }
0425:
0426:                Vector v = new Vector(10, 0);
0427:                Token p;
0428:                while ((p = peek()).getID() != Token.RBRACE) {
0429:                    if (p.getID() == Token.EOF) {
0430:                        error("block.rbrace.expected", p);
0431:                        break;
0432:                    }
0433:                    v.addElement(parseStatement());
0434:                }
0435:                token = read(); // read the right brace
0436:
0437:                Statement[] statements = new Statement[v.size()];
0438:                v.copyInto(statements);
0439:
0440:                info = info.setEndPosition(token.getSourceInfo());
0441:
0442:                return new Block(info, statements);
0443:            }
0444:
0445:            private Statement parseStatement() throws IOException {
0446:                Statement st = null;
0447:
0448:                while (st == null) {
0449:                    Token token = read();
0450:
0451:                    switch (token.getID()) {
0452:                    case Token.SEMI:
0453:                        // If the token after the semi-colon is a right brace,
0454:                        // we can't simply skip it because this method
0455:                        // can't properly parse a right brace. Instead, return
0456:                        // an empty placeholder statement. The parseBlock method
0457:                        // will then be able to parse the right brace properly.
0458:
0459:                        int ID = peek().getID();
0460:                        if (ID == Token.RBRACE || ID == Token.EOF) {
0461:                            st = new Statement(token.getSourceInfo());
0462:                        } else {
0463:                            // Skip this token
0464:                        }
0465:                        break;
0466:                    case Token.BREAK:
0467:                        st = parseBreakStatement(token);
0468:                        break;
0469:                    case Token.IF:
0470:                        st = parseIfStatement(token);
0471:                        break;
0472:                    case Token.FOREACH:
0473:                        st = parseForeachStatement(token);
0474:                        break;
0475:                    case Token.IDENT:
0476:                        if (peek().getID() == Token.ASSIGN) {
0477:                            st = parseAssignmentStatement(token);
0478:                        } else {
0479:                            st = new ExpressionStatement(parseExpression(token));
0480:                        }
0481:                        break;
0482:                    case Token.ELLIPSIS:
0483:                        st = new SubstitutionStatement(token.getSourceInfo());
0484:                        break;
0485:
0486:                    case Token.EOF:
0487:                        error("statement.expected", token);
0488:                        st = new Statement(token.getSourceInfo());
0489:                        break;
0490:
0491:                    // Handle some error cases in a specialized way so that
0492:                    // the error message produced is more meaningful.
0493:                    case Token.ELSE:
0494:                        error("statement.misuse.else", token);
0495:                        st = parseBlock();
0496:                        break;
0497:                    case Token.IN:
0498:                        error("statement.misuse.in", token);
0499:                        st = new ExpressionStatement(parseExpression(token));
0500:                        break;
0501:
0502:                    case Token.REVERSE:
0503:                        error("statement.misuse.reverse", token);
0504:                        st = new ExpressionStatement(parseExpression(token));
0505:                        break;
0506:
0507:                    default:
0508:                        st = new ExpressionStatement(parseExpression(token));
0509:                        break;
0510:                    }
0511:                }
0512:
0513:                return st;
0514:            }
0515:
0516:            // When this is called, the keyword "break" has already been read.
0517:            private BreakStatement parseBreakStatement(Token token)
0518:                    throws IOException {
0519:                return new BreakStatement(token.getSourceInfo());
0520:            }
0521:
0522:            // When this is called, the keyword "if" has already been read.
0523:            private IfStatement parseIfStatement(Token token)
0524:                    throws IOException {
0525:                SourceInfo info = token.getSourceInfo();
0526:
0527:                Expression condition = parseExpression();
0528:
0529:                if (!(condition instanceof  ParenExpression)) {
0530:                    error("if.condition", condition.getSourceInfo());
0531:                }
0532:
0533:                Block thenPart = parseBlock();
0534:                Block elsePart = null;
0535:
0536:                token = peek();
0537:                if (token.getID() != Token.ELSE) {
0538:                    info = info.setEndPosition(thenPart.getSourceInfo());
0539:                } else {
0540:                    read(); // read the else keyword
0541:                    token = peek();
0542:                    if (token.getID() == Token.IF) {
0543:                        elsePart = new Block(parseIfStatement(read()));
0544:                    } else {
0545:                        elsePart = parseBlock();
0546:                    }
0547:
0548:                    info = info.setEndPosition(elsePart.getSourceInfo());
0549:                }
0550:
0551:                return new IfStatement(info, condition, thenPart, elsePart);
0552:            }
0553:
0554:            // When this is called, the keyword "foreach" has already been read.
0555:            private ForeachStatement parseForeachStatement(Token token)
0556:                    throws IOException {
0557:
0558:                SourceInfo info = token.getSourceInfo();
0559:
0560:                token = peek();
0561:                if (token.getID() == Token.LPAREN) {
0562:                    read();
0563:                } else {
0564:                    error("foreach.lparen.expected", token);
0565:                }
0566:
0567:                VariableRef loopVar = parseLValue();
0568:
0569:                token = peek();
0570:                if (token.getID() == Token.IN) {
0571:                    read();
0572:                } else {
0573:                    error("foreach.in.expected", token);
0574:                }
0575:
0576:                Expression range = parseExpression();
0577:                Expression endRange = null;
0578:
0579:                token = peek();
0580:                if (token.getID() == Token.DOTDOT) {
0581:                    read();
0582:                    endRange = parseExpression();
0583:                    token = peek();
0584:                }
0585:
0586:                boolean reverse = false;
0587:                if (token.getID() == Token.REVERSE) {
0588:                    read();
0589:                    reverse = true;
0590:                    token = peek();
0591:                }
0592:
0593:                if (token.getID() == Token.RPAREN) {
0594:                    read();
0595:                } else {
0596:                    error("foreach.rparen.expected", token);
0597:                }
0598:
0599:                Block body = parseBlock();
0600:
0601:                info = info.setEndPosition(body.getSourceInfo());
0602:
0603:                return new ForeachStatement(info, loopVar, range, endRange,
0604:                        reverse, body);
0605:            }
0606:
0607:            // When this is called, the identifier token has already been read.
0608:            private AssignmentStatement parseAssignmentStatement(Token token)
0609:                    throws IOException {
0610:
0611:                SourceInfo info = token.getSourceInfo();
0612:                VariableRef lvalue = parseLValue(token);
0613:
0614:                if (peek().getID() == Token.ASSIGN) {
0615:                    read();
0616:                } else {
0617:                    error("assignment.equals.expected", peek());
0618:                }
0619:
0620:                Expression rvalue = parseExpression();
0621:                info = info.setEndPosition(rvalue.getSourceInfo());
0622:
0623:                return new AssignmentStatement(info, lvalue, rvalue);
0624:            }
0625:
0626:            /**
0627:             * @param bracketed True if the list is bounded by brackets instead of
0628:             * parenthesis.
0629:             */
0630:            private ExpressionList parseList(boolean bracketed)
0631:                    throws IOException {
0632:                int leftID;
0633:                int rightID;
0634:
0635:                if (!bracketed) {
0636:                    leftID = Token.LPAREN;
0637:                    rightID = Token.RPAREN;
0638:                } else {
0639:                    leftID = Token.LBRACK;
0640:                    rightID = Token.RBRACK;
0641:                }
0642:
0643:                Token token = peek();
0644:                SourceInfo info = token.getSourceInfo();
0645:
0646:                if (token.getID() == leftID) {
0647:                    read(); // read the left paren
0648:                    token = peek();
0649:                } else {
0650:                    if (!bracketed) {
0651:                        error("list.lparen.expected", token);
0652:                    } else {
0653:                        error("list.lbracket.expected", token);
0654:                    }
0655:                }
0656:
0657:                Vector exprs = new Vector(10, 0);
0658:                boolean done = false;
0659:
0660:                if (token.getID() == rightID) {
0661:                    // Empty list detected
0662:                } else {
0663:                    Expression expr = null;
0664:                    while (true) {
0665:                        token = read();
0666:
0667:                        if (token.getID() == rightID) {
0668:                            error("list.premature.end", token);
0669:                            info = info.setEndPosition(token.getSourceInfo());
0670:                            done = true;
0671:                            break;
0672:                        }
0673:
0674:                        expr = parseExpression(token);
0675:                        exprs.addElement(expr);
0676:
0677:                        token = peek();
0678:
0679:                        if (token.getID() != Token.COMMA) {
0680:                            break;
0681:                        } else {
0682:                            token = read(); // read the comma
0683:                        }
0684:                    }
0685:
0686:                    if (!done && expr != null) {
0687:                        info = info.setEndPosition(expr.getSourceInfo());
0688:                    }
0689:                }
0690:
0691:                if (!done) {
0692:                    token = peek();
0693:
0694:                    if (token.getID() == rightID) {
0695:                        token = read(); // read the right paren
0696:                        info = info.setEndPosition(token.getSourceInfo());
0697:                    } else {
0698:                        if (!bracketed) {
0699:                            error("list.rparen.expected", token);
0700:                        } else {
0701:                            error("list.rbracket.expected", token);
0702:                        }
0703:                    }
0704:                }
0705:
0706:                Expression[] elements = new Expression[exprs.size()];
0707:                exprs.copyInto(elements);
0708:
0709:                return new ExpressionList(info, elements);
0710:            }
0711:
0712:            private Expression parseExpression() throws IOException {
0713:                return parseExpression(read());
0714:            }
0715:
0716:            private Expression parseExpression(Token token) throws IOException {
0717:                return parseOrExpression(token);
0718:            }
0719:
0720:            private Expression parseOrExpression(Token token)
0721:                    throws IOException {
0722:                SourceInfo info = token.getSourceInfo();
0723:                Expression expr = parseAndExpression(token);
0724:
0725:                loop: while (true) {
0726:                    token = peek();
0727:
0728:                    if (token.getID() == Token.OR) {
0729:                        read();
0730:                        Expression right = parseAndExpression(read());
0731:                        info = info.setEndPosition(right.getSourceInfo());
0732:                        expr = new OrExpression(info, token, expr, right);
0733:                    } else {
0734:                        break loop;
0735:                    }
0736:                }
0737:
0738:                return expr;
0739:            }
0740:
0741:            private Expression parseAndExpression(Token token)
0742:                    throws IOException {
0743:                SourceInfo info = token.getSourceInfo();
0744:                Expression expr = parseEqualityExpression(token);
0745:
0746:                loop: while (true) {
0747:                    token = peek();
0748:
0749:                    if (token.getID() == Token.AND) {
0750:                        read();
0751:                        Expression right = parseEqualityExpression(read());
0752:                        info = info.setEndPosition(right.getSourceInfo());
0753:                        expr = new AndExpression(info, token, expr, right);
0754:                    } else {
0755:                        break loop;
0756:                    }
0757:                }
0758:
0759:                return expr;
0760:            }
0761:
0762:            private Expression parseEqualityExpression(Token token)
0763:                    throws IOException {
0764:
0765:                SourceInfo info = token.getSourceInfo();
0766:                Expression expr = parseRelationalExpression(token);
0767:
0768:                loop: while (true) {
0769:                    token = peek();
0770:
0771:                    switch (token.getID()) {
0772:                    case Token.ASSIGN:
0773:                        error("equality.misuse.assign", token);
0774:                        token = new Token(token.getSourceInfo(), Token.EQ);
0775:                    case Token.EQ:
0776:                    case Token.NE:
0777:                        read();
0778:                        Expression right = parseRelationalExpression(read());
0779:                        info = info.setEndPosition(right.getSourceInfo());
0780:                        expr = new RelationalExpression(info, token, expr,
0781:                                right);
0782:                        break;
0783:                    default:
0784:                        break loop;
0785:                    }
0786:                }
0787:
0788:                return expr;
0789:            }
0790:
0791:            private Expression parseRelationalExpression(Token token)
0792:                    throws IOException {
0793:
0794:                SourceInfo info = token.getSourceInfo();
0795:                Expression expr = parseConcatenateExpression(token);
0796:
0797:                loop: while (true) {
0798:                    token = peek();
0799:
0800:                    switch (token.getID()) {
0801:                    case Token.LT:
0802:                    case Token.GT:
0803:                    case Token.LE:
0804:                    case Token.GE:
0805:                        read();
0806:                        Expression right = parseConcatenateExpression(read());
0807:                        info = info.setEndPosition(right.getSourceInfo());
0808:                        expr = new RelationalExpression(info, token, expr,
0809:                                right);
0810:                        break;
0811:                    case Token.ISA:
0812:                        read();
0813:                        TypeName typeName = parseTypeName();
0814:                        info = info.setEndPosition(typeName.getSourceInfo());
0815:                        expr = new RelationalExpression(info, token, expr,
0816:                                typeName);
0817:                        break;
0818:                    default:
0819:                        break loop;
0820:                    }
0821:                }
0822:
0823:                return expr;
0824:            }
0825:
0826:            private Expression parseConcatenateExpression(Token token)
0827:                    throws IOException {
0828:
0829:                SourceInfo info = token.getSourceInfo();
0830:                Expression expr = parseAdditiveExpression(token);
0831:
0832:                loop: while (true) {
0833:                    token = peek();
0834:
0835:                    if (token.getID() == Token.CONCAT) {
0836:                        read();
0837:                        Expression right = parseAdditiveExpression(read());
0838:                        info = info.setEndPosition(right.getSourceInfo());
0839:                        expr = new ConcatenateExpression(info, token, expr,
0840:                                right);
0841:                    } else {
0842:                        break loop;
0843:                    }
0844:                }
0845:
0846:                return expr;
0847:            }
0848:
0849:            private Expression parseAdditiveExpression(Token token)
0850:                    throws IOException {
0851:
0852:                SourceInfo info = token.getSourceInfo();
0853:                Expression expr = parseMultiplicativeExpression(token);
0854:
0855:                loop: while (true) {
0856:                    token = peek();
0857:
0858:                    switch (token.getID()) {
0859:                    case Token.PLUS:
0860:                    case Token.MINUS:
0861:                        read();
0862:                        Expression right = parseMultiplicativeExpression(read());
0863:                        info = info.setEndPosition(right.getSourceInfo());
0864:                        expr = new ArithmeticExpression(info, token, expr,
0865:                                right);
0866:                        break;
0867:                    default:
0868:                        break loop;
0869:                    }
0870:                }
0871:
0872:                return expr;
0873:            }
0874:
0875:            private Expression parseMultiplicativeExpression(Token token)
0876:                    throws IOException {
0877:
0878:                SourceInfo info = token.getSourceInfo();
0879:                Expression expr = parseUnaryExpression(token);
0880:
0881:                loop: while (true) {
0882:                    token = peek();
0883:
0884:                    switch (token.getID()) {
0885:                    case Token.MULT:
0886:                    case Token.DIV:
0887:                    case Token.MOD:
0888:                        read();
0889:                        Expression right = parseUnaryExpression(read());
0890:                        info = info.setEndPosition(right.getSourceInfo());
0891:                        expr = new ArithmeticExpression(info, token, expr,
0892:                                right);
0893:                        break;
0894:                    default:
0895:                        break loop;
0896:                    }
0897:                }
0898:
0899:                return expr;
0900:            }
0901:
0902:            private Expression parseUnaryExpression(Token token)
0903:                    throws IOException {
0904:                SourceInfo info;
0905:                Expression expr;
0906:
0907:                switch (token.getID()) {
0908:                case Token.NOT:
0909:                    info = token.getSourceInfo();
0910:                    expr = parseUnaryExpression(read());
0911:                    info = info.setEndPosition(expr.getSourceInfo());
0912:                    return new NotExpression(info, expr);
0913:                case Token.MINUS:
0914:                    info = token.getSourceInfo();
0915:                    expr = parseUnaryExpression(read());
0916:                    info = info.setEndPosition(expr.getSourceInfo());
0917:                    return new NegateExpression(info, expr);
0918:                }
0919:
0920:                return parseLookup(token);
0921:            }
0922:
0923:            private Expression parseLookup(Token token) throws IOException {
0924:
0925:                SourceInfo info = token.getSourceInfo();
0926:                Expression expr = parseFactor(token);
0927:
0928:                while (true) {
0929:                    token = peek();
0930:
0931:                    if (token.getID() == Token.DOT) {
0932:                        // "dot" lookup i.e.: a.b
0933:
0934:                        Token dot = read(); // read the dot
0935:
0936:                        token = read();
0937:
0938:                        Name lookupName;
0939:                        SourceInfo nameInfo = token.getSourceInfo();
0940:                        if (token.getID() != Token.IDENT) {
0941:                            if (token.isReservedWord()) {
0942:                                error("lookup.reserved.word", token.getImage(),
0943:                                        token);
0944:                                lookupName = new Name(nameInfo, token
0945:                                        .getImage());
0946:                            } else {
0947:                                error("lookup.identifier.expected", token);
0948:                                lookupName = new Name(nameInfo, null);
0949:                            }
0950:                        } else {
0951:                            lookupName = new Name(nameInfo, token
0952:                                    .getStringValue());
0953:                            info = info.setEndPosition(nameInfo);
0954:                        }
0955:
0956:                        expr = new Lookup(info, expr, dot, lookupName);
0957:                    } else if (token.getID() == Token.LBRACK) {
0958:                        // array lookup i.e.: a[b]
0959:
0960:                        Token lbrack = read(); // read the left bracket
0961:
0962:                        token = read();
0963:
0964:                        if (token.getID() == Token.RBRACK) {
0965:                            info = info.setEndPosition(token.getSourceInfo());
0966:
0967:                            error("lookup.empty.brackets", token);
0968:
0969:                            expr = new ArrayLookup(info, expr, lbrack,
0970:                                    new Expression(info));
0971:
0972:                            continue;
0973:                        }
0974:
0975:                        Expression arrayLookup = parseExpression(token);
0976:
0977:                        token = peek();
0978:
0979:                        if (token.getID() == Token.RBRACK) {
0980:                            read(); // read the right bracket
0981:                            info = info.setEndPosition(token.getSourceInfo());
0982:                        } else {
0983:                            error("lookup.rbracket.expected", token);
0984:                            info = info.setEndPosition(arrayLookup
0985:                                    .getSourceInfo());
0986:                        }
0987:
0988:                        expr = new ArrayLookup(info, expr, lbrack, arrayLookup);
0989:                    } else {
0990:                        break;
0991:                    }
0992:                }
0993:
0994:                return expr;
0995:            }
0996:
0997:            private Expression parseFactor(Token token) throws IOException {
0998:                SourceInfo info = token.getSourceInfo();
0999:                Token value;
1000:
1001:                switch (token.getID()) {
1002:                case Token.HASH:
1003:                case Token.DOUBLE_HASH:
1004:                    return parseNewArrayExpression(token);
1005:
1006:                case Token.LPAREN:
1007:                    Expression expr;
1008:
1009:                    token = peek();
1010:                    if (token.getID() == Token.RPAREN) {
1011:                        expr = null;
1012:                    } else {
1013:                        expr = parseExpression(read());
1014:                    }
1015:
1016:                    token = peek();
1017:                    if (token.getID() == Token.RPAREN) {
1018:                        read(); // read the right paren
1019:                        info = info.setEndPosition(token.getSourceInfo());
1020:                    } else {
1021:                        error("factor.rparen.expected", token);
1022:                        info = info.setEndPosition(expr.getSourceInfo());
1023:                    }
1024:
1025:                    if (expr == null) {
1026:                        error("factor.empty.parens", info);
1027:                        expr = new Expression(info);
1028:                    }
1029:
1030:                    return new ParenExpression(info, expr);
1031:
1032:                case Token.NULL:
1033:                    return new NullLiteral(info);
1034:
1035:                case Token.TRUE:
1036:                    return new BooleanLiteral(info, true);
1037:
1038:                case Token.FALSE:
1039:                    return new BooleanLiteral(info, false);
1040:
1041:                case Token.CALL:
1042:                    Name target = parseName();
1043:                    info.setEndPosition(target.getSourceInfo());
1044:
1045:                    ExpressionList list = parseList(false);
1046:                    info = info.setEndPosition(list.getSourceInfo());
1047:
1048:                    // Check if a block is being passed in the call.
1049:                    Block subParam = null;
1050:                    if (peek().getID() == Token.LBRACE) {
1051:                        subParam = parseBlock();
1052:                        info = info.setEndPosition(subParam.getSourceInfo());
1053:                    }
1054:
1055:                    return new TemplateCallExpression(info, target, list,
1056:                            subParam);
1057:
1058:                case Token.NUMBER:
1059:                    if (token.getNumericType() == 0) {
1060:                        error("factor.number.invalid", token);
1061:                    }
1062:
1063:                    switch (token.getNumericType()) {
1064:                    case 1:
1065:                        return new NumberLiteral(info, token.getIntValue());
1066:                    case 2:
1067:                        return new NumberLiteral(info, token.getLongValue());
1068:                    case 3:
1069:                        return new NumberLiteral(info, token.getFloatValue());
1070:                    case 4:
1071:                    default:
1072:                        return new NumberLiteral(info, token.getDoubleValue());
1073:                    }
1074:
1075:                case Token.STRING:
1076:                    return new StringLiteral(info, token.getStringValue());
1077:
1078:                case Token.IDENT:
1079:                    FunctionCallExpression call = parseFunctionCallExpression(token);
1080:                    if (call != null) {
1081:                        return call;
1082:                    } else {
1083:                        return new VariableRef(info, token.getStringValue());
1084:                    }
1085:
1086:                case Token.EOF:
1087:                    error("factor.expression.expected", token);
1088:                    break;
1089:
1090:                case Token.RPAREN:
1091:                    error("factor.rparen.unmatched", token);
1092:                    break;
1093:
1094:                case Token.RBRACE:
1095:                    error("factor.rbrace.unmatched", token);
1096:                    break;
1097:
1098:                case Token.RBRACK:
1099:                    error("factor.rbracket.unmatched", token);
1100:                    break;
1101:
1102:                case Token.ASSIGN:
1103:                    error("factor.illegal.assignment", token);
1104:                    break;
1105:
1106:                case Token.DOTDOT:
1107:                    error("factor.misuse.dotdot", token);
1108:                    break;
1109:
1110:                default:
1111:                    if (token.isReservedWord()) {
1112:                        error("factor.reserved.word", token.getImage(), token);
1113:                    } else {
1114:                        error("factor.unexpected.token", token);
1115:                    }
1116:                    break;
1117:                }
1118:
1119:                return new Expression(token.getSourceInfo());
1120:            }
1121:
1122:            private Expression parseNewArrayExpression(Token token)
1123:                    throws IOException {
1124:
1125:                boolean associative = (token.getID() == Token.DOUBLE_HASH);
1126:
1127:                SourceInfo info = token.getSourceInfo();
1128:                ExpressionList list = parseList(false);
1129:                info = info.setEndPosition(list.getSourceInfo());
1130:                return new NewArrayExpression(info, list, associative);
1131:            }
1132:
1133:            // Special parse method in that it may return null if it couldn't parse
1134:            // a FunctionCallExpression. Token passed in must be an identifier.
1135:            private FunctionCallExpression parseFunctionCallExpression(
1136:                    Token token) throws IOException {
1137:
1138:                SourceInfo info = token.getSourceInfo();
1139:
1140:                // Search for pattern <ident> {<dot> <ident>} <lparen>
1141:                Vector lookahead = new Vector();
1142:                StringBuffer name = new StringBuffer(token.getStringValue());
1143:                Name target = null;
1144:
1145:                while (true) {
1146:                    token = read();
1147:                    lookahead.addElement(token);
1148:
1149:                    if (token.getID() == Token.DOT) {
1150:                        name.append('.');
1151:                        info = info.setEndPosition(token.getSourceInfo());
1152:                    } else if (token.getID() == Token.LPAREN) {
1153:                        target = new Name(info, name.toString());
1154:                        unread(token);
1155:                        break;
1156:                    } else {
1157:                        break;
1158:                    }
1159:
1160:                    token = read();
1161:                    lookahead.addElement(token);
1162:
1163:                    if (token.getID() == Token.IDENT) {
1164:                        name.append(token.getStringValue());
1165:                        info = info.setEndPosition(token.getSourceInfo());
1166:                    } else {
1167:                        break;
1168:                    }
1169:                }
1170:
1171:                if (target == null) {
1172:                    // Pattern not found, unread all lookahead tokens.
1173:                    for (int i = lookahead.size() - 1; i >= 0; --i) {
1174:                        unread((Token) lookahead.elementAt(i));
1175:                    }
1176:                    return null;
1177:                }
1178:
1179:                ExpressionList list = parseList(false);
1180:                info = info.setEndPosition(list.getSourceInfo());
1181:
1182:                // Check if a block is being passed in the call.
1183:                Block subParam = null;
1184:                if (peek().getID() == Token.LBRACE) {
1185:                    subParam = parseBlock();
1186:                    info = info.setEndPosition(subParam.getSourceInfo());
1187:                }
1188:
1189:                return new FunctionCallExpression(info, target, list, subParam);
1190:            }
1191:
1192:            /** Test program */
1193:            public static void main(String[] arg) throws Exception {
1194:                Tester.test(arg);
1195:            }
1196:
1197:            /**************************************************************************
1198:             * 
1199:             * @author Brian S O'Neill
1200:             * @version
1201:             * <!--$$Revision:--> 64 <!-- $--> 36 <!-- $$JustDate:-->  5/31/01 <!-- $-->
1202:             */
1203:            private static class Tester implements  ErrorListener {
1204:                String mFilename;
1205:
1206:                public static void test(String[] arg) throws Exception {
1207:                    new Tester(arg[0]);
1208:                }
1209:
1210:                public Tester(String filename) throws Exception {
1211:                    mFilename = filename;
1212:                    Reader file = new BufferedReader(new FileReader(filename));
1213:                    Scanner scanner = new Scanner(new SourceReader(file, "<%",
1214:                            "%>"));
1215:                    scanner.addErrorListener(this );
1216:                    Parser parser = new Parser(scanner);
1217:                    parser.addErrorListener(this );
1218:                    Template tree = parser.parse();
1219:
1220:                    if (tree != null) {
1221:                        TreePrinter printer = new TreePrinter(tree);
1222:                        printer.writeTo(System.out);
1223:                    }
1224:                }
1225:
1226:                public void compileError(ErrorEvent e) {
1227:                    System.out.println(e.getDetailedErrorMessage());
1228:                }
1229:            }
1230:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.