2
* Copyright 2001-2004 The Apache Software Foundation.
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
10
* Unless required by applicable law or agreed to in writing, software
11
* distributed under the License is distributed on an "AS IS" BASIS,
12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
18
* $Id: xpath.cup 351910 2005-12-03 10:55:53Z zongaro $
22
* @author Jacek Ambroziak
23
* @author Santiago Pericas-Geertsen
24
* @author Morten Jorgensen
25
* @author G. Todd Miller
28
package org.apache.xalan.xsltc.compiler;
30
import java.util.Stack;
31
import java.util.Vector;
32
import java.io.StringReader;
33
import java_cup.runtime.*;
35
import org.apache.xml.dtm.DTM;
36
import org.apache.xalan.xsltc.DOM;
37
import org.apache.xml.dtm.Axis;
38
import org.apache.xalan.xsltc.runtime.Operators;
39
import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
43
* Used by function calls with no args.
45
static public final Vector EmptyArgs = new Vector(0);
48
* Reference to non-existing variable.
50
static public final VariableRef DummyVarRef = null;
53
* Reference to the Parser class.
55
private Parser _parser;
59
* String representation of the expression being parsed.
61
private String _expression;
64
* Line number where this expression/pattern was declared.
66
private int _lineNumber = 0;
69
* Reference to the symbol table.
71
public SymbolTable _symbolTable;
73
public XPathParser(Parser parser) {
75
_xsltc = parser.getXSLTC();
76
_symbolTable = parser.getSymbolTable();
79
public int getLineNumber() {
83
public QName getQNameIgnoreDefaultNs(String name) {
84
return _parser.getQNameIgnoreDefaultNs(name);
87
public QName getQName(String namespace, String prefix, String localname) {
88
return _parser.getQName(namespace, prefix, localname);
91
public void setMultiDocument(boolean flag) {
92
_xsltc.setMultiDocument(flag);
95
public void setCallsNodeset(boolean flag) {
96
_xsltc.setCallsNodeset(flag);
99
public void setHasIdCall(boolean flag) {
100
_xsltc.setHasIdCall(flag);
105
* This method is similar to findNodeType(int, Object) except that it
106
* creates a StepPattern instead of just returning a node type. It also
107
* differs in the way it handles "{uri}:*" and "{uri}:@*". The last two
108
* patterns are expanded as "*[namespace-uri() = 'uri']" and
109
* "@*[namespace-uri() = 'uri']", respectively. This expansion considerably
110
* simplifies the grouping of patterns in the Mode class. For this
111
* expansion to be correct, the priority of the pattern/template must be
112
* set to -0.25 (when no other predicates are present).
114
public StepPattern createStepPattern(int axis, Object test, Vector predicates) {
117
if (test == null) { // "*"
118
nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE :
119
(axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT;
121
return new StepPattern(axis, nodeType, predicates);
123
else if (test instanceof Integer) {
124
nodeType = ((Integer) test).intValue();
126
return new StepPattern(axis, nodeType, predicates);
129
QName name = (QName)test;
130
boolean setPriority = false;
132
if (axis == Axis.NAMESPACE) {
133
nodeType = (name.toString().equals("*")) ? -1
134
: _xsltc.registerNamespacePrefix(name);;
137
final String uri = name.getNamespace();
138
final String local = name.getLocalPart();
139
final QName namespace_uri =
140
_parser.getQNameIgnoreDefaultNs("namespace-uri");
142
// Expand {uri}:* to *[namespace-uri() = 'uri'] - same for @*
143
if (uri != null && (local.equals("*") || local.equals("@*"))) {
144
if (predicates == null) {
145
predicates = new Vector(2);
148
// Priority is set by hand if no other predicates exist
149
setPriority = (predicates.size() == 0);
153
new EqualityExpr(Operators.EQ,
154
new NamespaceUriCall(namespace_uri),
155
new LiteralExpr(uri))));
158
if (local.equals("*")) {
159
nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE
162
else if (local.equals("@*")) {
163
nodeType = NodeTest.ATTRIBUTE;
166
nodeType = (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name)
167
: _xsltc.registerElement(name);
171
final StepPattern result = new StepPattern(axis, nodeType, predicates);
173
// Set priority for case prefix:* and prefix:@* (no predicates)
175
result.setPriority(-0.25);
182
public int findNodeType(int axis, Object test) {
183
if (test == null) { // *
184
return (axis == Axis.ATTRIBUTE) ?
186
(axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT;
188
else if (test instanceof Integer) {
189
return ((Integer)test).intValue();
192
QName name = (QName)test;
194
if (axis == Axis.NAMESPACE) {
195
return (name.toString().equals("*")) ? -1
196
: _xsltc.registerNamespacePrefix(name);
199
if (name.getNamespace() == null) {
200
final String local = name.getLocalPart();
202
if (local.equals("*")) {
203
return (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE
206
else if (local.equals("@*")) {
207
return NodeTest.ATTRIBUTE;
211
return (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name)
212
: _xsltc.registerElement(name);
217
* Parse the expression passed to the current scanner. If this
218
* expression contains references to local variables and it will be
219
* compiled in an external module (not in the main class) request
220
* the current template to create a new variable stack frame.
222
* @param lineNumber Line where the current expression is defined.
223
* @param external Set to <tt>true</tt> if this expression is
224
* compiled in a separate module.
227
public Symbol parse(String expression, int lineNumber) throws Exception {
229
_expression = expression;
230
_lineNumber = lineNumber;
231
return super.parse();
233
catch (IllegalCharException e) {
234
ErrorMsg err = new ErrorMsg(ErrorMsg.ILLEGAL_CHAR_ERR,
235
lineNumber, e.getMessage());
236
_parser.reportError(Constants.FATAL, err);
242
* Lookup a variable or parameter in the symbol table given its name.
244
* @param name Name of the symbol being looked up.
246
final SyntaxTreeNode lookupName(QName name) {
247
// Is it a local var or param ?
248
final SyntaxTreeNode result = _parser.lookupVariable(name);
252
return(_symbolTable.lookupName(name));
255
public final void addError(ErrorMsg error) {
256
_parser.reportError(Constants.ERROR, error);
259
public void report_error(String message, Object info) {
260
final ErrorMsg err = new ErrorMsg(ErrorMsg.SYNTAX_ERR, _lineNumber,
262
_parser.reportError(Constants.FATAL, err);
265
public void report_fatal_error(String message, Object info) {
269
public RelativeLocationPath insertStep(Step step, RelativeLocationPath rlp) {
270
if (rlp instanceof Step) {
271
return new ParentLocationPath(step, (Step) rlp);
273
else if (rlp instanceof ParentLocationPath) {
274
final ParentLocationPath plp = (ParentLocationPath) rlp;
275
final RelativeLocationPath newrlp = insertStep(step, plp.getPath());
276
return new ParentLocationPath(newrlp, plp.getStep());
279
addError(new ErrorMsg(ErrorMsg.INTERNAL_ERR, "XPathParser.insertStep"));
285
* Returns true if the axis applies to elements only. The axes
286
* child, attribute, namespace, descendant result in non-empty
287
* nodesets only if the context node is of type element.
289
public boolean isElementAxis(int axis) {
290
return (axis == Axis.CHILD || axis == Axis.ATTRIBUTE ||
291
axis == Axis.NAMESPACE || axis == Axis.DESCENDANT);
295
terminal SLASH, DOT, LBRACK, RBRACK, VBAR, LPAREN, RPAREN, STAR, COMMA;
296
terminal DOLLAR, ATSIGN;
297
terminal DDOT, DCOLON, DSLASH;
299
terminal LT, GT, LE, GE;
300
terminal PLUS, MINUS, DIV, MOD, MULT;
301
terminal String Literal;
302
terminal String QNAME;
303
terminal ID, KEY, TEXT, NODE, OR, AND, COMMENT, PI, PIPARAM, PRECEDINGSIBLING;
304
terminal SELF, PARENT, CHILD, ATTRIBUTE, ANCESTOR, ANCESTORORSELF, DESCENDANT;
305
terminal DESCENDANTORSELF, FOLLOWING, FOLLOWINGSIBLING, NAMESPACE, PRECEDING;
306
terminal Double REAL;
308
terminal PATTERN, EXPRESSION;
310
non terminal SyntaxTreeNode TopLevel;
312
non terminal Expression Expr, Argument, LocationPath;
313
non terminal Expression Predicate, FilterExpr, Step;
314
non terminal Expression OrExpr, AndExpr, EqualityExpr;
315
non terminal Expression RelationalExpr, AdditiveExpr;
316
non terminal Expression MultiplicativeExpr, UnaryExpr;
317
non terminal Expression VariableReference, FunctionCall;
318
non terminal Expression PrimaryExpr, UnionExpr, PathExpr, AbbreviatedStep;
319
non terminal Expression RelativeLocationPath, AbbreviatedRelativeLocationPath;
320
non terminal Expression AbsoluteLocationPath, AbbreviatedAbsoluteLocationPath;
322
non terminal Object NodeTest, NameTest;
324
non terminal IdKeyPattern IdKeyPattern;
325
non terminal Pattern Pattern;
326
non terminal Pattern LocationPathPattern;
327
non terminal StepPattern ProcessingInstructionPattern;
328
non terminal RelativePathPattern RelativePathPattern;
329
non terminal StepPattern StepPattern;
330
non terminal Object NodeTestPattern, NameTestPattern;
332
non terminal Vector Predicates, NonemptyArgumentList;
333
non terminal QName QName, FunctionName, VariableName;
334
non terminal Integer AxisName, AxisSpecifier;
335
non terminal Integer ChildOrAttributeAxisSpecifier;
337
precedence left VBAR;
340
precedence nonassoc EQ, NE;
341
precedence left LT, GT, LE, GE;
343
precedence left PLUS, MINUS;
344
precedence left DIV, MOD, MULT;
345
precedence left DOLLAR;
346
precedence left ATSIGN;
347
precedence right DCOLON;
351
TopLevel ::= PATTERN Pattern:pattern
352
{: RESULT = pattern; :}
354
| EXPRESSION Expr:expr
355
{: RESULT = expr; :};
357
/* --------------------------- Patterns ----------------------------------- */
359
Pattern ::= LocationPathPattern:lpp
362
| LocationPathPattern:lpp VBAR Pattern:p
363
{: RESULT = new AlternativePattern(lpp, p); :};
365
LocationPathPattern ::= SLASH
366
{: RESULT = new AbsolutePathPattern(null); :}
368
| SLASH RelativePathPattern:rpp
369
{: RESULT = new AbsolutePathPattern(rpp); :}
374
| IdKeyPattern:ikp SLASH RelativePathPattern:rpp
375
{: RESULT = new ParentPattern(ikp, rpp); :}
377
| IdKeyPattern:ikp DSLASH RelativePathPattern:rpp
378
{: RESULT = new AncestorPattern(ikp, rpp); :}
380
| DSLASH RelativePathPattern:rpp
381
{: RESULT = new AncestorPattern(rpp); :}
383
| RelativePathPattern:rpp
386
IdKeyPattern ::= ID LPAREN Literal:l RPAREN
387
{: RESULT = new IdPattern(l);
388
parser.setHasIdCall(true);
391
| KEY LPAREN Literal:l1 COMMA Literal:l2 RPAREN
392
{: RESULT = new KeyPattern(l1, l2); :};
394
ProcessingInstructionPattern ::= PIPARAM LPAREN Literal:l RPAREN
395
{: RESULT = new ProcessingInstructionPattern(l); :};
397
RelativePathPattern ::= StepPattern:sp
400
| StepPattern:sp SLASH RelativePathPattern:rpp
401
{: RESULT = new ParentPattern(sp, rpp); :}
403
| StepPattern:sp DSLASH RelativePathPattern:rpp
404
{: RESULT = new AncestorPattern(sp, rpp); :};
406
StepPattern ::= NodeTestPattern:nt
408
RESULT = parser.createStepPattern(Axis.CHILD, nt, null);
411
| NodeTestPattern:nt Predicates:pp
413
RESULT = parser.createStepPattern(Axis.CHILD, nt, pp);
416
| ProcessingInstructionPattern:pip
419
| ProcessingInstructionPattern:pip Predicates:pp
420
{: RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :}
422
| ChildOrAttributeAxisSpecifier:axis NodeTestPattern:nt
424
RESULT = parser.createStepPattern(axis.intValue(), nt, null);
427
| ChildOrAttributeAxisSpecifier:axis
428
NodeTestPattern:nt Predicates:pp
430
RESULT = parser.createStepPattern(axis.intValue(), nt, pp);
433
| ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip
435
RESULT = pip; // TODO: report error if axis is attribute
438
| ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip
441
// TODO: report error if axis is attribute
442
RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp);
445
NodeTestPattern ::= NameTestPattern:nt
449
{: RESULT = new Integer(NodeTest.ANODE); :}
452
{: RESULT = new Integer(NodeTest.TEXT); :}
455
{: RESULT = new Integer(NodeTest.COMMENT); :}
458
{: RESULT = new Integer(NodeTest.PI); :};
460
NameTestPattern ::= STAR
466
ChildOrAttributeAxisSpecifier ::= ATSIGN
467
{: RESULT = new Integer(Axis.ATTRIBUTE); :}
470
{: RESULT = new Integer(Axis.CHILD); :}
473
{: RESULT = new Integer(Axis.ATTRIBUTE); :};
475
Predicates ::= Predicate:p
477
Vector temp = new Vector();
482
| Predicate:p Predicates:pp
483
{: pp.insertElementAt(p, 0); RESULT = pp; :};
485
Predicate ::= LBRACK Expr:e RBRACK
487
RESULT = new Predicate(e);
490
/* --------------------------- Expressions --------------------------------- */
495
OrExpr ::= AndExpr:ae
498
| OrExpr:oe OR AndExpr:ae
499
{: RESULT = new LogicalExpr(LogicalExpr.OR, oe, ae); :};
501
AndExpr ::= EqualityExpr:e
504
| AndExpr:ae AND EqualityExpr:ee
505
{: RESULT = new LogicalExpr(LogicalExpr.AND, ae, ee); :};
507
EqualityExpr ::= RelationalExpr:re
510
| EqualityExpr:ee EQ RelationalExpr:re
511
{: RESULT = new EqualityExpr(Operators.EQ, ee, re); :}
513
| EqualityExpr:ee NE RelationalExpr:re
514
{: RESULT = new EqualityExpr(Operators.NE, ee, re); :};
516
RelationalExpr ::= AdditiveExpr:ae
519
| RelationalExpr:re LT AdditiveExpr:ae
520
{: RESULT = new RelationalExpr(Operators.LT, re, ae); :}
522
| RelationalExpr:re GT AdditiveExpr:ae
523
{: RESULT = new RelationalExpr(Operators.GT, re, ae); :}
525
| RelationalExpr:re LE AdditiveExpr:ae
526
{: RESULT = new RelationalExpr(Operators.LE, re, ae); :}
528
| RelationalExpr:re GE AdditiveExpr:ae
529
{: RESULT = new RelationalExpr(Operators.GE, re, ae); :};
531
AdditiveExpr ::= MultiplicativeExpr:me
534
| AdditiveExpr:ae PLUS MultiplicativeExpr:me
535
{: RESULT = new BinOpExpr(BinOpExpr.PLUS, ae, me); :}
537
| AdditiveExpr:ae MINUS MultiplicativeExpr:me
538
{: RESULT = new BinOpExpr(BinOpExpr.MINUS, ae, me); :};
540
MultiplicativeExpr ::= UnaryExpr:ue
543
| MultiplicativeExpr:me MULT UnaryExpr:ue
544
{: RESULT = new BinOpExpr(BinOpExpr.TIMES, me, ue); :}
546
| MultiplicativeExpr:me DIV UnaryExpr:ue
547
{: RESULT = new BinOpExpr(BinOpExpr.DIV, me, ue); :}
549
| MultiplicativeExpr:me MOD UnaryExpr:ue
550
{: RESULT = new BinOpExpr(BinOpExpr.MOD, me, ue); :};
552
UnaryExpr ::= UnionExpr:ue
556
{: RESULT = new UnaryOpExpr(ue); :};
558
UnionExpr ::= PathExpr:pe
561
| PathExpr:pe VBAR UnionExpr:rest
562
{: RESULT = new UnionPathExpr(pe, rest); :};
564
PathExpr ::= LocationPath:lp
570
| FilterExpr:fexp SLASH RelativeLocationPath:rlp
571
{: RESULT = new FilterParentPath(fexp, rlp); :}
573
| FilterExpr:fexp DSLASH RelativeLocationPath:rlp
576
// Expand '//' into '/descendant-or-self::node()/' or
577
// into /descendant-or-self::*/
579
int nodeType = DOM.NO_TYPE;
580
if (rlp instanceof Step &&
581
parser.isElementAxis(((Step) rlp).getAxis()))
583
nodeType = DTM.ELEMENT_NODE;
585
final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
586
FilterParentPath fpp = new FilterParentPath(fexp, step);
587
fpp = new FilterParentPath(fpp, rlp);
588
if (fexp instanceof KeyCall == false) {
589
fpp.setDescendantAxis();
594
LocationPath ::= RelativeLocationPath:rlp
597
| AbsoluteLocationPath:alp
600
RelativeLocationPath ::= Step:step
603
| RelativeLocationPath:rlp SLASH Step:step
605
if (rlp instanceof Step && ((Step) rlp).isAbbreviatedDot()) {
606
RESULT = step; // Remove './' from the middle
608
else if (((Step) step).isAbbreviatedDot()) {
609
RESULT = rlp; // Remove '/.' from the end
613
new ParentLocationPath((RelativeLocationPath) rlp, step);
617
| AbbreviatedRelativeLocationPath:arlp
618
{: RESULT = arlp; :};
620
AbsoluteLocationPath ::= SLASH
621
{: RESULT = new AbsoluteLocationPath(); :}
623
| SLASH RelativeLocationPath:rlp
624
{: RESULT = new AbsoluteLocationPath(rlp); :}
626
| AbbreviatedAbsoluteLocationPath:aalp
627
{: RESULT = aalp; :};
629
AbbreviatedRelativeLocationPath ::= RelativeLocationPath:rlp DSLASH Step:step
631
final Step right = (Step)step;
632
final int axis = right.getAxis();
633
final int type = right.getNodeType();
634
final Vector predicates = right.getPredicates();
636
if ((axis == Axis.CHILD) && (type != NodeTest.ATTRIBUTE)) {
637
// Compress './/child:E' into 'descendant::E' - if possible
638
if (predicates == null) {
639
right.setAxis(Axis.DESCENDANT);
640
if (rlp instanceof Step && ((Step)rlp).isAbbreviatedDot()) {
644
// Expand 'rlp//child::E' into 'rlp/descendant::E'
645
RelativeLocationPath left = (RelativeLocationPath)rlp;
646
RESULT = new ParentLocationPath(left, right);
650
// Expand './/step' -> 'descendant-or-self::*/step'
651
if (rlp instanceof Step && ((Step)rlp).isAbbreviatedDot()) {
652
Step left = new Step(Axis.DESCENDANTORSELF,
653
DTM.ELEMENT_NODE, null);
654
RESULT = new ParentLocationPath(left, right);
657
// Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step'
658
RelativeLocationPath left = (RelativeLocationPath)rlp;
659
Step mid = new Step(Axis.DESCENDANTORSELF,
660
DTM.ELEMENT_NODE, null);
661
ParentLocationPath ppl = new ParentLocationPath(mid, right);
662
RESULT = new ParentLocationPath(left, ppl);
666
else if ((axis == Axis.ATTRIBUTE) || (type == NodeTest.ATTRIBUTE)) {
667
// Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step'
668
RelativeLocationPath left = (RelativeLocationPath)rlp;
669
Step middle = new Step(Axis.DESCENDANTORSELF,
670
DTM.ELEMENT_NODE, null);
671
ParentLocationPath ppl = new ParentLocationPath(middle, right);
672
RESULT = new ParentLocationPath(left, ppl);
675
// Expand 'rlp//step' -> 'rlp/descendant-or-self::node()/step'
676
RelativeLocationPath left = (RelativeLocationPath)rlp;
677
Step middle = new Step(Axis.DESCENDANTORSELF,
679
ParentLocationPath ppl = new ParentLocationPath(middle, right);
680
RESULT = new ParentLocationPath(left, ppl);
685
AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp
688
// Expand '//' into '/descendant-or-self::node()/' or
689
// into /descendant-or-self::*/
691
int nodeType = DOM.NO_TYPE;
692
if (rlp instanceof Step &&
693
parser.isElementAxis(((Step) rlp).getAxis()))
695
nodeType = DTM.ELEMENT_NODE;
697
final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null);
698
RESULT = new AbsoluteLocationPath(parser.insertStep(step,
699
(RelativeLocationPath) rlp));
702
Step ::= NodeTest:ntest
704
if (ntest instanceof Step) {
705
RESULT = (Step)ntest;
708
RESULT = new Step(Axis.CHILD,
709
parser.findNodeType(Axis.CHILD, ntest),
714
| NodeTest:ntest Predicates:pp
716
if (ntest instanceof Step) {
717
Step step = (Step)ntest;
718
step.addPredicates(pp);
719
RESULT = (Step)ntest;
722
RESULT = new Step(Axis.CHILD,
723
parser.findNodeType(Axis.CHILD, ntest), pp);
727
| AxisSpecifier:axis NodeTest:ntest Predicates:pp
728
{: RESULT = new Step(axis.intValue(),
729
parser.findNodeType(axis.intValue(), ntest),
733
| AxisSpecifier:axis NodeTest:ntest
734
{: RESULT = new Step(axis.intValue(),
735
parser.findNodeType(axis.intValue(), ntest),
739
| AbbreviatedStep:abbrev
740
{: RESULT = abbrev; :};
742
AxisSpecifier ::= AxisName:an DCOLON
746
{: RESULT = new Integer(Axis.ATTRIBUTE); :};
748
AxisName ::= ANCESTOR
749
{: RESULT = new Integer(Axis.ANCESTOR); :}
752
{: RESULT = new Integer(Axis.ANCESTORORSELF); :}
755
{: RESULT = new Integer(Axis.ATTRIBUTE); :}
758
{: RESULT = new Integer(Axis.CHILD); :}
761
{: RESULT = new Integer(Axis.DESCENDANT); :}
764
{: RESULT = new Integer(Axis.DESCENDANTORSELF); :}
767
{: RESULT = new Integer(Axis.FOLLOWING); :}
770
{: RESULT = new Integer(Axis.FOLLOWINGSIBLING); :}
773
{: RESULT = new Integer(Axis.NAMESPACE); :}
776
{: RESULT = new Integer(Axis.PARENT); :}
779
{: RESULT = new Integer(Axis.PRECEDING); :}
782
{: RESULT = new Integer(Axis.PRECEDINGSIBLING); :}
785
{: RESULT = new Integer(Axis.SELF); :};
787
AbbreviatedStep ::= DOT
788
{: RESULT = new Step(Axis.SELF, NodeTest.ANODE, null); :}
791
{: RESULT = new Step(Axis.PARENT, NodeTest.ANODE, null); :};
793
FilterExpr ::= PrimaryExpr:primary
794
{: RESULT = primary; :}
796
| PrimaryExpr:primary Predicates:pp
797
{: RESULT = new FilterExpr(primary, pp); :};
799
PrimaryExpr ::= VariableReference:vr
802
| LPAREN Expr:ex RPAREN
808
* If the string appears to have the syntax of a QName, store
809
* namespace info in the literal expression. This is used for
810
* element-available and function-available functions, among
811
* others. Also, the default namespace must be ignored.
813
String namespace = null;
814
final int index = string.lastIndexOf(':');
817
final String prefix = string.substring(0, index);
818
namespace = parser._symbolTable.lookupNamespace(prefix);
820
RESULT = (namespace == null) ? new LiteralExpr(string)
821
: new LiteralExpr(string, namespace);
826
long value = num.longValue();
827
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
828
RESULT = new RealExpr(value);
831
if (num.doubleValue() == -0)
832
RESULT = new RealExpr(num.doubleValue());
833
else if (num.intValue() == 0)
834
RESULT = new IntExpr(num.intValue());
835
else if (num.doubleValue() == 0.0)
836
RESULT = new RealExpr(num.doubleValue());
838
RESULT = new IntExpr(num.intValue());
843
{: RESULT = new RealExpr(num.doubleValue()); :}
848
VariableReference ::= DOLLAR VariableName:varName
850
// An empty qname prefix for a variable or parameter reference
851
// should map to the null namespace and not the default URI.
852
SyntaxTreeNode node = parser.lookupName(varName);
855
if (node instanceof Variable) {
856
RESULT = new VariableRef((Variable)node);
858
else if (node instanceof Param) {
859
RESULT = new ParameterRef((Param)node);
862
RESULT = new UnresolvedRef(varName);
867
RESULT = new UnresolvedRef(varName);
871
FunctionCall ::= FunctionName:fname LPAREN RPAREN
874
if (fname == parser.getQNameIgnoreDefaultNs("current")) {
875
RESULT = new CurrentCall(fname);
877
else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
878
RESULT = new NumberCall(fname, parser.EmptyArgs);
880
else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
881
RESULT = new StringCall(fname, parser.EmptyArgs);
883
else if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
884
RESULT = new ConcatCall(fname, parser.EmptyArgs);
886
else if (fname == parser.getQNameIgnoreDefaultNs("true")) {
887
RESULT = new BooleanExpr(true);
889
else if (fname == parser.getQNameIgnoreDefaultNs("false")) {
890
RESULT = new BooleanExpr(false);
892
else if (fname == parser.getQNameIgnoreDefaultNs("name")) {
893
RESULT = new NameCall(fname);
895
else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
896
RESULT = new GenerateIdCall(fname, parser.EmptyArgs);
898
else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
899
RESULT = new StringLengthCall(fname, parser.EmptyArgs);
901
else if (fname == parser.getQNameIgnoreDefaultNs("position")) {
902
RESULT = new PositionCall(fname);
904
else if (fname == parser.getQNameIgnoreDefaultNs("last")) {
905
RESULT = new LastCall(fname);
907
else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) {
908
RESULT = new LocalNameCall(fname);
910
else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
911
RESULT = new NamespaceUriCall(fname);
914
RESULT = new FunctionCall(fname, parser.EmptyArgs);
918
| FunctionName:fname LPAREN NonemptyArgumentList:argl RPAREN
920
if (fname == parser.getQNameIgnoreDefaultNs("concat")) {
921
RESULT = new ConcatCall(fname, argl);
923
else if (fname == parser.getQNameIgnoreDefaultNs("number")) {
924
RESULT = new NumberCall(fname, argl);
926
else if (fname == parser.getQNameIgnoreDefaultNs("document")) {
927
parser.setMultiDocument(true);
928
RESULT = new DocumentCall(fname, argl);
930
else if (fname == parser.getQNameIgnoreDefaultNs("string")) {
931
RESULT = new StringCall(fname, argl);
933
else if (fname == parser.getQNameIgnoreDefaultNs("boolean")) {
934
RESULT = new BooleanCall(fname, argl);
936
else if (fname == parser.getQNameIgnoreDefaultNs("name")) {
937
RESULT = new NameCall(fname, argl);
939
else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) {
940
RESULT = new GenerateIdCall(fname, argl);
942
else if (fname == parser.getQNameIgnoreDefaultNs("not")) {
943
RESULT = new NotCall(fname, argl);
945
else if (fname == parser.getQNameIgnoreDefaultNs("format-number")) {
946
RESULT = new FormatNumberCall(fname, argl);
948
else if (fname == parser.getQNameIgnoreDefaultNs("unparsed-entity-uri")) {
949
RESULT = new UnparsedEntityUriCall(fname, argl);
951
else if (fname == parser.getQNameIgnoreDefaultNs("key")) {
952
RESULT = new KeyCall(fname, argl);
954
else if (fname == parser.getQNameIgnoreDefaultNs("id")) {
955
RESULT = new KeyCall(fname, argl);
956
parser.setHasIdCall(true);
958
else if (fname == parser.getQNameIgnoreDefaultNs("ceiling")) {
959
RESULT = new CeilingCall(fname, argl);
961
else if (fname == parser.getQNameIgnoreDefaultNs("round")) {
962
RESULT = new RoundCall(fname, argl);
964
else if (fname == parser.getQNameIgnoreDefaultNs("floor")) {
965
RESULT = new FloorCall(fname, argl);
967
else if (fname == parser.getQNameIgnoreDefaultNs("contains")) {
968
RESULT = new ContainsCall(fname, argl);
970
else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) {
971
RESULT = new StringLengthCall(fname, argl);
973
else if (fname == parser.getQNameIgnoreDefaultNs("starts-with")) {
974
RESULT = new StartsWithCall(fname, argl);
976
else if (fname == parser.getQNameIgnoreDefaultNs("function-available")) {
977
RESULT = new FunctionAvailableCall(fname, argl);
979
else if (fname == parser.getQNameIgnoreDefaultNs("element-available")) {
980
RESULT = new ElementAvailableCall(fname, argl);
982
else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) {
983
RESULT = new LocalNameCall(fname, argl);
985
else if (fname == parser.getQNameIgnoreDefaultNs("lang")) {
986
RESULT = new LangCall(fname, argl);
988
else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) {
989
RESULT = new NamespaceUriCall(fname, argl);
991
else if (fname == parser.getQName(Constants.TRANSLET_URI, "xsltc", "cast")) {
992
RESULT = new CastCall(fname, argl);
994
// Special case for extension function nodeset()
995
else if (fname.getLocalPart().equals("nodeset") || fname.getLocalPart().equals("node-set")) {
996
parser.setCallsNodeset(true); // implies MultiDOM
997
RESULT = new FunctionCall(fname, argl);
1000
RESULT = new FunctionCall(fname, argl);
1004
NonemptyArgumentList ::= Argument:arg
1006
Vector temp = new Vector();
1007
temp.addElement(arg);
1011
| Argument:arg COMMA NonemptyArgumentList:argl
1012
{: argl.insertElementAt(arg, 0); RESULT = argl; :};
1014
FunctionName ::= QName:fname
1019
VariableName ::= QName:vname
1024
Argument ::= Expr:ex
1027
NodeTest ::= NameTest:nt
1031
{: RESULT = new Integer(NodeTest.ANODE); :}
1034
{: RESULT = new Integer(NodeTest.TEXT); :}
1037
{: RESULT = new Integer(NodeTest.COMMENT); :}
1039
| PIPARAM LPAREN Literal:l RPAREN
1041
QName name = parser.getQNameIgnoreDefaultNs("name");
1042
Expression exp = new EqualityExpr(Operators.EQ,
1044
new LiteralExpr(l));
1045
Vector predicates = new Vector();
1046
predicates.addElement(new Predicate(exp));
1047
RESULT = new Step(Axis.CHILD, NodeTest.PI, predicates);
1051
{: RESULT = new Integer(NodeTest.PI); :};
1054
{: RESULT = null; :}
1059
QName ::= QNAME:qname
1060
{: RESULT = parser.getQNameIgnoreDefaultNs(qname); :}
1063
{: RESULT = parser.getQNameIgnoreDefaultNs("div"); :}
1066
{: RESULT = parser.getQNameIgnoreDefaultNs("mod"); :}
1069
{: RESULT = parser.getQNameIgnoreDefaultNs("key"); :}
1072
{: RESULT = parser.getQNameIgnoreDefaultNs("child"); :}
1075
{: RESULT = parser.getQNameIgnoreDefaultNs("ancestor-or-self"); :}
1078
{: RESULT = parser.getQNameIgnoreDefaultNs("attribute"); :}
1081
{: RESULT = parser.getQNameIgnoreDefaultNs("child"); :}
1084
{: RESULT = parser.getQNameIgnoreDefaultNs("decendant"); :}
1087
{: RESULT = parser.getQNameIgnoreDefaultNs("decendant-or-self"); :}
1090
{: RESULT = parser.getQNameIgnoreDefaultNs("following"); :}
1093
{: RESULT = parser.getQNameIgnoreDefaultNs("following-sibling"); :}
1096
{: RESULT = parser.getQNameIgnoreDefaultNs("namespace"); :}
1099
{: RESULT = parser.getQNameIgnoreDefaultNs("parent"); :}
1102
{: RESULT = parser.getQNameIgnoreDefaultNs("preceding"); :}
1105
{: RESULT = parser.getQNameIgnoreDefaultNs("preceding-sibling"); :}
1108
{: RESULT = parser.getQNameIgnoreDefaultNs("self"); :}
1111
{: RESULT = parser.getQNameIgnoreDefaultNs("id"); :};