⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 parser.php

📁 很棒的在线教学系统
💻 PHP
📖 第 1 页 / 共 5 页
字号:
        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GE) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgGE', $result, $result2);        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_EQ) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgEQ', $result, $result2);        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_NE) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgNE', $result, $result2);        }        return $result;    }    /**    * It parses a expression. It assumes the following rule:    * Expr -> Term [("+" | "-") Term]    *      -> "string"    *      -> "-" Term    *    * @access private    * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure    */    function _expression()    {        // If it's a string return a string node        if (ereg("^\"[^\"]{0,255}\"$", $this->_current_token)) {            $result = $this->_createTree($this->_current_token, '', '');            $this->_advance();            return $result;        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB) {            // catch "-" Term            $this->_advance();            $result2 = $this->_expression();            $result = $this->_createTree('ptgUminus', $result2, '');            return $result;        }        $result = $this->_term();        if (PEAR::isError($result)) {            return $result;        }        while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) or               ($this->_current_token == SPREADSHEET_EXCEL_WRITER_SUB)) {        /**/            if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_ADD) {                $this->_advance();                $result2 = $this->_term();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('ptgAdd', $result, $result2);            } else {                $this->_advance();                $result2 = $this->_term();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('ptgSub', $result, $result2);            }        }        return $result;    }    /**    * This function just introduces a ptgParen element in the tree, so that Excel    * doesn't get confused when working with a parenthesized formula afterwards.    *    * @access private    * @see _fact()    * @return array The parsed ptg'd tree    */    function _parenthesizedExpression()    {        $result = $this->_createTree('ptgParen', $this->_expression(), '');        return $result;    }    /**    * It parses a term. It assumes the following rule:    * Term -> Fact [("*" | "/") Fact]    *    * @access private    * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure    */    function _term()    {        $result = $this->_fact();        if (PEAR::isError($result)) {            return $result;        }        while (($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) or               ($this->_current_token == SPREADSHEET_EXCEL_WRITER_DIV)) {        /**/            if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_MUL) {                $this->_advance();                $result2 = $this->_fact();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('ptgMul', $result, $result2);            } else {                $this->_advance();                $result2 = $this->_fact();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('ptgDiv', $result, $result2);            }        }        return $result;    }    /**    * It parses a factor. It assumes the following rule:    * Fact -> ( Expr )    *       | CellRef    *       | CellRange    *       | Number    *       | Function    *    * @access private    * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure    */    function _fact()    {        if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_OPEN) {            $this->_advance();         // eat the "("            $result = $this->_parenthesizedExpression();            if ($this->_current_token != SPREADSHEET_EXCEL_WRITER_CLOSE) {                return $this->raiseError("')' token expected.");            }            $this->_advance();         // eat the ")"            return $result;        }        // if it's a reference        if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$this->_current_token))        {            $result = $this->_createTree($this->_current_token, '', '');            $this->_advance();            return $result;        }        // If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1)        elseif (preg_match("/^\w+(\:\w+)?\![A-Ia-i]?[A-Za-z][0-9]+$/u",$this->_current_token))        {            $result = $this->_createTree($this->_current_token, '', '');            $this->_advance();            return $result;        }        // If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1)        elseif (preg_match("/^'[\w -]+(\:[\w -]+)?'\![A-Ia-i]?[A-Za-z][0-9]+$/u",$this->_current_token))        {            $result = $this->_createTree($this->_current_token, '', '');            $this->_advance();            return $result;        }        // if it's a range        elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token) or                 preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$this->_current_token))        {            $result = $this->_current_token;            $this->_advance();            return $result;        }        // If it's an external range (Sheet1!A1 or Sheet1!A1:B2)        elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$this->_current_token))        {            $result = $this->_current_token;            $this->_advance();            return $result;        }        // If it's an external range ('Sheet1'!A1 or 'Sheet1'!A1:B2)        elseif (preg_match("/^'[\w -]+(\:[\w -]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$this->_current_token))        {            $result = $this->_current_token;            $this->_advance();            return $result;        }        elseif (is_numeric($this->_current_token))        {            $result = $this->_createTree($this->_current_token, '', '');            $this->_advance();            return $result;        }        // if it's a function call        elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$this->_current_token))        {            $result = $this->_func();            return $result;        }        return $this->raiseError("Syntax error: ".$this->_current_token.                                 ", lookahead: ".$this->_lookahead.                                 ", current char: ".$this->_current_char);    }    /**    * It parses a function call. It assumes the following rule:    * Func -> ( Expr [,Expr]* )    *    * @access private    * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure    */    function _func()    {        $num_args = 0; // number of arguments received        $function = strtoupper($this->_current_token);        $result   = ''; // initialize result        $this->_advance();        $this->_advance();         // eat the "("        while ($this->_current_token != ')') {        /**/            if ($num_args > 0) {                if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_COMA or                    $this->_current_token == SPREADSHEET_EXCEL_WRITER_SEMICOLON)                {                    $this->_advance();  // eat the "," or ";"                } else {                    return $this->raiseError("Syntax error: comma expected in ".                                      "function $function, arg #{$num_args}");                }                $result2 = $this->_condition();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('arg', $result, $result2);            } else { // first argument                $result2 = $this->_condition();                if (PEAR::isError($result2)) {                    return $result2;                }                $result = $this->_createTree('arg', '', $result2);            }            $num_args++;        }        if (!isset($this->_functions[$function])) {            return $this->raiseError("Function $function() doesn't exist");        }        $args = $this->_functions[$function][1];        // If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid.        if (($args >= 0) and ($args != $num_args)) {            return $this->raiseError("Incorrect number of arguments in function $function() ");        }        $result = $this->_createTree($function, $result, $num_args);        $this->_advance();         // eat the ")"        return $result;    }    /**    * Creates a tree. In fact an array which may have one or two arrays (sub-trees)    * as elements.    *    * @access private    * @param mixed $value The value of this node.    * @param mixed $left  The left array (sub-tree) or a final node.    * @param mixed $right The right array (sub-tree) or a final node.    * @return array A tree    */    function _createTree($value, $left, $right)    {        return array('value' => $value, 'left' => $left, 'right' => $right);    }    /**    * Builds a string containing the tree in reverse polish notation (What you    * would use in a HP calculator stack).    * The following tree:    *    *    +    *   / \    *  2   3    *    * produces: "23+"    *    * The following tree:    *    *    +    *   / \    *  3   *    *     / \    *    6   A1    *    * produces: "36A1*+"    *    * In fact all operands, functions, references, etc... are written as ptg's    *    * @access public    * @param array $tree The optional tree to convert.    * @return string The tree in reverse polish notation    */    function toReversePolish($tree = array())    {        $polish = ""; // the string we are going to return        if (empty($tree)) { // If it's the first call use _parse_tree            $tree = $this->_parse_tree;        }        if (is_array($tree['left'])) {            $converted_tree = $this->toReversePolish($tree['left']);            if (PEAR::isError($converted_tree)) {                return $converted_tree;            }            $polish .= $converted_tree;        } elseif ($tree['left'] != '') { // It's a final node            $converted_tree = $this->_convert($tree['left']);            if (PEAR::isError($converted_tree)) {                return $converted_tree;            }            $polish .= $converted_tree;        }        if (is_array($tree['right'])) {            $converted_tree = $this->toReversePolish($tree['right']);            if (PEAR::isError($converted_tree)) {                return $converted_tree;            }            $polish .= $converted_tree;        } elseif ($tree['right'] != '') { // It's a final node            $converted_tree = $this->_convert($tree['right']);            i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -