KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > org > apache > xerces > internal > impl > xpath > XPath


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2000-2002 The Apache Software Foundation.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57
58 package com.sun.org.apache.xerces.internal.impl.xpath;
59
60 import java.util.Vector JavaDoc;
61
62 import com.sun.org.apache.xerces.internal.util.SymbolTable;
63 import com.sun.org.apache.xerces.internal.util.XMLSymbols;
64 import com.sun.org.apache.xerces.internal.util.XMLChar;
65 import com.sun.org.apache.xerces.internal.xni.NamespaceContext;
66 import com.sun.org.apache.xerces.internal.xni.QName;
67
68 /**
69  * Bare minimum XPath parser.
70  *
71  * @author Andy Clark, IBM
72  * @version $Id: XPath.java,v 1.13 2004/02/09 22:50:01 kohsuke Exp $
73  */

74 public class XPath {
75
76     //
77
// Constants
78
//
79

80     private static final boolean DEBUG_ALL = false;
81
82     private static final boolean DEBUG_XPATH_PARSE = DEBUG_ALL || false;
83
84     private static final boolean DEBUG_ANY = DEBUG_XPATH_PARSE;
85
86     //
87
// Data
88
//
89

90     /** Expression. */
91     protected String JavaDoc fExpression;
92
93     /** Symbol table. */
94     protected SymbolTable fSymbolTable;
95
96     /** Location paths. */
97     protected LocationPath[] fLocationPaths;
98
99     //
100
// Constructors
101
//
102

103     /** Constructs an XPath object from the specified expression. */
104     public XPath(String JavaDoc xpath, SymbolTable symbolTable,
105                  NamespaceContext context)
106         throws XPathException {
107         fExpression = xpath;
108         fSymbolTable = symbolTable;
109         parseExpression(context);
110     } // <init>(String,SymbolTable,NamespaceContext)
111

112     //
113
// Public methods
114
//
115

116     /**
117      * Returns a representation of all location paths for this XPath.
118      * XPath = locationPath ( '|' locationPath)
119      */

120     public LocationPath[] getLocationPaths() {
121         LocationPath[] ret=new LocationPath[fLocationPaths.length];
122         for (int i=0;i<fLocationPaths.length;i++){
123             ret[i]=(LocationPath)fLocationPaths[i].clone();
124         }
125         return ret;
126     } // getLocationPath(LocationPath)
127

128     /** Returns a representation of the first location path for this XPath. */
129     public LocationPath getLocationPath() {
130         return (LocationPath)fLocationPaths[0].clone();
131     } // getLocationPath(LocationPath)
132

133     //
134
// Object methods
135
//
136

137     /** Returns a string representation of this object. */
138     public String JavaDoc toString() {
139         StringBuffer JavaDoc buf=new StringBuffer JavaDoc();
140         for (int i=0;i<fLocationPaths.length;i++){
141             if (i>0){
142                 buf.append("|");
143             }
144             buf.append(fLocationPaths[i].toString());
145         }
146         return buf.toString();
147     } // toString():String
148

149     //
150
// Private methods
151
//
152

153     /**
154      * Used by the {@link #parseExpression(NamespaceContext)} method
155      * to verify the assumption.
156      *
157      * If <tt>b</tt> is false, this method throws XPathException
158      * to report the error.
159      */

160     private static void check( boolean b ) throws XPathException {
161         if(!b) throw new XPathException("c-general-xpath");
162     }
163     
164     /**
165      * Used by the {@link #parseExpression(NamespaceContext)} method
166      * to build a {@link LocationPath} object from the accumulated
167      * {@link Step}s.
168      */

169     private LocationPath buildLocationPath( Vector JavaDoc stepsVector ) throws XPathException {
170         int size = stepsVector.size();
171         check(size!=0);
172         Step[] steps = new Step[size];
173         stepsVector.copyInto(steps);
174         stepsVector.removeAllElements();
175         
176         return new LocationPath(steps);
177     }
178     
179     /**
180      * This method is implemented by using the XPathExprScanner and
181      * examining the list of tokens that it returns.
182      */

183     private void parseExpression(final NamespaceContext context)
184         throws XPathException {
185
186         // tokens
187
final XPath.Tokens xtokens = new XPath.Tokens(fSymbolTable);
188
189         // scanner
190
XPath.Scanner scanner = new XPath.Scanner(fSymbolTable) {
191             protected void addToken(XPath.Tokens tokens, int token)
192                 throws XPathException {
193                 if (
194                     token == XPath.Tokens.EXPRTOKEN_ATSIGN ||
195                     token == XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME ||
196                     token == XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH ||
197                     token == XPath.Tokens.EXPRTOKEN_PERIOD ||
198                     token == XPath.Tokens.EXPRTOKEN_NAMETEST_ANY ||
199                     token == XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE ||
200                     token == XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH ||
201                     token == XPath.Tokens.EXPRTOKEN_OPERATOR_UNION
202                     //
203
) {
204                     super.addToken(tokens, token);
205                     return;
206                 }
207                 throw new XPathException("c-general-xpath");
208             }
209         };
210
211         int length = fExpression.length();
212         
213         boolean success = scanner.scanExpr(fSymbolTable,
214                                            xtokens, fExpression, 0, length);
215         if(!success)
216             throw new XPathException("c-general-xpath");
217         
218         //fTokens.dumpTokens();
219
Vector JavaDoc stepsVector = new Vector JavaDoc();
220         Vector JavaDoc locationPathsVector= new Vector JavaDoc();
221         
222         // true when the next token should be 'Step' (as defined in
223
// the production rule [3] of XML Schema P1 section 3.11.6
224
// if false, we are expecting either '|' or '/'.
225
//
226
// this is to make sure we can detect a token list like
227
// 'abc' '/' '/' 'def' 'ghi'
228
boolean expectingStep = true;
229
230         while(xtokens.hasMore()) {
231             final int token = xtokens.nextToken();
232
233             switch (token) {
234                 case XPath.Tokens.EXPRTOKEN_OPERATOR_UNION :{
235                     check(!expectingStep);
236                     locationPathsVector.addElement(buildLocationPath(stepsVector));
237                     expectingStep=true;
238                     break;
239                 }
240
241                 case XPath.Tokens.EXPRTOKEN_ATSIGN: {
242                     check(expectingStep);
243                     Step step = new Step(
244                             new Axis(Axis.ATTRIBUTE),
245                             parseNodeTest(xtokens.nextToken(),xtokens,context));
246                     stepsVector.addElement(step);
247                     expectingStep=false;
248                     break;
249                 }
250                 case XPath.Tokens.EXPRTOKEN_NAMETEST_ANY:
251                 case XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE:
252                 case XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME: {
253                     check(expectingStep);
254                     Step step = new Step(
255                             new Axis(Axis.CHILD),
256                             parseNodeTest(token,xtokens,context));
257                     stepsVector.addElement(step);
258                     expectingStep=false;
259                     break;
260                 }
261
262                 case XPath.Tokens.EXPRTOKEN_PERIOD: {
263                     check(expectingStep);
264                     expectingStep=false;
265
266                     // unless this is the first step in this location path,
267
// there's really no reason to keep them in LocationPath.
268
// This amounts to shorten "a/././b/./c" to "a/b/c".
269
// Also, the matcher fails to work correctly if XPath
270
// has those redundant dots.
271
if (stepsVector.size()==0) {
272                         // build step
273
Axis axis = new Axis(Axis.SELF);
274                         NodeTest nodeTest = new NodeTest(NodeTest.NODE);
275                         Step step = new Step(axis, nodeTest);
276                         stepsVector.addElement(step);
277                         
278                         if( xtokens.hasMore()
279                          && xtokens.peekToken() == XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH){
280                             // consume '//'
281
xtokens.nextToken();
282                             
283                             // build step
284
axis = new Axis(Axis.DESCENDANT);
285                             nodeTest = new NodeTest(NodeTest.NODE);
286                             step = new Step(axis, nodeTest);
287                             stepsVector.addElement(step);
288                             expectingStep=true;
289                         }
290                     }
291                     break;
292                 }
293
294                 case XPath.Tokens.EXPRTOKEN_OPERATOR_DOUBLE_SLASH:{
295                     // this cannot appear in arbitrary position.
296
// it is only allowed right after '.' when
297
// '.' is the first token of a location path.
298
throw new XPathException("c-general-xpath");
299                 }
300                 case XPath.Tokens.EXPRTOKEN_OPERATOR_SLASH: {
301                     check(!expectingStep);
302                     expectingStep=true;
303                     break;
304                 }
305                 default:
306                     // we should have covered all the tokens that we can possibly see.
307
throw new InternalError JavaDoc();
308             }
309         }
310         
311         check(!expectingStep);
312
313         locationPathsVector.addElement(buildLocationPath(stepsVector));
314
315         // save location path
316
fLocationPaths=new LocationPath[locationPathsVector.size()];
317         locationPathsVector.copyInto(fLocationPaths);
318
319
320         if (DEBUG_XPATH_PARSE) {
321             System.out.println(">>> "+fLocationPaths);
322         }
323
324     } // parseExpression(SymbolTable,NamespaceContext)
325

326     /**
327      * Used by {@link #parseExpression} to parse a node test
328      * from the token list.
329      */

330     private NodeTest parseNodeTest( int typeToken, Tokens xtokens, NamespaceContext context )
331         throws XPathException {
332         switch(typeToken) {
333         case XPath.Tokens.EXPRTOKEN_NAMETEST_ANY:
334             return new NodeTest(NodeTest.WILDCARD);
335             
336         case XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE:
337         case XPath.Tokens.EXPRTOKEN_NAMETEST_QNAME:
338             // consume QName token
339
String JavaDoc prefix = xtokens.nextTokenAsString();
340             String JavaDoc uri = null;
341             if (context != null && prefix != XMLSymbols.EMPTY_STRING) {
342                 uri = context.getURI(prefix);
343             }
344             if (prefix != XMLSymbols.EMPTY_STRING && context != null && uri == null) {
345                 throw new XPathException("c-general-xpath-ns");
346             }
347     
348             if (typeToken==XPath.Tokens.EXPRTOKEN_NAMETEST_NAMESPACE)
349                 return new NodeTest(prefix,uri);
350     
351             String JavaDoc localpart = xtokens.nextTokenAsString();
352             String JavaDoc rawname = prefix != XMLSymbols.EMPTY_STRING
353             ? fSymbolTable.addSymbol(prefix+':'+localpart)
354             : localpart;
355     
356             return new NodeTest(new QName(prefix, localpart, rawname, uri));
357         
358         default:
359             // assertion error
360
throw new InternalError JavaDoc();
361         }
362     }
363     
364     
365     //
366
// Classes
367
//
368

369     // location path information
370

371     /**
372      * A location path representation for an XPath expression.
373      *
374      * @author Andy Clark, IBM
375      */

376     public static class LocationPath
377         implements Cloneable JavaDoc {
378
379         //
380
// Data
381
//
382

383         /** List of steps. */
384         public Step[] steps;
385
386         //
387
// Constructors
388
//
389

390         /** Creates a location path from a series of steps. */
391         public LocationPath(Step[] steps) {
392             this.steps = steps;
393         } // <init>(Step[])
394

395         /** Copy constructor. */
396         protected LocationPath(LocationPath path) {
397             steps = new Step[path.steps.length];
398             for (int i = 0; i < steps.length; i++) {
399                 steps[i] = (Step)path.steps[i].clone();
400             }
401         } // <init>(LocationPath)
402

403         //
404
// Object methods
405
//
406

407         /** Returns a string representation of this object. */
408         public String JavaDoc toString() {
409             StringBuffer JavaDoc str = new StringBuffer JavaDoc();
410             for (int i = 0; i < steps.length; i++) {
411                 if (i > 0 && (steps[i-1].axis.type!=Axis.DESCENDANT
412                     && steps[i].axis.type!=Axis.DESCENDANT) ){
413                     str.append('/');
414                 }
415                 str.append(steps[i].toString());
416             }
417             // DEBUG: This code is just for debugging and should *not*
418
// be left in because it will mess up hashcodes of
419
// serialized versions of this object. -Ac
420
if (false) {
421                 str.append('[');
422                 String JavaDoc s = super.toString();
423                 str.append(s.substring(s.indexOf('@')));
424                 str.append(']');
425             }
426             return str.toString();
427         } // toString():String
428

429         /** Returns a clone of this object. */
430         public Object JavaDoc clone() {
431             return new LocationPath(this);
432         } // clone():Object
433

434     } // class locationPath
435

436     /**
437      * A location path step comprised of an axis and node test.
438      *
439      * @author Andy Clark, IBM
440      */

441     public static class Step
442         implements Cloneable JavaDoc {
443
444         //
445
// Data
446
//
447

448         /** Axis. */
449         public Axis axis;
450
451         /** Node test. */
452         public NodeTest nodeTest;
453
454         //
455
// Constructors
456
//
457

458         /** Constructs a step from an axis and node test. */
459         public Step(Axis axis, NodeTest nodeTest) {
460             this.axis = axis;
461             this.nodeTest = nodeTest;
462         } // <init>(Axis,NodeTest)
463

464         /** Copy constructor. */
465         protected Step(Step step) {
466             axis = (Axis)step.axis.clone();
467             nodeTest = (NodeTest)step.nodeTest.clone();
468         } // <init>(Step)
469

470         //
471
// Object methods
472
//
473

474         /** Returns a string representation of this object. */
475         public String JavaDoc toString() {
476             if (axis.type == Axis.SELF) {
477                 return ".";
478             }
479             if (axis.type == Axis.ATTRIBUTE) {
480                 return "@" + nodeTest.toString();
481             }
482             if (axis.type == Axis.CHILD) {
483                 return nodeTest.toString();
484             }
485             if (axis.type == Axis.DESCENDANT) {
486                 return "//";
487             }
488             return "??? ("+axis.type+')';
489         } // toString():String
490

491         /** Returns a clone of this object. */
492         public Object JavaDoc clone() {
493             return new Step(this);
494         } // clone():Object
495

496     } // class Step
497

498     /**
499      * Axis.
500      *
501      * @author Andy Clark, IBM
502      */

503     public static class Axis
504         implements Cloneable JavaDoc {
505
506         //
507
// Constants
508
//
509

510         /** Type: child. */
511         public static final short CHILD = 1;
512
513         /** Type: attribute. */
514         public static final short ATTRIBUTE = 2;
515
516         /** Type: self. */
517         public static final short SELF = 3;
518
519
520         /** Type: descendant. */
521         public static final short DESCENDANT = 4;
522         //
523
// Data
524
//
525

526         /** Axis type. */
527         public short type;
528
529         //
530
// Constructors
531
//
532

533         /** Constructs an axis with the specified type. */
534         public Axis(short type) {
535             this.type = type;
536         } // <init>(short)
537

538         /** Copy constructor. */
539         protected Axis(Axis axis) {
540             type = axis.type;
541         } // <init>(Axis)
542

543         //
544
// Object methods
545
//
546

547         /** Returns a string representation of this object. */
548         public String JavaDoc toString() {
549             switch (type) {
550                 case CHILD: return "child";
551                 case ATTRIBUTE: return "attribute";
552                 case SELF: return "self";
553                 case DESCENDANT: return "descendant";
554             }
555             return "???";
556         } // toString():String
557

558         /** Returns a clone of this object. */
559         public Object JavaDoc clone() {
560             return new Axis(this);
561         } // clone():Object
562

563     } // class Axis
564

565     /**
566      * Node test.
567      *
568      * @author Andy Clark, IBM
569      */

570     public static class NodeTest
571         implements Cloneable JavaDoc {
572
573         //
574
// Constants
575
//
576

577         /** Type: qualified name. */
578         public static final short QNAME = 1;
579
580         /** Type: wildcard. */
581         public static final short WILDCARD = 2;
582
583         /** Type: node. */
584         public static final short NODE = 3;
585
586         /** Type: namespace */
587         public static final short NAMESPACE= 4;
588
589         //
590
// Data
591
//
592

593         /** Node test type. */
594         public short type;
595
596         /** Node qualified name. */
597         public final QName name = new QName();
598
599         //
600
// Constructors
601
//
602

603         /** Constructs a node test of type WILDCARD or NODE. */
604         public NodeTest(short type) {
605             this.type = type;
606         } // <init>(int)
607

608         /** Constructs a node test of type QName. */
609         public NodeTest(QName name) {
610             this.type = QNAME;
611             this.name.setValues(name);
612         } // <init>(QName)
613
/** Constructs a node test of type Namespace. */
614         public NodeTest(String JavaDoc prefix, String JavaDoc uri) {
615             this.type = NAMESPACE;
616             this.name.setValues(prefix, null, null, uri);
617         } // <init>(String,String)
618

619         /** Copy constructor. */
620         public NodeTest(NodeTest nodeTest) {
621             type = nodeTest.type;
622             name.setValues(nodeTest.name);
623         } // <init>(NodeTest)
624

625         //
626
// Object methods
627
//
628

629         /** Returns a string representation of this object. */
630         public String JavaDoc toString() {
631
632             switch (type) {
633                 case QNAME: {
634                     if (name.prefix.length() !=0) {
635                         if (name.uri != null) {
636                             return name.prefix+':'+name.localpart;
637                         }
638                         return "{"+name.uri+'}'+name.prefix+':'+name.localpart;
639                     }
640                     return name.localpart;
641                 }
642                 case NAMESPACE: {
643                     if (name.prefix.length() !=0) {
644                         if (name.uri != null) {
645                             return name.prefix+":*";
646                         }
647                         return "{"+name.uri+'}'+name.prefix+":*";
648                     }
649                     return "???:*";
650                 }
651                 case WILDCARD: {
652                     return "*";
653                 }
654                 case NODE: {
655                     return "node()";
656                 }
657             }
658             return "???";
659
660         } // toString():String
661

662         /** Returns a clone of this object. */
663         public Object JavaDoc clone() {
664             return new NodeTest(this);
665         } // clone():Object
666

667     } // class NodeTest
668

669     // xpath implementation
670

671     // NOTE: The XPath implementation classes are kept internal because
672
// this implementation is just a temporary hack until a better
673
// and/or more appropriate implementation can be written.
674
// keeping the code in separate source files would "muddy" the
675
// CVS directory when it's not needed. -Ac
676

677     /**
678      * List of tokens.
679      *
680      * @author Glenn Marcy, IBM
681      * @author Andy Clark, IBM
682      *
683      * @version $Id: XPath.java,v 1.13 2004/02/09 22:50:01 kohsuke Exp $
684      */

685     private static final class Tokens {
686
687         static final boolean DUMP_TOKENS = false;
688
689         /**
690          * [28] ExprToken ::= '(' | ')' | '[' | ']' | '.' | '..' | '@' | ',' | '::'
691          * | NameTest | NodeType | Operator | FunctionName
692          * | AxisName | Literal | Number | VariableReference
693          */

694         public static final int
695             EXPRTOKEN_OPEN_PAREN = 0,
696             EXPRTOKEN_CLOSE_PAREN = 1,
697             EXPRTOKEN_OPEN_BRACKET = 2,
698             EXPRTOKEN_CLOSE_BRACKET = 3,
699             EXPRTOKEN_PERIOD = 4,
700             EXPRTOKEN_DOUBLE_PERIOD = 5,
701             EXPRTOKEN_ATSIGN = 6,
702             EXPRTOKEN_COMMA = 7,
703             EXPRTOKEN_DOUBLE_COLON = 8,
704             //
705
// [37] NameTest ::= '*' | NCName ':' '*' | QName
706
//
707
// followed by symbol handle of NCName or QName
708
//
709
EXPRTOKEN_NAMETEST_ANY = 9,
710             EXPRTOKEN_NAMETEST_NAMESPACE = 10,
711             EXPRTOKEN_NAMETEST_QNAME = 11,
712             //
713
// [38] NodeType ::= 'comment' | 'text' | 'processing-instruction' | 'node'
714
//
715
EXPRTOKEN_NODETYPE_COMMENT = 12,
716             EXPRTOKEN_NODETYPE_TEXT = 13,
717             EXPRTOKEN_NODETYPE_PI = 14,
718             EXPRTOKEN_NODETYPE_NODE = 15,
719             //
720
// [32] Operator ::= OperatorName
721
// | MultiplyOperator
722
// | '/' | '//' | '|' | '+' | '-' | '=' | '!=' | '<' | '<=' | '>' | '>='
723
// [33] OperatorName ::= 'and' | 'or' | 'mod' | 'div'
724
// [34] MultiplyOperator ::= '*'
725
//
726
EXPRTOKEN_OPERATOR_AND = 16,
727             EXPRTOKEN_OPERATOR_OR = 17,
728             EXPRTOKEN_OPERATOR_MOD = 18,
729             EXPRTOKEN_OPERATOR_DIV = 19,
730             EXPRTOKEN_OPERATOR_MULT = 20,
731             EXPRTOKEN_OPERATOR_SLASH = 21,
732             EXPRTOKEN_OPERATOR_DOUBLE_SLASH = 22,
733             EXPRTOKEN_OPERATOR_UNION = 23,
734             EXPRTOKEN_OPERATOR_PLUS = 24,
735             EXPRTOKEN_OPERATOR_MINUS = 25,
736             EXPRTOKEN_OPERATOR_EQUAL = 26,
737             EXPRTOKEN_OPERATOR_NOT_EQUAL = 27,
738             EXPRTOKEN_OPERATOR_LESS = 28,
739             EXPRTOKEN_OPERATOR_LESS_EQUAL = 29,
740             EXPRTOKEN_OPERATOR_GREATER = 30,
741             EXPRTOKEN_OPERATOR_GREATER_EQUAL = 31,
742
743             //EXPRTOKEN_FIRST_OPERATOR = EXPRTOKEN_OPERATOR_AND,
744
//EXPRTOKEN_LAST_OPERATOR = EXPRTOKEN_OPERATOR_GREATER_EQUAL,
745

746             //
747
// [35] FunctionName ::= QName - NodeType
748
//
749
// followed by symbol handle
750
//
751
EXPRTOKEN_FUNCTION_NAME = 32,
752             //
753
// [6] AxisName ::= 'ancestor' | 'ancestor-or-self'
754
// | 'attribute'
755
// | 'child'
756
// | 'descendant' | 'descendant-or-self'
757
// | 'following' | 'following-sibling'
758
// | 'namespace'
759
// | 'parent'
760
// | 'preceding' | 'preceding-sibling'
761
// | 'self'
762
//
763
EXPRTOKEN_AXISNAME_ANCESTOR = 33,
764             EXPRTOKEN_AXISNAME_ANCESTOR_OR_SELF = 34,
765             EXPRTOKEN_AXISNAME_ATTRIBUTE = 35,
766             EXPRTOKEN_AXISNAME_CHILD = 36,
767             EXPRTOKEN_AXISNAME_DESCENDANT = 37,
768             EXPRTOKEN_AXISNAME_DESCENDANT_OR_SELF = 38,
769             EXPRTOKEN_AXISNAME_FOLLOWING = 39,
770             EXPRTOKEN_AXISNAME_FOLLOWING_SIBLING = 40,
771             EXPRTOKEN_AXISNAME_NAMESPACE = 41,
772             EXPRTOKEN_AXISNAME_PARENT = 42,
773             EXPRTOKEN_AXISNAME_PRECEDING = 43,
774             EXPRTOKEN_AXISNAME_PRECEDING_SIBLING = 44,
775             EXPRTOKEN_AXISNAME_SELF = 45,
776             //
777
// [29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"
778
//
779
// followed by symbol handle for literal
780
//
781
EXPRTOKEN_LITERAL = 46,
782             //
783
// [30] Number ::= Digits ('.' Digits?)? | '.' Digits
784
// [31] Digits ::= [0-9]+
785
//
786
// followed by number handle
787
//
788
EXPRTOKEN_NUMBER = 47,
789             //
790
// [36] VariableReference ::= '$' QName
791
//
792
// followed by symbol handle for QName
793
//
794
EXPRTOKEN_VARIABLE_REFERENCE = 48;
795
796         private static final String JavaDoc[] fgTokenNames = {
797             "EXPRTOKEN_OPEN_PAREN",
798             "EXPRTOKEN_CLOSE_PAREN",
799             "EXPRTOKEN_OPEN_BRACKET",
800             "EXPRTOKEN_CLOSE_BRACKET",
801             "EXPRTOKEN_PERIOD",
802             "EXPRTOKEN_DOUBLE_PERIOD",
803             "EXPRTOKEN_ATSIGN",
804             "EXPRTOKEN_COMMA",
805             "EXPRTOKEN_DOUBLE_COLON",
806             "EXPRTOKEN_NAMETEST_ANY",
807             "EXPRTOKEN_NAMETEST_NAMESPACE",
808             "EXPRTOKEN_NAMETEST_QNAME",
809             "EXPRTOKEN_NODETYPE_COMMENT",
810             "EXPRTOKEN_NODETYPE_TEXT",
811             "EXPRTOKEN_NODETYPE_PI",
812             "EXPRTOKEN_NODETYPE_NODE",
813             "EXPRTOKEN_OPERATOR_AND",
814             "EXPRTOKEN_OPERATOR_OR",
815             "EXPRTOKEN_OPERATOR_MOD",
816             "EXPRTOKEN_OPERATOR_DIV",
817             "EXPRTOKEN_OPERATOR_MULT",
818             "EXPRTOKEN_OPERATOR_SLASH",
819             "EXPRTOKEN_OPERATOR_DOUBLE_SLASH",
820             "EXPRTOKEN_OPERATOR_UNION",
821             "EXPRTOKEN_OPERATOR_PLUS",
822             "EXPRTOKEN_OPERATOR_MINUS",
823             "EXPRTOKEN_OPERATOR_EQUAL",
824             "EXPRTOKEN_OPERATOR_NOT_EQUAL",
825             "EXPRTOKEN_OPERATOR_LESS",
826             "EXPRTOKEN_OPERATOR_LESS_EQUAL",
827             "EXPRTOKEN_OPERATOR_GREATER",
828             "EXPRTOKEN_OPERATOR_GREATER_EQUAL",
829             "EXPRTOKEN_FUNCTION_NAME",
830             "EXPRTOKEN_AXISNAME_ANCESTOR",
831