Plugin Directory

Changeset 842669


Ignore:
Timestamp:
01/21/2014 09:22:11 PM (12 years ago)
Author:
jazzigor
Message:

Updating trunk to 1.1.1

Location:
jazzy-forms/trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • jazzy-forms/trunk/core/Parser.php

    r839285 r842669  
    55formula = comparison;
    66comparison = concatenation, [("<" | ">" | "<=" | "=>" | "<>"), comparison];
    7 concatenation = sum, [ "&", concatenation ];
    8 sum = product, [("+" | "-"), sum];
    9 product = exponentiation, [("*" | "/"), product];
    10 exponentiation = negation, ["^", exponentiation];
    11 negation = ["-"], percentage
     7concatenation = addition, [ "&", concatenation ];
     8addition = subtraction, ["+", addition];
     9subtraction = product, ["-", difference];
     10multiplication = division, ["*", multiplication];
     11division = exponentiation, ["/", division];
     12exponentiation = additive_inverse, ["^", exponentiation];
     13additive_inverse = ["-"], percentage
    1214percentage = term ["%"]
    1315term = number | string | function | identifier | association;
     
    3941
    4042class Jzzf_Parser {
     43    private $rest;
     44    private $rule_stack;
     45    private $result_stack;
     46   
    4147    public function __construct($tokens) {
    4248        $this->rest = $tokens;
    43     }
    44 
     49        $this->execution_stack = array();
     50        $this->result_stack = array();
     51    }
     52   
     53    private function push_execution($step, $data=null) {
     54        array_push($this->execution_stack, array($step, $data));
     55    }
     56   
     57    private function pop_execution() {
     58        return array_pop($this->execution_stack);
     59    }
     60
     61    private function push_result($result) {
     62        array_push($this->result_stack, $result);
     63    }
     64   
     65    private function pop_result() {
     66        return array_pop($this->result_stack);
     67    }
     68   
    4569    public function output() {
    46         $result = $this->comparison();
     70        $this->push_execution('operation', 'comparison');
     71        while($this->execution_stack) {
     72            //$this->dump();
     73            list($step, $data) = $this->pop_execution();
     74            $this->$step($data);
     75        }
     76        //$this->dump();
    4777        if($this->rest) {
    4878            throw new Exception('unexpected trailing symbols');
    4979        }
     80        if(!$this->result_stack) {
     81            $result = array();
     82        } else {
     83            $result = $this->pop_result();
     84        }
     85        if($this->result_stack) {
     86            throw new Exception('internal parsing error');           
     87        }
    5088        return $result;
    5189    }
    5290
    53     private function comparison() {
    54         return $this->operation('comparison', array('<=', '>=', '<', '>', '=', '<>'), 'concatenation');
    55     }
    56    
    57     private function concatenation() {
    58         return $this->operation('concatenation', array('&'), 'sum');
    59     }
    60 
    61     private function sum() {
    62         return $this->operation('sum', array('+', '-'), 'product');
    63     }
    64    
    65     private function product() {
    66         return $this->operation('product', array('*', '/'), 'exponentiation');
    67     }
    68    
    69     private function exponentiation() {
    70         return $this->operation('exponentiation', '^', 'negation');
    71     }
    72    
    73     private function operation($name, $operators, $subordinate) {
    74         $left = $this->$subordinate();
    75         if(!$left) {
    76             return array();
    77         }
    78         if($this->ahead($operators)) {
    79             $op = $this->consume();
    80             $right = $this->$name();
    81             if(!$right) {
    82                 throw new Exception('missing right operand');
    83                 return array();
    84             }
    85             return array('o', $op[0], $left, $right);
    86         }
    87         return $left;
    88     }
    89    
     91    private function operation($rule) {
     92        $left_subrules = array(
     93            'comparison' => 'concatenation',
     94            'concatenation' => 'addition',
     95            'addition' => 'subtraction',
     96            'subtraction' => 'multiplication',
     97            'multiplication' => 'division',
     98            'division' => 'exponentiation',
     99            'exponentiation' => 'additive_inverse'
     100        );
     101        $this->push_execution('operation_ahead', $rule);
     102        $left_subrule = $left_subrules[$rule];
     103        if($left_subrule == 'additive_inverse') {
     104            $this->push_execution($left_subrule);
     105        } else {
     106            $this->push_execution('operation', $left_subrules[$rule]);
     107        }
     108    }
     109
     110    private function operation_ahead($rule) {
     111        static $operators = array(
     112            'comparison' => array("<", ">", "<=", ">=", "<>", "="),
     113            'concatenation' => array("&"),
     114            'addition' => array("+"),
     115            'subtraction' => array("-"),
     116            'multiplication' => array("*"),
     117            'division' => array("/"),
     118            'exponentiation' => array("^")
     119        );
     120        if($this->ahead($operators[$rule])) {
     121            $operator = $this->consume();
     122            $this->push_execution('operation_production', $operator[0]);
     123            $this->push_execution('operation', $rule);
     124        }
     125    }
     126   
     127    private function operation_production($operator) {
     128        $right = $this->pop_result();
     129        $left = $this->pop_result();
     130        $this->push_result(array('o', $operator, $left, $right));
     131    }
     132       
    90133    private function ahead($tokens, $skip=0) {
    91134        if(count($this->rest) <= $skip) {
     
    116159
    117160    private function arguments() {
    118         $num = 0;
    119         $result = array();
    120         $first = $this->comparison();
    121         if($first) {
    122             $result[] = $first;
    123         }
    124         while(true) {
    125             if($this->ahead(')')) {
    126                 break;
    127             }
    128             if($this->ahead(',')) {
    129                 $this->consume();
    130                 $next = $this->comparison();
    131                 $result[] = $next;
    132                 $num++;
    133             } else {
    134                 throw new Exception("Closing bracket or comma expected");
    135             }
    136         }
    137         $this->consume(); // closing bracket
    138         return $result;
     161        if(!$this->ahead(')')) {
     162            $this->push_execution('arguments_production', 1);
     163            $this->push_execution('operation', 'comparison');
     164        } else {
     165            $this->push_execution('arguments_production', 0);           
     166        }
     167    }
     168   
     169    private function arguments_production($number) {
     170        if($this->ahead(')')) {
     171            $this->consume();
     172            $arguments = array();
     173            for($i=0; $i<$number; $i++) {
     174                $argument = $this->pop_result();
     175                array_unshift($arguments, $argument);
     176            }
     177            $this->push_result($arguments);           
     178        } elseif($this->ahead(',')) {
     179            $this->consume();
     180            $this->push_execution('arguments_production', $number+1);
     181            $this->push_execution('operation', 'comparison');
     182        } else {
     183            throw new Exception('Closing bracket or comma expected');           
     184        }
    139185    }
    140186
     
    142188        $id = $this->consume();
    143189        $this->consume();
    144         $args = $this->arguments();
    145         return array_merge(array('f', strtolower($id[1])), $args);
     190        $this->push_execution('func_production', strtolower($id[1]));
     191        $this->push_execution('arguments', 0);
     192    }
     193   
     194    private function func_production($id) {
     195        $args = $this->pop_result();
     196        $result = array_merge(array('f', $id), $args);
     197        $this->push_result($result);
    146198    }
    147199   
    148200    private function variable() {
    149201        $id = $this->consume();
    150         return array('v', strtolower($id[1]));
     202        $this->push_result(array('v', strtolower($id[1])));
    151203    }
    152204       
    153205    private function association() {
    154206        $this->consume();
    155         $content = $this->comparison();
    156         if(!$content) {
    157             throw new Exception('Empty bracket term');
    158         }
     207       
     208        $this->push_execution('association_production');
     209        $this->push_execution('operation', 'comparison');
     210    }
     211   
     212    private function association_production() {
     213        $content = $this->pop_result();
    159214        if(!$this->ahead(')')) {
    160215            throw new Exception('Close bracket expected');
    161216        }
    162217        $this->consume();
    163         return $content;
    164     }
    165 
    166     private function negation() {
     218        $this->push_result($content);
     219    }
     220
     221    private function additive_inverse() {
    167222        if($this->ahead('-')) {
    168223            $this->consume();
    169             if($this->ahead('n')) {
    170                 $num = $this->consume();
    171                 $num[1] *= (-1);
    172                 return $num;
    173             } else {
    174                 $positive = $this->percentage();
    175                     if(!$positive) {
    176                     throw new Exception('missing negation operand');
    177                     return array();
    178                 }
    179                 return array("o", "-", array("n", 0), $positive);
    180             }
    181         } else {
    182             return $this->percentage();
     224            $this->push_execution('additive_inverse_production');
     225        }
     226        $this->push_execution('percentage');
     227    }
     228   
     229    private function additive_inverse_production() {
     230        $operand = $this->pop_result();
     231        if(!$operand) {
     232            throw new Exception('missing operand for additive inverse');
     233        }
     234        if($operand[0] == 'n') {
     235            $operand[1] *= (-1);
     236            $this->push_result($operand);
     237        } else {
     238            $this->push_result(array("o", "-", array("n", 0), $operand));
    183239        }
    184240    }
    185241
    186242    private function percentage() {
    187         $value = $this->term();
    188         if($this->ahead('%')) {
    189             if(!$value) {
    190                 throw new Exception("Unexpected percentage sign");
    191             }
     243        $this->push_execution('percentage_production');
     244        $this->push_execution('term');
     245    }
     246
     247    private function percentage_production() {
     248        $value = $this->pop_result();
     249        if($this->ahead(array('%'))) {
    192250            $this->consume();
    193251            if($value[0] == 'n') {
    194252                $value[1] /= 100;
    195                 return $value;
     253                $this->push_result($value);
    196254            } else {
    197                 return array("o", "/", $value, array("n", 100));
    198             }
    199         }
    200         return $value;
     255                $this->push_result(array("o", "/", $value, array("n", 100)));
     256            }
     257        } else {
     258            $this->push_result($value);
     259        }
    201260    }
    202261       
    203262    private function term() {
    204         //$this->dump();
    205263        if($this->complete()) {
    206             return array();
     264            $this->push_result(array());
    207265        }
    208266        else if($this->ahead(array('n', 's'))) { // number or string
    209             return $this->consume();
     267            $this->push_result($this->consume());
    210268        }
    211269        else if($this->ahead('i')) { // identifier
    212270            if($this->ahead('(', 1)) {
    213                 return $this->func();
    214             }
    215             return $this->variable();
     271                $this->push_execution('func');
     272            } else {
     273                $this->push_execution('variable');
     274            }
    216275        }
    217276        else if($this->ahead('(')) {
    218             return $this->association();
    219         }
    220         return null;
     277            $this->push_execution('association');
     278        }
     279        else {
     280            $this->push_result(array());
     281        }
    221282    }
    222283   
    223284    // for debugging only
    224285    private function dump() {
    225         print json_encode($this->rest) . "\n";
     286        print "Rest: " . json_encode($this->rest) . "\n";
     287        print "Execution stack: " . json_encode($this->execution_stack) . "\n";
     288        print "Result stack: " . json_encode($this->result_stack) . "\n";
    226289    }
    227290}
  • jazzy-forms/trunk/jazzy-forms.php

    r839285 r842669  
    44Plugin URI: http://www.jazzyforms.com/
    55Description: Online form builder with an emphasis on calculation
    6 Version: 1.1
     6Version: 1.1.1
    77Author: Igor Prochazka
    88Author URI: http://www.jazzyforms.com/
     
    2828*/
    2929
    30 define(JZZF_VERSION, 1.0100);
    31 define(JZZF_VERSION_STRING, "1.0100");
     30define(JZZF_VERSION, 1.0101);
     31define(JZZF_VERSION_STRING, "1.0101");
    3232define(JZZF_OPTION_VERSION, 'jzzf_version');
    3333
     
    6666
    6767function jzzf_admin() {
    68     $page = add_menu_page( 'Forms', 'Forms', 8, 'jzzf_forms_top', 'jzzf_forms', null, 30);
     68    $page = add_menu_page( 'Forms', 'Forms', 8, 'jzzf_forms_top', 'jzzf_forms', null, '30.08161929');
    6969    /* add_submenu_page('jzzf_forms_top', "Data", "Data", 8, 'jzzf_data', 'jzzf_data'); */
    7070    add_action('admin_print_styles-' . $page, 'jzzf_head');
  • jazzy-forms/trunk/readme.txt

    r839285 r842669  
    55Requires at least: 3.2.1
    66Tested up to: 3.8
    7 Stable tag: 1.1 
     7Stable tag: 1.1.1
    88
    99Online form builder, ideal for cost-estimates and calculations
     
    118118
    119119== Changelog ==
     120
     121= 1.1.1 =
     122* Fix operator precedence
     123* Avoid excessive recursion (nested functions error)
     124* Avoid conflicts in backend menu position
    120125
    121126= 1.1 =
Note: See TracChangeset for help on using the changeset viewer.