3 homepage: http://arc.semsol.org/
4 license: http://arc.semsol.org/license
6 class: ARC2 SPARQL+ Parser (SPARQL + Aggregates + LOAD + INSERT + DELETE)
7 author: Benjamin Nowack
8 version: 2008-05-30 (Tweak: CONSTRUCT keyword is now optional)
11 ARC2::inc('SPARQLParser');
13 class ARC2_SPARQLPlusParser extends ARC2_SPARQLParser {
15 function __construct($a = '', &$caller) {
16 parent::__construct($a, $caller);
19 function ARC2_SPARQLPlusParser($a = '', &$caller) {
20 $this->__construct($a, $caller);
30 list($r, $v) = $this->xPrologue($v);
31 foreach (array('Select', 'Construct', 'Describe', 'Ask', 'Insert', 'Delete', 'Load') as $type) {
32 $m = 'x' . $type . 'Query';
33 if ((list($r, $v) = $this->$m($v)) && $r) {
42 function xResultVar($v) {
45 if ($sub_r = $this->x('\(?(AVG|COUNT|MAX|MIN|SUM)\s*\(\s*([^\)]+)\)\s+AS\s+([^\s\)]+)\)?', $v)) {
46 $aggregate = $sub_r[1];
47 $result_var = $sub_r[3];
48 $v = $sub_r[2] . $sub_r[4];
50 if ($sub_r && (list($sub_r, $sub_v) = $this->xVar($result_var)) && $sub_r) {
51 $result_var = $sub_r['value'];
54 if ((list($sub_r, $sub_v) = $this->x('\*', $v)) && $sub_r) {
55 return array(array('var' => $sub_r['value'], 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''), $sub_v);
57 if ((list($sub_r, $sub_v) = $this->xVar($v)) && $sub_r) {
58 return array(array('var' => $sub_r['value'], 'aggregate' => $aggregate, 'alias' => $aggregate ? $result_var : ''), $sub_v);
65 function xLoadQuery($v) {
66 if ($sub_r = $this->x('LOAD\s+', $v)) {
68 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
69 $r = array('type' => 'load', 'url' => $sub_r, 'target_graph' => '');
70 if ($sub_r = $this->x('INTO\s+', $sub_v)) {
72 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
73 $r['target_graph'] = $sub_r;
76 return array($r, $sub_v);
84 function xInsertQuery($v) {
85 if ($sub_r = $this->x('INSERT\s+', $v)) {
92 if ($sub_r = $this->x('INTO\s+', $sub_v)) {
94 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
95 $r['target_graph'] = $sub_r;
96 /* CONSTRUCT keyword, optional */
97 if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
100 /* construct template */
101 if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && is_array($sub_r)) {
102 $r['construct_triples'] = $sub_r;
105 $this->addError('Construct Template not found');
109 while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
110 $r['dataset'][] = $sub_r;
113 if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
114 $r['pattern'] = $sub_r;
116 /* solution modifier */
117 if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
118 $r = array_merge($r, $sub_r);
120 return array($r, $sub_v);
129 function xDeleteQuery($v) {
130 if ($sub_r = $this->x('DELETE\s+', $v)) {
133 'target_graphs' => array()
139 if ($sub_r = $this->x('FROM\s+', $sub_v)) {
141 if ((list($sub_r, $sub_v) = $this->xIRIref($sub_v)) && $sub_r) {
142 $r['target_graphs'][] = $sub_r;
147 /* CONSTRUCT keyword, optional */
148 if ($sub_r = $this->x('CONSTRUCT\s+', $sub_v)) {
151 /* construct template */
152 if ((list($sub_r, $sub_v) = $this->xConstructTemplate($sub_v)) && is_array($sub_r)) {
153 $r['construct_triples'] = $sub_r;
155 while ((list($sub_r, $sub_v) = $this->xDatasetClause($sub_v)) && $sub_r) {
156 $r['dataset'][] = $sub_r;
159 if ((list($sub_r, $sub_v) = $this->xWhereClause($sub_v)) && $sub_r) {
160 $r['pattern'] = $sub_r;
162 /* solution modifier */
163 if ((list($sub_r, $sub_v) = $this->xSolutionModifier($sub_v)) && $sub_r) {
164 $r = array_merge($r, $sub_r);
167 return array($r, $sub_v);
174 function xSolutionModifier($v) {
176 if ((list($sub_r, $sub_v) = $this->xGroupClause($v)) && $sub_r) {
177 $r['group_infos'] = $sub_r;
179 if ((list($sub_r, $sub_v) = $this->xOrderClause($sub_v)) && $sub_r) {
180 $r['order_infos'] = $sub_r;
182 while ((list($sub_r, $sub_v) = $this->xLimitOrOffsetClause($sub_v)) && $sub_r) {
183 $r = array_merge($r, $sub_r);
185 return ($v == $sub_v) ? array(0, $v) : array($r, $sub_v);
190 function xGroupClause($v) {
191 if ($sub_r = $this->x('GROUP BY\s+', $v)) {
196 if ((list($sub_r, $sub_v) = $this->xVar($sub_v)) && $sub_r) {
199 if ($sub_r = $this->x('\,', $sub_v)) {
205 return array($r, $sub_v);
208 $this->addError('No columns specified in GROUP BY clause.');