Dead
[official-gcc.git] / gomp-20050608-branch / libjava / classpath / gnu / xml / xpath / XPathParser.y
blob550151386558973a4f1b3b8a3808a33a46c2eeae
1 %{
2 /* XPathParser.y - An XPath 1.0 parser.
3 Copyright (C) 2004 The Free Software Foundation
5 This file is part of GNU Classpath.
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library. Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module. An independent module is a module which is not derived from
34 or based on this library. If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so. If you do not wish to do so, delete this
37 exception statement from your version. */
40 package gnu.xml.xpath;
42 import java.util.ArrayList;
43 import java.util.Collections;
44 import java.util.List;
45 import java.util.Map;
46 import javax.xml.namespace.NamespaceContext;
47 import javax.xml.namespace.QName;
48 import javax.xml.xpath.XPathFunctionResolver;
49 import javax.xml.xpath.XPathVariableResolver;
50 import org.w3c.dom.Node;
52 /**
53 * An XPath 1.0 parser.
55 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
57 public class XPathParser
60 NamespaceContext namespaceContext;
61 XPathVariableResolver variableResolver;
62 XPathFunctionResolver functionResolver;
64 QName getQName(String name)
66 QName qName = QName.valueOf(name);
67 if (namespaceContext != null)
69 String prefix = qName.getPrefix();
70 String uri = qName.getNamespaceURI();
71 if (prefix != null && (uri == null || uri.length() == 0))
73 uri = namespaceContext.getNamespaceURI(prefix);
74 String localName = qName.getLocalPart();
75 qName = new QName(uri, localName, prefix);
78 return qName;
81 Expr lookupFunction(String name, List args)
83 int arity = args.size();
84 if ("position".equals(name) && arity == 0)
86 return new PositionFunction();
88 else if ("last".equals(name) && arity == 0)
90 return new LastFunction();
92 else if ("string".equals(name) && (arity == 1 || arity == 0))
94 return new StringFunction(args);
96 else if ("number".equals(name) && (arity == 1 || arity == 0))
98 return new NumberFunction(args);
100 else if ("boolean".equals(name) && arity == 1)
102 return new BooleanFunction(args);
104 else if ("count".equals(name) && arity == 1)
106 return new CountFunction(args);
108 else if ("not".equals(name) && arity == 1)
110 return new NotFunction(args);
112 else if ("id".equals(name) && arity == 1)
114 return new IdFunction(args);
116 else if ("concat".equals(name) && arity > 1)
118 return new ConcatFunction(args);
120 else if ("true".equals(name) && arity == 0)
122 return new TrueFunction();
124 else if ("false".equals(name) && arity == 0)
126 return new FalseFunction();
128 else if ("name".equals(name) && (arity == 1 || arity == 0))
130 return new NameFunction(args);
132 else if ("local-name".equals(name) && (arity == 1 || arity == 0))
134 return new LocalNameFunction(args);
136 else if ("namespace-uri".equals(name) && (arity == 1 || arity == 0))
138 return new NamespaceUriFunction(args);
140 else if ("starts-with".equals(name) && arity == 2)
142 return new StartsWithFunction(args);
144 else if ("contains".equals(name) && arity == 2)
146 return new ContainsFunction(args);
148 else if ("string-length".equals(name) && (arity == 1 || arity == 0))
150 return new StringLengthFunction(args);
152 else if ("translate".equals(name) && arity == 3)
154 return new TranslateFunction(args);
156 else if ("normalize-space".equals(name) && (arity == 1 || arity == 0))
158 return new NormalizeSpaceFunction(args);
160 else if ("substring".equals(name) && (arity == 2 || arity == 3))
162 return new SubstringFunction(args);
164 else if ("substring-before".equals(name) && arity == 2)
166 return new SubstringBeforeFunction(args);
168 else if ("substring-after".equals(name) && arity == 2)
170 return new SubstringAfterFunction(args);
172 else if ("lang".equals(name) && arity == 1)
174 return new LangFunction(args);
176 else if ("sum".equals(name) && arity == 1)
178 return new SumFunction(args);
180 else if ("floor".equals(name) && arity == 1)
182 return new FloorFunction(args);
184 else if ("ceiling".equals(name) && arity == 1)
186 return new CeilingFunction(args);
188 else if ("round".equals(name) && arity == 1)
190 return new RoundFunction(args);
192 else if (functionResolver != null)
194 QName qName = QName.valueOf(name);
195 Object function = functionResolver.resolveFunction(qName, arity);
196 if (function != null &&
197 function instanceof Function &&
198 function instanceof Expr)
200 Function f = (Function) function;
201 f.setArguments(args);
202 return (Expr) function;
205 return new FunctionCall(functionResolver, name, args);
210 %token LITERAL
211 %token DIGITS
212 %token NAME
214 %token LP // '('
215 %token RP // ')'
216 %token LB // '['
217 %token RB // ']'
218 %token COMMA // ','
219 %token PIPE // '|'
220 %token SLASH // '/'
221 %token DOUBLE_SLASH // '//'
222 %token EQ // '='
223 %token NE // '!='
224 %token GT // '>'
225 %token LT // '<'
226 %token GTE // '>='
227 %token LTE // '<='
228 %token PLUS // '+'
229 %token MINUS // '-'
230 %token AT // '@'
231 %token STAR // '*'
232 %token DOLLAR // '$'
233 %token COLON // ':'
234 %token DOUBLE_COLON // '::'
235 %token DOT // '.'
236 %token DOUBLE_DOT // '..'
238 %token ANCESTOR
239 %token ANCESTOR_OR_SELF
240 %token ATTRIBUTE
241 %token CHILD
242 %token DESCENDANT
243 %token DESCENDANT_OR_SELF
244 %token FOLLOWING
245 %token FOLLOWING_SIBLING
246 %token NAMESPACE
247 %token PARENT
248 %token PRECEDING
249 %token PRECEDING_SIBLING
250 %token SELF
251 %token DIV
252 %token MOD
253 %token OR
254 %token AND
255 %token COMMENT
256 %token PROCESSING_INSTRUCTION
257 %token TEXT
258 %token NODE
260 %right UNARY
262 %start expr
266 expr:
267 or_expr
270 location_path:
271 relative_location_path
272 | absolute_location_path
275 absolute_location_path:
276 SLASH
278 $$ = new Root();
280 | SLASH relative_location_path
282 Steps steps;
283 if ($2 instanceof Steps)
285 steps = (Steps) $2;
287 else
289 steps = new Steps();
290 steps.path.addFirst($2);
292 steps.path.addFirst(new Root());
293 $$ = steps;
294 //$$ = new Step(new Root(), (Path) $2);
296 | DOUBLE_SLASH relative_location_path
298 Test nt = new NodeTypeTest((short) 0);
299 Selector s = new Selector(Selector.DESCENDANT_OR_SELF,
300 Collections.singletonList (nt));
301 Steps steps;
302 if ($2 instanceof Steps)
304 steps = (Steps) $2;
306 else
308 steps = new Steps();
309 steps.path.addFirst($2);
311 steps.path.addFirst(s);
312 steps.path.addFirst(new Root());
313 $$ = steps;
314 //Step step = new Step(s, (Path) $2);
315 //$$ = new Step(new Root(), step);
319 relative_location_path:
320 step
321 | relative_location_path SLASH step
323 Steps steps;
324 if ($1 instanceof Steps)
326 steps = (Steps) $1;
328 else
330 steps = new Steps();
331 steps.path.addFirst($1);
333 steps.path.addLast($3);
334 $$ = steps;
335 //$$ = new Step((Expr) $1, (Path) $3);
337 | relative_location_path DOUBLE_SLASH step
339 Test nt = new NodeTypeTest((short) 0);
340 Selector s = new Selector(Selector.DESCENDANT_OR_SELF,
341 Collections.singletonList (nt));
342 Steps steps;
343 if ($1 instanceof Steps)
345 steps = (Steps) $1;
347 else
349 steps = new Steps();
350 steps.path.addFirst($1);
352 steps.path.addLast(s);
353 steps.path.addLast($3);
354 $$ = steps;
355 //Step step = new Step(s, (Path) $3);
356 //$$ = new Step((Expr) $1, step);
360 step:
361 step_node_test
363 $$ = new Selector (Selector.CHILD, (List) $1);
365 | AT step_node_test
367 $$ = new Selector (Selector.ATTRIBUTE, (List) $2);
369 | axis_name DOUBLE_COLON step_node_test
371 $$ = new Selector (((Integer) $1).intValue (), (List) $3);
373 | DOT
375 $$ = new Selector (Selector.SELF, Collections.EMPTY_LIST);
377 | DOUBLE_DOT
379 $$ = new Selector (Selector.PARENT, Collections.EMPTY_LIST);
383 step_node_test:
384 node_test
386 List list = new ArrayList();
387 list.add($1);
388 $$ = list;
390 | step_node_test predicate
392 List list = (List)$1;
393 list.add($2);
394 $$ = list;
398 /*predicate_list:
399 predicate
401 List list = new ArrayList ();
402 list.add ($1);
403 $$ = list;
405 | predicate predicate_list
407 List list = (List) $3;
408 list.add (0, $1);
409 $$ = list;
413 axis_name:
414 ANCESTOR
416 $$ = new Integer(Selector.ANCESTOR);
418 | ANCESTOR_OR_SELF
420 $$ = new Integer(Selector.ANCESTOR_OR_SELF);
422 | ATTRIBUTE
424 $$ = new Integer(Selector.ATTRIBUTE);
426 | CHILD
428 $$ = new Integer(Selector.CHILD);
430 | DESCENDANT
432 $$ = new Integer(Selector.DESCENDANT);
434 | DESCENDANT_OR_SELF
436 $$ = new Integer(Selector.DESCENDANT_OR_SELF);
438 | FOLLOWING
440 $$ = new Integer(Selector.FOLLOWING);
442 | FOLLOWING_SIBLING
444 $$ = new Integer(Selector.FOLLOWING_SIBLING);
446 | NAMESPACE
448 $$ = new Integer(Selector.NAMESPACE);
450 | PARENT
452 $$ = new Integer(Selector.PARENT);
454 | PRECEDING
456 $$ = new Integer(Selector.PRECEDING);
458 | PRECEDING_SIBLING
460 $$ = new Integer(Selector.PRECEDING_SIBLING);
462 | SELF
464 $$ = new Integer(Selector.SELF);
468 node_test:
469 name_test
470 /*| PROCESSING_INSTRUCTION LP LITERAL RP*/
471 | PROCESSING_INSTRUCTION LITERAL RP
473 $$ = new NodeTypeTest(Node.PROCESSING_INSTRUCTION_NODE, (String) $2);
475 /*| node_type LP RP*/
476 | node_type RP
478 $$ = new NodeTypeTest(((Short) $1).shortValue());
482 predicate:
483 LB expr RB
485 $$ = new Predicate((Expr) $2);
489 primary_expr:
490 variable_reference
491 | LP expr RP
493 $$ = new ParenthesizedExpr((Expr) $2);
495 | LITERAL
497 $$ = new Constant($1);
499 | number
501 $$ = new Constant($1);
503 | function_call
506 function_call:
507 function_name LP RP
509 $$ = lookupFunction((String) $1, Collections.EMPTY_LIST);
511 | function_name LP argument_list RP
513 $$ = lookupFunction((String) $1, (List) $3);
517 argument_list:
518 expr
520 List list = new ArrayList();
521 list.add($1);
522 $$ = list;
524 | expr COMMA argument_list
526 List list = (List) $3;
527 list.add(0, $1);
528 $$ = list;
532 union_expr:
533 path_expr
534 | union_expr PIPE path_expr
536 $$ = new UnionExpr((Expr) $1, (Expr) $3);
540 path_expr:
541 location_path
542 | filter_expr
543 | filter_expr SLASH relative_location_path
545 Steps steps;
546 if ($3 instanceof Steps)
548 steps = (Steps) $3;
550 else
552 steps = new Steps();
553 steps.path.addFirst($3);
555 steps.path.addFirst($1);
556 $$ = steps;
557 //$$ = new Step ((Expr) $1, (Path) $3);
559 | filter_expr DOUBLE_SLASH relative_location_path
561 Test nt = new NodeTypeTest((short) 0);
562 Selector s = new Selector(Selector.DESCENDANT_OR_SELF,
563 Collections.singletonList(nt));
564 Steps steps;
565 if ($3 instanceof Steps)
567 steps = (Steps) $3;
569 else
571 steps = new Steps();
572 steps.path.addFirst($3);
574 steps.path.addFirst(s);
575 steps.path.addFirst($1);
576 $$ = steps;
577 //Step step = new Step (s, (Path) $3);
578 //$$ = new Step ((Expr) $1, step);
582 filter_expr:
583 primary_expr
584 | filter_expr predicate
586 Predicate filter = (Predicate) $2;
587 Selector s = new Selector(Selector.SELF,
588 Collections.singletonList(filter));
589 Steps steps;
590 if ($1 instanceof Steps)
592 steps = (Steps) $1;
594 else
596 steps = new Steps();
597 steps.path.addFirst($1);
599 steps.path.addLast(s);
600 $$ = steps;
601 //$$ = new Step ((Expr) $1, s);
605 or_expr:
606 and_expr
607 | or_expr OR and_expr
609 $$ = new OrExpr((Expr) $1, (Expr) $3);
613 and_expr:
614 equality_expr
615 | and_expr AND equality_expr
617 $$ = new AndExpr((Expr) $1, (Expr) $3);
621 equality_expr:
622 relational_expr
623 | equality_expr EQ relational_expr
625 $$ = new EqualityExpr((Expr) $1, (Expr) $3, false);
627 | equality_expr NE relational_expr
629 $$ = new EqualityExpr((Expr) $1, (Expr) $3, true);
633 relational_expr:
634 additive_expr
635 | relational_expr LT additive_expr
637 $$ = new RelationalExpr((Expr) $1, (Expr) $3, true, false);
639 | relational_expr GT additive_expr
641 $$ = new RelationalExpr((Expr) $1, (Expr) $3, false, false);
643 | relational_expr LTE additive_expr
645 $$ = new RelationalExpr((Expr) $1, (Expr) $3, true, true);
647 | relational_expr GTE additive_expr
649 $$ = new RelationalExpr((Expr) $1, (Expr) $3, false, true);
653 additive_expr:
654 multiplicative_expr
655 | additive_expr PLUS multiplicative_expr
657 $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.ADD);
659 | additive_expr MINUS multiplicative_expr
661 $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.SUBTRACT);
665 multiplicative_expr:
666 unary_expr
667 | multiplicative_expr STAR unary_expr
669 $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.MULTIPLY);
671 | multiplicative_expr DIV unary_expr
673 $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.DIVIDE);
675 | multiplicative_expr MOD unary_expr
677 $$ = new ArithmeticExpr((Expr) $1, (Expr) $3, ArithmeticExpr.MODULO);
681 unary_expr:
682 union_expr
683 | MINUS unary_expr %prec UNARY
685 $$ = new NegativeExpr((Expr) $2);
689 number:
690 DIGITS
692 $$ = new Double((String) $1 + ".0");
694 | DIGITS DOT
696 $$ = new Double((String) $1 + ".0");
698 | DIGITS DOT DIGITS
700 $$ = new Double((String) $1 + "." + (String) $3);
702 | DOT DIGITS
704 $$ = new Double("0." + (String) $2);
708 function_name:
709 qname
710 /* | node_type
712 switch (((Short) $1).shortValue ())
714 case Node.COMMENT_NODE:
715 $$ = "comment";
716 break;
717 case Node.TEXT_NODE:
718 $$ = "text";
719 break;
720 case Node.PROCESSING_INSTRUCTION_NODE:
721 $$ = "processing-instruction";
722 break;
723 default:
724 $$ = "node";
725 break;
730 variable_reference:
731 DOLLAR qname
733 String name = (String) $2;
734 $$ = new VariableReference(variableResolver, getQName(name));
738 name_test:
739 STAR
741 $$ = new NameTest(null, true, true);
743 | NAME COLON STAR
745 QName qName = getQName((String) $1);
746 $$ = new NameTest(qName, true, false);
748 | qname
750 QName qName = getQName((String) $1);
751 $$ = new NameTest(qName, false, false);
755 qname:
756 NAME
757 | NAME COLON NAME
759 $$ = (String) $1 + ':' + (String) $3;
763 node_type:
764 COMMENT
766 $$ = new Short(Node.COMMENT_NODE);
768 | TEXT
770 $$ = new Short(Node.TEXT_NODE);
772 | PROCESSING_INSTRUCTION
774 $$ = new Short(Node.PROCESSING_INSTRUCTION_NODE);
776 | NODE
778 $$ = new Short((short) 0);