Skip to content

Commit 95b35d8

Browse files
committed
sqlite: Add experimental parser for SQLite
1 parent 954d207 commit 95b35d8

13 files changed

+24616
-0
lines changed

internal/sqlite/parse.go

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package sqlite
2+
3+
import (
4+
"errors"
5+
"io"
6+
"io/ioutil"
7+
8+
"github.com/antlr/antlr4/runtime/Go/antlr"
9+
10+
"github.com/kyleconroy/sqlc/internal/sql/ast"
11+
"github.com/kyleconroy/sqlc/internal/sqlite/parser"
12+
)
13+
14+
type listener struct {
15+
*parser.BaseSQLiteListener
16+
17+
stmt *ast.RawStmt
18+
19+
stmts []ast.Statement
20+
}
21+
22+
func (l *listener) EnterSql_stmt(c *parser.Sql_stmtContext) {
23+
l.stmt = nil
24+
}
25+
26+
func (l *listener) ExitSql_stmt(c *parser.Sql_stmtContext) {
27+
if l.stmt != nil {
28+
l.stmts = append(l.stmts, ast.Statement{
29+
Raw: l.stmt,
30+
})
31+
return
32+
}
33+
}
34+
35+
func (l *listener) EnterCreate_table_stmt(c *parser.Create_table_stmtContext) {
36+
name := ast.TableName{
37+
Name: c.Table_name().GetText(),
38+
}
39+
40+
if c.Database_name() != nil {
41+
name.Schema = c.Database_name().GetText()
42+
}
43+
44+
stmt := &ast.CreateTableStmt{
45+
Name: &name,
46+
IfNotExists: c.K_EXISTS() != nil,
47+
}
48+
49+
for _, idef := range c.AllColumn_def() {
50+
if def, ok := idef.(*parser.Column_defContext); ok {
51+
stmt.Cols = append(stmt.Cols, &ast.ColumnDef{
52+
Colname: def.Column_name().GetText(),
53+
TypeName: &ast.TypeName{
54+
Name: def.Type_name().GetText(),
55+
},
56+
})
57+
}
58+
}
59+
60+
l.stmt = &ast.RawStmt{Stmt: stmt}
61+
}
62+
63+
type errorListener struct {
64+
*antlr.DefaultErrorListener
65+
66+
err string
67+
}
68+
69+
func (el *errorListener) SyntaxError(recognizer antlr.Recognizer, offendingSymbol interface{}, line, column int, msg string, e antlr.RecognitionException) {
70+
el.err = msg
71+
}
72+
73+
// func (el *errorListener) ReportAmbiguity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, exact bool, ambigAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
74+
// }
75+
//
76+
// func (el *errorListener) ReportAttemptingFullContext(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex int, conflictingAlts *antlr.BitSet, configs antlr.ATNConfigSet) {
77+
// }
78+
//
79+
// func (el *errorListener) ReportContextSensitivity(recognizer antlr.Parser, dfa *antlr.DFA, startIndex, stopIndex, prediction int, configs antlr.ATNConfigSet) {
80+
// }
81+
82+
func NewParser() *Parser {
83+
return &Parser{}
84+
}
85+
86+
type Parser struct {
87+
}
88+
89+
func (p *Parser) Parse(r io.Reader) ([]ast.Statement, error) {
90+
blob, err := ioutil.ReadAll(r)
91+
if err != nil {
92+
return nil, err
93+
}
94+
input := antlr.NewInputStream(string(blob))
95+
lexer := parser.NewSQLiteLexer(input)
96+
stream := antlr.NewCommonTokenStream(lexer, 0)
97+
pp := parser.NewSQLiteParser(stream)
98+
l := &listener{}
99+
el := &errorListener{}
100+
pp.AddErrorListener(el)
101+
tree := pp.Parse()
102+
if el.err != "" {
103+
return nil, errors.New(el.err)
104+
}
105+
// p.BuildParseTrees = true
106+
antlr.ParseTreeWalkerDefault.Walk(l, tree)
107+
return l.stmts, nil
108+
}

internal/sqlite/parser/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
sqlite_parser.go: SQLite.g4
2+
antlr -Dlanguage=Go -visitor SQLite.g4

0 commit comments

Comments
 (0)