[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/modules/com_vtiger_workflow/expression_engine/ -> VTParser.inc (source)

   1  <?php
   2  /*+*******************************************************************************
   3   * The contents of this file are subject to the vtiger CRM Public License Version 1.0
   4   * ("License"); You may not use this file except in compliance with the License
   5   * The Original Code is:  vtiger CRM Open Source
   6   * The Initial Developer of the Original Code is vtiger.
   7   * Portions created by vtiger are Copyright (C) vtiger.
   8   * All Rights Reserved.
   9   ******************************************************************************/
  10  class VTExpressionTreeNode{
  11  	function __construct($arr){
  12          $this->arr = $arr;
  13      }
  14  
  15  	function getParams(){
  16          $arr = $this->arr;
  17          return array_slice($arr, 1, sizeof($arr)-1);
  18      }
  19  
  20  	function getName(){
  21          return $this->arr[0];
  22      }
  23  }
  24  
  25  
  26  class VTExpressionSymbol{
  27  	function __construct($value){
  28          $this->value = $value;
  29      }
  30  
  31  	function __toString(){
  32          return "VTExpressionSymbol({$this->value})";
  33      }
  34  }
  35  
  36  class VTExpressionParser{
  37  	function __construct($tokens){
  38          $this->tokens = $tokens;
  39          $this->tokenQueue = array();
  40      }
  41  
  42  	function nextToken(){
  43          if(sizeof($this->tokenQueue)==0){
  44              return $this->tokens->nextToken();
  45          }else{
  46              return array_shift($this->tokenQueue);
  47          }
  48      }
  49  
  50      function la($n = 1){
  51          for($i=sizeof($this->tokenQueue); $i<$n; $i++){
  52              $token = $this->tokens->nextToken();
  53              $this->tokenQueue[] = $token;
  54          }
  55          return $this->tokenQueue[$n-1];
  56      }
  57  
  58  	function consume($label, $value){
  59          $token=$this->nextToken();
  60          if($token->label!=$label || $token->value!=$value){
  61              echo "Was expecting a $label of value $value got a {$token->label} of {$token->value} instead.";
  62              throw new Exception("Was expecting a $label of value $value got a {$token->label} of {$token->value} instead.");
  63          }
  64      }
  65  
  66  	function consumeSymbol($sym){
  67          $this->consume('SYMBOL', new VTExpressionSymbol($sym));
  68      }
  69  
  70  
  71  	function check($token, $label, $value){
  72          return $token->label == $label && $token->value==$value;
  73      }
  74  
  75  	function checkSymbol($token, $sym){
  76          return $this->check($token, 'SYMBOL', new VTExpressionSymbol($sym));
  77      }
  78  
  79  	function atom(){
  80          $token = $this->nextToken();
  81          switch($token->label){
  82              case "STRING":
  83                  return $token->value;
  84              case "INTEGER":
  85                  return $token->value;
  86              case "FLOAT":
  87                  return $token->value;
  88              case "SYMBOL":
  89                  return $token->value;
  90              case "OPEN_BRACKET":
  91                  $val = $this->expression();
  92                  $close = $this->nextToken();
  93                  if($close->label != 'CLOSE_BRACKET'){
  94                      throw new Exception("Was expecting a close bracket");
  95                  }
  96                  return $val;
  97              default:
  98                  print_r($token);
  99                  throw new Exception();
 100          }
 101      }
 102  
 103  	function ifCondition(){
 104          $this->consumeSymbol('if');
 105          $cond = $this->expression();
 106          $this->consumeSymbol('then');
 107          $ifTrue = $this->expression();
 108          $this->consumeSymbol('else');
 109          if($this->checkSymbol($this->la(), 'if')){
 110              $ifFalse = $this->ifCondition();
 111          }else{
 112              $ifFalse = $this->expression();
 113              $this->consumeSymbol('end');
 114          }
 115          return new VTExpressionTreeNode(array(new VTExpressionSymbol('if'), $cond, $ifTrue, $ifFalse));
 116      }
 117  
 118  	function expression(){
 119          $la1 = $this->la(1);
 120          $la2 = $this->la(2);
 121          if($this->checkSymbol($la1, 'if')){
 122              return $this->ifCondition();
 123          }else if($la1->label=='SYMBOL' && $la2->label=='OPEN_BRACKET'){
 124              $arr = array($this->nextToken()->value);
 125              $this->nextToken();
 126              if($this->la()->label != 'CLOSE_BRACKET'){
 127                  $arr[] = $this->expression();
 128                  $comma = $this->nextToken();
 129                  while($comma->label == 'COMMA'){
 130                      $arr[] = $this->expression();
 131                      $comma = $this->nextToken();
 132                  }
 133                  if($comma->label != 'CLOSE_BRACKET'){
 134                      throw new Exception("Was expecting a closing bracket");
 135                  }
 136              }else{
 137                  $this->consume('CLOSE_BRACKET', new Symbol(')'));
 138              }
 139              return new VTExpressionTreeNode($arr);
 140          }else{
 141              return $this->binOp();
 142          }
 143      }
 144  
 145      var $precedence = array(
 146          array('*', '/'),
 147          array('+', '-'),
 148          array('and', 'or'),
 149          array('==', '>=', '<=', '>', '<')        
 150      );
 151  
 152  	function binOp(){
 153          return $this->binOpPrec(sizeof($this->precedence)-1);
 154      }
 155  
 156  	private function binOpPrec($prec){
 157          if($prec>=0){
 158              $lhs = $this->binOpPrec($prec-1);
 159              $la = $this->la();
 160              if($la->label == 'OPERATOR' && in_array($la->value->value, $this->precedence[$prec])){
 161                  $operator = $this->nextToken()->value;
 162                  $rhs = $this->binOpPrec($prec);
 163                  return new VTExpressionTreeNode(array($operator, $lhs, $rhs));
 164              }else{
 165                  return $lhs;
 166              }
 167          }else{
 168              return $this->unaryOp();
 169          }
 170      }
 171  
 172  	function unaryOp(){
 173          $la = $this->la();
 174          if($la->label=="OPERATOR" && in_array($la->value->value, array('+', '-'))){
 175              $token = $this->nextToken();
 176              $operator = $la->value;
 177              $operand = $this->unaryOp();
 178              return new VTExpressionTreeNode(array($operator, $operand));
 179          }else{
 180              return $this->atom();
 181          }
 182      }
 183  }
 184  ?>


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1