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

📄 parser.php

📁 很棒的在线教学系统
💻 PHP
📖 第 1 页 / 共 5 页
字号:
            return $this->raiseError("Column in: $cell greater than 255");        }        // FIXME: change for BIFF8        if ($row >= 16384) {            return $this->raiseError("Row in: $cell greater than 16384 ");        }        // Set the high bits to indicate if row or col are relative.        if ($this->_BIFF_version == 0x0500) {            $row    |= $col_rel << 14;            $row    |= $row_rel << 15;            $col     = pack('C', $col);        } elseif ($this->_BIFF_version == 0x0600) {            $col    |= $col_rel << 14;            $col    |= $row_rel << 15;            $col     = pack('v', $col);        }        $row     = pack('v', $row);        return array($row, $col);    }    /**    * pack() row range into the required 3 or 4 byte format.    * Just using maximum col/rows, which is probably not the correct solution    *    * @access private    * @param string $range The Excel range to be packed    * @return array Array containing (row1,col1,row2,col2) in packed() format    */    function _rangeToPackedRange($range)    {        preg_match('/(\$)?(\d+)\:(\$)?(\d+)/', $range, $match);        // return absolute rows if there is a $ in the ref        $row1_rel = empty($match[1]) ? 1 : 0;        $row1     = $match[2];        $row2_rel = empty($match[3]) ? 1 : 0;        $row2     = $match[4];        // Convert 1-index to zero-index        $row1--;        $row2--;        // Trick poor inocent Excel        $col1 = 0;        $col2 = 16383; // FIXME: maximum possible value for Excel 5 (change this!!!)        // FIXME: this changes for BIFF8        if (($row1 >= 16384) or ($row2 >= 16384)) {            return $this->raiseError("Row in: $range greater than 16384 ");        }        // Set the high bits to indicate if rows are relative.        if ($this->_BIFF_version == 0x0500) {            $row1    |= $row1_rel << 14; // FIXME: probably a bug            $row2    |= $row2_rel << 15;            $col1     = pack('C', $col1);            $col2     = pack('C', $col2);        } elseif ($this->_BIFF_version == 0x0600) {            $col1    |= $row1_rel << 15;            $col2    |= $row2_rel << 15;            $col1     = pack('v', $col1);            $col2     = pack('v', $col2);        }        $row1     = pack('v', $row1);        $row2     = pack('v', $row2);        return array($row1, $col1, $row2, $col2);    }    /**    * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero    * indexed row and column number. Also returns two (0,1) values to indicate    * whether the row or column are relative references.    *    * @access private    * @param string $cell The Excel cell reference in A1 format.    * @return array    */    function _cellToRowcol($cell)    {        preg_match('/(\$)?([A-I]?[A-Z])(\$)?(\d+)/',$cell,$match);        // return absolute column if there is a $ in the ref        $col_rel = empty($match[1]) ? 1 : 0;        $col_ref = $match[2];        $row_rel = empty($match[3]) ? 1 : 0;        $row     = $match[4];        // Convert base26 column string to a number.        $expn   = strlen($col_ref) - 1;        $col    = 0;        $col_ref_length = strlen($col_ref);        for ($i = 0; $i < $col_ref_length; $i++) {            $col += (ord($col_ref{$i}) - ord('A') + 1) * pow(26, $expn);            $expn--;        }        // Convert 1-index to zero-index        $row--;        $col--;        return array($row, $col, $row_rel, $col_rel);    }    /**    * Advance to the next valid token.    *    * @access private    */    function _advance()    {        $i = $this->_current_char;        $formula_length = strlen($this->_formula);        // eat up white spaces        if ($i < $formula_length) {            while ($this->_formula{$i} == " ") {                $i++;            }            if ($i < ($formula_length - 1)) {                $this->_lookahead = $this->_formula{$i+1};            }            $token = '';        }        while ($i < $formula_length) {            $token .= $this->_formula{$i};            if ($i < ($formula_length - 1)) {                $this->_lookahead = $this->_formula{$i+1};            } else {                $this->_lookahead = '';            }            if ($this->_match($token) != '') {                //if ($i < strlen($this->_formula) - 1) {                //    $this->_lookahead = $this->_formula{$i+1};                //}                $this->_current_char = $i + 1;                $this->_current_token = $token;                return 1;            }            if ($i < ($formula_length - 2)) {                $this->_lookahead = $this->_formula{$i+2};            } else { // if we run out of characters _lookahead becomes empty                $this->_lookahead = '';            }            $i++;        }        //die("Lexical error ".$this->_current_char);    }    /**    * Checks if it's a valid token.    *    * @access private    * @param mixed $token The token to check.    * @return mixed       The checked token or false on failure    */    function _match($token)    {        switch($token) {            case SPREADSHEET_EXCEL_WRITER_ADD:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_SUB:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_MUL:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_DIV:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_OPEN:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_CLOSE:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_COMA:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_SEMICOLON:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_GT:                if ($this->_lookahead == '=') { // it's a GE token                    break;                }                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_LT:                // it's a LE or a NE token                if (($this->_lookahead == '=') or ($this->_lookahead == '>')) {                    break;                }                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_GE:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_LE:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_EQ:                return $token;                break;            case SPREADSHEET_EXCEL_WRITER_NE:                return $token;                break;            default:                // if it's a reference                if (preg_match('/^\$?[A-Ia-i]?[A-Za-z]\$?[0-9]+$/',$token) and                   !ereg("[0-9]",$this->_lookahead) and                    ($this->_lookahead != ':') and ($this->_lookahead != '.') and                   ($this->_lookahead != '!'))                {                    return $token;                }                // 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",$token) and                       !ereg("[0-9]",$this->_lookahead) and                       ($this->_lookahead != ':') and ($this->_lookahead != '.'))                {                    return $token;                }                // 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",$token) and                       !ereg("[0-9]",$this->_lookahead) and                       ($this->_lookahead != ':') and ($this->_lookahead != '.'))                {                    return $token;                }                // if it's a range (A1:A2)                elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+:(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and                        !ereg("[0-9]",$this->_lookahead))                {                    return $token;                }                // if it's a range (A1..A2)                elseif (preg_match("/^(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+\.\.(\$)?[A-Ia-i]?[A-Za-z](\$)?[0-9]+$/",$token) and                        !ereg("[0-9]",$this->_lookahead))                {                    return $token;                }                // If it's an external range like Sheet1!A1 or Sheet1:Sheet2!A1:B2                elseif (preg_match("/^\w+(\:\w+)?\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$token) and                       !ereg("[0-9]",$this->_lookahead))                {                    return $token;                }                // If it's an external range like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1:B2                elseif (preg_match("/^'[\w -]+(\:[\w -]+)?'\!([A-Ia-i]?[A-Za-z])?[0-9]+:([A-Ia-i]?[A-Za-z])?[0-9]+$/u",$token) and                       !ereg("[0-9]",$this->_lookahead))                {                    return $token;                }                // If it's a number (check that it's not a sheet name or range)                elseif (is_numeric($token) and                         (!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and                        ($this->_lookahead != '!') and ($this->_lookahead != ':'))                {                    return $token;                }                // If it's a string (of maximum 255 characters)                elseif (ereg("^\"[^\"]{0,255}\"$",$token))                {                    return $token;                }                // if it's a function call                elseif (eregi("^[A-Z0-9\xc0-\xdc\.]+$",$token) and ($this->_lookahead == "("))                {                    return $token;                }                return '';        }    }    /**    * The parsing method. It parses a formula.    *    * @access public    * @param string $formula The formula to parse, without the initial equal    *                        sign (=).    * @return mixed true on success, PEAR_Error on failure    */    function parse($formula)    {        $this->_current_char = 0;        $this->_formula      = $formula;        $this->_lookahead    = $formula{1};        $this->_advance();        $this->_parse_tree   = $this->_condition();        if (PEAR::isError($this->_parse_tree)) {            return $this->_parse_tree;        }        return true;    }    /**    * It parses a condition. It assumes the following rule:    * Cond -> Expr [(">" | "<") Expr]    *    * @access private    * @return mixed The parsed ptg'd tree on success, PEAR_Error on failure    */    function _condition()    {        $result = $this->_expression();        if (PEAR::isError($result)) {            return $result;        }        if ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LT) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgLT', $result, $result2);        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_GT) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgGT', $result, $result2);        } elseif ($this->_current_token == SPREADSHEET_EXCEL_WRITER_LE) {            $this->_advance();            $result2 = $this->_expression();            if (PEAR::isError($result2)) {                return $result2;            }            $result = $this->_createTree('ptgLE', $result, $result2);

⌨️ 快捷键说明

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