Code

Updated sieve filter styles.
[gosa.git] / include / sieve / class_parser.inc
index 7ca1f9e3b25e349eb5a6f04db852aee016c1b742..345895231f2ec801cd55107e00153f68ec004406 100644 (file)
@@ -1,15 +1,22 @@
 <?php
+
+#include_once 'class.tree.php';
+#include_once 'class.scanner.php';
+#include_once 'class.semantics.php';
+
 class Parser
 {
        var $scanner_;
        var $script_;
        var $tree_;
        var $status_;
+       var $registeredExtensions_;
 
        var $status_text;
 
        function parse($script)
        {
+               $this->registeredExtensions_ = array();
                $this->status_text = "incomplete";
 
                $this->script_ = $script;
@@ -47,6 +54,47 @@ class Parser
                return strval($token);
        }
 
+       function getPrevTokenText_($parent_id)
+       {
+               $childs = $this->tree_->getChilds($parent_id);
+
+               for ($i=count($childs); $i>0; --$i)
+               {
+                       $prev = $this->tree_->getNode($childs[$i-1]);
+
+                       if (in_array($prev['text'], array('{', '(', ',')))
+                       {
+                               // use command owning a block or list
+                               $prev = $this->tree_->getNode($parent_id);
+                       }
+
+                       if ($prev['class'] != 'comment')
+                       {
+                               return $prev['text'];
+                       }
+               }
+
+               $prev = $this->tree_->getNode($parent_id);
+               return $prev['text'];
+       }
+
+       function getSemantics_($token_text)
+       {
+               $semantics = new Semantics($token_text);
+               $semantics->setExtensionFuncs(array(&$this, 'registerExtension_'), array(&$this, 'isExtensionRegistered_'));
+               return $semantics;
+       }
+
+       function registerExtension_($extension)
+       {
+               array_push($this->registeredExtensions_, str_replace('"', '', $extension));
+       }
+
+       function isExtensionRegistered_($extension)
+       {
+               return (in_array($extension, $this->registeredExtensions_) ? true : false);
+       }
+
        function success_($text = null)
        {
                if ($text != null)
@@ -74,6 +122,10 @@ class Parser
                return false;
        }
 
+       /*******************************************************************************
+        * methods for recursive descent start below
+        */
+
        function comment_($token)
        {
                $this->tree_->addChild($token);
@@ -100,16 +152,10 @@ class Parser
 
                // Get and check a command token
                $token = $this->scanner_->nextToken();
-               $semantics = new Semantics($token['text']);
-               if ($semantics->unknown)
+               $semantics = $this->getSemantics_($token['text']);
+               if (!$semantics->validCommand($this->getPrevTokenText_($parent_id), $token['line']))
                {
-                       return $this->error_('unknown command: '. $token['text']);
-               }
-
-               $last = $this->tree_->getLastNode($parent_id);
-               if (!$semantics->validAfter($last['text']))
-               {
-                       return $this->error_('"'. $token['text'] .'" may not appear after "'. $last['text'] .'"');
+                       return $this->error_($semantics->message);
                }
 
                // Process eventual arguments
@@ -274,10 +320,10 @@ class Parser
                }
 
                // Get semantics for this test command
-               $this_semantics = new Semantics($token['text']);
-               if ($this_semantics->unknown)
+               $this_semantics = $this->getSemantics_($token['text']);
+               if (!$this_semantics->validCommand($this->getPrevTokenText_($parent_id), $token['line']))
                {
-                       return $this->error_('unknown test: '. $token['text']);
+                       return $this->error_($this_semantics->message);
                }
 
                $this_node = $this->tree_->addChildTo($parent_id, $token);