parser.php

来自「太烦了」· PHP 代码 · 共 1,122 行 · 第 1/3 页

PHP
1,122
字号
                if (PEAR::isError($clause)) {                    return $clause;                }                $tree['where_clause'] = $clause;                break;            } elseif ($this->token != ',') {                return $this->raiseError('Expected "where" or ","');            }        }        return $tree;    }    // }}}    // {{{ parseDelete()    function parseDelete() {        $this->getTok();        if ($this->token != 'from') {            return $this->raiseError('Expected "from"');        }        $tree = array('command' => 'delete');        $this->getTok();        if ($this->token != 'ident') {            return $this->raiseError('Expected a table name');        }        $tree['table_names'][] = $this->lexer->tokText;        $this->getTok();        if ($this->token != 'where') {            return $this->raiseError('Expected "where"');        }        $clause = $this->parseSearchClause();        if (PEAR::isError($clause)) {            return $clause;        }        $tree['where_clause'] = $clause;        return $tree;    }    // }}}    // {{{ parseDrop()    function parseDrop() {        $this->getTok();        switch ($this->token) {            case 'table':                $tree = array('command' => 'drop_table');                $this->getTok();                if ($this->token != 'ident') {                    return $this->raiseError('Expected a table name');                }                $tree['table_names'][] = $this->lexer->tokText;                $this->getTok();                if (($this->token == 'restrict') ||                    ($this->token == 'cascade')) {                    $tree['drop_behavior'] = $this->token;                }                $this->getTok();                if (!is_null($this->token)) {                    return $this->raiseError('Unexpected token');                }                return $tree;                break;            case 'index':                $tree = array('command' => 'drop_index');                break;            case 'constraint':                $tree = array('command' => 'drop_constraint');                break;            case 'sequence':                $tree = array('command' => 'drop_sequence');                break;            default:                return $this->raiseError('Unknown object to drop');        }        return $tree;    }    // }}}    // {{{ parseSelect()    function parseSelect($subSelect = false) {        $tree = array('command' => 'select');        $this->getTok();        if (($this->token == 'distinct') || ($this->token == 'all')) {            $tree['set_quantifier'] = $this->token;            $this->getTok();        }        if ($this->token == '*') {            $tree['column_names'][] = '*';            $this->getTok();        } elseif ($this->token == 'ident' || $this->isFunc()) {            while ($this->token != 'from') {                if ($this->token == 'ident') {                    $prevTok = $this->token;                    $prevTokText = $this->lexer->tokText;                    $this->getTok();                    if ($this->token == '.') {                        $columnTable = $prevTokText;                        $this->getTok();                        $prevTok = $this->token;                        $prevTokText = $this->lexer->tokText;                    } else {                        $columnTable = '';                    }                    if ($prevTok == 'ident') {                        $columnName = $prevTokText;                    } else {                        return $this->raiseError('Expected column name');                    }                    if ($this->token == 'as') {                        $this->getTok();                        if ($this->token == 'ident' ) {                            $columnAlias = $this->lexer->tokText;                        } else {                            return $this->raiseError('Expected column alias');                        }                    } elseif ($this->token == 'ident') {                        $columnAlias = $this->lexer->tokText;                    } else {                        $columnAlias = '';                    }                    $tree['column_tables'][] = $columnTable;                    $tree['column_names'][] = $columnName;                    $tree['column_aliases'][] = $columnAlias;                    if ($this->token != 'from') {                        $this->getTok();                    }                    if ($this->token == ',') {                        $this->getTok();                    }                } elseif ($this->isFunc()) {                    if (!isset($tree['set_quantifier'])) {                        $result = $this->parseFunctionOpts();                        if (PEAR::isError($result)) {                            return $result;                        }                        $tree['set_function'][] = $result;                        $this->getTok();                        if ($this->token == 'as') {                            $this->getTok();                            if ($this->token == 'ident' ) {                                $columnAlias = $this->lexer->tokText;                            } else {                                return $this->raiseError('Expected column alias');                            }                        } else {                            $columnAlias = '';                        }                    } else {                        return $this->raiseError('Cannot use "'.                                $tree['set_quantifier'].'" with '.$this->token);                    }                } elseif ($this->token == ',') {                    $this->getTok();                } else {                        return $this->raiseError('Unexpected token "'.$this->token.'"');                }            }        } else {            return $this->raiseError('Expected columns or a set function');        }        if ($this->token != 'from') {            return $this->raiseError('Expected "from"');        }        $this->getTok();        while ($this->token == 'ident') {            $tree['table_names'][] = $this->lexer->tokText;            $this->getTok();            if ($this->token == 'ident') {                $tree['table_aliases'][] = $this->lexer->tokText;                $this->getTok();            } elseif ($this->token == 'as') {                $this->getTok();                if ($this->token == 'ident') {                    $tree['table_aliases'][] = $this->lexer->tokText;                } else {                    return $this->raiseError('Expected table alias');                }                $this->getTok();            } else {                $tree['table_aliases'][] = '';            }            if ($this->token == 'on') {                $clause = $this->parseSearchClause();                if (PEAR::isError($clause)) {                    return $clause;                }                $tree['table_join_clause'][] = $clause;            } else {                $tree['table_join_clause'][] = '';            }            if ($this->token == ',') {                $tree['table_join'][] = ',';                $this->getTok();            } elseif ($this->token == 'join') {                $tree['table_join'][] = 'join';                $this->getTok();            } elseif (($this->token == 'cross') ||                        ($this->token == 'inner')) {                $join = $this->lexer->tokText;                $this->getTok();                if ($this->token != 'join') {                    return $this->raiseError('Expected token "join"');                }                $tree['table_join'][] = $join.' join';                $this->getTok();            } elseif (($this->token == 'left') ||                        ($this->token == 'right')) {                $join = $this->lexer->tokText;                $this->getTok();                if ($this->token == 'join') {                    $tree['table_join'][] = $join.' join';                } elseif ($this->token == 'outer') {                        $join .= ' outer';                    $this->getTok();                    if ($this->token == 'join') {                        $tree['table_join'][] = $join.' join';                    } else {                        return $this->raiseError('Expected token "join"');                    }                } else {                    return $this->raiseError('Expected token "outer" or "join"');                }                $this->getTok();            } elseif ($this->token == 'natural') {                $join = $this->lexer->tokText;                $this->getTok();                if ($this->token == 'join') {                    $tree['table_join'][] = $join.' join';                } elseif (($this->token == 'left') ||                            ($this->token == 'right')) {                        $join .= ' '.$this->token;                    $this->getTok();                    if ($this->token == 'join') {                        $tree['table_join'][] = $join.' join';                    } elseif ($this->token == 'outer') {                        $join .= ' '.$this->token;                        $this->getTok();                        if ($this->token == 'join') {                            $tree['table_join'][] = $join.' join';                        } else {                            return $this->raiseError('Expected token "join" or "outer"');                        }                    } else {                        return $this->raiseError('Expected token "join" or "outer"');                    }                } else {                    return $this->raiseError('Expected token "left", "right" or "join"');                }                $this->getTok();            } elseif (($this->token == 'where') ||                        ($this->token == 'order') ||                        ($this->token == 'limit') ||                        (is_null($this->token))) {                break;            }        }        while (!is_null($this->token) && (!$subSelect || $this->token != ')')               && $this->token != ')') {            switch ($this->token) {                case 'where':                    $clause = $this->parseSearchClause();                    if (PEAR::isError($clause)) {                        return $clause;                    }                    $tree['where_clause'] = $clause;                    break;                case 'order':                    $this->getTok();                    if ($this->token != 'by') {                        return $this->raiseError('Expected "by"');                    }                    $this->getTok();                    while ($this->token == 'ident') {                        $col = $this->lexer->tokText;                        $this->getTok();                        if (isset($this->synonyms[$this->token])) {                            $order = $this->synonyms[$this->token];                            if (($order != 'asc') && ($order != 'desc')) {                                return $this->raiseError('Unexpected token');                            }                            $this->getTok();                        } else {                            $order = 'asc';                        }                        if ($this->token == ',') {                            $this->getTok();                        }                        $tree['sort_order'][$col] = $order;                    }                    break;                case 'limit':                    $this->getTok();                    if ($this->token != 'int_val') {                        return $this->raiseError('Expected an integer value');                    }                    $length = $this->lexer->tokText;                    $start = 0;                    $this->getTok();                    if ($this->token == ',') {                        $this->getTok();                        if ($this->token != 'int_val') {                            return $this->raiseError('Expected an integer value');                        }                        $start = $length;                        $length = $this->lexer->tokText;                        $this->getTok();                    }                    $tree['limit_clause'] = array('start'=>$start,                                                  'length'=>$length);                    break;                case 'group':                    $this->getTok();                    if ($this->token != 'by') {                        return $this->raiseError('Expected "by"');                    }                    $this->getTok();                    while ($this->token == 'ident') {                        $col = $this->lexer->tokText;                        $this->getTok();                        if ($this->token == ',') {                            $this->getTok();                        }                        $tree['group_by'][] = $col;                    }                    break;                default:                    return $this->raiseError('Unexpected clause');            }        }        return $tree;    }    // }}}    // {{{ parse($string)    function parse($string = null)    {        if (is_string($string)) {            // Initialize the Lexer with a 3-level look-back buffer            $this->lexer = new Lexer($string, 3);            $this->lexer->symbols =& $this->symbols;        } else {            if (!is_object($this->lexer)) {                return $this->raiseError('No initial string specified');            }        }        // get query action        $this->getTok();        switch ($this->token) {            case null:                // null == end of string                return $this->raiseError('Nothing to do');            case 'select':                return $this->parseSelect();            case 'update':                return $this->parseUpdate();            case 'insert':                return $this->parseInsert();            case 'delete':                return $this->parseDelete();            case 'create':                return $this->parseCreate();            case 'drop':                return $this->parseDrop();            default:                return $this->raiseError('Unknown action :'.$this->token);        }    }    // }}}}?>

⌨️ 快捷键说明

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