Source Code Cross Referenced for XQParser.java in  » Scripting » Kawa » gnu » xquery » lang » 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 » Scripting » Kawa » gnu.xquery.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        // Copyright (c) 2001, 2002, 2003, 2004, 2006  Per M.A. Bothner and Brainfood Inc.
0002:        // This is free software;  for terms and warranty disclaimer see ./COPYING.
0003:
0004:        package gnu.xquery.lang;
0005:
0006:        import gnu.kawa.lispexpr.*;
0007:        import gnu.mapping.*;
0008:        import gnu.lists.*;
0009:        import gnu.text.*;
0010:        import gnu.expr.*;
0011:        import gnu.math.IntNum;
0012:        import java.util.Vector;
0013:        import java.util.Stack;
0014:        import java.io.File;
0015:        import gnu.kawa.xml.*;
0016:        import gnu.xml.*;
0017:        import gnu.bytecode.*;
0018:        import gnu.kawa.reflect.OccurrenceType;
0019:        import gnu.kawa.reflect.SingletonType;
0020:        import gnu.kawa.functions.Convert;
0021:        import gnu.xquery.util.NamedCollator;
0022:        import gnu.xquery.util.CastableAs;
0023:        import gnu.xquery.util.QNameUtils;
0024:        import gnu.xquery.util.RelativeStep;
0025:        import gnu.xquery.util.ValuesFilter;
0026:        import kawa.standard.require;
0027:
0028:        /** A class to read xquery forms. */
0029:
0030:        public class XQParser extends Lexer {
0031:            int curToken;
0032:            Object curValue;
0033:
0034:            /** Normally null.
0035:             * 'C' means parsing the type of a 'cast as' or 'castable as'. */
0036:            int parseContext;
0037:            /** True if we've seen a VarDecl, FunctionDecl, or OptionDecl. */
0038:            boolean seenDeclaration;
0039:
0040:            String libraryModuleNamespace;
0041:
0042:            /** Value of getLineNumber() at start of current token.
0043:             * Sometimes set otherwise, to report errors. */
0044:            int curLine;
0045:
0046:            /** Value of getColumnNumber() at start of current token.
0047:             * Sometimes set otherwise, to report errors. */
0048:            int curColumn;
0049:
0050:            XQuery interpreter;
0051:
0052:            int seenPosition;
0053:            int seenLast;
0054:
0055:            public static boolean warnOldVersion = true;
0056:            public static boolean warnHidePreviousDeclaration = false;
0057:
0058:            /** The internal name of the variable containing '.', the context node. */
0059:            static final Symbol DOT_VARNAME = Symbol.makeUninterned("$dot$");
0060:
0061:            /** The pseduo-function position() is mapped to a reference. */
0062:            static final Symbol POSITION_VARNAME = Symbol
0063:                    .makeUninterned("$position$");
0064:
0065:            /** The pseduo-function last() is mapped to a reference to this variable. */
0066:            static final Symbol LAST_VARNAME = Symbol.makeUninterned("$last$");
0067:
0068:            public static final gnu.kawa.reflect.InstanceOf instanceOf = new gnu.kawa.reflect.InstanceOf(
0069:                    XQuery.getInstance(), "instance");
0070:            public static final CastableAs castableAs = CastableAs.castableAs;
0071:            public static final Convert treatAs = Convert.as;
0072:
0073:            NameLookup lexical;
0074:
0075:            NamedCollator defaultCollator = null;
0076:
0077:            /** The default order for empty sequences.
0078:             * Either <code>'L'</code> (for "least") or <code>'G'</code> (for "greatest").
0079:             */
0080:            char defaultEmptyOrder = 'L';
0081:            boolean emptyOrderDeclarationSeen;
0082:
0083:            Path baseURI = null;
0084:            boolean baseURIDeclarationSeen;
0085:
0086:            public void setStaticBaseUri(String uri) {
0087:                try {
0088:                    baseURI = fixupStaticBaseUri(URIPath.valueOf(uri));
0089:                } catch (Throwable ex) {
0090:                    if (ex instanceof  WrappedException)
0091:                        ex = ((WrappedException) ex).getCause();
0092:                    error('e', "invalid URI: " + ex.getMessage());
0093:                }
0094:            }
0095:
0096:            static Path fixupStaticBaseUri(Path path) {
0097:                path = path.getAbsolute();
0098:                if (path instanceof  FilePath)
0099:                    path = URIPath.valueOf(path.toURI());
0100:                return path;
0101:            }
0102:
0103:            public String getStaticBaseUri() {
0104:                Path path = baseURI;
0105:                if (path == null) {
0106:                    Environment env = Environment.getCurrent();
0107:                    Object value = env.get(Symbol.make("", "base-uri"), null,
0108:                            null);
0109:                    if (value != null) {
0110:                        if (value instanceof  Path)
0111:                            path = (Path) path;
0112:                        else
0113:                            path = URIPath.valueOf(value.toString());
0114:                    }
0115:
0116:                    if (path == null) {
0117:                        LineBufferedReader port = getPort();
0118:                        path = port.getPath();
0119:                        if (path instanceof  FilePath
0120:                                && (!path.exists() || port instanceof  TtyInPort || port instanceof  CharArrayInPort))
0121:                            path = null;
0122:                    }
0123:
0124:                    if (path == null)
0125:                        path = Path.currentPath();
0126:
0127:                    path = fixupStaticBaseUri(path);
0128:                    baseURI = path;
0129:                }
0130:
0131:                return path.toString();
0132:            }
0133:
0134:            public String resolveAgainstBaseUri(String uri) {
0135:                if (Path.uriSchemeSpecified(uri))
0136:                    return uri;
0137:                String base = getStaticBaseUri();
0138:                Path basePath = Path.valueOf(base);
0139:                return basePath.resolve(uri).toString();
0140:            }
0141:
0142:            boolean boundarySpacePreserve;
0143:            boolean boundarySpaceDeclarationSeen;
0144:
0145:            boolean orderingModeUnordered;
0146:            boolean orderingModeSeen;
0147:
0148:            /** True if we've seen a 'copy-namespaces' declaration'. */
0149:            boolean copyNamespacesDeclarationSeen;
0150:            int copyNamespacesMode = XMLFilter.COPY_NAMESPACES_PRESERVE
0151:                    | XMLFilter.COPY_NAMESPACES_INHERIT;
0152:
0153:            /** The static construction mode. True if "strip"; false if "preserve". */
0154:            boolean constructionModeStrip;
0155:            /** True if a construction mode declaration has been seen. */
0156:            boolean constructionModeDeclarationSeen;
0157:
0158:            public Namespace[] functionNamespacePath = XQuery.defaultFunctionNamespacePath;
0159:
0160:            /** Stack of currently active for/let Declarations. */
0161:            Declaration[] flworDecls;
0162:            /* Index in flworDecls of first Declaration in current FLWOR. */
0163:            int flworDeclsFirst;
0164:            /* Total number of currently active for/let Declarations. */
0165:            int flworDeclsCount;
0166:
0167:            int parseCount;
0168:            int commentCount;
0169:            /** An error message if comments are disallowed.  Normally null. */
0170:            String errorIfComment;
0171:
0172:            /** Skip whitespace.
0173:             * Sets 'index' to the that of the next non-whitespace character,
0174:             * and returns that.  If there are no more non-space characters,
0175:             * returns ' '.  */
0176:            final int skipSpace() throws java.io.IOException, SyntaxException {
0177:                return skipSpace(true);
0178:            }
0179:
0180:            final int skipSpace(boolean verticalToo)
0181:                    throws java.io.IOException, SyntaxException {
0182:                for (;;) {
0183:                    int ch = read();
0184:                    if (ch == '(') {
0185:                        if (!checkNext(':'))
0186:                            return '(';
0187:                        skipComment();
0188:                    } else if (ch == '{') {
0189:                        ch = read();
0190:                        if (ch != '-') {
0191:                            unread(ch);
0192:                            return '{';
0193:                        }
0194:                        ch = read();
0195:                        if (ch != '-') {
0196:                            unread(ch);
0197:                            unread('-');
0198:                            return '{';
0199:                        }
0200:                        skipOldComment();
0201:                    } else if (verticalToo ? (ch < 0 || !Character
0202:                            .isWhitespace((char) ch))
0203:                            : (ch != ' ' && ch != '\t'))
0204:                        return ch;
0205:                }
0206:            }
0207:
0208:            final void skipToSemicolon() throws java.io.IOException {
0209:                for (;;) {
0210:                    int next = read();
0211:                    if (next < 0 || next == ';')
0212:                        break;
0213:                }
0214:            }
0215:
0216:            final void skipOldComment() throws java.io.IOException,
0217:                    SyntaxException {
0218:                int seenDashes = 0;
0219:                int startLine = getLineNumber() + 1;
0220:                int startColumn = getColumnNumber() - 2;
0221:                warnOldVersion("use (: :) instead of old-style comment {-- --}");
0222:                for (;;) {
0223:                    int ch = read();
0224:                    if (ch == '-')
0225:                        seenDashes++;
0226:                    else if (ch == '}' && seenDashes >= 2)
0227:                        return;
0228:                    else if (ch < 0) {
0229:                        curLine = startLine;
0230:                        curColumn = startColumn;
0231:                        eofError("non-terminated comment starting here");
0232:                    } else
0233:                        seenDashes = 0;
0234:                }
0235:            }
0236:
0237:            final void skipComment() throws java.io.IOException,
0238:                    SyntaxException {
0239:                commentCount++;
0240:                int startLine = getLineNumber() + 1;
0241:                int startColumn = getColumnNumber() - 1;
0242:                if (errorIfComment != null) {
0243:                    curLine = startLine;
0244:                    curColumn = startColumn;
0245:                    error('e', errorIfComment);
0246:                }
0247:                int prev = 0;
0248:                int commentNesting = 0;
0249:                char saveReadState = pushNesting(':');
0250:                for (;;) {
0251:                    int ch = read();
0252:                    if (ch == ':') {
0253:                        if (prev == '(') {
0254:                            commentNesting++;
0255:                            ch = 0;
0256:                        }
0257:                    } else if (ch == ')' && prev == ':') {
0258:                        if (commentNesting == 0) {
0259:                            popNesting(saveReadState);
0260:                            return;
0261:                        }
0262:                        --commentNesting;
0263:                    } else if (ch < 0) {
0264:                        curLine = startLine;
0265:                        curColumn = startColumn;
0266:                        eofError("non-terminated comment starting here");
0267:                    }
0268:                    prev = ch;
0269:                }
0270:            }
0271:
0272:            /** Do skipSpace followed by unread to find next non-space character. */
0273:            final int peekNonSpace(String message) throws java.io.IOException,
0274:                    SyntaxException {
0275:                int ch = skipSpace();
0276:                if (ch < 0)
0277:                    eofError(message);
0278:                unread(ch);
0279:                return ch;
0280:            }
0281:
0282:            static final int EOF_TOKEN = -1;
0283:            static final int EOL_TOKEN = '\n';
0284:            static final char INTEGER_TOKEN = '0';
0285:            static final char DECIMAL_TOKEN = '1';
0286:            static final char DOUBLE_TOKEN = '2';
0287:            static final int STRING_TOKEN = '"';
0288:            static final int SLASHSLASH_TOKEN = 'D';
0289:            static final int DOTDOT_TOKEN = '3';
0290:            static final int COLON_EQUAL_TOKEN = 'L'; // ":="
0291:            static final int COLON_COLON_TOKEN = 'X';
0292:
0293:            /** A non-qualified (simple) name (NCName).
0294:             * The tokenBuffer contains the name (which does not contain a ':'). */
0295:            static final int NCNAME_TOKEN = 'A';
0296:
0297:            /** A non-qualified (simple) name (NCName) followed by a colon.
0298:             * The colon is not followed by another NCNAME (in which it would
0299:             * be a QNAME_TOKEN instead).
0300:             * The tokenBuffer contains the name (which does not contain the ':'). */
0301:            static final int NCNAME_COLON_TOKEN = 'C';
0302:
0303:            /** A Qualified name (QName).
0304:             * The tokenBuffer contains the full name, which contains one ':'. */
0305:            static final int QNAME_TOKEN = 'Q';
0306:
0307:            static final int ARROW_TOKEN = 'R';
0308:
0309:            /* FuncName including following '('). */
0310:            static final int FNAME_TOKEN = 'F';
0311:
0312:            static final int IMPORT_MODULE_TOKEN = 'I'; // <"import" "module">
0313:            static final int IMPORT_SCHEMA_TOKEN = 'T'; // <"import" "schema">
0314:            static final int MODULE_NAMESPACE_TOKEN = 'M'; // <"module" "namespace">
0315:            static final int DECLARE_NAMESPACE_TOKEN = 'N'; // <"declare" "namespace">
0316:            static final int DECLARE_BOUNDARY_SPACE_TOKEN = 'S'; // <"declare" "boundary-space">
0317:            static final int DEFAULT_ELEMENT_TOKEN = 'E'; // <"declare" "default" "element">
0318:            static final int DEFAULT_FUNCTION_TOKEN = 'O'; // <"declare" "default" "function">
0319:            static final int DEFAULT_COLLATION_TOKEN = 'G';
0320:            static final int DEFAULT_ORDER_TOKEN = 'H'; // <"declare" "default" "order">
0321:
0322:            static final int DECLARE_FUNCTION_TOKEN = 'P'; // <"declare" "function">
0323:            static final int DECLARE_VARIABLE_TOKEN = 'V'; // <"declare" "variable">
0324:            static final int DECLARE_BASE_URI_TOKEN = 'B'; // <"declare" "base-uri">
0325:            static final int DECLARE_ORDERING_TOKEN = 'U'; // <"declare" "ordering">
0326:            static final int DECLARE_CONSTRUCTION_TOKEN = 'K'; // <"declare" "construction">
0327:            static final int DECLARE_OPTION_TOKEN = 'o'; // <"declare" "option">
0328:            static final int DECLARE_COPY_NAMESPACES_TOKEN = 'L'; // <"declare" "copy-namespaces">
0329:            static final int DEFINE_QNAME_TOKEN = 'W'; // <"define" QName> - an error
0330:            static final int XQUERY_VERSION_TOKEN = 'Y'; // <"xquery" "version">
0331:
0332:            /* 'Q': QName (intern'ed name is curValue)
0333:             * 'R': NCName ':' '*'
0334:             * OP_AXIS_FIRST: 'ancestor' followed by '::'
0335:             * ...
0336:             * OP_AXIS_FIRST+AXIS_SELF: 'self' followed by '::'
0337:             */
0338:
0339:            static final int OP_AXIS_FIRST = 100;
0340:            static final int COUNT_OP_AXIS = 13;
0341:            static final int AXIS_ANCESTOR = 0;
0342:            static final int AXIS_ANCESTOR_OR_SELF = 1;
0343:            static final int AXIS_ATTRIBUTE = 2;
0344:            static final int AXIS_CHILD = 3;
0345:            static final int AXIS_DESCENDANT = 4;
0346:            static final int AXIS_DESCENDANT_OR_SELF = 5;
0347:            static final int AXIS_FOLLOWING = 6;
0348:            static final int AXIS_FOLLOWING_SIBLING = 7;
0349:            static final int AXIS_NAMESPACE = 8;
0350:            static final int AXIS_PARENT = 9;
0351:            static final int AXIS_PRECEDING = 10;
0352:            static final int AXIS_PRECEDING_SIBLING = 11;
0353:            static final int AXIS_SELF = 12;
0354:            static final int OP_WHERE = 196;
0355:            static final int PRAGMA_START_TOKEN = 197; // '{#'
0356:            // Token types for binary operators.
0357:            static final int OP_BASE = 400;
0358:            static final int OP_OR = OP_BASE; // 'or'
0359:            static final int OP_AND = OP_BASE + 1; // 'and'
0360:            static final int OP_EQU = OP_BASE + 2; // ' ='
0361:            static final int OP_NEQ = OP_BASE + 3; // '! ='
0362:            static final int OP_LSS = OP_BASE + 4; // '<'
0363:            static final int OP_GRT = OP_BASE + 5; // '>'
0364:            static final int OP_LEQ = OP_BASE + 6; // '< ='
0365:            static final int OP_GEQ = OP_BASE + 7; // '> ='
0366:            static final int OP_IS = OP_BASE + 8; // 'is'
0367:            static final int OP_ISNOT = OP_BASE + 9; // 'isnot'
0368:            static final int OP_GRTGRT = OP_BASE + 10; // '>>'
0369:            static final int OP_LSSLSS = OP_BASE + 11; // '<<'
0370:
0371:            static final int OP_RANGE_TO = OP_BASE + 12; // 'to'
0372:
0373:            static final int OP_ADD = OP_BASE + 13; // '+'
0374:            static final int OP_SUB = OP_BASE + 14; // '-'
0375:
0376:            static final int OP_MUL = OP_BASE + 15; // '*'
0377:            static final int OP_DIV = OP_BASE + 16; // 'div'
0378:            static final int OP_IDIV = OP_BASE + 17; // 'idiv'
0379:            static final int OP_MOD = OP_BASE + 18; // 'mod'
0380:
0381:            static final int OP_UNION = OP_BASE + 19; // 'union'
0382:
0383:            static final int OP_INTERSECT = OP_BASE + 20; // 'intersect'
0384:            static final int OP_EXCEPT = OP_BASE + 21; // 'except'
0385:
0386:            static final int OP_INSTANCEOF = OP_BASE + 22; // 'instance' 'of'
0387:            static final int OP_TREAT_AS = OP_BASE + 23; // 'treat' 'as'
0388:            static final int OP_CASTABLE_AS = OP_BASE + 24; // 'castable' 'as'
0389:            static final int OP_CAST_AS = OP_BASE + 25; // 'cast' 'as'
0390:
0391:            static final int OP_EQ = OP_BASE + 26; // 'eq'
0392:            static final int OP_NE = OP_BASE + 27; // 'ne'
0393:            static final int OP_LT = OP_BASE + 28; // 'lt'
0394:            static final int OP_LE = OP_BASE + 29; // 'le
0395:            static final int OP_GT = OP_BASE + 30; // 'gt'
0396:            static final int OP_GE = OP_BASE + 31; // 'ge'
0397:
0398:            static final int OP_NODE = 230; // 'node' followed by '('
0399:            static final int OP_TEXT = 231; // 'text' followed by '('
0400:            static final int OP_COMMENT = 232; // 'comment' followed by '('
0401:            static final int OP_PI = 233; // 'processing-instruction' '('
0402:            static final int OP_DOCUMENT = 234; // 'document-node' '('
0403:            static final int OP_ELEMENT = 235; // 'element' '('
0404:            static final int OP_ATTRIBUTE = 236; // 'attribute' '('
0405:            static final int OP_ITEM = 237; // 'item' '('
0406:            static final int OP_EMPTY_SEQUENCE = 238; // 'empty-sequence' '('
0407:            static final int OP_SCHEMA_ATTRIBUTE = 239; // 'schema-attribute' '('
0408:            static final int OP_SCHEMA_ELEMENT = 240; // 'schema-element' '('
0409:            static final int IF_LPAREN_TOKEN = 241; // 'if' '('
0410:            static final int TYPESWITCH_LPAREN_TOKEN = 242; // 'typeswitch' '('
0411:
0412:            static final int FOR_DOLLAR_TOKEN = 243; // 'for' '$'
0413:            static final int LET_DOLLAR_TOKEN = 244; // 'let' '$'
0414:            static final int SOME_DOLLAR_TOKEN = 245; // 'some' '$'
0415:            static final int EVERY_DOLLAR_TOKEN = 246; // 'every' '$'
0416:            static final int CASE_DOLLAR_TOKEN = 247; // 'case' '$'
0417:            static final int VALIDATE_LBRACE_TOKEN = 248; // 'validate' '{'
0418:            static final int ORDERED_LBRACE_TOKEN = 249; // 'ordered' '{'
0419:            static final int UNORDERED_LBRACE_TOKEN = 250; // 'unordered' '{'
0420:            static final int ELEMENT_TOKEN = 251; // 'element' followed by '{' or alpha
0421:            static final int ATTRIBUTE_TOKEN = 252;// 'attribute' followed by '{' or alpha
0422:            static final int TEXT_TOKEN = 253; // 'text' followed by '{'
0423:            static final int COMMENT_TOKEN = 254; // 'text' followed by '{'
0424:            static final int PI_TOKEN = 255; // 'processing-instruction' followed by '{' or alpha
0425:            static final int DOCUMENT_TOKEN = 256; // ;document' followed by '{'
0426:
0427:            private int saveToken;
0428:            private Object saveValue;
0429:
0430:            public void mark() throws java.io.IOException {
0431:                super .mark();
0432:                saveToken = curToken;
0433:                saveValue = curValue;
0434:            }
0435:
0436:            public void reset() throws java.io.IOException {
0437:                curToken = saveToken;
0438:                curValue = saveValue;
0439:                super .reset();
0440:            }
0441:
0442:            private int setToken(int token, int width) {
0443:                curToken = token;
0444:                curLine = port.getLineNumber() + 1;
0445:                curColumn = port.getColumnNumber() + 1 - width;
0446:                return token;
0447:            }
0448:
0449:            void checkSeparator(char ch) {
0450:                if (XName.isNameStart(ch))
0451:                    error('e', "missing separator", "XPST0003");
0452:            }
0453:
0454:            int getRawToken() throws java.io.IOException, SyntaxException {
0455:                int next;
0456:                for (;;) {
0457:                    next = read();
0458:                    if (next < 0)
0459:                        return setToken(EOF_TOKEN, 0);
0460:                    if (next == '\n' || next == '\r') {
0461:                        if (nesting <= 0)
0462:                            return setToken(EOL_TOKEN, 0);
0463:                    } else if (next == '(') {
0464:                        if (checkNext(':'))
0465:                            skipComment();
0466:                        else if (checkNext('#'))
0467:                            return setToken(PRAGMA_START_TOKEN, 2);
0468:                        else
0469:                            return setToken('(', 1);
0470:                    } else if (next == '{') {
0471:                        if (!checkNext('-'))
0472:                            return setToken('{', 1);
0473:                        next = read();
0474:                        if (next != '-') {
0475:                            // FIXME backup 2 chars. Can fix using special token for '{-'.
0476:                            unread();
0477:                            unread();
0478:                            return setToken('{', 1);
0479:                        }
0480:                        skipOldComment();
0481:                    } else if (next != ' ' && next != '\t')
0482:                        break;
0483:                }
0484:                tokenBufferLength = 0;
0485:                curLine = port.getLineNumber() + 1;
0486:                curColumn = port.getColumnNumber();
0487:                char ch = (char) next;
0488:                switch (ch) {
0489:                case ')':
0490:                case '[':
0491:                case ']':
0492:                case '}':
0493:                case '$':
0494:                case '@':
0495:                case ',':
0496:                case '?':
0497:                case ';':
0498:                    break;
0499:                case ':':
0500:                    if (checkNext('='))
0501:                        ch = COLON_EQUAL_TOKEN;
0502:                    else if (checkNext(':'))
0503:                        ch = COLON_COLON_TOKEN;
0504:                    break;
0505:                case '|':
0506:                    ch = OP_UNION;
0507:                    break;
0508:                case '*':
0509:                    ch = OP_MUL;
0510:                    break;
0511:                case '+':
0512:                    ch = OP_ADD;
0513:                    break;
0514:                case '-':
0515:                    ch = OP_SUB;
0516:                    break;
0517:                case '!':
0518:                    if (checkNext('='))
0519:                        ch = OP_NEQ;
0520:                    break;
0521:                case '/':
0522:                    if (checkNext('/'))
0523:                        ch = SLASHSLASH_TOKEN;
0524:                    break;
0525:                case '=':
0526:                    if (checkNext('>'))
0527:                        ch = ARROW_TOKEN;
0528:                    ch = OP_EQU;
0529:                    break;
0530:                case '>':
0531:                    ch = checkNext('=') ? (char) OP_GEQ
0532:                            : checkNext('>') ? (char) OP_GRTGRT : (char) OP_GRT;
0533:                    break;
0534:                case '<':
0535:                    ch = checkNext('=') ? (char) OP_LEQ
0536:                            : checkNext('<') ? (char) OP_LSSLSS : (char) OP_LSS;
0537:                    break;
0538:                case '\'':
0539:                case '\"':
0540:                    char saveReadState = pushNesting((char) next);
0541:                    for (;;) {
0542:                        next = read();
0543:                        if (next < 0)
0544:                            eofError("unexpected end-of-file in string starting here");
0545:                        if (next == '&') {
0546:                            parseEntityOrCharRef();
0547:                            continue;
0548:                        } else if (ch == next) {
0549:                            next = read();
0550:                            if (ch != next) {
0551:                                unread(next);
0552:                                break;
0553:                            }
0554:                        }
0555:                        tokenBufferAppend((char) next);
0556:                    }
0557:                    popNesting(saveReadState);
0558:                    ch = STRING_TOKEN;
0559:                    break;
0560:                default:
0561:                    if (Character.isDigit(ch)
0562:                            || (ch == '.' && Character.isDigit((char) peek()))) {
0563:                        boolean seenDot = ch == '.';
0564:                        for (;;) {
0565:                            tokenBufferAppend(ch);
0566:                            next = read();
0567:                            if (next < 0)
0568:                                break;
0569:                            ch = (char) next;
0570:                            if (ch == '.') {
0571:                                if (seenDot)
0572:                                    break;
0573:                                seenDot = true;
0574:                            } else if (!Character.isDigit(ch))
0575:                                break;
0576:                        }
0577:                        if (next == 'e' || next == 'E') {
0578:                            tokenBufferAppend((char) next);
0579:                            next = read();
0580:                            if (next == '+' || next == '-') {
0581:                                tokenBufferAppend((char) next);
0582:                                next = read();
0583:                            }
0584:                            int expDigits = 0;
0585:                            for (;;) {
0586:                                if (next < 0)
0587:                                    break;
0588:                                ch = (char) next;
0589:                                if (!Character.isDigit(ch)) {
0590:                                    checkSeparator(ch);
0591:                                    unread();
0592:                                    break;
0593:                                }
0594:                                tokenBufferAppend(ch);
0595:                                next = read();
0596:                                expDigits++;
0597:                            }
0598:                            if (expDigits == 0)
0599:                                error('e', "no digits following exponent",
0600:                                        "XPST0003");
0601:                            ch = DOUBLE_TOKEN;
0602:                        } else {
0603:                            ch = seenDot ? DECIMAL_TOKEN : INTEGER_TOKEN;
0604:                            if (next >= 0) {
0605:                                checkSeparator((char) next);
0606:                                unread(next);
0607:                            }
0608:                        }
0609:                    } else if (ch == '.') {
0610:                        if (checkNext('.'))
0611:                            ch = DOTDOT_TOKEN;
0612:                        break;
0613:                    } else if (XName.isNameStart(ch)) {
0614:                        for (;;) {
0615:                            tokenBufferAppend(ch);
0616:                            next = read();
0617:                            ch = (char) next;
0618:                            if (!XName.isNamePart(ch))
0619:                                break;
0620:                        }
0621:                        if (next < 0)
0622:                            ch = NCNAME_TOKEN;
0623:                        else {
0624:                            if (next != ':')
0625:                                ch = NCNAME_TOKEN;
0626:                            else {
0627:                                next = read();
0628:                                if (next < 0)
0629:                                    eofError("unexpected end-of-file after NAME ':'");
0630:                                ch = (char) next;
0631:                                if (XName.isNameStart(ch)) {
0632:                                    tokenBufferAppend(':');
0633:                                    for (;;) {
0634:                                        tokenBufferAppend(ch);
0635:                                        next = read();
0636:                                        ch = (char) next;
0637:                                        if (!XName.isNamePart(ch))
0638:                                            break;
0639:                                    }
0640:                                    ch = QNAME_TOKEN;
0641:                                } else if (ch == '=') {
0642:                                    unread(ch);
0643:                                    ch = NCNAME_TOKEN;
0644:                                } else
0645:                                    ch = NCNAME_COLON_TOKEN;
0646:                            }
0647:                            unread(next);
0648:                        }
0649:                    } else if (ch >= ' ' && ch < 127)
0650:                        syntaxError("invalid character '" + ch + '\'');
0651:                    else
0652:                        syntaxError("invalid character '\\u"
0653:                                + Integer.toHexString(ch) + '\'');
0654:                }
0655:                curToken = ch;
0656:                return ch;
0657:            }
0658:
0659:            /** Scan until a given delimiter.
0660:             * On success, text upto the delimiter is in then tokenBuffer (with
0661:             * tokenBufferLength marking its length); the delimiter is not included.
0662:             */
0663:            public void getDelimited(String delimiter)
0664:                    throws java.io.IOException, SyntaxException {
0665:                tokenBufferLength = 0;
0666:                int dlen = delimiter.length();
0667:                char last = delimiter.charAt(dlen - 1);
0668:                for (;;) {
0669:                    int ch = read();
0670:                    if (ch < 0)
0671:                        eofError("unexpected end-of-file looking for '"
0672:                                + delimiter + '\'');
0673:                    int dstart, j;
0674:                    // Look for a match for the last delimiter character.
0675:                    if (ch == last
0676:                            && (dstart = tokenBufferLength - (j = dlen - 1)) >= 0) {
0677:                        // Check that the initial part of the delimiter has also been seen.
0678:                        do {
0679:                            if (j == 0) {
0680:                                tokenBufferLength = dstart;
0681:                                return;
0682:                            }
0683:                            j--;
0684:                        } while (tokenBuffer[dstart + j] == delimiter.charAt(j));
0685:                    }
0686:                    tokenBufferAppend((char) ch);
0687:                }
0688:            }
0689:
0690:            public void appendNamedEntity(String name) {
0691:                name = name.intern();
0692:                char ch = '?';
0693:                if (name == "lt")
0694:                    ch = '<';
0695:                else if (name == "gt")
0696:                    ch = '>';
0697:                else if (name == "amp")
0698:                    ch = '&';
0699:                else if (name == "quot")
0700:                    ch = '"';
0701:                else if (name == "apos")
0702:                    ch = '\'';
0703:                else
0704:                    error("unknown enity reference: '" + name + "'");
0705:                tokenBufferAppend(ch);
0706:            }
0707:
0708:            boolean match(String word1, String word2, boolean force)
0709:                    throws java.io.IOException, SyntaxException {
0710:                if (match(word1)) {
0711:                    mark();
0712:                    getRawToken();
0713:                    if (match(word2)) {
0714:                        reset();
0715:                        getRawToken();
0716:                        return true;
0717:                    }
0718:                    reset();
0719:                    if (force) {
0720:                        error('e', "'" + word1 + "' must be followed by '"
0721:                                + word2 + "'", "XPST0003");
0722:                        return true;
0723:                    }
0724:                }
0725:                return false;
0726:            }
0727:
0728:            /** Return the current token, assuming it is in operator context.
0729:             * Resolve NCNAME_TOKEN (identifier) to 'and', 'or', 'div', etc.
0730:             */
0731:            int peekOperator() throws java.io.IOException, SyntaxException {
0732:                while (curToken == EOL_TOKEN) {
0733:                    if (nesting == 0)
0734:                        return EOL_TOKEN;
0735:                    getRawToken();
0736:                }
0737:                if (curToken == NCNAME_TOKEN) {
0738:                    int len = tokenBufferLength;
0739:                    char c1, c2, c3;
0740:                    switch (len) {
0741:                    case 2:
0742:                        c1 = tokenBuffer[0];
0743:                        c2 = tokenBuffer[1];
0744:                        if (c1 == 'o' && c2 == 'r')
0745:                            curToken = OP_OR;
0746:                        else if (c1 == 't' && c2 == 'o')
0747:                            curToken = OP_RANGE_TO;
0748:                        else if (c1 == 'i' && c2 == 's')
0749:                            curToken = OP_IS;
0750:                        else if (c1 == 'e' && c2 == 'q')
0751:                            curToken = OP_EQ;
0752:                        else if (c1 == 'n' && c2 == 'e')
0753:                            curToken = OP_NE;
0754:                        else if (c1 == 'g') {
0755:                            if (c2 == 'e')
0756:                                curToken = OP_GE;
0757:                            else if (c2 == 't')
0758:                                curToken = OP_GT;
0759:                        } else if (c1 == 'l') {
0760:                            if (c2 == 'e')
0761:                                curToken = OP_LE;
0762:                            else if (c2 == 't')
0763:                                curToken = OP_LT;
0764:                        }
0765:                        break;
0766:
0767:                    case 3:
0768:                        c1 = tokenBuffer[0];
0769:                        c2 = tokenBuffer[1];
0770:                        c3 = tokenBuffer[2];
0771:                        if (c1 == 'a') {
0772:                            if (c2 == 'n' && c3 == 'd')
0773:                                curToken = OP_AND;
0774:                        } else if (c1 == 'm') {
0775:                            if (c2 == 'u' && c3 == 'l')
0776:                                curToken = OP_MUL;
0777:                            if (c2 == 'o' && c3 == 'd')
0778:                                curToken = OP_MOD;
0779:                        } else if (c1 == 'd') {
0780:                            if (c2 == 'i' && c3 == 'v')
0781:                                curToken = OP_DIV;
0782:                        }
0783:                        break;
0784:                    case 4:
0785:                        if (match("idiv"))
0786:                            curToken = OP_IDIV;
0787:                        else if (match("cast", "as", true))
0788:                            curToken = OP_CAST_AS;
0789:                        break;
0790:                    case 5:
0791:                        if (match("where"))
0792:                            curToken = OP_WHERE;
0793:                        else if (match("isnot"))
0794:                            curToken = OP_ISNOT;
0795:                        else if (match("union"))
0796:                            curToken = OP_UNION;
0797:                        else if (match("treat", "as", true))
0798:                            curToken = OP_TREAT_AS;
0799:                        break;
0800:                    case 6:
0801:                        if (match("except"))
0802:                            curToken = OP_EXCEPT;
0803:                        break;
0804:                    case 8:
0805:                        if (match("instance", "of", true))
0806:                            curToken = OP_INSTANCEOF;
0807:                        else if (match("castable", "as", true))
0808:                            curToken = OP_CASTABLE_AS;
0809:                        break;
0810:                    case 9:
0811:                        if (match("intersect"))
0812:                            curToken = OP_INTERSECT;
0813:                        break;
0814:                    case 10:
0815:                        if (match("instanceof")) // obsolete
0816:                        {
0817:                            warnOldVersion("use 'instanceof of' (two words) instead of 'instanceof'");
0818:                            curToken = OP_INSTANCEOF;
0819:                        }
0820:                        break;
0821:                    default:
0822:                        break;
0823:                    }
0824:                }
0825:                return curToken;
0826:            }
0827:
0828:            /**
0829:             * Internal method to match against double-lexeme tokens.
0830:             * @param word0 expected previous word
0831:             * @param word1 expected next word
0832:             */
0833:            private boolean lookingAt(String word0, String word1)
0834:                    throws java.io.IOException, SyntaxException {
0835:                if (!word0.equals(curValue))
0836:                    return false;
0837:                int i = 0;
0838:                int len = word1.length();
0839:                for (;;) {
0840:                    int ch = read();
0841:                    if (i == len) {
0842:                        if (ch < 0)
0843:                            return true;
0844:                        if (!XName.isNamePart((char) ch)) {
0845:                            unread();
0846:                            return true;
0847:                        }
0848:                        i++;
0849:                        break;
0850:                    }
0851:                    if (ch < 0 || ch != word1.charAt(i++))
0852:                        break;
0853:                }
0854:                port.skip(-i);
0855:                return false;
0856:            }
0857:
0858:            int getAxis() {
0859:                // match axis name
0860:                String name = new String(tokenBuffer, 0, tokenBufferLength)
0861:                        .intern();
0862:                int i;
0863:                for (i = COUNT_OP_AXIS; --i >= 0;)
0864:                    if (axisNames[i] == name)
0865:                        break;
0866:                if (i < 0 || i == AXIS_NAMESPACE) // The namespace-axis is XSLT/XPath-only.
0867:                {
0868:                    error('e', "unknown axis name '" + name + '\'', "XPST0003");
0869:                    i = AXIS_CHILD;
0870:                }
0871:                return (char) (OP_AXIS_FIRST + i);
0872:            }
0873:
0874:            /** Process token, assuming we are in operand context.
0875:             */
0876:
0877:            int peekOperand() throws java.io.IOException, SyntaxException {
0878:                while (curToken == EOL_TOKEN)
0879:                    getRawToken();
0880:                if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN) {
0881:                    int next = skipSpace(nesting != 0);
0882:                    switch (tokenBuffer[0]) {
0883:                    case 'a':
0884:                        if (match("attribute")) {
0885:                            if (next == '(')
0886:                                return curToken = OP_ATTRIBUTE;
0887:                            if (next == '{' || XName.isNameStart((char) next)) {
0888:                                unread();
0889:                                return curToken = ATTRIBUTE_TOKEN;
0890:                            }
0891:                            break;
0892:                        }
0893:                        break;
0894:                    case 'c':
0895:                        if (match("comment")) {
0896:                            if (next == '(')
0897:                                return curToken = OP_COMMENT;
0898:                            if (next == '{') {
0899:                                unread();
0900:                                return curToken = COMMENT_TOKEN;
0901:                            }
0902:                        }
0903:                        break;
0904:                    case 'd':
0905:                        if (next == '{' && match("document")) {
0906:                            unread();
0907:                            return curToken = DOCUMENT_TOKEN;
0908:                        }
0909:                        if (next == '(' && match("document-node"))
0910:                            return curToken = OP_DOCUMENT;
0911:                        break;
0912:                    case 'e':
0913:                        if (match("element")) {
0914:                            if (next == '(')
0915:                                return curToken = OP_ELEMENT;
0916:                            if (next == '{' || XName.isNameStart((char) next)) {
0917:                                unread();
0918:                                return curToken = ELEMENT_TOKEN;
0919:                            }
0920:                            break;
0921:                        }
0922:                        if (match("empty-sequence"))
0923:                            return curToken = OP_EMPTY_SEQUENCE;
0924:                        if (next == '$' && match("every"))
0925:                            return curToken = EVERY_DOLLAR_TOKEN;
0926:                        break;
0927:                    case 'f':
0928:                        if (next == '$' && match("for"))
0929:                            return curToken = FOR_DOLLAR_TOKEN;
0930:                        break;
0931:                    case 'i':
0932:                        if (next == '(' && match("if"))
0933:                            return curToken = IF_LPAREN_TOKEN;
0934:                        if (next == '(' && match("item"))
0935:                            return curToken = OP_ITEM;
0936:                        break;
0937:                    case 'l':
0938:                        if (next == '$' && match("let"))
0939:                            return curToken = LET_DOLLAR_TOKEN;
0940:                        break;
0941:                    case 'n':
0942:                        if (next == '(' && match("node"))
0943:                            return curToken = OP_NODE;
0944:                        break;
0945:                    case 'o':
0946:                        if (next == '{' && match("ordered"))
0947:                            return curToken = ORDERED_LBRACE_TOKEN;
0948:                        break;
0949:                    case 'p':
0950:                        if (match("processing-instruction")) {
0951:                            if (next == '(')
0952:                                return curToken = OP_PI;
0953:                            if (next == '{' || XName.isNameStart((char) next)) {
0954:                                unread();
0955:                                return curToken = PI_TOKEN;
0956:                            }
0957:                            break;
0958:                        }
0959:                        break;
0960:                    case 's':
0961:                        if (next == '$' && match("some"))
0962:                            return curToken = SOME_DOLLAR_TOKEN;
0963:                        if (next == '(' && match("schema-attribute"))
0964:                            return curToken = OP_SCHEMA_ATTRIBUTE;
0965:                        if (next == '(' && match("schema-element"))
0966:                            return curToken = OP_SCHEMA_ELEMENT;
0967:                        break;
0968:                    case 't':
0969:                        if (match("text")) {
0970:                            if (next == '(')
0971:                                return curToken = OP_TEXT;
0972:                            if (next == '{') {
0973:                                unread();
0974:                                return curToken = TEXT_TOKEN;
0975:                            }
0976:                        }
0977:                        if (next == '(' && match("typeswitch"))
0978:                            return curToken = TYPESWITCH_LPAREN_TOKEN;
0979:                        break;
0980:                    case 'u':
0981:                        if (next == '{' && match("unordered"))
0982:                            return curToken = UNORDERED_LBRACE_TOKEN;
0983:                        break;
0984:                    case 'v':
0985:                        if (next == '{' && match("validate"))
0986:                            return curToken = VALIDATE_LBRACE_TOKEN;
0987:                        break;
0988:                    }
0989:                    if (next == '(' && peek() != ':') {
0990:                        return curToken = FNAME_TOKEN;
0991:                    }
0992:                    if (next == ':' && peek() == ':')
0993:                        return curToken = getAxis();
0994:                    String name = new String(tokenBuffer, 0, tokenBufferLength);
0995:                    curValue = name;
0996:                    switch (next) {
0997:                    case 'b':
0998:                        if (lookingAt("declare", /*"b"+*/"ase-uri"))
0999:                            return curToken = DECLARE_BASE_URI_TOKEN;
1000:                        if (lookingAt("declare", /*"b"+*/"oundary-space"))
1001:                            return curToken = DECLARE_BOUNDARY_SPACE_TOKEN;
1002:                        break;
1003:                    case 'c':
1004:                        if (lookingAt("declare", /*"c"+*/"onstruction"))
1005:                            return curToken = DECLARE_CONSTRUCTION_TOKEN;
1006:                        if (lookingAt("declare", /*"c"+*/"opy-namespaces"))
1007:                            return curToken = DECLARE_COPY_NAMESPACES_TOKEN;
1008:                        break;
1009:                    case 'd':
1010:                        if (lookingAt("declare", /*"d"+*/"efault")) {
1011:                            getRawToken();
1012:                            if (match("function"))
1013:                                return curToken = DEFAULT_FUNCTION_TOKEN;
1014:                            if (match("element"))
1015:                                return curToken = DEFAULT_ELEMENT_TOKEN;
1016:                            if (match("collation"))
1017:                                return curToken = DEFAULT_COLLATION_TOKEN;
1018:                            if (match("order"))
1019:                                return curToken = DEFAULT_ORDER_TOKEN;
1020:                            error("unrecognized/unimplemented 'declare default'");
1021:                            skipToSemicolon();
1022:                            return peekOperand();
1023:                        }
1024:                    case 'e':
1025:                        if (lookingAt("default", /*"e"+*/"lement")) {
1026:                            warnOldVersion("replace 'default element' by 'declare default element namespace'");
1027:                            return curToken = DEFAULT_ELEMENT_TOKEN;
1028:                        }
1029:                        break;
1030:                    case 'f':
1031:                        if (lookingAt("declare", /*"f"+*/"unction"))
1032:                            return curToken = DECLARE_FUNCTION_TOKEN;
1033:                        if (lookingAt("define", /*"f"+*/"unction")) {
1034:                            warnOldVersion("replace 'define function' by 'declare function'");
1035:                            return curToken = DECLARE_FUNCTION_TOKEN;
1036:                        }
1037:                        if (lookingAt("default", /*"f"+*/"unction")) {
1038:                            warnOldVersion("replace 'default function' by 'declare default function namespace'");
1039:                            return curToken = DEFAULT_FUNCTION_TOKEN;
1040:                        }
1041:                        break;
1042:                    case 'm':
1043:                        if (lookingAt("import", /*"m"+*/"odule"))
1044:                            return curToken = IMPORT_MODULE_TOKEN;
1045:                        break;
1046:                    case 'n':
1047:                        if (lookingAt("declare", /*"n"+*/"amespace"))
1048:                            return curToken = DECLARE_NAMESPACE_TOKEN;
1049:                        if (lookingAt("default", /*"n"+*/"amespace")) {
1050:                            warnOldVersion("replace 'default namespace' by 'declare default element namespace'");
1051:                            return curToken = DEFAULT_ELEMENT_TOKEN;
1052:                        }
1053:                        if (lookingAt("module", /*"n"+*/"amespace"))
1054:                            return curToken = MODULE_NAMESPACE_TOKEN;
1055:                        break;
1056:                    case 'o':
1057:                        if (lookingAt("declare", /*"o"+*/"rdering"))
1058:                            return curToken = DECLARE_ORDERING_TOKEN;
1059:                        if (lookingAt("declare", /*"o"+*/"ption"))
1060:                            return curToken = DECLARE_OPTION_TOKEN;
1061:                        break;
1062:                    case 's':
1063:                        if (lookingAt("import", /*"s"+*/"chema"))
1064:                            return curToken = IMPORT_SCHEMA_TOKEN;
1065:                        break;
1066:                    case 'v':
1067:                        if (lookingAt("declare", /*"v"+*/"ariable"))
1068:                            return curToken = DECLARE_VARIABLE_TOKEN;
1069:                        if (lookingAt("define", /*"v"+*/"ariable")) {
1070:                            warnOldVersion("replace 'define variable' by 'declare variable'");
1071:                            return curToken = DECLARE_VARIABLE_TOKEN;
1072:                        }
1073:                        if (lookingAt("xquery", /*"v"+*/"ersion"))
1074:                            return curToken = XQUERY_VERSION_TOKEN;
1075:                        break;
1076:                    case 'x':
1077:                        if (lookingAt("declare", /*"x"+*/"mlspace")) {
1078:                            warnOldVersion("replace 'define xmlspace' by 'declare boundary-space'");
1079:                            return curToken = DECLARE_BOUNDARY_SPACE_TOKEN;
1080:                        }
1081:                        break;
1082:                    }
1083:                    if (next >= 0) {
1084:                        unread();
1085:                        if (XName.isNameStart((char) next)
1086:                                && curValue.equals("define")) {
1087:                            getRawToken();
1088:                            curToken = DEFINE_QNAME_TOKEN;
1089:                        }
1090:                    }
1091:                    return curToken;
1092:                }
1093:                if (curToken == NCNAME_COLON_TOKEN) {
1094:                    int next = read();
1095:                    if (next == ':') // We've seen an Axis specifier.
1096:                        curToken = getAxis();
1097:                    else
1098:                        unread(next);
1099:                }
1100:                return curToken;
1101:            }
1102:
1103:            void checkAllowedNamespaceDeclaration(String prefix, String uri,
1104:                    boolean inConstructor) {
1105:                boolean xmlPrefix = "xml".equals(prefix);
1106:                if (NamespaceBinding.XML_NAMESPACE.equals(uri)) {
1107:                    if (!xmlPrefix || !inConstructor)
1108:                        error(
1109:                                'e',
1110:                                "namespace uri cannot be the same as the prefined xml namespace",
1111:                                "XQST0070");
1112:                } else if (xmlPrefix || "xmlns".equals(prefix))
1113:                    error('e', "namespace prefix cannot be 'xml' or 'xmlns'",
1114:                            "XQST0070");
1115:            }
1116:
1117:            void pushNamespace(String prefix, String uri) {
1118:                if (uri.length() == 0)
1119:                    uri = null;
1120:                prologNamespaces = new NamespaceBinding(prefix, uri,
1121:                        prologNamespaces);
1122:            }
1123:
1124:            public XQParser(InPort port, SourceMessages messages, XQuery interp) {
1125:                super (port, messages);
1126:                interpreter = interp;
1127:                lexical = new NameLookup(interp);
1128:                nesting = 1;
1129:
1130:                // Push standard namespaces into lexical scope.
1131:                NamespaceBinding ns = builtinNamespaces;
1132:                prologNamespaces = ns;
1133:            }
1134:
1135:            public void setInteractive(boolean v) {
1136:                if (interactive != v)
1137:                    if (v)
1138:                        nesting--;
1139:                    else
1140:                        nesting++;
1141:                interactive = v;
1142:            }
1143:
1144:            private static final int priority(int opcode) {
1145:                switch (opcode) {
1146:                case OP_OR:
1147:                    return 1;
1148:                case OP_AND:
1149:                    return 2;
1150:                case OP_EQU:
1151:                case OP_NEQ:
1152:                case OP_LSS:
1153:                case OP_GRT:
1154:                case OP_LEQ:
1155:                case OP_GEQ:
1156:                case OP_EQ:
1157:                case OP_NE:
1158:                case OP_LT:
1159:                case OP_GT:
1160:                case OP_LE:
1161:                case OP_GE:
1162:                case OP_IS:
1163:                case OP_ISNOT:
1164:                case OP_GRTGRT:
1165:                case OP_LSSLSS:
1166:                    return 3;
1167:                case OP_RANGE_TO:
1168:                    return 4;
1169:                case OP_ADD:
1170:                case OP_SUB:
1171:                    return 5;
1172:                case OP_MUL:
1173:                case OP_DIV:
1174:                case OP_IDIV:
1175:                case OP_MOD:
1176:                    return 6;
1177:                case OP_UNION:
1178:                    return 7;
1179:                case OP_INTERSECT:
1180:                case OP_EXCEPT:
1181:                    return 8;
1182:                case OP_INSTANCEOF:
1183:                    return 9;
1184:                case OP_TREAT_AS:
1185:                    return 10;
1186:                case OP_CASTABLE_AS:
1187:                    return 11;
1188:                case OP_CAST_AS:
1189:                    return 12;
1190:                default:
1191:                    return 0;
1192:                }
1193:            }
1194:
1195:            static Expression makeBinary(Expression func, Expression exp1,
1196:                    Expression exp2) {
1197:                Expression[] args = new Expression[2];
1198:                args[0] = exp1;
1199:                args[1] = exp2;
1200:                return new ApplyExp(func, args);
1201:            }
1202:
1203:            static Expression makeExprSequence(Expression exp1, Expression exp2) {
1204:                return makeBinary(makeFunctionExp(
1205:                        "gnu.kawa.functions.AppendValues", "appendValues"),
1206:                        exp1, exp2);
1207:            }
1208:
1209:            Expression makeBinary(int op, Expression exp1, Expression exp2)
1210:                    throws java.io.IOException, SyntaxException {
1211:                Expression func;
1212:                switch (op) {
1213:                case OP_ADD:
1214:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "add",
1215:                            "+");
1216:                    break;
1217:                case OP_SUB:
1218:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "sub",
1219:                            "-");
1220:                    break;
1221:                case OP_MUL:
1222:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "mul",
1223:                            "*");
1224:                    break;
1225:                case OP_DIV:
1226:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "div",
1227:                            "div");
1228:                    break;
1229:                case OP_IDIV:
1230:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "idiv",
1231:                            "idiv");
1232:                    break;
1233:                case OP_MOD:
1234:                    func = makeFunctionExp("gnu.xquery.util.ArithOp", "mod",
1235:                            "mod");
1236:                    break;
1237:                case OP_EQ:
1238:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valEq",
1239:                            "eq");
1240:                    break;
1241:                case OP_NE:
1242:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valNe",
1243:                            "ne");
1244:                    break;
1245:                case OP_LT:
1246:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valLt",
1247:                            "lt");
1248:                    break;
1249:                case OP_LE:
1250:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valLe",
1251:                            "le");
1252:                    break;
1253:                case OP_GT:
1254:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valGt",
1255:                            "gt");
1256:                    break;
1257:                case OP_GE:
1258:                    func = makeFunctionExp("gnu.xquery.util.Compare", "valGe",
1259:                            "ge");
1260:                    break;
1261:                case OP_EQU:
1262:                    func = makeFunctionExp("gnu.xquery.util.Compare", "=");
1263:                    break;
1264:                case OP_NEQ:
1265:                    func = makeFunctionExp("gnu.xquery.util.Compare", "!=");
1266:                    break;
1267:                case OP_LSS:
1268:                    func = makeFunctionExp("gnu.xquery.util.Compare", "<");
1269:                    break;
1270:                case OP_LEQ:
1271:                    func = makeFunctionExp("gnu.xquery.util.Compare", "<=");
1272:                    break;
1273:                case OP_GRT:
1274:                    func = makeFunctionExp("gnu.xquery.util.Compare", ">");
1275:                    break;
1276:                case OP_GEQ:
1277:                    func = makeFunctionExp("gnu.xquery.util.Compare", ">=");
1278:                    break;
1279:                case OP_IS:
1280:                    func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Eq",
1281:                            "is");
1282:                    break;
1283:                case OP_ISNOT:
1284:                    func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Ne",
1285:                            "isnot");
1286:                    break;
1287:                case OP_GRTGRT:
1288:                    func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Gr",
1289:                            ">>");
1290:                    break;
1291:                case OP_LSSLSS:
1292:                    func = makeFunctionExp("gnu.kawa.xml.NodeCompare", "$Ls",
1293:                            "<<");
1294:                    break;
1295:                case OP_RANGE_TO:
1296:                    func = makeFunctionExp("gnu.xquery.util.IntegerRange",
1297:                            "integerRange");
1298:                    break;
1299:                case OP_UNION:
1300:                    func = makeFunctionExp("gnu.kawa.xml.UnionNodes",
1301:                            "unionNodes");
1302:                    break;
1303:                case OP_INTERSECT:
1304:                    func = makeFunctionExp("gnu.kawa.xml.IntersectNodes",
1305:                            "intersectNodes");
1306:                    break;
1307:                case OP_EXCEPT:
1308:                    func = makeFunctionExp("gnu.kawa.xml.IntersectNodes",
1309:                            "exceptNodes");
1310:                    break;
1311:                default:
1312:                    return syntaxError("unimplemented binary op: " + op);
1313:                }
1314:                return makeBinary(func, exp1, exp2);
1315:            }
1316:
1317:            private void parseSimpleKindType() throws java.io.IOException,
1318:                    SyntaxException {
1319:                getRawToken();
1320:                if (curToken == ')')
1321:                    getRawToken();
1322:                else
1323:                    error("expected ')'");
1324:            }
1325:
1326:            public Expression parseNamedNodeType(boolean attribute)
1327:                    throws java.io.IOException, SyntaxException {
1328:                Expression qname;
1329:                getRawToken();
1330:                if (curToken == ')') {
1331:                    qname = QuoteExp.getInstance(ElementType.MATCH_ANY_QNAME);
1332:                    getRawToken();
1333:                } else {
1334:                    if (curToken == QNAME_TOKEN || curToken == NCNAME_TOKEN)
1335:                        qname = parseNameTest(attribute);
1336:                    else {
1337:                        if (curToken != OP_MUL)
1338:                            syntaxError("expected QName or *");
1339:                        qname = QuoteExp
1340:                                .getInstance(ElementType.MATCH_ANY_QNAME);
1341:                    }
1342:
1343:                    getRawToken();
1344:                    if (curToken == ',') {
1345:                        getRawToken();
1346:                        if (curToken == QNAME_TOKEN || curToken == NCNAME_TOKEN) {
1347:                            Expression tname = parseNameTest(true);
1348:                        } else
1349:                            syntaxError("expected QName");
1350:                        getRawToken();
1351:                    }
1352:                    if (curToken == ')')
1353:                        getRawToken();
1354:                    else
1355:                        error("expected ')' after element");
1356:                }
1357:                return makeNamedNodeType(attribute, qname);
1358:            }
1359:
1360:            static Expression makeNamedNodeType(boolean attribute,
1361:                    Expression qname) {
1362:                Expression[] name = new Expression[2];
1363:                ClassType nodeType = ClassType
1364:                        .make(attribute ? "gnu.kawa.xml.AttributeType"
1365:                                : "gnu.kawa.xml.ElementType");
1366:                ApplyExp elt = new ApplyExp(nodeType.getDeclaredMethod("make",
1367:                        1), new Expression[] { qname });
1368:                elt.setFlag(ApplyExp.INLINE_IF_CONSTANT);
1369:                return elt;
1370:            }
1371:
1372:            private boolean warnedOldStyleKindTest;
1373:
1374:            private void warnOldStyleKindTest() {
1375:                if (warnedOldStyleKindTest)
1376:                    return;
1377:                error('w', "old-style KindTest - first one here");
1378:                warnedOldStyleKindTest = true;
1379:            }
1380:
1381:            /** Parse: ["as" SequenceType] */
1382:            public Expression parseOptionalTypeDeclaration()
1383:                    throws java.io.IOException, SyntaxException {
1384:                if (!match("as"))
1385:                    return null;
1386:                getRawToken();
1387:                return parseDataType();
1388:            }
1389:
1390:            public Expression parseDataType() throws java.io.IOException,
1391:                    SyntaxException {
1392:                Expression etype = parseItemType();
1393:                int min, max;
1394:                if (etype == null) {
1395:                    if (curToken != OP_EMPTY_SEQUENCE)
1396:                        return syntaxError("bad syntax - expected DataType");
1397:                    parseSimpleKindType();
1398:                    if (curToken == '?' || curToken == OP_ADD
1399:                            || curToken == OP_MUL) {
1400:                        getRawToken();
1401:                        return syntaxError("occurrence-indicator meaningless after empty-sequence()");
1402:                    }
1403:                    etype = QuoteExp
1404:                            .getInstance(OccurrenceType.emptySequenceType);
1405:                    min = 0;
1406:                    max = 0;
1407:                } else if (curToken == '?') {
1408:                    min = 0;
1409:                    max = 1;
1410:                } else if (curToken == OP_ADD) {
1411:                    min = 1;
1412:                    max = -1;
1413:                } else if (curToken == OP_MUL) {
1414:                    min = 0;
1415:                    max = -1;
1416:                } else {
1417:                    min = 1;
1418:                    max = 1;
1419:                }
1420:                if (parseContext == 'C') {
1421:                    if (max != 1)
1422:                        return syntaxError("type to 'cast as' or 'castable as' must be a 'SingleType'");
1423:                }
1424:                if (min != max) {
1425:                    getRawToken();
1426:                    Expression[] args = { etype,
1427:                            QuoteExp.getInstance(gnu.math.IntNum.make(min)),
1428:                            QuoteExp.getInstance(gnu.math.IntNum.make(max)) };
1429:                    ApplyExp otype = new ApplyExp(ClassType.make(
1430:                            "gnu.kawa.reflect.OccurrenceType")
1431:                            .getDeclaredMethod("getInstance", 3), args);
1432:                    otype.setFlag(ApplyExp.INLINE_IF_CONSTANT);
1433:                    return otype;
1434:                }
1435:                return etype;
1436:            }
1437:
1438:            public Expression parseMaybeKindTest() throws java.io.IOException,
1439:                    SyntaxException {
1440:                Type type;
1441:                switch (curToken) {
1442:                case OP_ATTRIBUTE:
1443:                case OP_ELEMENT:
1444:                    return parseNamedNodeType(curToken == OP_ATTRIBUTE);
1445:
1446:                case OP_TEXT:
1447:                    parseSimpleKindType();
1448:                    type = NodeType.textNodeTest;
1449:                    break;
1450:
1451:                case OP_COMMENT:
1452:                    parseSimpleKindType();
1453:                    type = NodeType.commentNodeTest;
1454:                    break;
1455:
1456:                case OP_DOCUMENT:
1457:                    parseSimpleKindType();
1458:                    type = NodeType.documentNodeTest;
1459:                    break;
1460:
1461:                case OP_NODE:
1462:                    parseSimpleKindType();
1463:                    type = NodeType.anyNodeTest;
1464:                    break;
1465:
1466:                case OP_PI:
1467:                    getRawToken();
1468:                    String piTarget = null;
1469:                    if (curToken == NCNAME_TOKEN || curToken == STRING_TOKEN) {
1470:                        piTarget = new String(tokenBuffer, 0, tokenBufferLength);
1471:                        getRawToken();
1472:                    }
1473:                    if (curToken == ')')
1474:                        getRawToken();
1475:                    else
1476:                        error("expected ')'");
1477:                    type = ProcessingInstructionType.getInstance(piTarget);
1478:                    break;
1479:
1480:                default:
1481:                    return null;
1482:                }
1483:                return QuoteExp.getInstance(type);
1484:            }
1485:
1486:            public Expression parseItemType() throws java.io.IOException,
1487:                    SyntaxException {
1488:                peekOperand();
1489:                Expression etype = parseMaybeKindTest();
1490:                Type type;
1491:                if (etype != null) {
1492:                    if (parseContext == 'C')
1493:                        // Kludge to force error below.
1494:                        type = XDataType.anyAtomicType;
1495:                    else
1496:                        return etype;
1497:                } else if (curToken == OP_ITEM) {
1498:                    parseSimpleKindType();
1499:                    type = SingletonType.getInstance();
1500:                } else if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN) {
1501:                    String tname = new String(tokenBuffer, 0, tokenBufferLength);
1502:                    getRawToken();
1503:                    type = interpreter.getTypeFor(tname);
1504:                    if (type == null) {
1505:                        error('e', "unknown type " + tname, "XPST0051");
1506:                        type = Type.pointer_type;
1507:                    }
1508:                } else
1509:                    return null;
1510:                if (parseContext == 'C') {
1511:                    if (type == SingletonType.getInstance())
1512:                        return syntaxError(
1513:                                "type to 'cast as' or 'castable as' must be atomic",
1514:                                "XPST0080");
1515:                    if (type == XDataType.anyAtomicType)
1516:                        return syntaxError(
1517:                                "type to 'cast as' or 'castable as' cannot be anyAtomicType",
1518:                                "XPST0080");
1519:                    if (type == XDataType.NotationType)
1520:                        return syntaxError(
1521:                                "type to 'cast as' or 'castable as' cannot be NOTATION",
1522:                                "XPST0080");
1523:                }
1524:                return QuoteExp.getInstance(type);
1525:            }
1526:
1527:            /** Parse a <code>URILiteral</code>..
1528:             * @return either a String (on success),
1529:             * or an ErrorExp (after emitting an error).
1530:             */
1531:            Object parseURILiteral() throws java.io.IOException,
1532:                    SyntaxException {
1533:                getRawToken();
1534:                if (curToken != STRING_TOKEN)
1535:                    return declError("expected a URILiteral");
1536:                String str = new String(tokenBuffer, 0, tokenBufferLength);
1537:                str = TextUtils.replaceWhitespace(str, true);
1538:                // FUTURE: An implementation MAY raise a static error if the value
1539:                // of a URILiteral is of nonzero length and is not in the lexical
1540:                // space of xs:anyURI, or if it is a string that represents a
1541:                // relative URI as defined in [RFC2396].  err:XQST0046
1542:                return str;
1543:            }
1544:
1545:            Expression parseExpr() throws java.io.IOException, SyntaxException {
1546:                return parseExprSingle();
1547:            }
1548:
1549:            final Expression parseExprSingle() throws java.io.IOException,
1550:                    SyntaxException {
1551:                int startLine = curLine;
1552:                int startColumn = curColumn;
1553:                peekOperand();
1554:                switch (curToken) {
1555:                // FIXME old code tweaked line/column
1556:                // as in:
1557:                // maybeSetLine(exp, startLine, startColumn - 3);
1558:
1559:                case IF_LPAREN_TOKEN:
1560:                    return parseIfExpr();
1561:                case TYPESWITCH_LPAREN_TOKEN:
1562:                    return parseTypeSwitch();
1563:                case FOR_DOLLAR_TOKEN:
1564:                    return parseFLWRExpression(true);
1565:                case LET_DOLLAR_TOKEN:
1566:                    return parseFLWRExpression(false);
1567:                case SOME_DOLLAR_TOKEN:
1568:                    return parseQuantifiedExpr(false);
1569:                case EVERY_DOLLAR_TOKEN:
1570:                    return parseQuantifiedExpr(true);
1571:                default:
1572:                    return parseBinaryExpr(priority(OP_OR));
1573:                }
1574:            }
1575:
1576:            Expression parseBinaryExpr(int prio) throws java.io.IOException,
1577:                    SyntaxException {
1578:                Expression exp = parseUnaryExpr();
1579:                for (;;) {
1580:                    int token = peekOperator();
1581:                    if (token == EOL_TOKEN
1582:                    // Following makes for better error handling.
1583:                            || (token == OP_LSS && peek() == '/'))
1584:                        return exp;
1585:                    int tokPriority = priority(token);
1586:                    if (tokPriority < prio)
1587:                        return exp;
1588:                    char saveReadState = pushNesting('%');
1589:                    getRawToken();
1590:                    popNesting(saveReadState);
1591:                    if (token >= OP_INSTANCEOF && token <= OP_CAST_AS) {
1592:                        if (token == OP_CAST_AS || token == OP_CASTABLE_AS)
1593:                            parseContext = 'C';
1594:                        Expression type = parseDataType();
1595:                        parseContext = '\0';
1596:                        Expression[] args = new Expression[2];
1597:                        Expression func;
1598:                        switch (token) {
1599:                        case OP_INSTANCEOF:
1600:                            args[0] = exp;
1601:                            args[1] = type;
1602:                            func = makeFunctionExp("gnu.xquery.lang.XQParser",
1603:                                    "instanceOf");
1604:                            break;
1605:                        case OP_CASTABLE_AS:
1606:                            args[0] = exp;
1607:                            args[1] = type;
1608:                            func = new ReferenceExp(
1609:                                    XQResolveNames.castableAsDecl);
1610:                            break;
1611:                        case OP_TREAT_AS:
1612:                            args[0] = type;
1613:                            args[1] = exp;
1614:                            func = makeFunctionExp("gnu.xquery.lang.XQParser",
1615:                                    "treatAs");
1616:                            break;
1617:                        default: // i.e. case OP_CAST_AS:
1618:                            args[0] = type;
1619:                            args[1] = exp;
1620:                            func = new ReferenceExp(XQResolveNames.castAsDecl);
1621:                            break;
1622:                        }
1623:                        exp = new ApplyExp(func, args);
1624:                    } else if (token == OP_INSTANCEOF) {
1625:                        Expression[] args = { exp, parseDataType() };
1626:                        exp = new ApplyExp(makeFunctionExp(
1627:                                "gnu.xquery.lang.XQParser", "instanceOf"), args);
1628:                    } else {
1629:                        Expression exp2 = parseBinaryExpr(tokPriority + 1);
1630:                        if (token == OP_AND)
1631:                            exp = new IfExp(booleanValue(exp),
1632:                                    booleanValue(exp2), XQuery.falseExp);
1633:                        else if (token == OP_OR)
1634:                            exp = new IfExp(booleanValue(exp), XQuery.trueExp,
1635:                                    booleanValue(exp2));
1636:                        else
1637:                            exp = makeBinary(token, exp, exp2);
1638:                    }
1639:                }
1640:            }
1641:
1642:            Expression parseUnaryExpr() throws java.io.IOException,
1643:                    SyntaxException {
1644:                Expression exp;
1645:                if (curToken == OP_SUB || curToken == OP_ADD) {
1646:                    int op = curToken;
1647:                    getRawToken();
1648:                    exp = parseUnaryExpr();
1649:                    Expression func = makeFunctionExp(
1650:                            "gnu.xquery.util.ArithOp", op == OP_ADD ? "plus"
1651:                                    : "minus", op == OP_ADD ? "+" : "-");
1652:                    exp = new ApplyExp(func, new Expression[] { exp });
1653:                } else
1654:                    exp = parseUnionExpr();
1655:                return exp;
1656:            }
1657:
1658:            Expression parseUnionExpr() throws java.io.IOException,
1659:                    SyntaxException {
1660:                Expression exp = parseIntersectExceptExpr();
1661:                for (;;) {
1662:                    int op = peekOperator();
1663:                    if (op != OP_UNION)
1664:                        break;
1665:                    getRawToken();
1666:                    Expression exp2 = parseIntersectExceptExpr();
1667:                    exp = makeBinary(op, exp, exp2);
1668:                }
1669:                return exp;
1670:            }
1671:
1672:            Expression parseIntersectExceptExpr() throws java.io.IOException,
1673:                    SyntaxException {
1674:                Expression exp = parsePathExpr();
1675:                for (;;) {
1676:                    int op = peekOperator();
1677:                    if (op != OP_INTERSECT && op != OP_EXCEPT)
1678:                        break;
1679:                    getRawToken();
1680:                    Expression exp2 = parsePathExpr();
1681:                    exp = makeBinary(op, exp, exp2);
1682:                }
1683:                return exp;
1684:            }
1685:
1686:            Expression parsePathExpr() throws java.io.IOException,
1687:                    SyntaxException {
1688:                Expression step1;
1689:                if (curToken == '/' || curToken == SLASHSLASH_TOKEN) {
1690:                    Declaration dotDecl = lexical.lookup(DOT_VARNAME, false);
1691:                    Expression dot;
1692:                    if (dotDecl == null)
1693:                        dot = syntaxError("context item is undefined",
1694:                                "XPDY0002");
1695:                    else
1696:                        dot = new ReferenceExp(DOT_VARNAME, dotDecl);
1697:                    step1 = new ApplyExp(ClassType.make(
1698:                            "gnu.xquery.util.NodeUtils").getDeclaredMethod(
1699:                            "rootDocument", 1), new Expression[] { dot });
1700:                    int next = skipSpace(nesting != 0);
1701:                    unread(next);
1702:                    if (next < 0 || next == ')' || next == '}') {
1703:                        getRawToken();
1704:                        return step1;
1705:                    }
1706:                } else
1707:                    step1 = parseStepExpr();
1708:                return parseRelativePathExpr(step1);
1709:            }
1710:
1711:            /** Returns an expression that evaluates to a Symbol.
1712:             * The expression will normally be constant
1713:             * folded to a Symbol, but we cannot do that yet. */
1714:            Expression parseNameTest(boolean attribute)
1715:                    throws java.io.IOException, SyntaxException {
1716:                String local = null, prefix = null;
1717:                if (curToken == QNAME_TOKEN) {
1718:                    int colon = tokenBufferLength;
1719:                    while (tokenBuffer[--colon] != ':')
1720:                        ;
1721:                    prefix = new String(tokenBuffer, 0, colon);
1722:                    colon++;
1723:                    local = new String(tokenBuffer, colon, tokenBufferLength
1724:                            - colon);
1725:                } else if (curToken == OP_MUL) {
1726:                    int next = read();
1727:                    local = ElementType.MATCH_ANY_LOCALNAME;
1728:                    if (next != ':')
1729:                        unread(next);
1730:                    else {
1731:                        next = read();
1732:                        if (next < 0)
1733:                            eofError("unexpected end-of-file after '*:'");
1734:                        if (XName.isNameStart((char) next)) {
1735:                            unread();
1736:                            getRawToken();
1737:                            if (curToken != NCNAME_TOKEN)
1738:                                syntaxError("invalid name test");
1739:                            else
1740:                                local = new String(tokenBuffer, 0,
1741:                                        tokenBufferLength).intern();
1742:                        } else if (next != '*')
1743:                            syntaxError("missing local-name after '*:'");
1744:                    }
1745:                    return QuoteExp.getInstance(new Symbol(null, local));
1746:                } else if (curToken == NCNAME_TOKEN) {
1747:                    local = new String(tokenBuffer, 0, tokenBufferLength);
1748:                    if (attribute)
1749:                        return new QuoteExp(Namespace.EmptyNamespace
1750:                                .getSymbol(local.intern()));
1751:                    prefix = null;
1752:                } else if (curToken == NCNAME_COLON_TOKEN) {
1753:                    prefix = new String(tokenBuffer, 0, tokenBufferLength);
1754:                    int next = read();
1755:                    if (next != '*')
1756:                        syntaxError("invalid characters after 'NCName:'");
1757:                    local = ElementType.MATCH_ANY_LOCALNAME;
1758:                }
1759:                if (prefix != null)
1760:                    prefix = prefix.intern();
1761:                Expression[] args = new Expression[3];
1762:                args[0] = new ApplyExp(new ReferenceExp(
1763:                        XQResolveNames.resolvePrefixDecl),
1764:                        new Expression[] { QuoteExp.getInstance(prefix) });
1765:                args[1] = new QuoteExp(local == null ? "" : local);
1766:                args[2] = new QuoteExp(prefix);
1767:                ApplyExp make = new ApplyExp(Compilation.typeSymbol
1768:                        .getDeclaredMethod("make", 3), args);
1769:                make.setFlag(ApplyExp.INLINE_IF_CONSTANT);
1770:                return make;
1771:            }
1772:
1773:            Expression parseNodeTest(int axis) throws java.io.IOException,
1774:                    SyntaxException {
1775:                int token = peekOperand();
1776:                Expression[] args = new Expression[1];
1777:
1778:                Expression etype = parseMaybeKindTest();
1779:
1780:                if (etype != null) {
1781:                    args[0] = etype;
1782:                } else if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN
1783:                        || curToken == NCNAME_COLON_TOKEN || curToken == OP_MUL) {
1784:                    args[0] = makeNamedNodeType(axis == AXIS_ATTRIBUTE,
1785:                            parseNameTest(axis == AXIS_ATTRIBUTE));
1786:                } else if (axis >= 0)
1787:                    return syntaxError("unsupported axis '" + axisNames[axis]
1788:                            + "::'");
1789:                else
1790:                    return null;
1791:
1792:                Declaration dotDecl = lexical.lookup(DOT_VARNAME, false);
1793:                Expression dot;
1794:                if (dotDecl == null)
1795:                    dot = syntaxError(
1796:                            "node test when context item is undefined",
1797:                            "XPDY0002");
1798:                else
1799:                    dot = new ReferenceExp(DOT_VARNAME, dotDecl);
1800:                if (etype == null)
1801:                    getRawToken();
1802:
1803:                Expression makeAxisStep;
1804:                if (axis == AXIS_CHILD || axis == -1)
1805:                    makeAxisStep = makeChildAxisStep;
1806:                else if (axis == AXIS_DESCENDANT)
1807:                    makeAxisStep = makeDescendantAxisStep;
1808:                else {
1809:                    String axisName;
1810:                    switch (axis) {
1811:                    case AXIS_DESCENDANT_OR_SELF:
1812:                        axisName = "DescendantOrSelf";
1813:                        break;
1814:                    case AXIS_SELF:
1815:                        axisName = "Self";
1816:                        break;
1817:                    case AXIS_PARENT:
1818:                        axisName = "Parent";
1819:                        break;
1820:                    case AXIS_ANCESTOR:
1821:                        axisName = "Ancestor";
1822:                        break;
1823:                    case AXIS_ANCESTOR_OR_SELF:
1824:                        axisName = "AncestorOrSelf";
1825:                        break;
1826:                    case AXIS_FOLLOWING:
1827:                        axisName = "Following";
1828:                        break;
1829:                    case AXIS_FOLLOWING_SIBLING:
1830:                        axisName = "FollowingSibling";
1831:                        break;
1832:                    case AXIS_PRECEDING:
1833:                        axisName = "Preceding";
1834:                        break;
1835:                    case AXIS_PRECEDING_SIBLING:
1836:                        axisName = "PrecedingSibling";
1837:                        break;
1838:                    case AXIS_ATTRIBUTE:
1839:                        axisName = "Attribute";
1840:                        break;
1841:                    default:
1842:                        throw new Error();
1843:                    }
1844:                    makeAxisStep = QuoteExp.getInstance(new PrimProcedure(
1845:                            "gnu.kawa.xml." + axisName + "Axis", "make", 1));
1846:                }
1847:                ApplyExp mkAxis = new ApplyExp(makeAxisStep, args);
1848:                mkAxis.setFlag(ApplyExp.INLINE_IF_CONSTANT);
1849:                return new ApplyExp(mkAxis, new Expression[] { dot });
1850:            }
1851:
1852:            public static QuoteExp makeChildAxisStep = QuoteExp
1853:                    .getInstance(new PrimProcedure("gnu.kawa.xml.ChildAxis",
1854:                            "make", 1));
1855:            public static QuoteExp makeDescendantAxisStep = QuoteExp
1856:                    .getInstance(new PrimProcedure(
1857:                            "gnu.kawa.xml.DescendantAxis", "make", 1));
1858:
1859:            Expression parseRelativePathExpr(Expression exp)
1860:                    throws java.io.IOException, SyntaxException {
1861:                // If the previous operator was '//', then the corresponding E1.
1862:                Expression beforeSlashSlash = null;
1863:
1864:                while (curToken == '/' || curToken == SLASHSLASH_TOKEN) {
1865:                    boolean descendants = curToken == SLASHSLASH_TOKEN;
1866:
1867:                    LambdaExp lexp = new LambdaExp(3);
1868:                    Declaration dotDecl = lexp.addDeclaration(DOT_VARNAME);
1869:                    dotDecl.setFlag(Declaration.IS_SINGLE_VALUE);
1870:                    dotDecl.setType(NodeType.anyNodeTest);
1871:                    dotDecl.noteValue(null); // Does not have a known value.
1872:                    lexp.addDeclaration(POSITION_VARNAME, LangPrimType.intType);
1873:                    lexp.addDeclaration(LAST_VARNAME, LangPrimType.intType);
1874:                    comp.push(lexp);
1875:                    if (descendants) {
1876:                        curToken = '/';
1877:                        Expression dot = new ReferenceExp(DOT_VARNAME, dotDecl);
1878:                        Expression[] args = { dot };
1879:                        TreeScanner op = DescendantOrSelfAxis.anyNode;
1880:                        lexp.body = new ApplyExp(op, args);
1881:                        beforeSlashSlash = exp;
1882:                    } else {
1883:                        getRawToken();
1884:                        Expression exp2 = parseStepExpr();
1885:
1886:                        // Optimize: 'E1//child::TEST' to 'E1/descendant::TEST'
1887:                        Expression func;
1888:                        ApplyExp aexp;
1889:                        if (beforeSlashSlash != null
1890:                                && exp2 instanceof  ApplyExp
1891:                                && (func = ((ApplyExp) exp2).getFunction()) instanceof  ApplyExp
1892:                                && (aexp = (ApplyExp) func).getFunction() == makeChildAxisStep) {
1893:                            aexp.setFunction(makeDescendantAxisStep);
1894:                            exp = beforeSlashSlash;
1895:                        }
1896:
1897:                        lexp.body = exp2;
1898:                        beforeSlashSlash = null;
1899:                    }
1900:                    comp.pop(lexp);
1901:
1902:                    /*
1903:                    if (lexp.body instanceof ApplyExp)
1904:                      {
1905:                        // Optimize the case of a simple name step.
1906:                        ApplyExp aexp = (ApplyExp) lexp.body;
1907:                        Expression func = aexp.getFunction();
1908:                        Expression[] args = aexp.getArgs();
1909:                        if (false
1910:                    	&& func == funcNamedChildren && args.length==2
1911:                    	&& args[0] instanceof ReferenceExp
1912:                    	&& ((ReferenceExp) args[0]).getBinding() == decl)
1913:                          {
1914:                    	args[0] = exp;
1915:                    	if (descendants)
1916:                    	  func = funcNamedDescendants;
1917:                    	exp = new ApplyExp (func, args);
1918:                    	handled = true;
1919:                          }
1920:                        else if (func == funcForwardFilter && args.length==2
1921:                    	     && args[0] instanceof ApplyExp
1922:                    	     && descendants)
1923:                          {
1924:                    	ApplyExp xapp = (ApplyExp) args[0];
1925:                    	Expression[] xargs = xapp.getArgs();
1926:                    	if (xapp.getFunction() == funcNamedChildren
1927:                    	    && xargs.length == 2
1928:                    	    && ((ReferenceExp) xargs[0]).getBinding() == decl)
1929:                    	  {
1930:                    	    xapp.setFunction(funcNamedDescendants);
1931:                    	  }
1932:                          }
1933:                      }
1934:                     */
1935:
1936:                    Expression[] args = new Expression[] { exp, lexp };
1937:                    exp = new ApplyExp(RelativeStep.relativeStep, args);
1938:                }
1939:                return exp;
1940:            }
1941:
1942:            Expression parseStepExpr() throws java.io.IOException,
1943:                    SyntaxException {
1944:                int axis;
1945:                if (curToken == '.' || curToken == DOTDOT_TOKEN) {
1946:                    axis = curToken == '.' ? AXIS_SELF : AXIS_PARENT;
1947:                    getRawToken();
1948:                    Declaration dotDecl = lexical.lookup(DOT_VARNAME, false);
1949:                    Expression exp;
1950:                    if (dotDecl == null)
1951:                        exp = syntaxError("context item is undefined",
1952:                                "XPDY0002");
1953:                    else
1954:                        exp = new ReferenceExp(DOT_VARNAME, dotDecl);
1955:                    if (axis == AXIS_PARENT) {
1956:                        Expression[] args = { exp };
1957:                        exp = new ApplyExp(ParentAxis
1958:                                .make(NodeType.anyNodeTest), args);
1959:                    }
1960:                    // Note that '..' is an AbbrevReverseStep,
1961:                    // but '.' is a FilterExpr - and hence not a valid ForwardStep.
1962:                    return parseStepQualifiers(exp, axis == AXIS_SELF ? -1
1963:                            : axis);
1964:                }
1965:                axis = peekOperand() - OP_AXIS_FIRST;
1966:                Expression unqualifiedStep;
1967:                if (axis >= 0 && axis < COUNT_OP_AXIS) {
1968:                    getRawToken();
1969:                    unqualifiedStep = parseNodeTest(axis);
1970:                } else if (curToken == '@') {
1971:                    getRawToken();
1972:                    axis = AXIS_ATTRIBUTE;
1973:                    unqualifiedStep = parseNodeTest(axis);
1974:                } else if (curToken == OP_ATTRIBUTE) {
1975:                    axis = AXIS_ATTRIBUTE;
1976:                    unqualifiedStep = parseNodeTest(axis);
1977:                } else {
1978:                    unqualifiedStep = parseNodeTest(-1);
1979:                    if (unqualifiedStep != null) {
1980:                        axis = AXIS_CHILD;
1981:                    } else {
1982:                        axis = -1;
1983:                        unqualifiedStep = parsePrimaryExpr();
1984:                    }
1985:                }
1986:                return parseStepQualifiers(unqualifiedStep, axis);
1987:            }
1988:
1989:            Expression parseStepQualifiers(Expression exp, int axis)
1990:                    throws java.io.IOException, SyntaxException {
1991:                for (;;) {
1992:                    if (curToken == '[') {
1993:                        int startLine = getLineNumber() + 1;
1994:                        int startColumn = getColumnNumber() + 1;
1995:                        int saveSeenPosition = seenPosition;
1996:                        int saveSawLast = seenLast;
1997:                        getRawToken();
1998:                        LambdaExp lexp = new LambdaExp(3);
1999:                        maybeSetLine(lexp, startLine, startColumn);
2000:                        Declaration dot = lexp.addDeclaration(DOT_VARNAME);
2001:                        if (axis >= 0)
2002:                            dot.setType(NodeType.anyNodeTest);
2003:                        else
2004:                            dot.setType(SingletonType.getInstance());
2005:                        lexp.addDeclaration(POSITION_VARNAME, Type.int_type);
2006:                        lexp.addDeclaration(LAST_VARNAME, Type.int_type);
2007:                        comp.push(lexp);
2008:                        dot.noteValue(null);
2009:                        Expression cond = parseExprSequence(']', false);
2010:                        if (curToken == EOF_TOKEN)
2011:                            eofError("missing ']' - unexpected end-of-file");
2012:                        char kind;
2013:                        Procedure valuesFilter;
2014:                        if (axis < 0) {
2015:                            kind = 'P';
2016:                            valuesFilter = ValuesFilter.exprFilter;
2017:                        } else if (axis == AXIS_ANCESTOR
2018:                                || axis == AXIS_ANCESTOR_OR_SELF
2019:                                || axis == AXIS_PARENT
2020:                                || axis == AXIS_PRECEDING
2021:                                || axis == AXIS_PRECEDING_SIBLING) {
2022:                            kind = 'R';
2023:                            valuesFilter = ValuesFilter.reverseFilter;
2024:                        } else {
2025:                            kind = 'F';
2026:                            valuesFilter = ValuesFilter.forwardFilter;
2027:                        }
2028:                        /*)
2029:                        boolean sawPosition = seenPosition > saveSeenPosition;
2030:                        boolean sawLast = seenLast > saveSeenLast;
2031:                         */
2032:                        maybeSetLine(cond, startLine, startColumn);
2033:                        comp.pop(lexp);
2034:                        lexp.body = cond;
2035:                        getRawToken();
2036:                        Expression[] args = { exp, lexp };
2037:                        exp = new ApplyExp(valuesFilter, args);
2038:                    }
2039:                    /*
2040:                    else if (curToken == ARROW_TOKEN)
2041:                      ...;
2042:                     */
2043:                    else {
2044:                        return exp;
2045:                    }
2046:                }
2047:            }
2048:
2049:            /**
2050:             * Parse a PrimaryExpr.
2051:             * @return an Expression.
2052:             */
2053:            Expression parsePrimaryExpr() throws java.io.IOException,
2054:                    SyntaxException {
2055:                Expression exp = parseMaybePrimaryExpr();
2056:                if (exp == null) {
2057:                    exp = syntaxError("missing expression");
2058:                    if (curToken != EOF_TOKEN)
2059:                        getRawToken();
2060:                    return exp;
2061:                }
2062:                return exp;
2063:            }
2064:
2065:            void parseEntityOrCharRef() throws java.io.IOException,
2066:                    SyntaxException {
2067:                int next = read();
2068:                if (next == '#') {
2069:                    int base;
2070:                    next = read();
2071:                    if (next == 'x') {
2072:                        base = 16;
2073:                        next = read();
2074:                    } else
2075:                        base = 10;
2076:                    int value = 0;
2077:                    while (next >= 0) {
2078:                        char ch = (char) next;
2079:                        int digit = Character.digit((char) ch, base);
2080:                        if (digit < 0)
2081:                            break;
2082:                        if (value >= 0x8000000)
2083:                            break; // Overflow likely.
2084:                        value = value * base;
2085:                        value += digit;
2086:                        next = read();
2087:                    }
2088:                    if (next != ';') {
2089:                        unread();
2090:                        error("invalid character reference");
2091:                    }
2092:                    // See definition of 'Char' in XML 1.1 2nd ed Specification.
2093:                    else if ((value > 0 && value <= 0xD7FF)
2094:                            || (value >= 0xE000 && value <= 0xFFFD)
2095:                            || (value >= 0x10000 && value <= 0x10FFFF))
2096:                        tokenBufferAppend(value);
2097:                    else
2098:                        error('e', "invalid character value " + value,
2099:                                "XQST0090");
2100:                } else {
2101:                    int saveLength = tokenBufferLength;
2102:                    while (next >= 0) {
2103:                        char ch = (char) next;
2104:                        if (!XName.isNamePart(ch))
2105:                            break;
2106:                        tokenBufferAppend(ch);
2107:                        next = read();
2108:                    }
2109:                    if (next != ';') {
2110:                        unread();
2111:                        error("invalid entity reference");
2112:                        return;
2113:                    }
2114:                    String ref = new String(tokenBuffer, saveLength,
2115:                            tokenBufferLength - saveLength);
2116:                    tokenBufferLength = saveLength;
2117:                    appendNamedEntity(ref);
2118:                }
2119:            }
2120:
2121:            /** Count of enclosed expressions seen in element or attribute content. */
2122:            int enclosedExpressionsSeen;
2123:
2124:            static Expression makeText = makeFunctionExp(
2125:                    "gnu.kawa.xml.MakeText", "makeText");
2126:
2127:            /** Parse ElementContent (delimiter == '<')  or AttributeContent (otherwise).
2128:             * @param delimiter is '<' if parsing ElementContent, is either '\'' or
2129:             *   '\"' if parsing AttributeContent depending on the starting quote
2130:             * @param result a buffer to place the resulting Expressions.
2131:             */
2132:            void parseContent(char delimiter, Vector result)
2133:                    throws java.io.IOException, SyntaxException {
2134:                tokenBufferLength = 0;
2135:                int startSize = result.size();
2136:                int prevEnclosed = startSize - 1;
2137:                boolean skipBoundarySpace = !boundarySpacePreserve
2138:                        && delimiter == '<';
2139:                boolean skippable = skipBoundarySpace;
2140:                for (;;) {
2141:                    int next = read();
2142:                    if (next == delimiter) {
2143:                        if (delimiter == '<') {
2144:                            next = read();
2145:                            Expression text = null;
2146:                            if (tokenBufferLength > 0) {
2147:                                String str = new String(tokenBuffer, 0,
2148:                                        tokenBufferLength);
2149:                                Expression[] args = { new QuoteExp(str) };
2150:                                text = new ApplyExp(makeText, args);
2151:                            }
2152:                            tokenBufferLength = 0;
2153:                            if (next == '/') {
2154:                                if (text != null && !skippable)
2155:                                    result.addElement(text);
2156:                                break;
2157:                            }
2158:                            Expression content = parseXMLConstructor(next, true);
2159:                            boolean isCDATA = false;
2160:                            boolean emptyCDATA = false;
2161:                            if (content instanceof  ApplyExp) {
2162:                                ApplyExp aexp = (ApplyExp) content;
2163:                                if (aexp.getFunction() == makeCDATA) {
2164:                                    isCDATA = true;
2165:                                    String str = (String) aexp.getArg(0)
2166:                                            .valueIfConstant();
2167:                                    emptyCDATA = str != null
2168:                                            && str.length() == 0;
2169:                                }
2170:                            }
2171:                            if (text != null && (!skippable || isCDATA))
2172:                                result.addElement(text);
2173:                            if (isCDATA)
2174:                                skippable = false;
2175:                            else
2176:                                skippable = skipBoundarySpace;
2177:                            if (!emptyCDATA)
2178:                                result.addElement(content);
2179:                            tokenBufferLength = 0;
2180:                            continue;
2181:                        } else if (checkNext(delimiter)) {
2182:                            tokenBufferAppend(delimiter);
2183:                            continue;
2184:                        }
2185:                    }
2186:                    if (next == delimiter || next < 0 || next == '{') {
2187:                        addText: {
2188:                            String text;
2189:                            if (tokenBufferLength > 0 && !skippable)
2190:                                text = new String(tokenBuffer, 0,
2191:                                        tokenBufferLength);
2192:                            else if (next == '{'
2193:                                    && prevEnclosed == result.size())
2194:                                // Handle the <a>{E1}{E2}</a> case - we must insert a
2195:                                // joiner between E1 ad E2 to avoid a space being inserted.
2196:                                text = "";
2197:                            else
2198:                                break addText; // Don't need to add anything.
2199:                            Expression[] args = { new QuoteExp(text) };
2200:                            result.addElement(new ApplyExp(makeText, args));
2201:                        }
2202:                        tokenBufferLength = 0;
2203:                        if (next == delimiter)
2204:                            break;
2205:                        else if (next < 0)
2206:                            eofError("unexpected end-of-file");
2207:                        else // if (next == '{')
2208:                        {
2209:                            next = read();
2210:                            if (next == '{') {
2211:                                tokenBufferAppend('{');
2212:                                skippable = false;
2213:                            } else {
2214:                                unread(next);
2215:                                enclosedExpressionsSeen++;
2216:                                Expression exp = parseEnclosedExpr();
2217:                                result.addElement(exp);
2218:                                tokenBufferLength = 0;
2219:                                prevEnclosed = result.size();
2220:                                skippable = skipBoundarySpace;
2221:                            }
2222:                        }
2223:                    } else if (next == '}') {
2224:                        next = read();
2225:                        if (next == '}') {
2226:                            tokenBufferAppend('}');
2227:                            skippable = false;
2228:                        } else {
2229:                            error("unexpected '}' in element content");
2230:                            unread(next);
2231:                        }
2232:                    } else if (next == '&') {
2233:                        parseEntityOrCharRef();
2234:                        skippable = false;
2235:                    } else {
2236:                        if (delimiter != '<'
2237:                                && (next == '\t' || next == '\n' || next == '\r'))
2238:                            next = ' ';
2239:                        if (next == '<')
2240:                            error('e',
2241:                                    "'<' must be quoted in a direct attribute value");
2242:                        if (skippable)
2243:                            skippable = Character.isWhitespace((char) next);
2244:                        tokenBufferAppend((char) next);
2245:                    }
2246:                }
2247:            }
2248:
2249:            /** Parse an EnclosedExpr.
2250:             * Assume the '{' has been read.
2251:             */
2252:            Expression parseEnclosedExpr() throws java.io.IOException,
2253:                    SyntaxException {
2254:                String saveErrorIfComment = errorIfComment;
2255:                errorIfComment = null;
2256:                char saveReadState = pushNesting('{');
2257:                peekNonSpace("unexpected end-of-file after '{'");
2258:                int startLine = getLineNumber() + 1;
2259:                int startColumn = getColumnNumber() + 1;
2260:                getRawToken();
2261:                Expression exp = parseExpr();
2262:                for (;;) {
2263:                    if (curToken == '}')
2264:                        break;
2265:                    if (curToken == EOF_TOKEN || curToken == ')'
2266:                            || curToken == ']') {
2267:                        exp = syntaxError("missing '}'");
2268:                        break;
2269:                    }
2270:                    if (curToken != ',')
2271:                        exp = syntaxError("missing '}' or ','");
2272:                    else
2273:                        getRawToken();
2274:
2275:                    exp = makeExprSequence(exp, parseExpr());
2276:
2277:                }
2278:                maybeSetLine(exp, startLine, startColumn);
2279:                popNesting(saveReadState);
2280:                errorIfComment = saveErrorIfComment;
2281:                return exp;
2282:            }
2283:
2284:            /** Coerce the value of an expresison to a boolean value. */
2285:            public static Expression booleanValue(Expression exp) {
2286:                Expression[] args = { exp };
2287:                Expression string = makeFunctionExp(
2288:                        "gnu.xquery.util.BooleanValue", "booleanValue");
2289:                return new ApplyExp(string, args);
2290:            }
2291:
2292:            static final Expression makeCDATA = makeFunctionExp(
2293:                    "gnu.kawa.xml.MakeCDATA", "makeCDATA");
2294:
2295:            /** Parse an ElementConstructor or other constructs starting with '<'.
2296:             * Assume initial '<' has been processed.
2297:             * @param next next character (after '<').
2298:             */
2299:            Expression parseXMLConstructor(int next, boolean inElementContent)
2300:                    throws java.io.IOException, SyntaxException {
2301:                Expression exp;
2302:                if (next == '!') {
2303:                    next = read();
2304:                    if (next == '-' && peek() == '-') {
2305:                        skip();
2306:                        getDelimited("-->");
2307:                        boolean bad = false;
2308:                        int i = tokenBufferLength;
2309:                        boolean sawHyphen = true;
2310:                        while (--i >= 0) {
2311:                            boolean curHyphen = tokenBuffer[i] == '-';
2312:                            if (sawHyphen && curHyphen) {
2313:                                bad = true;
2314:                                break;
2315:                            }
2316:                            sawHyphen = curHyphen;
2317:                        }
2318:                        if (bad)
2319:                            exp = syntaxError("consecutive or final hyphen in XML comment");
2320:                        else {
2321:                            Expression[] args = { new QuoteExp(new String(
2322:                                    tokenBuffer, 0, tokenBufferLength)) };
2323:                            exp = new ApplyExp(makeFunctionExp(
2324:                                    "gnu.kawa.xml.CommentConstructor",
2325:                                    "commentConstructor"), args);
2326:                        }
2327:                    } else if (next == '[' && read() == 'C' && read() == 'D'
2328:                            && read() == 'A' && read() == 'T' && read() == 'A'
2329:                            && read() == '[') {
2330:                        if (!inElementContent)
2331:                            error('e',
2332:                                    "CDATA section must be in element content");
2333:                        getDelimited("]]>");
2334:                        Expression[] args = { new QuoteExp(new String(
2335:                                tokenBuffer, 0, tokenBufferLength)) };
2336:                        exp = new ApplyExp(makeCDATA, args);
2337:                    } else
2338:                        exp = syntaxError("'<!' must be followed by '--' or '[CDATA['");
2339:                } else if (next == '?') {
2340:                    next = peek();
2341:                    if (next < 0 || !XName.isNameStart((char) next)
2342:                            || getRawToken() != NCNAME_TOKEN)
2343:                        syntaxError("missing target after '<?'");
2344:                    String target = new String(tokenBuffer, 0,
2345:                            tokenBufferLength);
2346:                    int nspaces = 0;
2347:                    for (;;) {
2348:                        int ch = read();
2349:                        if (ch < 0)
2350:                            break;
2351:                        if (!Character.isWhitespace((char) ch)) {
2352:                            unread();
2353:                            break;
2354:                        }
2355:                        nspaces++;
2356:                    }
2357:                    getDelimited("?>");
2358:                    if (nspaces == 0 && tokenBufferLength > 0)
2359:                        syntaxError("target must be followed by space or '?>'");
2360:                    String content = new String(tokenBuffer, 0,
2361:                            tokenBufferLength);
2362:                    Expression[] args = { new QuoteExp(target),
2363:                            new QuoteExp(content) };
2364:                    exp = new ApplyExp(makeFunctionExp(
2365:                            "gnu.kawa.xml.MakeProcInst", "makeProcInst"), args);
2366:                } else if (next < 0 || !XName.isNameStart((char) next))
2367:                    exp = syntaxError("expected QName after '<'");
2368:                else {
2369:                    unread(next);
2370:                    getRawToken();
2371:                    char saveReadState = pushNesting('<');
2372:                    exp = parseElementConstructor();
2373:                    if (!inElementContent)
2374:                        exp = wrapWithBaseUri(exp);
2375:                    popNesting(saveReadState);
2376:                }
2377:                return exp;
2378:            }
2379:
2380:            /** Generate code to cast argument to a QName
2381:             * (which is implemented using <code>Symbol</code>). */
2382:            static ApplyExp castQName(Expression value) {
2383:                return new ApplyExp(
2384:                        new ReferenceExp(XQResolveNames.xsQNameDecl),
2385:                        new Expression[] { value });
2386:            }
2387:
2388:            /** Parse ElementConstructor.
2389:             * Assume initial {@code '<'} has been processed,
2390:             * and we're looking at the next token..
2391:             * Reads through end of the end tag.  FIXME
2392:             */
2393:            Expression parseElementConstructor() throws java.io.IOException,
2394:                    SyntaxException {
2395:                // Note that we cannot do namespace resolution at parse time,
2396:                // because of constructs like this:  <a x="{$x:v}" xmlns:x="xx"/>
2397:                // Instead we defer namespaced lookup until XQResolveNames.  (Mostly -
2398:                // some places still incorrectly do premature namespace resolution.)
2399:                String startTag = new String(tokenBuffer, 0, tokenBufferLength);
2400:                Vector vec = new Vector();
2401:                Expression[] args;
2402:                vec.addElement(castQName(new QuoteExp(startTag)));
2403:                errorIfComment = "comment not allowed in element start tag";
2404:                NamespaceBinding nsBindings = null;
2405:                int ch;
2406:                for (;;) {
2407:                    ch = skipSpace();
2408:                    if (ch < 0 || ch == '>' || ch == '/')
2409:                        break;
2410:                    unread(ch);
2411:                    getRawToken();
2412:                    int vecSize = vec.size();
2413:                    if (curToken != NCNAME_TOKEN && curToken != QNAME_TOKEN)
2414:                        break;
2415:                    String attrName = new String(tokenBuffer, 0,
2416:                            tokenBufferLength);
2417:                    int startLine = getLineNumber() + 1;
2418:                    int startColumn = getColumnNumber() + 1 - tokenBufferLength;
2419:                    String definingNamespace = null;
2420:                    if (curToken == NCNAME_TOKEN) {
2421:                        if (attrName.equals("xmlns"))
2422:                            definingNamespace = "";
2423:                    } else {
2424:                        if (attrName.startsWith("xmlns:"))
2425:                            definingNamespace = attrName.substring(6).intern();
2426:                    }
2427:                    Expression makeAttr = definingNamespace != null ? null
2428:                            : MakeAttribute.makeAttributeExp;
2429:                    vec.addElement(castQName(new QuoteExp(attrName)));
2430:                    ch = skipSpace();
2431:                    if (ch != '=') {
2432:                        errorIfComment = null;
2433:                        return syntaxError("missing '=' after attribute");
2434:                    }
2435:                    ch = skipSpace();
2436:                    int enclosedExpressionsStart = enclosedExpressionsSeen;
2437:                    if (ch == '{') {
2438:                        warnOldVersion("enclosed attribute value expression should be quoted");
2439:                        vec.addElement(parseEnclosedExpr());
2440:                    } else
2441:                        parseContent((char) ch, vec);
2442:                    int n = vec.size() - vecSize;
2443:                    if (definingNamespace != null) {
2444:                        String ns = "";
2445:                        if (n == 1)
2446:                            ns = "";
2447:                        else if (enclosedExpressionsSeen > enclosedExpressionsStart)
2448:                            syntaxError("enclosed expression not allowed in namespace declaration");
2449:                        else {
2450:                            Object x = vec.elementAt(vecSize + 1);
2451:                            ApplyExp ax;
2452:                            if (x instanceof  ApplyExp
2453:                                    && (ax = (ApplyExp) x).getFunction() == makeText)
2454:                                x = ax.getArg(0);
2455:                            ns = ((QuoteExp) x).getValue().toString().intern();
2456:                        }
2457:                        vec.setSize(vecSize);
2458:                        checkAllowedNamespaceDeclaration(definingNamespace, ns,
2459:                                true);
2460:                        if (definingNamespace == "")
2461:                            definingNamespace = null;
2462:                        for (NamespaceBinding nsb = nsBindings; nsb != null; nsb = nsb
2463:                                .getNext()) {
2464:                            if (nsb.getPrefix() == definingNamespace) {
2465:                                error(
2466:                                        'e',
2467:                                        definingNamespace == null ? "duplicate default namespace declaration"
2468:                                                : "duplicate namespace prefix '"
2469:                                                        + definingNamespace
2470:                                                        + '\'', "XQST0071");
2471:                                break;
2472:                            }
2473:                        }
2474:                        nsBindings = new NamespaceBinding(definingNamespace,
2475:                                ns == "" ? null : ns, nsBindings);
2476:                    } else {
2477:                        args = new Expression[n];
2478:                        for (int i = n; --i >= 0;)
2479:                            args[i] = (Expression) vec.elementAt(vecSize + i);
2480:                        vec.setSize(vecSize);
2481:                        ApplyExp aexp = new ApplyExp(makeAttr, args);
2482:                        maybeSetLine(aexp, startLine, startColumn);
2483:                        vec.addElement(aexp);
2484:                    }
2485:                }
2486:                errorIfComment = null;
2487:                boolean empty = false;
2488:                if (ch == '/') {
2489:                    ch = read();
2490:                    if (ch == '>')
2491:                        empty = true;
2492:                    else
2493:                        unread(ch);
2494:                }
2495:                if (!empty) {
2496:                    if (ch != '>')
2497:                        return syntaxError("missing '>' after start element");
2498:                    parseContent('<', vec);
2499:                    ch = peek();
2500:                    if (ch >= 0) {
2501:                        if (!XName.isNameStart((char) ch))
2502:                            return syntaxError("invalid tag syntax after '</'");
2503:                        getRawToken();
2504:                        String tag = new String(tokenBuffer, 0,
2505:                                tokenBufferLength);
2506:                        if (!(tag.equals(startTag)))
2507:                            return syntaxError("'<" + startTag
2508:                                    + ">' closed by '</" + tag + ">'");
2509:                        errorIfComment = "comment not allowed in element end tag";
2510:                        ch = skipSpace();
2511:                        errorIfComment = null;
2512:                    }
2513:                    if (ch != '>')
2514:                        return syntaxError("missing '>' after end element");
2515:                }
2516:                args = new Expression[vec.size()];
2517:                vec.copyInto(args);
2518:                MakeElement mkElement = new MakeElement();
2519:                mkElement.copyNamespacesMode = copyNamespacesMode;
2520:                // Ths is just the chain of NamespaceBindings for namespace declaration
2521:                // attributes from this immediate constructor.  At resolve time we chain
2522:                // this list onto the list from outer element constructors.
2523:                mkElement.setNamespaceNodes(nsBindings);
2524:                Expression result = new ApplyExp(new QuoteExp(mkElement), args);
2525:                return result;
2526:            }
2527:
2528:            Expression wrapWithBaseUri(Expression exp) {
2529:                if (getStaticBaseUri() == null)
2530:                    return exp;
2531:                return new ApplyExp(MakeWithBaseUri.makeWithBaseUri,
2532:                        new Expression[] {
2533:                                new ApplyExp(new ReferenceExp(
2534:                                        XQResolveNames.staticBaseUriDecl),
2535:                                        Expression.noExpressions), exp })
2536:                        .setLine(exp);
2537:            }
2538:
2539:            /** Parse ParenthesizedExpr.
2540:             *.When called, curToken should be pointing at a '(',
2541:             * or a token which ends if a '(', such as IF_LPAREN_TOKEN.
2542:             */
2543:            Expression parseParenExpr() throws java.io.IOException,
2544:                    SyntaxException {
2545:                getRawToken();
2546:                char saveReadState = pushNesting('(');
2547:                Expression exp = parseExprSequence(')', true);
2548:                popNesting(saveReadState);
2549:                if (curToken == EOF_TOKEN)
2550:                    eofError("missing ')' - unexpected end-of-file");
2551:                return exp;
2552:            }
2553:
2554:            Expression parseExprSequence(int rightToken, boolean optional)
2555:                    throws java.io.IOException, SyntaxException {
2556:                if (curToken == rightToken || curToken == EOF_TOKEN) {
2557:                    if (!optional)
2558:                        syntaxError("missing expression");
2559:                    return QuoteExp.voidExp;
2560:                }
2561:                Expression exp = null;
2562:                for (;;) {
2563:                    Expression exp1 = parseExprSingle();
2564:
2565:                    exp = exp == null ? exp1 : makeExprSequence(exp, exp1);
2566:                    if (curToken == rightToken || curToken == EOF_TOKEN)
2567:                        break;
2568:                    if (nesting == 0 && curToken == EOL_TOKEN)
2569:                        return exp;
2570:                    if (curToken != ',')
2571:                        return syntaxError(rightToken == ')' ? "expected ')'"
2572:                                : "confused by syntax error");
2573:                    getRawToken();
2574:                }
2575:                return exp;
2576:            }
2577:
2578:            Expression parseTypeSwitch() throws java.io.IOException,
2579:                    SyntaxException {
2580:                char save = pushNesting('t');
2581:                Expression selector = parseParenExpr();
2582:                getRawToken();
2583:                Object varName = null;
2584:                Declaration decl;
2585:                Vector vec = new Vector();
2586:                vec.addElement(selector);
2587:                while (match("case")) {
2588:                    pushNesting('c');
2589:                    getRawToken();
2590:                    if (curToken == '$') {
2591:                        decl = parseVariableDeclaration();
2592:                        if (decl == null)
2593:                            return syntaxError("missing Variable after '$'");
2594:                        getRawToken();
2595:                        if (match("as"))
2596:                            getRawToken();
2597:                        else
2598:                            error('e', "missing 'as'");
2599:                    } else
2600:                        decl = new Declaration("(arg)");
2601:                    decl.setTypeExp(parseDataType());
2602:                    popNesting('t');
2603:                    LambdaExp lexp = new LambdaExp(1);
2604:                    lexp.addDeclaration(decl);
2605:                    if (match("return"))
2606:                        getRawToken();
2607:                    else
2608:                        error("missing 'return' after 'case'");
2609:                    comp.push(lexp);
2610:                    pushNesting('r');
2611:                    Expression caseExpr = parseExpr();
2612:                    lexp.body = caseExpr;
2613:                    popNesting('t');
2614:                    comp.pop(lexp);
2615:                    vec.addElement(lexp);
2616:                }
2617:
2618:                if (match("default")) {
2619:                    LambdaExp lexp = new LambdaExp(1);
2620:                    getRawToken();
2621:
2622:                    if (curToken == '$') {
2623:                        decl = parseVariableDeclaration();
2624:                        if (decl == null)
2625:                            return syntaxError("missing Variable after '$'");
2626:                        getRawToken();
2627:                    } else
2628:                        decl = new Declaration("(arg)");
2629:                    lexp.addDeclaration(decl);
2630:
2631:                    if (match("return"))
2632:                        getRawToken();
2633:                    else
2634:                        error("missing 'return' after 'default'");
2635:                    comp.push(lexp);
2636:                    Expression defaultExpr = parseExpr();
2637:                    lexp.body = defaultExpr;
2638:                    comp.pop(lexp);
2639:                    vec.addElement(lexp);
2640:                } else {
2641:                    error(comp.isPedantic() ? 'e' : 'w',
2642:                            "no 'default' clause in 'typeswitch'", "XPST0003");
2643:                }
2644:                popNesting(save);
2645:                Expression[] args = new Expression[vec.size()];
2646:                vec.copyInto(args);
2647:                return new ApplyExp(makeFunctionExp(
2648:                        "gnu.kawa.reflect.TypeSwitch", "typeSwitch"), args);
2649:            }
2650:
2651:            /**
2652:             * Try to parse a PrimaryExpr.
2653:             * @return an Expression, or null if no PrimaryExpr was seen.
2654:             */
2655:            Expression parseMaybePrimaryExpr() throws java.io.IOException,
2656:                    SyntaxException {
2657:                int startLine = curLine;
2658:                int startColumn = curColumn;
2659:                int token = peekOperand();
2660:                Expression exp;
2661:                int c1, c2, c3;
2662:                Vector vec;
2663:                Expression[] args;
2664:                switch (token) {
2665:                case '(':
2666:                    exp = parseParenExpr();
2667:                    break;
2668:
2669:                case PRAGMA_START_TOKEN:
2670:                    Stack extArgs = new Stack();
2671:                    for (;;) {
2672:                        getRawToken();
2673:                        Expression qname;
2674:                        if (curToken != QNAME_TOKEN && curToken != NCNAME_TOKEN)
2675:                            qname = syntaxError("missing pragma name");
2676:                        else
2677:                            qname = QuoteExp.getInstance(new String(
2678:                                    tokenBuffer, 0, tokenBufferLength));
2679:                        extArgs.push(qname);
2680:                        StringBuffer sbuf = new StringBuffer();
2681:                        int ch;
2682:                        int spaces = -1;
2683:                        do {
2684:                            ch = read();
2685:                            spaces++;
2686:                        } while (ch >= 0 && Character.isWhitespace((char) ch));
2687:                        while (ch != '#' || peek() != ')') {
2688:                            if (ch < 0)
2689:                                eofError("pragma ended by end-of-file");
2690:                            if (spaces == 0)
2691:                                error("missing space between pragma and extension content");
2692:                            spaces = 1;
2693:                            sbuf.append((char) ch);
2694:                            ch = read();
2695:                        }
2696:                        read(); // skip ')'
2697:                        extArgs.push(QuoteExp.getInstance(sbuf.toString()));
2698:                        getRawToken();
2699:                        if (curToken != PRAGMA_START_TOKEN)
2700:                            break;
2701:                    }
2702:                    if (curToken == '{') {
2703:                        getRawToken();
2704:                        if (curToken != '}') {
2705:                            char saveReadState = pushNesting('{');
2706:                            extArgs.push(parseExprSequence('}', false));
2707:                            popNesting(saveReadState);
2708:                            if (curToken == EOF_TOKEN)
2709:                                eofError("missing '}' - unexpected end-of-file");
2710:                        }
2711:                        args = new Expression[extArgs.size()];
2712:                        extArgs.copyInto(args);
2713:                        exp = new ApplyExp(new ReferenceExp(
2714:                                XQResolveNames.handleExtensionDecl), args);
2715:                    } else
2716:                        exp = syntaxError("missing '{' after pragma");
2717:                    break;
2718:
2719:                case '{':
2720:                    exp = syntaxError("saw unexpected '{' - assume you meant '('");
2721:                    parseEnclosedExpr();
2722:                    break;
2723:
2724:                case OP_LSS:
2725:                    int next = read();
2726:                    if (next == '/') {
2727:                        getRawToken();
2728:                        String msg;
2729:                        if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN
2730:                                || curToken == NCNAME_COLON_TOKEN)
2731:                            msg = "saw end tag '</"
2732:                                    + new String(tokenBuffer, 0,
2733:                                            tokenBufferLength)
2734:                                    + ">' not in an element constructor";
2735:                        else
2736:                            msg = "saw end tag '</' not in an element constructor";
2737:                        curLine = startLine;
2738:                        curColumn = startColumn;
2739:                        exp = syntaxError(msg);
2740:                        while (curToken != OP_GRT && curToken != EOF_TOKEN
2741:                                && curToken != EOL_TOKEN)
2742:                            getRawToken();
2743:                        return exp;
2744:                    } else {
2745:                        exp = parseXMLConstructor(next, false);
2746:                        maybeSetLine(exp, startLine, startColumn);
2747:                    }
2748:                    break;
2749:
2750:                case STRING_TOKEN:
2751:                    exp = new QuoteExp(new String(tokenBuffer, 0,
2752:                            tokenBufferLength).intern());
2753:                    break;
2754:
2755:                case INTEGER_TOKEN:
2756:                    exp = new QuoteExp(IntNum.valueOf(tokenBuffer, 0,
2757:                            tokenBufferLength, 10, false));
2758:                    break;
2759:
2760:                case DECIMAL_TOKEN:
2761:                case DOUBLE_TOKEN:
2762:                    String str = new String(tokenBuffer, 0, tokenBufferLength);
2763:                    try {
2764:                        Object val;
2765:                        if (token == DECIMAL_TOKEN)
2766:                            val = new java.math.BigDecimal(str);
2767:                        else
2768:                            val = new java.lang.Double(str);
2769:                        exp = new QuoteExp(val);
2770:                    } catch (Throwable ex) {
2771:                        exp = syntaxError("invalid decimal literal: '" + str
2772:                                + "'");
2773:                    }
2774:                    break;
2775:                case '$':
2776:                    Object name = parseVariable();
2777:                    if (name == null)
2778:                        return syntaxError("missing Variable");
2779:                    exp = new ReferenceExp(name);
2780:                    break;
2781:                case FNAME_TOKEN:
2782:                    name = new String(tokenBuffer, 0, tokenBufferLength);
2783:                    char save = pushNesting('(');
2784:                    getRawToken();
2785:                    vec = new Vector(10);
2786:                    if (curToken != ')') {
2787:                        for (;;) {
2788:                            Expression arg = parseExpr();
2789:                            vec.addElement(arg);
2790:                            if (curToken == ')')
2791:                                break;
2792:                            if (curToken != ',')
2793:                                return syntaxError("missing ')' after function call");
2794:                            getRawToken();
2795:                        }
2796:                    }
2797:                    args = new Expression[vec.size()];
2798:
2799:                    vec.copyInto(args);
2800:                    ReferenceExp rexp = new ReferenceExp(name, null);
2801:                    rexp.setProcedureName(true);
2802:                    exp = new ApplyExp(rexp, args);
2803:                    maybeSetLine(exp, startLine, startColumn);
2804:                    popNesting(save);
2805:                    break;
2806:
2807:                case ELEMENT_TOKEN:
2808:                case ATTRIBUTE_TOKEN:
2809:                case COMMENT_TOKEN:
2810:                case DOCUMENT_TOKEN:
2811:                case TEXT_TOKEN:
2812:                case PI_TOKEN:
2813:                    getRawToken(); // Skip 'element'.
2814:                    vec = new Vector();
2815:                    Expression func;
2816:
2817:                    if (token == ELEMENT_TOKEN || token == ATTRIBUTE_TOKEN) {
2818:                        Expression element;
2819:                        if (curToken == NCNAME_TOKEN || curToken == QNAME_TOKEN)
2820:                            element = parseNameTest(token != ELEMENT_TOKEN);
2821:                        else if (curToken == '{')
2822:                            element = parseEnclosedExpr();
2823:                        else
2824:                            return syntaxError("missing element/attribute name");
2825:                        vec.addElement(castQName(element));
2826:                        if (token == ELEMENT_TOKEN) {
2827:                            MakeElement mk = new MakeElement();
2828:                            mk.copyNamespacesMode = copyNamespacesMode;
2829:                            func = new QuoteExp(mk);
2830:                        } else
2831:                            func = MakeAttribute.makeAttributeExp;
2832:                        getRawToken();
2833:                    } else if (token == DOCUMENT_TOKEN)
2834:                        func = makeFunctionExp(
2835:                                "gnu.kawa.xml.DocumentConstructor",
2836:                                "documentConstructor");
2837:                    else if (token == COMMENT_TOKEN)
2838:                        func = makeFunctionExp(
2839:                                "gnu.kawa.xml.CommentConstructor",
2840:                                "commentConstructor");
2841:                    else if (token == PI_TOKEN) {
2842:                        Expression target;
2843:                        if (curToken == NCNAME_TOKEN)
2844:                            target = new QuoteExp(new String(tokenBuffer, 0,
2845:                                    tokenBufferLength).intern());
2846:                        else if (curToken == '{') {
2847:                            target = parseEnclosedExpr();
2848:                        } else {
2849:                            target = syntaxError("expected NCName or '{' after 'processing-instruction'");
2850:                            if (curToken != QNAME_TOKEN)
2851:                                return target;
2852:                        }
2853:                        vec.addElement(target);
2854:                        func = makeFunctionExp("gnu.kawa.xml.MakeProcInst",
2855:                                "makeProcInst");
2856:                        getRawToken();
2857:                    } else
2858:                        /* token == TEXT_TOKEN */
2859:                        func = makeFunctionExp("gnu.kawa.xml.MakeText",
2860:                                "makeText");
2861:                    char saveReadState = pushNesting('{');
2862:                    peekNonSpace("unexpected end-of-file after '{'");
2863:                    if (curToken != '{')
2864:                        return syntaxError("missing '{'");
2865:                    getRawToken();
2866:                    if (token == TEXT_TOKEN || token == COMMENT_TOKEN
2867:                            || token == PI_TOKEN)
2868:                        vec
2869:                                .addElement(parseExprSequence('}',
2870:                                        token == PI_TOKEN));
2871:                    else if (curToken != '}') {
2872:                        vec.addElement(parseExpr());
2873:                        while (curToken == ',') {
2874:                            getRawToken();
2875:                            vec.addElement(parseExpr());
2876:                        }
2877:                    }
2878:                    popNesting(saveReadState);
2879:                    if (curToken != '}')
2880:                        return syntaxError("missing '}'");
2881:                    args = new Expression[vec.size()];
2882:                    vec.copyInto(args);
2883:                    exp = new ApplyExp(func, args);
2884:                    maybeSetLine(exp, startLine, startColumn);
2885:                    if (token == DOCUMENT_TOKEN || token == ELEMENT_TOKEN)
2886:                        exp = wrapWithBaseUri(exp);
2887:                    break;
2888:
2889:                case ORDERED_LBRACE_TOKEN:
2890:                case UNORDERED_LBRACE_TOKEN:
2891:                    getRawToken();
2892:                    exp = parseExprSequence('}', false);
2893:                    break;
2894:
2895:                default:
2896:                    return null;
2897:                }
2898:                /*
2899:                if (nesting == 0)
2900:                  {
2901:                int ch = skipSpace(false);
2902:                if (ch < 0 || ch == '\n' || ch == '\r')
2903:                  return exp;
2904:                unread(ch);
2905:                  }
2906:                 */
2907:                getRawToken();
2908:                return exp;
2909:            }
2910:
2911:            public Expression parseIfExpr() throws java.io.IOException,
2912:                    SyntaxException {
2913:                char saveReadState1 = pushNesting('i');
2914:                getRawToken();
2915:                char saveReadState2 = pushNesting('(');
2916:                Expression cond = parseExprSequence(')', false);
2917:                popNesting(saveReadState2);
2918:                if (curToken == EOF_TOKEN)
2919:                    eofError("missing ')' - unexpected end-of-file");
2920:                getRawToken();
2921:                if (!match("then"))
2922:                    syntaxError("missing 'then'");
2923:                else
2924:                    getRawToken();
2925:                Expression thenPart = parseExpr();
2926:                if (!match("else"))
2927:                    syntaxError("missing 'else'");
2928:                else
2929:                    getRawToken();
2930:                popNesting(saveReadState1);
2931:                Expression elsePart = parseExpr();
2932:                return new IfExp(booleanValue(cond), thenPart, elsePart);
2933:            }
2934:
2935:            public boolean match(String word) {
2936:                if (curToken != NCNAME_TOKEN)
2937:                    return false;
2938:                int len = word.length();
2939:                if (tokenBufferLength != len)
2940:                    return false;
2941:                for (int i = len; --i >= 0;) {
2942:                    char cs = word.charAt(i);
2943:                    char cb = tokenBuffer[i];
2944:                    if (cs != cb)
2945:                        return false;
2946:                }
2947:                return true;
2948:            }
2949:
2950:            /** Parse a Variable. */
2951:            public Object parseVariable() throws java.io.IOException,
2952:                    SyntaxException {
2953:                if (curToken == '$')
2954:                    getRawToken();
2955:                else
2956:                    syntaxError("missing '$' before variable name");
2957:                String str = new String(tokenBuffer, 0, tokenBufferLength);
2958:                // Note we cannot do namespace resolution here - see comment in
2959:                // parseElementConstructor.
2960:                if (curToken == QNAME_TOKEN)
2961:                    return str;
2962:                else if (curToken == NCNAME_TOKEN)
2963:                    return Namespace.EmptyNamespace.getSymbol(str.intern());
2964:                else
2965:                    return null;
2966:            }
2967:
2968:            public Declaration parseVariableDeclaration()
2969:                    throws java.io.IOException, SyntaxException {
2970:                Object name = parseVariable();
2971:                if (name == null)
2972:                    return null;
2973:                Declaration decl = new Declaration(name);
2974:                maybeSetLine(decl, getLineNumber() + 1, getColumnNumber() + 1
2975:                        - tokenBufferLength);
2976:                return decl;
2977:            }
2978:
2979:            public Expression parseFLWRExpression(boolean isFor)
2980:                    throws java.io.IOException, SyntaxException {
2981:                int flworDeclsSave = flworDeclsFirst;
2982:                flworDeclsFirst = flworDeclsCount;
2983:                Expression exp = parseFLWRInner(isFor);
2984:
2985:                if (match("order")) {
2986:                    getRawToken();
2987:                    if (match("by"))
2988:                        getRawToken();
2989:                    else
2990:                        error("missing 'by' following 'order'");
2991:                    Stack specs = new Stack();
2992:                    for (;;) {
2993:                        boolean descending = false;
2994:                        char emptyOrder = defaultEmptyOrder;
2995:
2996:                        LambdaExp lexp = new LambdaExp(flworDeclsCount
2997:                                - flworDeclsFirst);
2998:                        for (int i = flworDeclsFirst; i < flworDeclsCount; i++)
2999:                            lexp.addDeclaration(flworDecls[i].getSymbol());
3000:                        comp.push(lexp);
3001:                        lexp.body = parseExprSingle();
3002:                        comp.pop(lexp);
3003:                        specs.push(lexp);
3004:
3005:                        if (match("ascending"))
3006:                            getRawToken();
3007:                        else if (match("descending")) {
3008:                            getRawToken();
3009:                            descending = true;
3010:                        }
3011:                        if (match("empty")) {
3012:                            getRawToken();
3013:                            if (match("greatest")) {
3014:                                getRawToken();
3015:                                emptyOrder = 'G';
3016:                            } else if (match("least")) {
3017:                                getRawToken();
3018:                                emptyOrder = 'L';
3019:                            } else
3020:                                error("'empty' sequence order must be 'greatest' or 'least'");
3021:                        }
3022:                        specs.push(new QuoteExp((descending ? "D" : "A")
3023:                                + emptyOrder));
3024:                        Object collation = defaultCollator;
3025:                        if (match("collation")) {
3026:                            Object uri = parseURILiteral();
3027:                            if (uri instanceof  String) {
3028:                                try {
3029:                                    String uriString = resolveAgainstBaseUri((String) uri);
3030:                                    collation = NamedCollator.make(uriString);
3031:                                } catch (Exception name) {
3032:                                    error('e', "unknown collation '" + uri
3033:                                            + "'", "XQST0076");
3034:                                }
3035:                            }
3036:                            getRawToken();
3037:                        }
3038:                        specs.push(new QuoteExp(collation));
3039:                        if (curToken != ',')
3040:                            break;
3041:                        getRawToken();
3042:                    }
3043:                    if (!match("return"))
3044:                        return syntaxError("expected 'return' clause");
3045:                    getRawToken();
3046:
3047:                    LambdaExp lexp = new LambdaExp(flworDeclsCount
3048:                            - flworDeclsFirst);
3049:                    //maybeSetLine(lexp, declLine, declColumn);
3050:                    for (int i = flworDeclsFirst; i < flworDeclsCount; i++)
3051:                        lexp.addDeclaration(flworDecls[i].getSymbol());
3052:                    comp.push(lexp);
3053:                    lexp.body = parseExprSingle();
3054:                    comp.pop(lexp);
3055:                    int nspecs = specs.size();
3056:                    Expression[] args = new Expression[2 + nspecs];
3057:                    args[0] = exp;
3058:                    args[1] = lexp;
3059:                    for (int i = 0; i < nspecs; i++)
3060:                        args[2 + i] = (Expression) specs.elementAt(i);
3061:                    return new ApplyExp(makeFunctionExp(
3062:                            "gnu.xquery.util.OrderedMap", "orderedMap"), args);
3063:
3064:                }
3065:                flworDeclsCount = flworDeclsFirst;
3066:                flworDeclsFirst = flworDeclsSave;
3067:                return exp;
3068:            }
3069:
3070:            /** Parse a let- or a for-expression.
3071:             * Assume the 'let'/'for'-token has been seen, and we've read '$'.
3072:             *
3073:             * If we see the 'order' keyword of an 'order by' clause then we stop
3074:             * parsing, and return a result as if we instead saw a
3075:             * 'return make-tuple($x, ...)'.  The 'order by' clause will get
3076:             * parsed by the outer-most 'for' or 'let'.
3077:             */
3078:            public Expression parseFLWRInner(boolean isFor)
3079:                    throws java.io.IOException, SyntaxException {
3080:                char saveNesting = pushNesting(isFor ? 'f' : 'l');
3081:                curToken = '$';
3082:                Declaration decl = parseVariableDeclaration();
3083:                if (decl == null)
3084:                    return syntaxError("missing Variable - saw "
3085:                            + tokenString());
3086:                if (flworDecls == null)
3087:                    flworDecls = new Declaration[8];
3088:                else if (flworDeclsCount >= flworDecls.length) {
3089:                    Declaration[] tmp = new Declaration[2 * flworDeclsCount];
3090:                    System.arraycopy(flworDecls, 0, tmp, 0, flworDeclsCount);
3091:                    flworDecls = tmp;
3092:                }
3093:                flworDecls[flworDeclsCount++] = decl;
3094:                getRawToken();
3095:
3096:                Expression type = parseOptionalTypeDeclaration();
3097:                ScopeExp sc;
3098:                Expression[] inits = new Expression[1];
3099:                Declaration posDecl = null;
3100:                if (isFor) {
3101:                    boolean sawAt = match("at");
3102:                    LambdaExp lexp = new LambdaExp(sawAt ? 2 : 1);
3103:                    if (sawAt) {
3104:                        getRawToken();
3105:                        if (curToken == '$') {
3106:                            posDecl = parseVariableDeclaration();
3107:                            getRawToken();
3108:                        }
3109:                        if (posDecl == null)
3110:                            syntaxError("missing Variable after 'at'");
3111:                    }
3112:                    sc = lexp;
3113:                    if (match("in"))
3114:                        getRawToken();
3115:                    else {
3116:                        if (curToken == COLON_EQUAL_TOKEN)
3117:                            getRawToken();
3118:                        syntaxError("missing 'in' in 'for' clause");
3119:                    }
3120:                } else {
3121:                    if (curToken == COLON_EQUAL_TOKEN)
3122:                        getRawToken();
3123:                    else {
3124:                        if (match("in"))
3125:                            getRawToken();
3126:                        syntaxError("missing ':=' in 'let' clause");
3127:                    }
3128:                    LetExp let = new LetExp(inits);
3129:                    sc = let;
3130:                }
3131:                inits[0] = parseExprSingle();
3132:                if (type != null && !isFor) // FIXME - for now
3133:                    inits[0] = Convert.makeCoercion(inits[0], type);
3134:                popNesting(saveNesting);
3135:                comp.push(sc);
3136:                sc.addDeclaration(decl);
3137:                decl.setTypeExp(type);
3138:                if (isFor) {
3139:                    decl.noteValue(null); // Does not have a known value.
3140:                    decl.setFlag(Declaration.IS_SINGLE_VALUE);
3141:                }
3142:                if (posDecl != null) {
3143:                    sc.addDeclaration(posDecl);
3144:                    posDecl.setType(LangPrimType.intType);
3145:                    posDecl.noteValue(null);
3146:                    posDecl.setFlag(Declaration.IS_SINGLE_VALUE);
3147:                }
3148:                Expression body;
3149:                if (curToken == ',') {
3150:                    getRawToken();
3151:                    if (curToken != '$')
3152:                        return syntaxError("missing $NAME after ','");
3153:                    body = parseFLWRInner(isFor);
3154:                } else if (match("for")) {
3155:                    getRawToken();
3156:                    if (curToken != '$')
3157:                        return syntaxError("missing $NAME after 'for'");
3158:                    body = parseFLWRInner(true);
3159:                } else if (match("let")) {
3160:                    getRawToken();
3161:                    if (curToken != '$')
3162:                        return syntaxError("missing $NAME after 'let'");
3163:                    body = parseFLWRInner(false);
3164:                } else {
3165:                    Expression cond;
3166:                    char save = pushNesting('w');
3167:                    if (curToken == OP_WHERE) {
3168:                        getRawToken();
3169:                        cond = parseExprSingle();
3170:                    } else if (match("where")) {
3171:                        cond = parseExprSingle();
3172:                    } else
3173:                        cond = null;
3174:                    popNesting(save);
3175:                    boolean sawStable = match("stable");
3176:                    if (sawStable)
3177:                        getRawToken();
3178:                    boolean sawReturn = match("return");
3179:                    boolean sawOrder = match("order");
3180:                    if (!sawReturn && !sawOrder && !match("let")
3181:                            && !match("for"))
3182:                        return syntaxError("missing 'return' clause");
3183:                    if (!sawOrder)
3184:                        peekNonSpace("unexpected eof-of-file after 'return'");
3185:                    int bodyLine = getLineNumber() + 1;
3186:                    int bodyColumn = getColumnNumber() + 1;
3187:                    if (sawReturn)
3188:                        getRawToken();
3189:                    if (sawOrder) {
3190:                        int ndecls = flworDeclsCount - flworDeclsFirst;
3191:                        Expression[] args = new Expression[ndecls];
3192:                        for (int i = 0; i < ndecls; i++)
3193:                            args[i] = new ReferenceExp(
3194:                                    flworDecls[flworDeclsFirst + i]);
3195:                        body = new ApplyExp(
3196:                                new PrimProcedure("gnu.xquery.util.OrderedMap",
3197:                                        "makeTuple$V", 1), args);
3198:                    } else
3199:                        body = parseExprSingle();
3200:                    if (cond != null)
3201:                        body = new IfExp(booleanValue(cond), body,
3202:                                QuoteExp.voidExp);
3203:                    maybeSetLine(body, bodyLine, bodyColumn);
3204:                }
3205:                comp.pop(sc);
3206:                if (isFor) {
3207:                    LambdaExp lexp = (LambdaExp) sc;
3208:                    lexp.body = body;
3209:                    Expression[] args = { sc, inits[0] }; // SIC
3210:                    return new ApplyExp(makeFunctionExp(
3211:                            "gnu.kawa.functions.ValuesMap",
3212:                            lexp.min_args == 1 ? "valuesMap"
3213:                                    : "valuesMapWithPos"), args);
3214:                } else
3215:                    ((LetExp) sc).setBody(body);
3216:                return sc;
3217:
3218:            }
3219:
3220:            /** Parse a some- or an every-expression.
3221:             * Assume the 'some'/'every'-token has been seen, and we've read '$'. */
3222:            public Expression parseQuantifiedExpr(boolean isEvery)
3223:                    throws java.io.IOException, SyntaxException {
3224:                char saveNesting = pushNesting(isEvery ? 'e' : 's');
3225:                curToken = '$';
3226:                Declaration decl = parseVariableDeclaration();
3227:                if (decl == null)
3228:                    return syntaxError("missing Variable token:" + curToken);
3229:                getRawToken();
3230:
3231:                LambdaExp lexp = new LambdaExp(1);
3232:                lexp.addDeclaration(decl);
3233:                decl.noteValue(null); // Does not have a known value.
3234:                decl.setFlag(Declaration.IS_SINGLE_VALUE);
3235:                decl.setTypeExp(parseOptionalTypeDeclaration());
3236:
3237:                if (match("in"))
3238:                    getRawToken();
3239:                else {
3240:                    if (curToken == COLON_EQUAL_TOKEN)
3241:                        getRawToken();
3242:                    syntaxError("missing 'in' in QuantifiedExpr");
3243:                }
3244:                Expression[] inits = { parseExprSingle() };
3245:                popNesting(saveNesting);
3246:                comp.push(lexp);
3247:                Expression body;
3248:                if (curToken == ',') {
3249:                    getRawToken();
3250:                    if (curToken != '$')
3251:                        return syntaxError("missing $NAME after ','");
3252:                    body = parseQuantifiedExpr(isEvery);
3253:                } else {
3254:                    boolean sawSatisfies = match("satisfies");
3255:                    if (!sawSatisfies && !match("every") && !match("some"))
3256:                        return syntaxError("missing 'satisfies' clause");
3257:                    peekNonSpace("unexpected eof-of-file after 'satisfies'");
3258:                    int bodyLine = getLineNumber() + 1;
3259:                    int bodyColumn = getColumnNumber() + 1;
3260:                    if (sawSatisfies)
3261:                        getRawToken();
3262:                    body = parseExprSingle();
3263:                    maybeSetLine(body, bodyLine, bodyColumn);
3264:                }
3265:                comp.pop(lexp);
3266:                lexp.body = body;
3267:                Expression[] args = { lexp, inits[0] }; // SIC
3268:                return new ApplyExp(makeFunctionExp(
3269:                        "gnu.xquery.util.ValuesEvery", isEvery ? "every"
3270:                                : "some"), args);
3271:            }
3272:
3273:            public Expression parseFunctionDefinition(int declLine,
3274:                    int declColumn) throws java.io.IOException, SyntaxException {
3275:                if (curToken != QNAME_TOKEN && curToken != NCNAME_TOKEN)
3276:                    return syntaxError("missing function name");
3277:                String name = new String(tokenBuffer, 0, tokenBufferLength);
3278:                Symbol sym = namespaceResolve(name, true);
3279:                String uri = sym.getNamespaceURI();
3280:                if (uri == NamespaceBinding.XML_NAMESPACE
3281:                        || uri == XQuery.SCHEMA_NAMESPACE
3282:                        || uri == XQuery.SCHEMA_INSTANCE_NAMESPACE
3283:                        || uri == XQuery.XQUERY_FUNCTION_NAMESPACE) {
3284:                    error('e',
3285:                            "cannot declare function in standard namespace '"
3286:                                    + uri + '\'', "XQST0045");
3287:                } else if (uri == "") {
3288:                    error(comp.isPedantic() ? 'e' : 'w',
3289:                            "cannot declare function in empty namespace",
3290:                            "XQST0060");
3291:                } else if (libraryModuleNamespace != null
3292:                        && uri != libraryModuleNamespace
3293:                        && (!XQuery.LOCAL_NAMESPACE.equals(uri) || comp
3294:                                .isPedantic())) {
3295:                    error('e', "function not in namespace of library module",
3296:                            "XQST0048");
3297:                }
3298:                getRawToken();
3299:                if (curToken != '(')
3300:                    return syntaxError("missing parameter list:" + curToken);
3301:                getRawToken();
3302:                LambdaExp lexp = new LambdaExp();
3303:                maybeSetLine(lexp, declLine, declColumn);
3304:                lexp.setName(name);
3305:                Declaration decl = comp.currentScope().addDeclaration(sym);
3306:                if (comp.isStatic())
3307:                    decl.setFlag(Declaration.STATIC_SPECIFIED);
3308:                lexp.setFlag(LambdaExp.OVERLOADABLE_FIELD);
3309:                decl.setCanRead(true);
3310:                decl.setProcedureDecl(true);
3311:                maybeSetLine(decl, declLine, declColumn);
3312:                comp.push(lexp);
3313:                if (curToken != ')') {
3314:                    paramLoop: for (;;) {
3315:                        Declaration param = parseVariableDeclaration();
3316:                        if (param == null)
3317:                            error("missing parameter name");
3318:                        else {
3319:                            lexp.addDeclaration(param);
3320:                            getRawToken();
3321:                            lexp.min_args++;
3322:                            lexp.max_args++;
3323:                            param.setTypeExp(parseOptionalTypeDeclaration());
3324:                        }
3325:                        if (curToken == ')')
3326:                            break;
3327:                        if (curToken != ',') {
3328:                            Expression err = syntaxError("missing ',' in parameter list");
3329:                            for (;;) {
3330:                                getRawToken();
3331:                                if (curToken < 0 || curToken == ';'
3332:                                        || curToken == ';')
3333:                                    return err;
3334:                                if (curToken == ')')
3335:                                    break paramLoop;
3336:                                if (curToken == ',')
3337:                                    break;
3338:                            }
3339:                        } else
3340:                            getRawToken();
3341:                    }
3342:                }
3343:                getRawToken();
3344:                Expression retType = parseOptionalTypeDeclaration();
3345:                lexp.body = parseEnclosedExpr();
3346:                comp.pop(lexp);
3347:                if (retType != null)
3348:                    Convert.setCoercedReturnValue(lexp, retType, interpreter);
3349:                SetExp sexp = new SetExp(decl, lexp);
3350:                sexp.setDefining(true);
3351:                decl.noteValue(lexp);
3352:                return sexp;
3353:            }
3354:
3355:            public Object readObject() throws java.io.IOException,
3356:                    SyntaxException {
3357:                return parse(null);
3358:            }
3359:
3360:            Compilation comp;
3361:
3362:            String defaultElementNamespace = "";
3363:
3364:            /** Chain of namespace bindings from namespace declaration attributes
3365:             * in outer direct element constructors.  This is only non-empty during
3366:             * resolve time, but it is declared here so namespaceResolve can use it. */
3367:            NamespaceBinding constructorNamespaces = NamespaceBinding.predefinedXML;
3368:
3369:            /** Chain of namespace bindings from declarations in prolog,
3370:             *  followed by the builtinNamespaces. */
3371:            NamespaceBinding prologNamespaces;
3372:
3373:            static NamespaceBinding builtinNamespaces;
3374:            static {
3375:                NamespaceBinding ns = NamespaceBinding.predefinedXML;
3376:                ns = new NamespaceBinding("xml",
3377:                        NamespaceBinding.XML_NAMESPACE, ns);
3378:                ns = new NamespaceBinding("xs", XQuery.SCHEMA_NAMESPACE, ns);
3379:                ns = new NamespaceBinding("xsi",
3380:                        XQuery.SCHEMA_INSTANCE_NAMESPACE, ns);
3381:                ns = new NamespaceBinding("fn",
3382:                        XQuery.XQUERY_FUNCTION_NAMESPACE, ns);
3383:                ns = new NamespaceBinding("html", XQuery.XHTML_NAMESPACE, ns);
3384:                ns = new NamespaceBinding("kawa",
3385:                        XQuery.KAWA_FUNCTION_NAMESPACE, ns);
3386:                ns = new NamespaceBinding("qexo",
3387:                        XQuery.QEXO_FUNCTION_NAMESPACE, ns);
3388:                ns = new NamespaceBinding("local", XQuery.LOCAL_NAMESPACE, ns);
3389:                builtinNamespaces = ns;
3390:            }
3391:
3392:            protected Symbol namespaceResolve(String name, boolean function) {
3393:                int colon = name.indexOf(':');
3394:                String prefix = colon >= 0 ? name.substring(0, colon).intern()
3395:                        : function ? XQuery.DEFAULT_FUNCTION_PREFIX
3396:                                : XQuery.DEFAULT_ELEMENT_PREFIX;
3397:                String uri = QNameUtils.lookupPrefix(prefix,
3398:                        constructorNamespaces, prologNamespaces);
3399:
3400:                if (uri == null) {
3401:                    if (colon < 0)
3402:                        uri = "";
3403:                    else if (!comp.isPedantic()) {
3404:                        try {
3405:                            Class cl = Class.forName(prefix);
3406:                            uri = "class:" + prefix;
3407:                        } catch (Exception ex) {
3408:                            uri = null;
3409:                        }
3410:                    }
3411:                    if (uri == null) {
3412:                        error('e', "unknown namespace prefix '" + prefix + "'",
3413:                                "XPST0081");
3414:                        uri = "(unknown namespace)";
3415:                    }
3416:                }
3417:                String local = colon < 0 ? name : name.substring(colon + 1);
3418:                return Symbol.make((String) uri, local, prefix);
3419:            }
3420:
3421:            void parseSeparator() throws java.io.IOException, SyntaxException {
3422:                int startLine = port.getLineNumber() + 1;
3423:                int startColumn = port.getColumnNumber() + 1;
3424:                int next = skipSpace(nesting != 0);
3425:                if (next == ';')
3426:                    return;
3427:                if (warnOldVersion && next != '\n') {
3428:                    curLine = startLine;
3429:                    curColumn = startColumn;
3430:                    error('w', "missing ';' after declaration");
3431:                }
3432:                if (next >= 0)
3433:                    unread(next);
3434:            }
3435:
3436:            public static final QuoteExp getExternalFunction = QuoteExp
3437:                    .getInstance(new PrimProcedure("gnu.xquery.lang.XQuery",
3438:                            "getExternal", 2));
3439:
3440:            /** Parse an expression.
3441:             * Return null on EOF. */
3442:            public Expression parse(Compilation comp)
3443:                    throws java.io.IOException, SyntaxException {
3444:                this .comp = comp;
3445:                int ch = skipSpace();
3446:                if (ch < 0)
3447:                    return null;
3448:                parseCount++;
3449:                unread(ch);
3450:                int startLine = getLineNumber() + 1;
3451:                int startColumn = getColumnNumber() + 1;
3452:
3453:                // Handle Unix #!PROGRAM convention. */
3454:                if (ch == '#' && startLine == 1 && startColumn == 1) {
3455:                    read();
3456:                    if ((ch = read()) != '!' || (ch = read()) != '/')
3457:                        error("'#' is only allowed in initial '#!/PROGRAM'");
3458:                    while (ch != '\r' && ch != '\n' && ch >= 0)
3459:                        ch = read();
3460:                }
3461:
3462:                if (getRawToken() == EOF_TOKEN)
3463:                    return null;
3464:                peekOperand();
3465:
3466:                if (curToken == NCNAME_TOKEN
3467:                        && "namespace".equals((String) curValue)) {
3468:                    if (warnOldVersion)
3469:                        error('w',
3470:                                "use 'declare namespace' instead of 'namespace'");
3471:                    curToken = DECLARE_NAMESPACE_TOKEN;
3472:                }
3473:
3474:                int declLine, declColumn, next;
3475:                Declaration decl;
3476:                String prefix, uri;
3477:                Object val;
3478:                Expression exp;
3479:                switch (curToken) {
3480:                case DEFINE_QNAME_TOKEN:
3481:                    declLine = getLineNumber() + 1;
3482:                    declColumn = getColumnNumber() + 1;
3483:                    next = peekNonSpace("unexpected end-of-file after 'define QName'");
3484:                    if (next == '(') {
3485:                        syntaxError("'missing 'function' after 'define'");
3486:                        curToken = NCNAME_TOKEN;
3487:                        return parseFunctionDefinition(declLine, declColumn);
3488:                    } else
3489:                        return syntaxError("missing keyword after 'define'");
3490:
3491:                case DECLARE_FUNCTION_TOKEN:
3492:                    declLine = getLineNumber() + 1;
3493:                    declColumn = getColumnNumber() + 1;
3494:                    getRawToken();
3495:                    peekNonSpace("unexpected end-of-file after 'define function'");
3496:                    char save = pushNesting('d');
3497:                    exp = parseFunctionDefinition(declLine, declColumn);
3498:                    popNesting(save);
3499:                    parseSeparator();
3500:                    maybeSetLine(exp, startLine, startColumn);
3501:                    seenDeclaration = true;
3502:                    return exp;
3503:
3504:                case DECLARE_VARIABLE_TOKEN:
3505:                    getRawToken();
3506:                    decl = parseVariableDeclaration();
3507:                    if (decl == null)
3508:                        return syntaxError("missing Variable");
3509:                    Object name = decl.getSymbol();
3510:                    if (name instanceof  String)
3511:                        decl.setSymbol(namespaceResolve((String) name, false));
3512:                    if (libraryModuleNamespace != null) {
3513:                        uri = ((Symbol) decl.getSymbol()).getNamespaceURI();
3514:                        if (uri != libraryModuleNamespace
3515:                                && (!XQuery.LOCAL_NAMESPACE.equals(uri) || comp
3516:                                        .isPedantic()))
3517:                            error(
3518:                                    'e',
3519:                                    "variable not in namespace of library module",
3520:                                    "XQST0048");
3521:                    }
3522:                    comp.currentScope().addDeclaration(decl);
3523:                    getRawToken();
3524:                    Expression type = parseOptionalTypeDeclaration();
3525:                    decl.setCanRead(true);
3526:                    //decl.setFlag(Declaration.NONSTATIC_SPECIFIED);
3527:                    decl.setFlag(Declaration.IS_CONSTANT);
3528:                    Expression init = null;
3529:                    boolean sawEq = false;
3530:                    if (curToken == OP_EQU || curToken == COLON_EQUAL_TOKEN) {
3531:                        if (curToken == OP_EQU)
3532:                            error("declare variable contains '=' instead of ':='");
3533:                        getRawToken();
3534:                        sawEq = true;
3535:                    }
3536:                    if (curToken == '{') {
3537:                        warnOldVersion("obsolete '{' in variable declaration");
3538:                        init = parseEnclosedExpr();
3539:                        parseSeparator();
3540:                    } else if (match("external")) {
3541:                        Expression[] args = {
3542:                                castQName(new QuoteExp(decl.getSymbol())),
3543:                                type == null ? QuoteExp.nullExp : type };
3544:                        init = new ApplyExp(getExternalFunction, args);
3545:                        maybeSetLine(init, curLine, curColumn);
3546:                        getRawToken();
3547:                    } else {
3548:                        init = parseExpr();
3549:                        Expression err = null;
3550:                        if (!sawEq || init == null)
3551:                            err = syntaxError("expected ':= init' or 'external'");
3552:                        if (init == null)
3553:                            init = err;
3554:                    }
3555:                    if (type != null)
3556:                        init = Convert.makeCoercion(init, type);
3557:                    decl.noteValue(init);
3558:                    exp = SetExp.makeDefinition(decl, init);
3559:                    maybeSetLine(exp, startLine, startColumn);
3560:                    seenDeclaration = true;
3561:                    return exp;
3562:
3563:                case DECLARE_NAMESPACE_TOKEN:
3564:                case MODULE_NAMESPACE_TOKEN:
3565:                    int command = curToken;
3566:                    if (command == MODULE_NAMESPACE_TOKEN
3567:                            && libraryModuleNamespace != null)
3568:                        error('e', "duplicate module declaration");
3569:                    else if (seenDeclaration && !interactive)
3570:                        error('e',
3571:                                "namespace declared after function/variable/option");
3572:                    next = skipSpace(nesting != 0);
3573:                    if (next >= 0) {
3574:                        unread();
3575:                        if (XName.isNameStart((char) next)) {
3576:                            getRawToken();
3577:                            if (curToken != NCNAME_TOKEN)
3578:                                return syntaxError("missing namespace prefix");
3579:                            prefix = new String(tokenBuffer, 0,
3580:                                    tokenBufferLength);
3581:                            getRawToken();
3582:                            if (curToken != OP_EQU)
3583:                                return syntaxError("missing '=' in namespace declaration");
3584:                            getRawToken();
3585:                            if (curToken != STRING_TOKEN)
3586:                                return syntaxError("missing uri in namespace declaration");
3587:                            uri = new String(tokenBuffer, 0, tokenBufferLength)
3588:                                    .intern();
3589:                            prefix = prefix.intern();
3590:                            for (NamespaceBinding ns = prologNamespaces; ns != builtinNamespaces; ns = ns
3591:                                    .getNext()) {
3592:                                if (ns.getPrefix() == prefix) {
3593:                                    error('e',
3594:                                            "duplicate declarations for the same namespace prefix '"
3595:                                                    + prefix + "'", "XQST0033");
3596:                                    break;
3597:                                }
3598:                            }
3599:                            pushNamespace(prefix, uri);
3600:                            checkAllowedNamespaceDeclaration(prefix, uri, false);
3601:                            parseSeparator();
3602:                            if (command == MODULE_NAMESPACE_TOKEN) {
3603:                                ModuleExp module = comp.getModule();
3604:                                String className = Compilation.mangleURI(uri)
3605:                                        + '.'
3606:                                        + XQuery.makeClassName(module
3607:                                                .getFileName());
3608:                                module.setName(className);
3609:                                comp.mainClass = new ClassType(className);
3610:                                module.setType(comp.mainClass);
3611:                                ModuleManager manager = ModuleManager
3612:                                        .getInstance();
3613:                                ModuleInfo info = manager.find(comp);
3614:                                info.setNamespaceUri(uri);
3615:                                module.setType(comp.mainClass);
3616:                                if (uri.length() == 0)
3617:                                    return syntaxError(
3618:                                            "zero-length module namespace",
3619:                                            "XQST0088");
3620:                                libraryModuleNamespace = uri;
3621:                            }
3622:                            return QuoteExp.voidExp;
3623:                        }
3624:                    }
3625:
3626:                case IMPORT_SCHEMA_TOKEN:
3627:                    fatal("'import schema' not implemented", "XQST0009");
3628:
3629:                case IMPORT_MODULE_TOKEN:
3630:                    getRawToken();
3631:                    prefix = null;
3632:                    if (match("namespace")) {
3633:                        getRawToken();
3634:                        if (curToken != NCNAME_TOKEN)
3635:                            return syntaxError("missing namespace prefix");
3636:                        prefix = new String(tokenBuffer, 0, tokenBufferLength);
3637:                        getRawToken();
3638:                        if (curToken != OP_EQU)
3639:                            return syntaxError("missing '=' in namespace declaration");
3640:                        getRawToken();
3641:                    }
3642:                    if (curToken != STRING_TOKEN)
3643:                        return syntaxError("missing uri in namespace declaration");
3644:                    if (tokenBufferLength == 0)
3645:                        return syntaxError("zero-length target namespace",
3646:                                "XQST0088");
3647:                    uri = new String(tokenBuffer, 0, tokenBufferLength)
3648:                            .intern();
3649:                    if (prefix != null) {
3650:                        checkAllowedNamespaceDeclaration(prefix, uri, false);
3651:                        pushNamespace(prefix.intern(), uri);
3652:                    }
3653:                    getRawToken();
3654:                    // Make sure we have a ModuleInfo before we call importDefinitions.
3655:                    ModuleManager.getInstance().find(comp);
3656:
3657:                    String at;
3658:                    ModuleExp module = comp.getModule();
3659:                    Vector forms = new Vector();
3660:                    String packageName = Compilation.mangleURI(uri);
3661:                    comp.setLine(port.getName(), startLine, startColumn);
3662:                    if (match("at")) {
3663:                        for (;;) {
3664:                            getRawToken();
3665:                            if (curToken != STRING_TOKEN)
3666:                                return syntaxError("missing module location");
3667:                            at = new String(tokenBuffer, 0, tokenBufferLength);
3668:                            String className = Compilation.mangleURI(uri) + '.'
3669:                                    + XQuery.makeClassName(at);
3670:
3671:                            ModuleInfo info = require
3672:                                    .lookupModuleFromSourcePath(at, module);
3673:                            if (info == null)
3674:                                comp.error('e', "malformed URL: " + at);
3675:                            require.importDefinitions(className, info, uri,
3676:                                    forms, module, comp);
3677:                            next = skipSpace(nesting != 0);
3678:                            if (next != ',') {
3679:                                unread(next);
3680:                                break;
3681:                            }
3682:                        }
3683:                        parseSeparator();
3684:                    } else {
3685:                        ModuleManager manager = ModuleManager.getInstance();
3686:                        int n = 0;
3687:                        try {
3688:                            manager.loadPackageInfo(packageName);
3689:                        } catch (ClassNotFoundException ex) {
3690:                            // Do nothing.  If there is no such module,
3691:                            // that will be reported below.
3692:                        } catch (Throwable ex) {
3693:                            error('e', "error loading map for " + uri + " - "
3694:                                    + ex);
3695:                        }
3696:                        for (ModuleInfo info = manager.firstModule(); info != null; info = info
3697:                                .nextModule()) {
3698:                            if (!uri.equals(info.getNamespaceUri()))
3699:                                continue;
3700:                            n++;
3701:                            require.importDefinitions(info.className, info,
3702:                                    uri, forms, module, comp);
3703:                        }
3704:                        if (n == 0)
3705:                            error('e', "no module found for " + uri);
3706:                        at = null;
3707:                        if (curToken != ';')
3708:                            parseSeparator();
3709:                    }
3710:                    if (comp.pendingImports != null
3711:                            && comp.pendingImports.size() > 0) {
3712:                        error('e', "module import forms a cycle", "XQST0073");
3713:                    }
3714:                    Expression[] inits = new Expression[forms.size()];
3715:                    forms.toArray(inits);
3716:                    return BeginExp.canonicalize(inits);
3717:
3718:                case DEFAULT_COLLATION_TOKEN:
3719:                    if (defaultCollator != null && !interactive)
3720:                        error('e', "duplicate default collation declaration",
3721:                                "XQST0038");
3722:                    val = parseURILiteral();
3723:                    if (val instanceof  Expression) // an ErrorExp
3724:                        return (Expression) val;
3725:                    String collation = (String) val;
3726:                    try {
3727:                        collation = resolveAgainstBaseUri(collation);
3728:                        defaultCollator = NamedCollator.make(collation);
3729:                    } catch (Exception ex) {
3730:                        defaultCollator = NamedCollator.codepointCollation;
3731:                        error('e', "unknown collation '" + collation + "'",
3732:                                "XQST0038");
3733:                    }
3734:                    parseSeparator();
3735:                    return QuoteExp.voidExp;
3736:
3737:                case DEFAULT_ELEMENT_TOKEN:
3738:                case DEFAULT_FUNCTION_TOKEN:
3739:                    boolean forFunctions = curToken == DEFAULT_FUNCTION_TOKEN;
3740:                    prefix = forFunctions ? XQuery.DEFAULT_FUNCTION_PREFIX
3741:                            : XQuery.DEFAULT_ELEMENT_PREFIX;
3742:                    if (prologNamespaces.resolve(prefix, builtinNamespaces) != null)
3743:                        error('e', "duplicate default namespace declaration",
3744:                                "XQST0066");
3745:                    getRawToken();
3746:                    if (match("namespace"))
3747:                        getRawToken();
3748:                    else {
3749:                        String msg = "expected 'namespace' keyword";
3750:                        if (curToken != STRING_TOKEN && curToken != OP_EQU)
3751:                            return declError(msg);
3752:                        else
3753:                            warnOldVersion(msg);
3754:                    }
3755:                    if (curToken == OP_EQU || curToken == COLON_EQUAL_TOKEN) {
3756:                        warnOldVersion("extra '=' in default namespace declaration");
3757:                        getRawToken();
3758:                    }
3759:                    if (curToken != STRING_TOKEN)
3760:                        return declError("missing namespace uri");
3761:                    uri = new String(tokenBuffer, 0, tokenBufferLength);
3762:                    if (forFunctions) {
3763:                        functionNamespacePath = new Namespace[1];
3764:                        functionNamespacePath[0] = Namespace.getInstance(uri);
3765:                    } else {
3766:                        defaultElementNamespace = uri;
3767:                    }
3768:                    pushNamespace(prefix, uri);
3769:                    checkAllowedNamespaceDeclaration(prefix, uri, false);
3770:                    parseSeparator();
3771:                    return QuoteExp.voidExp;
3772:
3773:                case DECLARE_BOUNDARY_SPACE_TOKEN:
3774:                    getRawToken();
3775:                    if (curToken == OP_EQU) {
3776:                        warnOldVersion("obsolate '=' in boundary-space declaration");
3777:                        getRawToken();
3778:                    }
3779:                    if (boundarySpaceDeclarationSeen && !interactive)
3780:                        syntaxError("duplicate 'declare boundary-space' seen",
3781:                                "XQST0068");
3782:                    boundarySpaceDeclarationSeen = true;
3783:                    if (match("preserve"))
3784:                        boundarySpacePreserve = true;
3785:                    else if (match("strip"))
3786:                        boundarySpacePreserve = false;
3787:                    else if (match("skip")) {
3788:                        warnOldVersion("update: declare boundary-space skip -> strip");
3789:                        boundarySpacePreserve = false;
3790:                    } else
3791:                        return syntaxError("boundary-space declaration must be preserve or strip");
3792:                    parseSeparator();
3793:                    return QuoteExp.voidExp;
3794:
3795:                case DECLARE_CONSTRUCTION_TOKEN:
3796:                    getRawToken();
3797:                    if (constructionModeDeclarationSeen && !interactive)
3798:                        syntaxError("duplicate 'declare construction' seen",
3799:                                "XQST0067");
3800:                    constructionModeDeclarationSeen = true;
3801:                    if (match("strip"))
3802:                        constructionModeStrip = true;
3803:                    else if (match("preserve"))
3804:                        constructionModeStrip = false;
3805:                    else
3806:                        return syntaxError("construction declaration must be strip or preserve");
3807:                    parseSeparator();
3808:                    return QuoteExp.voidExp;
3809:
3810:                case DECLARE_COPY_NAMESPACES_TOKEN:
3811:                    getRawToken();
3812:                    if (copyNamespacesDeclarationSeen && !interactive)
3813:                        syntaxError("duplicate 'declare copy-namespaces' seen",
3814:                                "XQST0055");
3815:                    copyNamespacesDeclarationSeen = true;
3816:                    if (match("preserve"))
3817:                        copyNamespacesMode |= XMLFilter.COPY_NAMESPACES_PRESERVE;
3818:                    else if (match("no-preserve"))
3819:                        copyNamespacesMode &= ~XMLFilter.COPY_NAMESPACES_PRESERVE;
3820:                    else
3821:                        return syntaxError("expected 'preserve' or 'no-preserve' after 'declare copy-namespaces'");
3822:                    getRawToken();
3823:                    if (curToken != ',')
3824:                        return syntaxError("missing ',' in copy-namespaces declaration");
3825:                    getRawToken();
3826:                    if (match("inherit"))
3827:                        copyNamespacesMode |= XMLFilter.COPY_NAMESPACES_INHERIT;
3828:                    else if (match("no-inherit"))
3829:                        copyNamespacesMode &= ~XMLFilter.COPY_NAMESPACES_INHERIT;
3830:                    else
3831:                        return syntaxError("expected 'inherit' or 'no-inherit' in copy-namespaces declaration");
3832:                    parseSeparator();
3833:                    return QuoteExp.voidExp;
3834:
3835:                case DEFAULT_ORDER_TOKEN:
3836:                    getRawToken();
3837:                    boolean sawEmpty = match("empty");
3838:                    if (emptyOrderDeclarationSeen && !interactive)
3839:                        syntaxError(
3840:                                "duplicate 'declare default empty order' seen",
3841:                                "XQST0069");
3842:                    emptyOrderDeclarationSeen = true;
3843:                    if (sawEmpty)
3844:                        getRawToken();
3845:                    else
3846:                        syntaxError("expected 'empty greatest' or 'empty least'");
3847:                    if (match("greatest"))
3848:                        defaultEmptyOrder = 'G';
3849:                    else if (match("least"))
3850:                        defaultEmptyOrder = 'L';
3851:                    else
3852:                        return syntaxError("expected 'empty greatest' or 'empty least'");
3853:                    parseSeparator();
3854:                    return QuoteExp.voidExp;
3855:
3856:                case DECLARE_OPTION_TOKEN:
3857:                    getRawToken();
3858:                    if (curToken != QNAME_TOKEN)
3859:                        syntaxError("expected QName after 'declare option'");
3860:                    else {
3861:                        String str = new String(tokenBuffer, 0,
3862:                                tokenBufferLength);
3863:                        getRawToken();
3864:                        if (curToken != STRING_TOKEN)
3865:                            syntaxError("expected string literal after 'declare option <QName>'");
3866:                        else
3867:                            handleOption(namespaceResolve(str, false),
3868:                                    new String(tokenBuffer, 0,
3869:                                            tokenBufferLength));
3870:                    }
3871:                    parseSeparator();
3872:                    seenDeclaration = true;
3873:                    return QuoteExp.voidExp;
3874:
3875:                case DECLARE_ORDERING_TOKEN:
3876:                    if (orderingModeSeen && !interactive)
3877:                        syntaxError("duplicate 'declare ordering' seen",
3878:                                "XQST0065");
3879:                    orderingModeSeen = true;
3880:                    getRawToken();
3881:                    if (match("ordered"))
3882:                        orderingModeUnordered = false;
3883:                    else if (match("unordered"))
3884:                        orderingModeUnordered = true;
3885:                    else
3886:                        return syntaxError("ordering declaration must be ordered or unordered");
3887:                    parseSeparator();
3888:                    return QuoteExp.voidExp;
3889:
3890:                case XQUERY_VERSION_TOKEN:
3891:                    if (parseCount != 1)
3892:                        error('e', "'xquery version' does not start module");
3893:                    else if (commentCount > 0)
3894:                        error('w',
3895:                                "comments should not precede 'xquery version'");
3896:                    getRawToken();
3897:                    if (curToken == STRING_TOKEN) {
3898:                        String version = new String(tokenBuffer, 0,
3899:                                tokenBufferLength);
3900:                        if (!version.equals("1.0"))
3901:                            error('e',
3902:                                    "unrecognized xquery version " + version,
3903:                                    "XQST0031");
3904:                        getRawToken();
3905:                    } else
3906:                        return syntaxError("missing version string after 'xquery version'");
3907:                    if (match("encoding")) {
3908:                        getRawToken();
3909:                        if (curToken != STRING_TOKEN)
3910:                            return syntaxError("invalid encoding specification");
3911:                        else {
3912:                            String encoding = new String(tokenBuffer, 0,
3913:                                    tokenBufferLength);
3914:                            int i = tokenBufferLength;
3915:                            boolean bad = i == 0;
3916:                            while (--i >= 0 && !bad) {
3917:                                ch = tokenBuffer[i];
3918:                                if ((ch >= 'A' && ch <= 'Z')
3919:                                        || (ch >= 'a' && ch <= 'z'))
3920:                                    continue;
3921:                                if (i == 0
3922:                                        || !((ch >= '0' && ch <= '9')
3923:                                                || ch == '.' || ch == '_' || ch == '-'))
3924:                                    bad = true;
3925:                            }
3926:                            if (bad)
3927:                                error('e', "invalid encoding name syntax",
3928:                                        "XQST0087");
3929:                            // ignore encoding specification.
3930:                            getRawToken();
3931:                        }
3932:                    }
3933:                    if (curToken != ';')
3934:                        syntaxError("missing ';'");
3935:                    return QuoteExp.voidExp;
3936:
3937:                case DECLARE_BASE_URI_TOKEN:
3938:                    if (baseURIDeclarationSeen && !interactive)
3939:                        syntaxError("duplicate 'declare base-uri' seen",
3940:                                "XQST0032");
3941:                    baseURIDeclarationSeen = true;
3942:                    val = parseURILiteral();
3943:                    if (val instanceof  Expression) // an ErrorExp
3944:                        return (Expression) val;
3945:                    parseSeparator();
3946:                    setStaticBaseUri((String) val);
3947:                    return QuoteExp.voidExp;
3948:                }
3949:                exp = parseExprSequence(EOF_TOKEN, true);
3950:                if (curToken == EOL_TOKEN)
3951:                    unread('\n');
3952:                maybeSetLine(exp, startLine, startColumn);
3953:                return exp;
3954:            }
3955:
3956:            public void handleOption(Symbol name, String value) {
3957:                // Nothing, for now.
3958:            }
3959:
3960:            public final static String[] axisNames = new String[COUNT_OP_AXIS];
3961:            static {
3962:                axisNames[AXIS_ANCESTOR] = "ancestor";
3963:                axisNames[AXIS_ANCESTOR_OR_SELF] = "ancestor-or-self";
3964:                axisNames[AXIS_ATTRIBUTE] = "attribute";
3965:                axisNames[AXIS_CHILD] = "child";
3966:                axisNames[AXIS_DESCENDANT] = "descendant";
3967:                axisNames[AXIS_DESCENDANT_OR_SELF] = "descendant-or-self";
3968:                axisNames[AXIS_FOLLOWING] = "following";
3969:                axisNames[AXIS_FOLLOWING_SIBLING] = "following-sibling";
3970:                axisNames[AXIS_NAMESPACE] = "namespace";
3971:                axisNames[AXIS_PARENT] = "parent";
3972:                axisNames[AXIS_PRECEDING] = "preceding";
3973:                axisNames[AXIS_PRECEDING_SIBLING] = "preceding-sibling";
3974:                axisNames[AXIS_SELF] = "self";
3975:            }
3976:
3977:            public static Expression makeFunctionExp(String className,
3978:                    String name) {
3979:                return makeFunctionExp(className, Compilation
3980:                        .mangleNameIfNeeded(name), name);
3981:            }
3982:
3983:            public static Expression makeFunctionExp(String className,
3984:                    String fieldName, String name) {
3985:                return new ReferenceExp(name, Declaration
3986:                        .getDeclarationValueFromStatic(className, fieldName,
3987:                                name));
3988:            }
3989:
3990:            /** Helper method for debugging. */
3991:            String tokenString() {
3992:                switch (curToken) {
3993:                case STRING_TOKEN:
3994:                    StringBuffer sbuf = new StringBuffer();
3995:                    sbuf.append('"');
3996:                    for (int i = 0; i < tokenBufferLength; i++) {
3997:                        char ch = tokenBuffer[i];
3998:                        if (ch == '"')
3999:                            sbuf.append('"');
4000:                        sbuf.append(ch);
4001:                    }
4002:                    sbuf.append('"');
4003:                    return sbuf.toString();
4004:                case FNAME_TOKEN:
4005:                    return new String(tokenBuffer, 0, tokenBufferLength)
4006:                            + " + '('";
4007:                case NCNAME_TOKEN:
4008:                case QNAME_TOKEN:
4009:                    return new String(tokenBuffer, 0, tokenBufferLength);
4010:                case EOF_TOKEN:
4011:                    return "<EOF>";
4012:                default:
4013:                    if (curToken >= OP_AXIS_FIRST
4014:                            && curToken - OP_AXIS_FIRST < COUNT_OP_AXIS)
4015:                        return axisNames[curToken - OP_AXIS_FIRST] + "::-axis("
4016:                                + curToken + ")";
4017:                    return Integer.toString(curToken);
4018:                }
4019:            }
4020:
4021:            public void error(char severity, String message, String code) {
4022:                SourceMessages messages = getMessages();
4023:                SourceError err = new SourceError(severity, port.getName(),
4024:                        curLine, curColumn, message);
4025:                err.code = code;
4026:                messages.error(err);
4027:            }
4028:
4029:            public void error(char severity, String message) {
4030:                error(severity, message, null);
4031:            }
4032:
4033:            public Expression declError(String message)
4034:                    throws java.io.IOException, SyntaxException {
4035:                if (interactive)
4036:                    return syntaxError(message);
4037:                error(message);
4038:                for (;;) {
4039:                    if (curToken == ';' || curToken == EOF_TOKEN)
4040:                        break;
4041:                    getRawToken();
4042:                }
4043:                return new ErrorExp(message);
4044:            }
4045:
4046:            /**
4047:             * Handle syntax errors (at rewrite time).
4048:             * @param message an error message to print out
4049:             * @return an ErrorExp
4050:             */
4051:            public Expression syntaxError(String message, String code)
4052:                    throws java.io.IOException, SyntaxException {
4053:                error('e', message, code);
4054:                if (interactive) {
4055:                    curToken = 0;
4056:                    curValue = null;
4057:                    nesting = 0;
4058:                    ((InPort) getPort()).readState = '\n';
4059:                    for (;;) {
4060:                        int ch = read();
4061:                        if (ch < 0)
4062:                            break;
4063:                        if (ch == '\r' || ch == '\n') {
4064:                            unread(ch);
4065:                            break;
4066:                        }
4067:                    }
4068:                    throw new SyntaxException(getMessages());
4069:                }
4070:                return new ErrorExp(message);
4071:            }
4072:
4073:            public Expression syntaxError(String message)
4074:                    throws java.io.IOException, SyntaxException {
4075:                return syntaxError(message, "XPST0003");
4076:            }
4077:
4078:            public void eofError(String msg) throws SyntaxException {
4079:                fatal(msg, "XPST0003");
4080:            }
4081:
4082:            public void fatal(String msg, String code) throws SyntaxException {
4083:                SourceMessages messages = getMessages();
4084:                SourceError err = new SourceError('f', port.getName(), curLine,
4085:                        curColumn, msg);
4086:                err.code = code;
4087:                messages.error(err);
4088:                throw new SyntaxException(messages);
4089:            }
4090:
4091:            void warnOldVersion(String message) {
4092:                if (warnOldVersion || comp.isPedantic())
4093:                    error(comp.isPedantic() ? 'e' : 'w', message);
4094:            }
4095:
4096:            public void maybeSetLine(Expression exp, int line, int column) {
4097:                String file = getName();
4098:                if (file != null) {
4099:                    exp.setFile(file);
4100:                    exp.setLine(line, column);
4101:                }
4102:            }
4103:
4104:            public void maybeSetLine(Declaration decl, int line, int column) {
4105:                String file = getName();
4106:                if (file != null) {
4107:                    decl.setFile(file);
4108:                    decl.setLine(line, column);
4109:                }
4110:            }
4111:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.