(***********************************************************************)
(*
- Time-stamp: <Last modified on 2013-03-09 19:24:28 CET by Kim Nguyen>
+ Time-stamp: <Last modified on 2013-03-13 14:21:53 CET by Kim Nguyen>
*)
open Ast
- let f () = ()
+ open Tree.Common
%}
%token <string> TAG
+%token <string> PI
+%token <string> ATTNAME
%token <string> STRING
%token <int> INT
%token <float> FLOAT
%token <Ast.axis> AXIS
%token RB LB LP RP
-%token SLASH SLASHSLASH COLONCOLON STAR PIPE
+%token SLASH SLASHSLASH COLONCOLON STAR PIPE DOT DOTDOT
%token EQ NEQ LT GT LTE GTE OR AND ADD SUB DIV MOD
-%token NODE TEXT
+%token NODE TEXT COMMENT
%token COMMA
%token EOF
absolute_path:
SLASH relative_path { $2 }
-| SLASHSLASH relative_path { $2 @ [(Descendant true, node, [])] }
+| SLASHSLASH relative_path { $2 @
+ [(Descendant true,
+ (node, NodeKind.Node),
+ [])] }
;
+/*
+ step is always a small list, of size 1-3 so @ is
+ cheap
+*/
relative_path:
- step { [ $1 ] }
-| relative_path SLASH step { $3 :: $1 }
-| relative_path SLASHSLASH step { $3
- :: (Descendant true, node, [])
- :: $1 }
+ step { $1 }
+| relative_path SLASH step { $3 @ $1 }
+| relative_path SLASHSLASH step { $3 @
+ ((Descendant true,
+ (node, NodeKind.Node),
+ [])
+ :: $1) }
;
step:
- axis_test pred_list { let a, b = $1 in a, b, $2 }
+ DOT { [ (Self, (node, NodeKind.Node), []) ] }
+| DOTDOT { [ (Parent, (node, NodeKind.Node), []) ] }
+| axis_test pred_list {
+ match $1 with
+ (a,b) :: r -> (a,b,$2) :: (List.map (fun (a,b) -> (a,b,[])) r)
+ | [] -> assert false
+ }
;
axis_test:
- AXIS COLONCOLON test { let a, t = $1, $3 in
- if a == Attribute && Utils.QNameSet.is_finite t then
- (a, Utils.QNameSet.fold
- (fun t a ->
- Utils.QNameSet.add
- (Utils.QName.add_attribute_prefix t) a)
- t Utils.QNameSet.empty)
- else
- (a, t)
+ AXIS COLONCOLON test { let a, (t,k) = $1, $3 in
+ match a with
+ Attribute when Utils.QNameSet.is_finite t ->
+ [ a, ((Utils.QNameSet.fold
+ (fun t a ->
+ Utils.QNameSet.add
+ (Utils.QName.attribute t) a)
+ t Utils.QNameSet.empty), k) ]
+ | Preceding|Following ->
+ [ (Descendant true, (t,k));
+ if a == Preceding then
+ (PrecedingSibling, (node, NodeKind.Node))
+ else
+ (FollowingSibling, (node, NodeKind.Node));
+ (Ancestor true, (node, NodeKind.Node)) ]
+
+ | _ -> [ a, (t,k) ]
}
-| test { Child, $1 }
+| test { [ Child, $1 ] }
| AXIS {
let _ = Format.flush_str_formatter () in
let () = Format.fprintf Format.str_formatter "%a" Ast.print_axis $1 in
let a = Format.flush_str_formatter () in
- Child, Utils.QNameSet.singleton (Utils.QName.of_string a)
+ [Child, (Utils.QNameSet.singleton (Utils.QName.of_string a),NodeKind.Element)]
}
+| ATTNAME { [(Attribute,
+ (Utils.QNameSet.singleton (Utils.QName.of_string $1),
+ NodeKind.Attribute))] }
;
test:
- NODE { node }
-| TEXT { text }
-| STAR { star }
-| TAG { Utils.QNameSet.singleton(Utils.QName.of_string $1) }
+ NODE { node, NodeKind.Node }
+| TEXT { text, NodeKind.Text }
+| STAR { star, NodeKind.Element }
+| COMMENT { Utils.QNameSet.singleton(Utils.QName.comment),
+ NodeKind.Comment
+ }
+| PI { (if $1 = "" then star
+ else Utils.QNameSet.singleton(
+ Utils.QName.processing_instruction (
+ Utils.QName.of_string $1)
+ )), NodeKind.ProcessingInstruction
+ }
+| TAG { Utils.QNameSet.singleton(Utils.QName.of_string $1),
+ NodeKind.Element
+ }
;
pred_list:
expr { [ $1 ] }
| arg_list1 COMMA expr { $3 :: $1 }
;
-