Add more syntax to lexer and parser, and make improvements to tview

This commit is contained in:
Pablu
2025-12-02 09:50:20 +01:00
parent c41b4cc5da
commit c4218cee51
7 changed files with 233 additions and 56 deletions

View File

@@ -91,11 +91,22 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
return nil, p.unexpectedToken()
}
tok, ok := p.expectOne(IDENT, IF)
tok, ok := p.expectOne(QUOTE, SINGLE_QUOTE, BACKQUOTE, IDENT, IF)
if !ok {
return nil, p.unexpectedToken(IDENT, IF)
} else if tok == IF && !p.expectSequence(NOT, EXISTS, IDENT) {
return nil, p.unexpectedToken()
}
switch tok {
case IF:
if !p.expectSequence(NOT, EXISTS) {
return nil, p.unexpectedToken()
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
fallthrough
case QUOTE, SINGLE_QUOTE, BACKQUOTE:
if !p.expectNext(IDENT) {
return nil, p.unexpectedToken()
}
}
_, _, lit := p.rescan()
@@ -104,11 +115,13 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
Columns: make([]Column, 0),
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(LPAREN) {
return nil, p.unexpectedToken(LPAREN)
}
for {
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
_, tok, _ := p.scan()
switch tok {
@@ -125,12 +138,29 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
}
stmt.Columns = append(stmt.Columns, column)
// TODO: HANDLE AND SAVE CONSTRAINTS
case CONSTRAINT:
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return nil, p.unexpectedToken()
}
// _, _, constraintName := p.rescan()
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
case FOREIGN:
if !p.expectSequence(KEY, LPAREN, IDENT) {
if !p.expectSequence(KEY, LPAREN) {
return nil, p.unexpectedToken()
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return nil, p.unexpectedToken()
}
_, _, columnName := p.rescan()
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectSequence(RPAREN, REFERENCES) {
return nil, p.unexpectedToken()
}
@@ -147,12 +177,19 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
stmt.Columns[column].Extra = append(stmt.Columns[column].Extra, ref)
case PRIMARY:
if !p.expectSequence(KEY, LPAREN, IDENT) {
if !p.expectSequence(KEY, LPAREN) {
return nil, p.unexpectedToken()
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return nil, p.unexpectedToken()
}
primaryKeyNames := make([]string, 0)
_, _, columnName := p.rescan()
primaryKeyNames = append(primaryKeyNames, columnName)
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
for {
tok, ok := p.expectOne(RPAREN, COMMA)
@@ -163,11 +200,14 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
break
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return nil, p.unexpectedToken()
}
_, _, columnName := p.rescan()
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
primaryKeyNames = append(primaryKeyNames, columnName)
}
@@ -190,9 +230,10 @@ func (p *Parser) parseCreateTable() (*CreateTableStatement, error) {
func (p *Parser) parseColumn() (Column, error) {
_, _, lit := p.rescan()
column := Column{Name: lit, Extra: make([]string, 0)}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if _, ok := p.expectOne(TEXT, INTEGER, REAL, BLOB); !ok {
return Column{}, p.unexpectedToken(TEXT, INTEGER, REAL, BLOB)
if _, ok := p.expectOne(TEXT, INTEGER, REAL, BLOB, NUMERIC); !ok {
return Column{}, p.unexpectedToken(TEXT, INTEGER, REAL, BLOB, NUMERIC)
}
_, _, column.Type = p.rescan()
@@ -222,6 +263,9 @@ func (p *Parser) parseColumn() (Column, error) {
column.Extra = append(column.Extra, ref)
fmt.Println(ref)
case AUTOINCREMENT:
column.Extra = append(column.Extra, "AUTOINCREMENT")
default:
return Column{}, p.unexpectedToken(COMMA, RPAREN, PRIMARY, NOT, REFERENCES)
}
@@ -253,17 +297,26 @@ func (p *Parser) unexpectedToken(expected ...Token) error {
}
func (p *Parser) references() (string, error) {
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return "", p.unexpectedToken(IDENT)
}
_, _, referenceTableName := p.rescan()
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectSequence(LPAREN, IDENT) {
if !p.expectNext(LPAREN) {
return "", p.unexpectedToken()
}
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(IDENT) {
return "", p.unexpectedToken()
}
_, _, referenceColumnName := p.rescan()
p.consumeIfOne(QUOTE, SINGLE_QUOTE, BACKQUOTE)
if !p.expectNext(RPAREN) {
return "", p.unexpectedToken(RPAREN)
}
@@ -316,6 +369,26 @@ func (p *Parser) consumeUntil(token Token, max int) bool {
return false
}
func (p *Parser) consumeIfOne(token ...Token) {
_, tok, _ := p.scan()
if slices.ContainsFunc(token, func(t Token) bool {
return tok == t
}) {
return
}
p.unscan()
}
func (p *Parser) consumeIf(token Token) {
_, tok, _ := p.scan()
if tok == token {
return
}
p.unscan()
}
func (p *Parser) scan() (Position, Token, string) {
if p.buf.avail {
p.buf.avail = false