github.com/vescale/zgraph@v0.0.0-20230410094002-959c02d50f95/parser/parser.go (about) 1 // Copyright 2022 zGraph Authors. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package parser 16 17 import ( 18 "github.com/pingcap/errors" 19 "github.com/vescale/zgraph/parser/ast" 20 ) 21 22 type Parser struct { 23 src string 24 lexer *Lexer 25 result []ast.StmtNode 26 27 // the following fields are used by yyParse to reduce allocation. 28 cache []yySymType 29 yylval yySymType 30 yyVAL *yySymType 31 } 32 33 func yySetOffset(yyVAL *yySymType, offset int) { 34 if yyVAL.expr != nil { 35 yyVAL.expr.SetOriginTextPosition(offset) 36 } 37 } 38 39 func New() *Parser { 40 return &Parser{ 41 lexer: NewLexer(""), 42 cache: make([]yySymType, 200), 43 } 44 } 45 46 func (p *Parser) Parse(sql string) (stmts []ast.StmtNode, warns []error, err error) { 47 p.lexer.reset(sql) 48 p.src = sql 49 p.result = p.result[:0] 50 yyParse(p.lexer, p) 51 52 warns, errs := p.lexer.Errors() 53 if len(warns) > 0 { 54 warns = append([]error(nil), warns...) 55 } else { 56 warns = nil 57 } 58 if len(errs) != 0 { 59 return nil, warns, errors.Trace(errs[0]) 60 } 61 return p.result, warns, nil 62 } 63 64 // ParseOneStmt parses a query and returns an ast.StmtNode. 65 // The query must have exactly one statement. 66 func (p *Parser) ParseOneStmt(sql string) (ast.StmtNode, error) { 67 stmts, _, err := p.Parse(sql) 68 if err != nil { 69 return nil, errors.Trace(err) 70 } 71 if len(stmts) != 1 { 72 return nil, errors.New("query must have exactly one statement") 73 } 74 return stmts[0], nil 75 }