danielebarchiesi@4
|
1 <?php
|
danielebarchiesi@4
|
2 /*
|
danielebarchiesi@4
|
3 homepage: http://arc.semsol.org/
|
danielebarchiesi@4
|
4 license: http://arc.semsol.org/license
|
danielebarchiesi@4
|
5
|
danielebarchiesi@4
|
6 class: ARC2 SPARQL+ Parser (SPARQL + Aggregates + LOAD + INSERT + DELETE)
|
danielebarchiesi@4
|
7 author: Benjamin Nowack
|
danielebarchiesi@4
|
8 version: 2010-11-16
|
danielebarchiesi@4
|
9 */
|
danielebarchiesi@4
|
10
|
danielebarchiesi@4
|
11 ARC2::inc('SPARQLParser');
|
danielebarchiesi@4
|
12
|
danielebarchiesi@4
|
13 class ARC2_SPARQLPlusParser extends ARC2_SPARQLParser {
|
danielebarchiesi@4
|
14
|
danielebarchiesi@4
|
15 function __construct($a, &$caller) {
|
danielebarchiesi@4
|
16 parent::__construct($a, $caller);
|
danielebarchiesi@4
|
17 }
|
danielebarchiesi@4
|
18
|
danielebarchiesi@4
|
19 function __init() {
|
danielebarchiesi@4
|
20 parent::__init();
|
danielebarchiesi@4
|
21 }
|
danielebarchiesi@4
|
22
|
danielebarchiesi@4
|
23 /* +1 */
|
danielebarchiesi@4
|
24
|
danielebarchiesi@4
|
25 function xQuery($v) {
|
danielebarchiesi@4
|
26 list($r, $v) = $this->xPrologue($v);
|
danielebarchiesi@4
|
27 foreach (array('Select', 'Construct', 'Describe', 'Ask', 'Insert', 'Delete', 'Load') as $type) {
|
danielebarchiesi@4
|
28 $m = 'x' . $type . 'Query';
|
danielebarchiesi@4
|
29 if ((list($r, $v) = $this->$m($v)) && $r) {
|
danielebarchiesi@4
|
30 return array($r, $v);
|
danielebarchiesi@4
|
31 }
|
danielebarchiesi@4
|
32 }
|
danielebarchiesi@4
|
33 return array(0, $v);
|
danielebarchiesi@4
|
34 }
|
danielebarchiesi@4
|
35
|
danielebarchiesi@4
|
36 /* +3 */
|
danielebarchiesi@4
|
37
|
danielebarchiesi@4
|
38 function xResultVar($v) {
|
danielebarchiesi@4
|
39 $aggregate = '';
|
danielebarchiesi@4
|
40 /* aggregate */
|
danielebarchiesi@4
|
41 if ($sub_r = $this->x('\(?(AVG|COUNT|MAX|MIN|SUM)\s*\(\s*([^\)]+)\)\s+AS\s+([^\s\)]+)\)?', $v)) {
|
danielebarchiesi@4
|
42 $aggregate = $sub_r[1];
|
danielebarchiesi@4
|
43 $result_var = $sub_r[3];
|
danielebarchiesi@4
|
44 $v = $sub_r[2] . $sub_r[4];
|
danielebarchiesi@4
|
45 }
|
danielebarchiesi@4
|
46 if ($sub_r && (list($sub_r, $sub_v) = $this->xVar($result_var)) && $sub_r) {
|
danielebarchiesi@4
|
47 $result_var = $sub_r['value'];
|
danielebarchiesi@4
|
48 }
|
danielebarchiesi@4
|
49 /* * or var */
|
danielebarchiesi@4
|
50 if ((list($sub_r, $sub_v) = $this->x('\*', $v)) && $sub_r) {
|
danielebarchiesi@4
|
51 return array(array('var' => $sub_r['value'], 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''), $sub_v);
|
danielebarchiesi@4
|
52 }
|
danielebarchiesi@4
|
53 if ((list($sub_r, $sub_v) = $this->xVar($v)) && $sub_r) {
|
danielebarchiesi@4
|
54 return array(array('var' => $sub_r['value'], 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''), $sub_v);
|
danielebarchiesi@4
|
55 }
|
danielebarchiesi@4
|
56 return array(0, $v);
|
danielebarchiesi@4
|
57 }
|
danielebarchiesi@4
|
58
|
danielebarchiesi@4
|
59 /* +4 */
|
danielebarchiesi@4
|
60
|
danielebarchiesi@4
|
61 function xLoadQuery($v) {
|
danielebarchiesi@4
|
62 if ($sub_r = $this->x('LOAD\s+', $v)) {
|
danielebarchiesi@4
|
63 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
64 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
65 $r = array('type' => 'load', 'url' => $sub_r, 'target_graph' => '');
|
danielebarchiesi@4
|
66 if ($sub_r = $this->x('INTO\s+', $sub_v)) {
|
danielebarchiesi@4
|
67 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
68 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
69 $r['target_graph'] = $sub_r;
|
danielebarchiesi@4
|
70 }
|
danielebarchiesi@4
|
71 }
|
danielebarchiesi@4
|
72 return array($r, $sub_v);
|
danielebarchiesi@4
|
73 }
|
danielebarchiesi@4
|
74 }
|
danielebarchiesi@4
|
75 return array(0, $v);
|
danielebarchiesi@4
|
76 }
|
danielebarchiesi@4
|
77
|
danielebarchiesi@4
|
78 /* +5 */
|
danielebarchiesi@4
|
79
|
danielebarchiesi@4
|
80 function xInsertQuery($v) {
|
danielebarchiesi@4
|
81 if ($sub_r = $this->x('INSERT\s+', $v)) {
|
danielebarchiesi@4
|
82 $r = array(
|
danielebarchiesi@4
|
83 'type' => 'insert',
|
danielebarchiesi@4
|
84 'dataset' => array(),
|
danielebarchiesi@4
|
85 );
|
danielebarchiesi@4
|
86 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
87 /* target */
|
danielebarchiesi@4
|
88 if ($sub_r = $this->x('INTO\s+', $sub_v)) {
|
danielebarchiesi@4
|
89 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
90 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
91 $r['target_graph'] = $sub_r;
|
danielebarchiesi@4
|
92 /* CONSTRUCT keyword, optional */
|
danielebarchiesi@4
|
93 if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
|
danielebarchiesi@4
|
94 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
95 }
|
danielebarchiesi@4
|
96 /* construct template */
|
danielebarchiesi@4
|
97 if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && is_array($sub_r)) {
|
danielebarchiesi@4
|
98 $r['construct_triples'] = $sub_r;
|
danielebarchiesi@4
|
99 }
|
danielebarchiesi@4
|
100 else {
|
danielebarchiesi@4
|
101 $this->addError('Construct Template not found');
|
danielebarchiesi@4
|
102 return array(0, $v);
|
danielebarchiesi@4
|
103 }
|
danielebarchiesi@4
|
104 /* dataset */
|
danielebarchiesi@4
|
105 while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
106 $r['dataset'][] = $sub_r;
|
danielebarchiesi@4
|
107 }
|
danielebarchiesi@4
|
108 /* where */
|
danielebarchiesi@4
|
109 if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
110 $r['pattern'] = $sub_r;
|
danielebarchiesi@4
|
111 }
|
danielebarchiesi@4
|
112 /* solution modifier */
|
danielebarchiesi@4
|
113 if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
114 $r = array_merge($r, $sub_r);
|
danielebarchiesi@4
|
115 }
|
danielebarchiesi@4
|
116 return array($r, $sub_v);
|
danielebarchiesi@4
|
117 }
|
danielebarchiesi@4
|
118 }
|
danielebarchiesi@4
|
119 }
|
danielebarchiesi@4
|
120 return array(0, $v);
|
danielebarchiesi@4
|
121 }
|
danielebarchiesi@4
|
122
|
danielebarchiesi@4
|
123 /* +6 */
|
danielebarchiesi@4
|
124
|
danielebarchiesi@4
|
125 function xDeleteQuery($v) {
|
danielebarchiesi@4
|
126 if ($sub_r = $this->x('DELETE\s+', $v)) {
|
danielebarchiesi@4
|
127 $r = array(
|
danielebarchiesi@4
|
128 'type' => 'delete',
|
danielebarchiesi@4
|
129 'target_graphs' => array()
|
danielebarchiesi@4
|
130 );
|
danielebarchiesi@4
|
131 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
132 /* target */
|
danielebarchiesi@4
|
133 do {
|
danielebarchiesi@4
|
134 $proceed = false;
|
danielebarchiesi@4
|
135 if ($sub_r = $this->x('FROM\s+', $sub_v)) {
|
danielebarchiesi@4
|
136 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
137 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
138 $r['target_graphs'][] = $sub_r;
|
danielebarchiesi@4
|
139 $proceed = 1;
|
danielebarchiesi@4
|
140 }
|
danielebarchiesi@4
|
141 }
|
danielebarchiesi@4
|
142 } while ($proceed);
|
danielebarchiesi@4
|
143 /* CONSTRUCT keyword, optional */
|
danielebarchiesi@4
|
144 if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
|
danielebarchiesi@4
|
145 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
146 }
|
danielebarchiesi@4
|
147 /* construct template */
|
danielebarchiesi@4
|
148 if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && is_array($sub_r)) {
|
danielebarchiesi@4
|
149 $r['construct_triples'] = $sub_r;
|
danielebarchiesi@4
|
150 /* dataset */
|
danielebarchiesi@4
|
151 while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
152 $r['dataset'][] = $sub_r;
|
danielebarchiesi@4
|
153 }
|
danielebarchiesi@4
|
154 /* where */
|
danielebarchiesi@4
|
155 if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
156 $r['pattern'] = $sub_r;
|
danielebarchiesi@4
|
157 }
|
danielebarchiesi@4
|
158 /* solution modifier */
|
danielebarchiesi@4
|
159 if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
160 $r = array_merge($r, $sub_r);
|
danielebarchiesi@4
|
161 }
|
danielebarchiesi@4
|
162 }
|
danielebarchiesi@4
|
163 return array($r, $sub_v);
|
danielebarchiesi@4
|
164 }
|
danielebarchiesi@4
|
165 return array(0, $v);
|
danielebarchiesi@4
|
166 }
|
danielebarchiesi@4
|
167
|
danielebarchiesi@4
|
168 /* +7 */
|
danielebarchiesi@4
|
169
|
danielebarchiesi@4
|
170 function xSolutionModifier($v) {
|
danielebarchiesi@4
|
171 $r = array();
|
danielebarchiesi@4
|
172 if ((list($sub_r, $sub_v) = $this->xGroupClause($v)) && $sub_r) {
|
danielebarchiesi@4
|
173 $r['group_infos'] = $sub_r;
|
danielebarchiesi@4
|
174 }
|
danielebarchiesi@4
|
175 if ((list($sub_r, $sub_v) = $this->xOrderClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
176 $r['order_infos'] = $sub_r;
|
danielebarchiesi@4
|
177 }
|
danielebarchiesi@4
|
178 while ((list($sub_r, $sub_v) = $this->xLimitOrOffsetClause($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
179 $r = array_merge($r, $sub_r);
|
danielebarchiesi@4
|
180 }
|
danielebarchiesi@4
|
181 return ($v == $sub_v) ? array(0, $v) : array($r, $sub_v);
|
danielebarchiesi@4
|
182 }
|
danielebarchiesi@4
|
183
|
danielebarchiesi@4
|
184 /* +8 */
|
danielebarchiesi@4
|
185
|
danielebarchiesi@4
|
186 function xGroupClause($v) {
|
danielebarchiesi@4
|
187 if ($sub_r = $this->x('GROUP BY\s+', $v)) {
|
danielebarchiesi@4
|
188 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
189 $r = array();
|
danielebarchiesi@4
|
190 do {
|
danielebarchiesi@4
|
191 $proceed = 0;
|
danielebarchiesi@4
|
192 if ((list($sub_r, $sub_v) = $this->xVar($sub_v)) && $sub_r) {
|
danielebarchiesi@4
|
193 $r[] = $sub_r;
|
danielebarchiesi@4
|
194 $proceed = 1;
|
danielebarchiesi@4
|
195 if ($sub_r = $this->x('\,', $sub_v)) {
|
danielebarchiesi@4
|
196 $sub_v = $sub_r[1];
|
danielebarchiesi@4
|
197 }
|
danielebarchiesi@4
|
198 }
|
danielebarchiesi@4
|
199 } while ($proceed);
|
danielebarchiesi@4
|
200 if (count($r)) {
|
danielebarchiesi@4
|
201 return array($r, $sub_v);
|
danielebarchiesi@4
|
202 }
|
danielebarchiesi@4
|
203 else {
|
danielebarchiesi@4
|
204 $this->addError('No columns specified in GROUP BY clause.');
|
danielebarchiesi@4
|
205 }
|
danielebarchiesi@4
|
206 }
|
danielebarchiesi@4
|
207 return array(0, $v);
|
danielebarchiesi@4
|
208 }
|
danielebarchiesi@4
|
209
|
danielebarchiesi@4
|
210 }
|