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 }