1 /* 2 * Copyright 2006-2008 The FLWOR Foundation. 3 * 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 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 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. 15 */ 16 #pragma once 17 #ifndef ZORBA_COMPILER_PATH_EXPR 18 #define ZORBA_COMPILER_PATH_EXPR 19 20 21 #include "compiler/expression/expr_base.h" 22 23 #include "zorbatypes/zstring.h" 24 25 26 namespace zorba 27 { 28 29 class match_expr; 30 31 32 /******************************************************************************* 33 34 PathExpr ::= ("/" RelativePathExpr?) | 35 ("//" RelativePathExpr) | 36 RelativePathExpr 37 38 RelativePathExpr ::= StepExpr (("/" | "//") StepExpr)* 39 40 41 Formal Semantics [http://www.w3.org/TR/xquery-semantics]: 42 / == fn:root(self::node()) 43 /A == fn:root(self::node())/A 44 //A == fn:root(self::node())/descendant-or-self::node()/A 45 A//B == A/descendant-or-self::node()/B 46 This implies that all path expressions are relative path expressions. So a 47 relative path is defined as follows: 48 49 RelativPathExpr ::= "/" | ("/" | "//")? StepExpr (("/" | "//") StepExpr)* 50 51 ********************************************************************************/ 52 class relpath_expr : public expr 53 { 54 friend class ExprIterator; 55 friend class expr; 56 friend class ExprManager; 57 58 protected: 59 std::vector<expr*> theSteps; 60 61 protected: 62 relpath_expr(CompilerCB* ccb, static_context* sctx, const QueryLoc& loc); 63 64 public: size()65 size_t size() const { return theSteps.size(); } 66 67 void add_back(expr* step); 68 erase(csize i)69 void erase(csize i) { theSteps.erase(theSteps.begin() + i); } 70 numSteps()71 csize numSteps() const { return theSteps.size(); } 72 73 expr* operator[](csize n) const { return theSteps[n]; } 74 begin()75 std::vector<expr*>::const_iterator begin() const { return theSteps.begin(); } 76 end()77 std::vector<expr*>::const_iterator end() const { return theSteps.end(); } 78 79 void compute_scripting_kind(); 80 81 expr* cloneImpl(substitution_t &) const; 82 83 void accept(expr_visitor&); 84 85 std::ostream& put(std::ostream&) const; 86 }; 87 88 89 /******************************************************************************* 90 91 StepExpr ::= AxisStep | FilterExpr 92 93 ********************************************************************************/ 94 95 96 /******************************************************************************* 97 98 AxisStep ::= Axis NodeTest Predicate* 99 100 ********************************************************************************/ 101 class axis_step_expr : public expr 102 { 103 friend class ExprIterator; 104 friend class expr; 105 friend class ExprManager; 106 107 protected: 108 axis_kind_t theAxis; 109 bool theReverseOrder; 110 expr * theNodeTest; 111 112 public: 113 static bool is_reverse_axis(axis_kind_t kind); 114 115 protected: 116 axis_step_expr(CompilerCB* ccb, static_context* sctx, const QueryLoc&); 117 118 public: getAxis()119 axis_kind_t getAxis() const { return theAxis; } 120 setAxis(axis_kind_t v)121 void setAxis(axis_kind_t v) { theAxis = v; } 122 set_reverse_order()123 void set_reverse_order() { theReverseOrder = true; } 124 use_reverse_order()125 bool use_reverse_order() const { return theReverseOrder; } 126 is_reverse_axis()127 bool is_reverse_axis() const { return is_reverse_axis(getAxis()); } 128 getTest()129 match_expr* getTest() const 130 { 131 return reinterpret_cast<match_expr*>(theNodeTest); 132 } 133 134 void setTest(match_expr* v); 135 136 void compute_scripting_kind(); 137 138 expr* cloneImpl(substitution_t &) const; 139 140 void accept(expr_visitor&); 141 142 std::ostream& put(std::ostream&) const; 143 }; 144 145 146 /******************************************************************************* 147 148 [78] NodeTest ::= KindTest | NameTest 149 150 [79] NameTest ::= QName | Wildcard 151 [80] Wildcard ::= "*" | (NCName ":" "*") | ("*" ":" NCName) 152 153 [123] KindTest ::= DocumentTest | ElementTest | AttributeTest | 154 SchemaElementTest | SchemaAttributeTest | 155 PITest | CommentTest | TextTest | AnyKindTest 156 157 If a match_expr represents a KindTest, then theWildKind and theWildName data 158 members are not used. If a match_expr represents a NameTest, then theTypeName 159 and theNilledAllowed data members are not used. 160 161 ********************************************************************************/ 162 class match_expr : public expr 163 { 164 friend class ExprIterator; 165 friend class expr; 166 friend class ExprManager; 167 168 protected: 169 match_test_t theTestKind; 170 match_test_t theDocTestKind; 171 172 match_wild_t theWildKind; 173 zstring theWildName; 174 175 store::Item_t theQName; 176 store::Item_t theTypeName; 177 bool theNilledAllowed; 178 179 protected: 180 match_expr(CompilerCB* ccb, static_context* sctx, const QueryLoc&); 181 182 public: getTestKind()183 match_test_t getTestKind() const { return theTestKind; } 184 setTestKind(enum match_test_t v)185 void setTestKind(enum match_test_t v) { theTestKind = v; } 186 getDocTestKind()187 match_test_t getDocTestKind() const { return theDocTestKind; } 188 setDocTestKind(enum match_test_t v)189 void setDocTestKind(enum match_test_t v) { theDocTestKind = v; } 190 getWildKind()191 match_wild_t getWildKind() const { return theWildKind; } 192 setWildKind(enum match_wild_t v)193 void setWildKind(enum match_wild_t v) { theWildKind = v; } 194 getWildName()195 const zstring& getWildName() const { return theWildName; } 196 197 template<class StringType> setWildName(const StringType & v)198 void setWildName(const StringType& v) { theWildName = v; } 199 getQName()200 store::Item* getQName() const { return theQName.getp(); } 201 setQName(const store::Item_t & v)202 void setQName(const store::Item_t& v) { theQName = v; } 203 getTypeName()204 store::Item* getTypeName() const { return theTypeName.getp(); } 205 setTypeName(const store::Item_t & v)206 void setTypeName(const store::Item_t& v) { theTypeName = v; } 207 getNilledAllowed()208 bool getNilledAllowed() const { return theNilledAllowed; } 209 setNilledAllowed(bool v)210 void setNilledAllowed(bool v) { theNilledAllowed = v; } 211 212 store::StoreConsts::NodeKind getNodeKind() const; 213 214 void compute_scripting_kind(); 215 216 expr* cloneImpl(substitution_t &) const; 217 218 void accept(expr_visitor&); 219 220 std::ostream& put(std::ostream&) const; 221 }; 222 223 224 225 } 226 227 #endif 228 229 /* 230 * Local variables: 231 * mode: c++ 232 * End: 233 */ 234 /* vim:set et sw=2 ts=2: */ 235