diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sites/all/libraries/ARC2/arc/sparqlscript/ARC2_SPARQLScriptParser.php	Thu Sep 19 10:38:44 2013 +0100
@@ -0,0 +1,280 @@
+<?php
+/*
+homepage: http://arc.semsol.org/
+license:  http://arc.semsol.org/license
+
+class:    ARC2 SPARQLScript Parser (SPARQL+ + functions)
+author:   Benjamin Nowack
+version:  2010-11-16
+*/
+
+ARC2::inc('ARC2_SPARQLPlusParser');
+
+class ARC2_SPARQLScriptParser extends ARC2_SPARQLPlusParser {
+
+  function __construct($a, &$caller) {
+    parent::__construct($a, $caller);
+  }
+  
+  function __init() {
+    parent::__init();
+  }
+
+  /*  */
+
+  function parse($v, $src = '', $iso_fallback = 'ignore') {
+    $this->setDefaultPrefixes();
+    $this->base = $src ? $this->calcBase($src) : ARC2::getScriptURI();
+    $this->blocks = array();
+    $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes);
+    do {
+      $proceed = 0;
+      if ((list($r, $v) = $this->xScriptBlock($v)) && $r) {
+        $this->blocks[] = $r;
+        $proceed = 1;
+      }
+      $this->unparsed_code = trim($v);
+    } while ($proceed);
+    if (trim($this->unparsed_code) && !$this->getErrors()) {
+      $rest = preg_replace('/[\x0a|\x0d]/i', ' ', substr($this->unparsed_code, 0, 30));
+      $msg = trim($rest) ? 'Could not properly handle "' . $rest . '"' : 'Syntax Error';
+      $this->addError($msg);
+    }
+  }
+  
+  function getScriptBlocks() {
+    return $this->v('blocks', array());
+  }
+
+  /*  */
+
+  function xScriptBlock($v) {
+    /* comment removal */  
+    while (preg_match('/^\s*(\#[^\xd\xa]*)(.*)$/si', $v, $m)) $v = $m[2];
+    /* BaseDecl */
+    if ((list($sub_r, $v) = $this->xBaseDecl($v)) && $sub_r) {
+      $this->base = $sub_r;
+    }
+    /* PrefixDecl */
+    while ((list($r, $v) = $this->xPrefixDecl($v)) && $r) {
+      $this->prefixes[$r['prefix']] = $r['uri'];
+    }
+    /* EndpointDecl */
+    if ((list($r, $v) = $this->xEndpointDecl($v)) && $r) {
+      return array($r, $v);
+    }
+    /* Return */
+    if ((list($r, $v) = $this->xReturn($v)) && $r) {
+      return array($r, $v);
+    }
+    /* Assignment */
+    if ((list($r, $v) = $this->xAssignment($v)) && $r) {
+      return array($r, $v);
+    }
+    /* IFBlock */
+    if ((list($r, $v) = $this->xIFBlock($v)) && $r) {
+      return array($r, $v);
+    }
+    /* FORBlock */
+    if ((list($r, $v) = $this->xFORBlock($v)) && $r) {
+      return array($r, $v);
+    }
+    /* String */
+    if ((list($r, $v) = $this->xString($v)) && $r) {
+      return array($r, $v);
+    }
+    /* FunctionCall */
+    if ((list($r, $v) = $this->xFunctionCall($v)) && $r) {
+      return array($r, ltrim($v, ';'));
+    }
+    /* Query */
+    $prev_r = $this->r;
+    $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes);
+    if ((list($r, $rest) = $this->xQuery($v)) && $r) {
+      $q = $rest ? trim(substr($v, 0, -strlen($rest))) : trim($v);
+      $v = $rest;
+      $r = array_merge($this->r, array(
+        'type' => 'query',
+        'query_type' => $r['type'],
+        'query' => $q,
+        //'prefixes' => $this->prefixes,
+        'base' => $this->base,
+        //'infos' => $r
+      ));
+      return array($r, $v);
+    }
+    else {
+      $this->r = $prev_r;
+    }
+    return array(0, $v);
+  }
+
+  function xBlockSet($v) {
+    if (!$r = $this->x("\{", $v)) return array(0, $v);
+    $blocks = array();
+    $sub_v = $r[1];
+    while ((list($sub_r, $sub_v) = $this->xScriptBlock($sub_v)) && $sub_r) {
+      $blocks[] = $sub_r;
+    }
+    if (!$sub_r = $this->x("\}", $sub_v)) return array(0, $v);
+    $sub_v = $sub_r[1];
+    return array(array('type' => 'block_set', 'blocks' => $blocks), $sub_v);
+  }
+  
+  /* s2 */
+  
+  function xEndpointDecl($v) {
+    if ($r = $this->x("ENDPOINT\s+", $v)) {
+      if ((list($r, $sub_v) = $this->xIRI_REF($r[1])) && $r) {
+        $r = $this->calcURI($r, $this->base);
+        if ($sub_r = $this->x('\.', $sub_v)) {
+          $sub_v = $sub_r[1];
+        }
+        return array(
+          array('type' => 'endpoint_decl', 'endpoint' => $r),
+          $sub_v
+        );
+      }
+    }
+    return array(0, $v);
+  }
+  
+  /* s3 */
+  
+  function xAssignment($v) {
+    /* Var */
+    list($r, $sub_v) = $this->xVar($v);
+    if (!$r) return array(0, $v);
+    $var = $r;
+    /* := | = */
+    if (!$sub_r = $this->x("\:?\=", $sub_v)) return array(0, $v);
+    $sub_v = $sub_r[1];
+    /* try String */
+    list($r, $sub_v) = $this->xString($sub_v);
+    if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'string', 'string' => $r), ltrim($sub_v, '; '));
+    /* try VarMerge */
+    list($r, $sub_v) = $this->xVarMerge($sub_v);
+    if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'var_merge', 'var2' => $r[0], 'var3' => $r[1]), ltrim($sub_v, '; '));
+    /* try Var */
+    list($r, $sub_v) = $this->xVar($sub_v);
+    if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'var', 'var2' => $r), ltrim($sub_v, '; '));
+    /* try function */
+    list($r, $sub_v) = $this->xFunctionCall($sub_v);
+    if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'function_call', 'function_call' => $r), ltrim($sub_v, '; '));
+    /* try Placeholder */
+    list($r, $sub_v) = $this->xPlaceholder($sub_v);
+    if ($r) return array(array('type' => 'assignment', 'var' => $var, 'sub_type' => 'placeholder', 'placeholder' => $r), ltrim($sub_v, '; '));
+    /* try query */
+    $prev_r = $this->r;
+    $this->r = array('base' => '', 'vars' => array(), 'prefixes' => $this->prefixes);
+    list($r, $rest) = $this->xQuery($sub_v);
+    if (!$r) {
+      $this->r = $prev_r;
+      return array(0, $v);
+    }
+    else {
+      $q = $rest ? trim(substr($sub_v, 0, -strlen($rest))) : trim($sub_v);
+      return array(
+        array(
+          'type' => 'assignment', 
+          'var' => $var,
+          'sub_type' => 'query',
+          'query' => array_merge($this->r, array(
+            'type' => 'query',
+            'query_type' => $r['type'],
+            'query' => $q,
+            'base' => $this->base,
+          )),
+        ),
+        ltrim($rest, '; ')
+      );
+    }
+  }
+
+  function xReturn($v) {
+    if ($r = $this->x("return\s+", $v)) {
+      /* fake assignment which accepts same right-hand values */
+      $sub_v = '$__return_value__ := ' . $r[1];
+      if ((list($r, $sub_v) = $this->xAssignment($sub_v)) && $r) {
+        $r['type'] = 'return';
+        return array($r, $sub_v);
+      }
+    }
+    return array(0, $v);
+  }
+  
+  /* s4 'IF' BrackettedExpression '{' Script '}' ( 'ELSE' '{' Script '}')?  */
+  
+  function xIFBlock($v) {
+    if ($r = $this->x("IF\s*", $v)) {
+      if ((list($sub_r, $sub_v) = $this->xBrackettedExpression($r[1])) && $sub_r) {
+        $cond = $sub_r;
+        if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_v)) && $sub_r) {
+          $blocks = $sub_r['blocks'];
+          /* else */
+          $else_blocks = array();
+          $rest = $sub_v;
+          if ($sub_r = $this->x("ELSE\s*", $sub_v)) {
+            if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_r[1])) && $sub_r) {
+              $else_blocks = $sub_r['blocks'];
+            }
+            else {
+              $sub_v = $rest;
+            }
+          }
+          return array(
+            array(
+              'type' => 'ifblock',
+              'condition' => $cond,
+              'blocks' => $blocks,
+              'else_blocks' => $else_blocks,
+            ),
+            $sub_v
+          );
+        }
+      }
+    }
+    return array(0, $v);
+  }
+  
+  /* s5 'FOR' '(' Var 'IN' Var ')' '{' Script '}' */
+  
+  function xFORBlock($v) {
+    if ($r = $this->x("FOR\s*\(\s*[\$\?]([^\s]+)\s+IN\s+[\$\?]([^\s]+)\s*\)", $v)) {/* @@todo split into sub-patterns? */
+      $iterator = $r[1];
+      $set_var = $r[2];
+      $sub_v = $r[3];
+      if ((list($sub_r, $sub_v) = $this->xBlockSet($sub_v)) && $sub_r) {
+        return array(
+          array(
+            'type' => 'forblock',
+            'set' => $set_var,
+            'iterator' => $iterator,
+            'blocks' => $sub_r['blocks']
+          ),
+          $sub_v
+        );
+      }
+    }
+    return array(0, $v);
+  }
+  
+  /* s6 Var '+' Var */
+  
+  function xVarMerge($v) {
+    if ((list($sub_r, $sub_v) = $this->xVar($v)) && $sub_r) {
+      $var1 = $sub_r;
+      if ($sub_r = $this->x("\+", $sub_v)) {
+        $sub_v = $sub_r[1];
+        if ((list($sub_r, $sub_v) = $this->xVar($sub_v)) && $sub_r) {
+          return array(
+            array($var1, $sub_r),
+            $sub_v
+          );
+        }
+      }
+    }
+    return array(0, $v);
+  }
+  
+}