Mercurial > hg > rr-repo
comparison sites/all/libraries/ARC2/arc/sparqlscript/ARC2_SPARQLScriptParser.php @ 4:ce11bbd8f642
added modules
author | danieleb <danielebarchiesi@me.com> |
---|---|
date | Thu, 19 Sep 2013 10:38:44 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3:b28be78d8160 | 4:ce11bbd8f642 |
---|---|
1 <?php | |
2 /* | |
3 homepage: http://arc.semsol.org/ | |
4 license: http://arc.semsol.org/license | |
5 | |
6 class: ARC2 SPARQLScript Parser (SPARQL+ + functions) | |
7 author: Benjamin Nowack | |
8 version: 2010-11-16 | |
9 */ | |
10 | |
11 ARC2::inc('ARC2_SPARQLPlusParser'); | |
12 | |
13 class ARC2_SPARQLScriptParser extends ARC2_SPARQLPlusParser { | |
14 | |
15 function __construct($a, &$caller) { | |
16 parent::__construct($a, $caller); | |
17 } | |
18 | |
19 function __init() { | |
20 parent::__init(); | |
21 } | |
22 | |
23 /* */ | |
24 | |
25 function parse($v, $src = '', $iso_fallback = 'ignore') { | |
26 $this->setDefaultPrefixes(); | |
27 $this->base = $src ? $this->calcBase($src) : ARC2::getScriptURI(); | |
28 $this->blocks = array(); | |
29 $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes); | |
30 do { | |
31 $proceed = 0; | |
32 if ((list($r, $v) = $this->xScriptBlock($v)) && $r) { | |
33 $this->blocks[] = $r; | |
34 $proceed = 1; | |
35 } | |
36 $this->unparsed_code = trim($v); | |
37 } while ($proceed); | |
38 if (trim($this->unparsed_code) && !$this->getErrors()) { | |
39 $rest = preg_replace('/[\x0a|\x0d]/i', ' ', substr($this->unparsed_code, 0, 30)); | |
40 $msg = trim($rest) ? 'Could not properly handle "' . $rest . '"' : 'Syntax Error'; | |
41 $this->addError($msg); | |
42 } | |
43 } | |
44 | |
45 function getScriptBlocks() { | |
46 return $this->v('blocks', array()); | |
47 } | |
48 | |
49 /* */ | |
50 | |
51 function xScriptBlock($v) { | |
52 /* comment removal */ | |
53 while (preg_match('/^\s*(\#[^\xd\xa]*)(.*)$/si', $v, $m)) $v = $m[2]; | |
54 /* BaseDecl */ | |
55 if ((list($sub_r, $v) = $this->xBaseDecl($v)) && $sub_r) { | |
56 $this->base = $sub_r; | |
57 } | |
58 /* PrefixDecl */ | |
59 while ((list($r, $v) = $this->xPrefixDecl($v)) && $r) { | |
60 $this->prefixes[$r['prefix']] = $r['uri']; | |
61 } | |
62 /* EndpointDecl */ | |
63 if ((list($r, $v) = $this->xEndpointDecl($v)) && $r) { | |
64 return array($r, $v); | |
65 } | |
66 /* Return */ | |
67 if ((list($r, $v) = $this->xReturn($v)) && $r) { | |
68 return array($r, $v); | |
69 } | |
70 /* Assignment */ | |
71 if ((list($r, $v) = $this->xAssignment($v)) && $r) { | |
72 return array($r, $v); | |
73 } | |
74 /* IFBlock */ | |
75 if ((list($r, $v) = $this->xIFBlock($v)) && $r) { | |
76 return array($r, $v); | |
77 } | |
78 /* FORBlock */ | |
79 if ((list($r, $v) = $this->xFORBlock($v)) && $r) { | |
80 return array($r, $v); | |
81 } | |
82 /* String */ | |
83 if ((list($r, $v) = $this->xString($v)) && $r) { | |
84 return array($r, $v); | |
85 } | |
86 /* FunctionCall */ | |
87 if ((list($r, $v) = $this->xFunctionCall($v)) && $r) { | |
88 return array($r, ltrim($v, ';')); | |
89 } | |
90 /* Query */ | |
91 $prev_r = $this->r; | |
92 $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes); | |
93 if ((list($r, $rest) = $this->xQuery($v)) && $r) { | |
94 $q = $rest ? trim(substr($v, 0, -strlen($rest))) : trim($v); | |
95 $v = $rest; | |
96 $r = array_merge($this->r, array( | |
97 'type' => 'query', | |
98 'query_type' => $r['type'], | |
99 'query' => $q, | |
100 //'prefixes' => $this->prefixes, | |
101 'base' => $this->base, | |
102 //'infos' => $r | |
103 )); | |
104 return array($r, $v); | |
105 } | |
106 else { | |
107 $this->r = $prev_r; | |
108 } | |
109 return array(0, $v); | |
110 } | |
111 | |
112 function xBlockSet($v) { | |
113 if (!$r = $this->x("\{", $v)) return array(0, $v); | |
114 $blocks = array(); | |
115 $sub_v = $r[1]; | |
116 while ((list($sub_r, $sub_v) = $this->xScriptBlock($sub_v)) && $sub_r) { | |
117 $blocks[] = $sub_r; | |
118 } | |
119 if (!$sub_r = $this->x("\}", $sub_v)) return array(0, $v); | |
120 $sub_v = $sub_r[1]; | |
121 return array(array('type' => 'block_set', 'blocks' => $blocks), $sub_v); | |
122 } | |
123 | |
124 /* s2 */ | |
125 | |
126 function xEndpointDecl($v) { | |
127 if ($r = $this->x("ENDPOINT\s+", $v)) { | |
128 if ((list($r, $sub_v) = $this->xIRI_REF($r[1])) && $r) { | |
129 $r = $this->calcURI($r, $this->base); | |
130 if ($sub_r = $this->x('\.', $sub_v)) { | |
131 $sub_v = $sub_r[1]; | |
132 } | |
133 return array( | |
134 array('type' => 'endpoint_decl', 'endpoint' => $r), | |
135 $sub_v | |
136 ); | |
137 } | |
138 } | |
139 return array(0, $v); | |
140 } | |
141 | |
142 /* s3 */ | |
143 | |
144 function xAssignment($v) { | |
145 /* Var */ | |
146 list($r, $sub_v) = $this->xVar($v); | |
147 if (!$r) return array(0, $v); | |
148 $var = $r; | |
149 /* := | = */ | |
150 if (!$sub_r = $this->x("\:?\=", $sub_v)) return array(0, $v); | |
151 $sub_v = $sub_r[1]; | |
152 /* try String */ | |
153 list($r, $sub_v) = $this->xString($sub_v); | |
154 if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'string', 'string' => $r), ltrim($sub_v, '; ')); | |
155 /* try VarMerge */ | |
156 list($r, $sub_v) = $this->xVarMerge($sub_v); | |
157 if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'var_merge', 'var2' => $r[0], 'var3' => $r[1]), ltrim($sub_v, '; ')); | |
158 /* try Var */ | |
159 list($r, $sub_v) = $this->xVar($sub_v); | |
160 if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'var', 'var2' => $r), ltrim($sub_v, '; ')); | |
161 /* try function */ | |
162 list($r, $sub_v) = $this->xFunctionCall($sub_v); | |
163 if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'function_call', 'function_call' => $r), ltrim($sub_v, '; ')); | |
164 /* try Placeholder */ | |
165 list($r, $sub_v) = $this->xPlaceholder($sub_v); | |
166 if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'placeholder', 'placeholder' => $r), ltrim($sub_v, '; ')); | |
167 /* try query */ | |
168 $prev_r = $this->r; | |
169 $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes); | |
170 list($r, $rest) = $this->xQuery($sub_v); | |
171 if (!$r) { | |
172 $this->r = $prev_r; | |
173 return array(0, $v); | |
174 } | |
175 else { | |
176 $q = $rest ? trim(substr($sub_v, 0, -strlen($rest))) : trim($sub_v); | |
177 return array( | |
178 array( | |
179 'type' => 'assignment', | |
180 'var' => $var, | |
181 'sub_type' => 'query', | |
182 'query' => array_merge($this->r, array( | |
183 'type' => 'query', | |
184 'query_type' => $r['type'], | |
185 'query' => $q, | |
186 'base' => $this->base, | |
187 )), | |
188 ), | |
189 ltrim($rest, '; ') | |
190 ); | |
191 } | |
192 } | |
193 | |
194 function xReturn($v) { | |
195 if ($r = $this->x("return\s+", $v)) { | |
196 /* fake assignment which accepts same right-hand values */ | |
197 $sub_v = '$__return_value__ := ' . $r[1]; | |
198 if ((list($r, $sub_v) = $this->xAssignment($sub_v)) && $r) { | |
199 $r['type'] = 'return'; | |
200 return array($r, $sub_v); | |
201 } | |
202 } | |
203 return array(0, $v); | |
204 } | |
205 | |
206 /* s4 'IF' BrackettedExpression '{' Script '}' ( 'ELSE' '{' Script '}')? */ | |
207 | |
208 function xIFBlock($v) { | |
209 if ($r = $this->x("IF\s*", $v)) { | |
210 if ((list($sub_r, $sub_v) = $this->xBrackettedExpression($r[1])) && $sub_r) { | |
211 $cond = $sub_r; | |
212 if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_v)) && $sub_r) { | |
213 $blocks = $sub_r['blocks']; | |
214 /* else */ | |
215 $else_blocks = array(); | |
216 $rest = $sub_v; | |
217 if ($sub_r = $this->x("ELSE\s*", $sub_v)) { | |
218 if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_r[1])) && $sub_r) { | |
219 $else_blocks = $sub_r['blocks']; | |
220 } | |
221 else { | |
222 $sub_v = $rest; | |
223 } | |
224 } | |
225 return array( | |
226 array( | |
227 'type' => 'ifblock', | |
228 'condition' => $cond, | |
229 'blocks' => $blocks, | |
230 'else_blocks' => $else_blocks, | |
231 ), | |
232 $sub_v | |
233 ); | |
234 } | |
235 } | |
236 } | |
237 return array(0, $v); | |
238 } | |
239 | |
240 /* s5 'FOR' '(' Var 'IN' Var ')' '{' Script '}' */ | |
241 | |
242 function xFORBlock($v) { | |
243 if ($r = $this->x("FOR\s*\(\s*[\$\?]([^\s]+)\s+IN\s+[\$\?]([^\s]+)\s*\)", $v)) {/* @@todo split into sub-patterns? */ | |
244 $iterator = $r[1]; | |
245 $set_var = $r[2]; | |
246 $sub_v = $r[3]; | |
247 if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_v)) && $sub_r) { | |
248 return array( | |
249 array( | |
250 'type' => 'forblock', | |
251 'set' => $set_var, | |
252 'iterator' => $iterator, | |
253 'blocks' => $sub_r['blocks'] | |
254 ), | |
255 $sub_v | |
256 ); | |
257 } | |
258 } | |
259 return array(0, $v); | |
260 } | |
261 | |
262 /* s6 Var '+' Var */ | |
263 | |
264 function xVarMerge($v) { | |
265 if ((list($sub_r, $sub_v) = $this->xVar($v)) && $sub_r) { | |
266 $var1 = $sub_r; | |
267 if ($sub_r = $this->x("\+", $sub_v)) { | |
268 $sub_v = $sub_r[1]; | |
269 if ((list($sub_r, $sub_v) = $this->xVar($sub_v)) && $sub_r) { | |
270 return array( | |
271 array($var1, $sub_r), | |
272 $sub_v | |
273 ); | |
274 } | |
275 } | |
276 } | |
277 return array(0, $v); | |
278 } | |
279 | |
280 } |