parser.php

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

PHP
1,122
字号
                    // parse for 'not in' operator                    if ($this->token != 'in') {                        return $this->raiseError('Expected "in"');                    }                    $clause['op'] = $this->token;                    $clause['neg'] = true;                    $this->getTok();                case 'in':                    // parse for 'in' operator                     if ($this->token != '(') {                        return $this->raiseError('Expected "("');                    }                    // read the subset                    $this->getTok();                    // is this a subselect?                    if ($this->token == 'select') {                        $clause['arg_2']['value'] = $this->parseSelect(true);                        $clause['arg_2']['type'] = 'command';                    } else {                        $this->lexer->pushBack();                        // parse the set                        $result = $this->getParams($clause['arg_2']['value'],                                                $clause['arg_2']['type']);                        if (PEAR::isError($result)) {                            return $result;                        }                    }                    if ($this->token != ')') {                        return $this->raiseError('Expected ")"');                    }                    break;                case 'and': case 'or':                    $this->lexer->unget();                    break;                default:                    // parse for in-fix binary operators                    if ($this->isReserved()) {                        return $this->raiseError('Expected a column name or value');                    }                    if ($this->token == '(') {                        $clause['arg_2']['value'] = $this->parseSearchClause(true);                        $clause['arg_2']['type'] = 'subclause';                        $this->getTok();                        if ($this->token != ')') {                            return $this->raiseError('Expected ")"');                        }                    } else {                        $clause['arg_2']['value'] = $this->lexer->tokText;                        $clause['arg_2']['type'] = $this->token;                    }            }        }        $this->getTok();        if (($this->token == 'and') || ($this->token == 'or')) {            $op = $this->token;            $subClause = $this->parseSearchClause($subSearch);            if (PEAR::isError($subClause)) {                return $subClause;            } else {                $clause = array('arg_1' => $clause,                                'op' => $op,                                'arg_2' => $subClause);            }        } else {            $this->lexer->unget();        }        return $clause;    }    // }}}    // {{{ parseFieldList()    function parseFieldList()    {        $this->getTok();        if ($this->token != '(') {            return $this->raiseError('Expected (');        }        $fields = array();        while (1) {            // parse field identifier            $this->getTok();            if ($this->token == 'ident') {                $name = $this->lexer->tokText;            } elseif ($this->token == ')') {                return $fields;            } else {                return $this->raiseError('Expected identifier');            }            // parse field type            $this->getTok();            if ($this->isType($this->token)) {                $type = $this->token;            } else {                return $this->raiseError('Expected a valid type');            }            $this->getTok();            // handle special case two-word types            if ($this->token == 'precision') {                // double precision == double                if ($type == 'double') {                    return $this->raiseError('Unexpected token');                }                $this->getTok();            } elseif ($this->token == 'varying') {                // character varying() == varchar()                if ($type == 'character') {                    $type == 'varchar';                    $this->getTok();                } else {                    return $this->raiseError('Unexpected token');                }            }            $fields[$name]['type'] = $this->synonyms[$type];            // parse type parameters            if ($this->token == '(') {                $results = $this->getParams($values, $types);                if (PEAR::isError($results)) {                    return $results;                }                switch ($fields[$name]['type']) {                    case 'numeric':                        if (isset($values[1])) {                            if ($types[1] != 'int_val') {                                return $this->raiseError('Expected an integer');                            }                            $fields[$name]['decimals'] = $values[1];                        }                    case 'float':                        if ($types[0] != 'int_val') {                            return $this->raiseError('Expected an integer');                        }                        $fields[$name]['length'] = $values[0];                        break;                    case 'char': case 'varchar':                    case 'integer': case 'int':                        if (sizeof($values) != 1) {                            return $this->raiseError('Expected 1 parameter');                        }                        if ($types[0] != 'int_val') {                            return $this->raiseError('Expected an integer');                        }                        $fields[$name]['length'] = $values[0];                        break;                    case 'set': case 'enum':                        if (!sizeof($values)) {                            return $this->raiseError('Expected a domain');                        }                        $fields[$name]['domain'] = $values;                        break;                    default:                        if (sizeof($values)) {                            return $this->raiseError('Unexpected )');                        }                }                $this->getTok();            }            $options = $this->parseFieldOptions();            if (PEAR::isError($options)) {                return $options;            }            $fields[$name] += $options;            if ($this->token == ')') {                return $fields;            } elseif (is_null($this->token)) {                return $this->raiseError('Expected )');            }        }    }    // }}}    // {{{ parseFunctionOpts()    function parseFunctionOpts()    {        $function = $this->token;        $opts['name'] = $function;        $this->getTok();        if ($this->token != '(') {            return $this->raiseError('Expected "("');        }        switch ($function) {            case 'count':                $this->getTok();                switch ($this->token) {                    case 'distinct':                        $opts['distinct'] = true;                        $this->getTok();                        if ($this->token != 'ident') {                            return $this->raiseError('Expected a column name');                        }                    case 'ident': case '*':                        $opts['arg'][] = $this->lexer->tokText;                        break;                    default:                        return $this->raiseError('Invalid argument');                }                break;            case 'concat':                $this->getTok();                while ($this->token != ')') {                    switch ($this->token) {                        case 'ident': case 'text_val':                            $opts['arg'][] = $this->lexer->tokText;                            break;                        case ',':                            // do nothing                            break;                        default:                            return $this->raiseError('Expected a string or a column name');                    }                    $this->getTok();                }                $this->lexer->pushBack();                break;            case 'avg': case 'min': case 'max': case 'sum':            default:                $this->getTok();                $opts['arg'] = $this->lexer->tokText;                break;        }        $this->getTok();        if ($this->token != ')') {            return $this->raiseError('Expected ")"');        }         // check for an alias        $this->getTok();        if ($this->token == ',' || $this->token == 'from') {            $this->lexer->pushBack();        } elseif ($this->token == 'as') {            $this->getTok();            if ($this->token == 'ident' ) {                $opts['alias'] = $this->lexer->tokText;            } else {                return $this->raiseError('Expected column alias');            }        } else {            if ($this->token == 'ident' ) {                $opts['alias'] = $this->lexer->tokText;            } else {                return $this->raiseError('Expected column alias, from or comma');            }        }        return $opts;    }    // }}}    // {{{ parseCreate()    function parseCreate() {        $this->getTok();        switch ($this->token) {            case 'table':                $tree = array('command' => 'create_table');                $this->getTok();                if ($this->token == 'ident') {                    $tree['table_names'][] = $this->lexer->tokText;                    $fields = $this->parseFieldList();                    if (PEAR::isError($fields)) {                        return $fields;                    }                    $tree['column_defs'] = $fields;//                    $tree['column_names'] = array_keys($fields);                } else {                    return $this->raiseError('Expected table name');                }                break;            case 'index':                $tree = array('command' => 'create_index');                break;            case 'constraint':                $tree = array('command' => 'create_constraint');                break;            case 'sequence':                $tree = array('command' => 'create_sequence');                break;            default:                return $this->raiseError('Unknown object to create');        }        return $tree;    }    // }}}    // {{{ parseInsert()    function parseInsert() {        $this->getTok();        if ($this->token == 'into') {            $tree = array('command' => 'insert');            $this->getTok();            if ($this->token == 'ident') {                $tree['table_names'][] = $this->lexer->tokText;                $this->getTok();            } else {                return $this->raiseError('Expected table name');            }            if ($this->token == '(') {                $results = $this->getParams($values, $types);                if (PEAR::isError($results)) {                    return $results;                } else {                    if (sizeof($values)) {                        $tree['column_names'] = $values;                    }                }                $this->getTok();            }            if ($this->token == 'values') {                $this->getTok();                $results = $this->getParams($values, $types);                if (PEAR::isError($results)) {                    return $results;                } else {                    if (isset($tree['column_defs']) &&                         (sizeof($tree['column_defs']) != sizeof($values))) {                        return $this->raiseError('field/value mismatch');                    }                    if (sizeof($values)) {                        foreach ($values as $key=>$value) {                            $values[$key] = array('value'=>$value,                                                    'type'=>$types[$key]);                        }                        $tree['values'] = $values;                    } else {                        return $this->raiseError('No fields to insert');                    }                }            } else {                return $this->raiseError('Expected "values"');            }        } else {            return $this->raiseError('Expected "into"');        }        return $tree;    }    // }}}    // {{{ parseUpdate()    function parseUpdate() {        $this->getTok();        if ($this->token == 'ident') {            $tree = array('command' => 'update');            $tree['table_names'][] = $this->lexer->tokText;        } else {            return $this->raiseError('Expected table name');        }        $this->getTok();        if ($this->token != 'set') {            return $this->raiseError('Expected "set"');        }        while (true) {            $this->getTok();            if ($this->token != 'ident') {                return $this->raiseError('Expected a column name');            }            $tree['column_names'][] = $this->lexer->tokText;            $this->getTok();            if ($this->token != '=') {                return $this->raiseError('Expected =');            }            $this->getTok();            if (!$this->isVal($this->token)) {                return $this->raiseError('Expected a value');            }            $tree['values'][] = array('value'=>$this->lexer->tokText,                                      'type'=>$this->token);            $this->getTok();            if ($this->token == 'where') {                $clause = $this->parseSearchClause();

⌨️ 快捷键说明

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