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