change parser for new PQL

This commit is contained in:
Matt Jaffee 2018-06-15 12:22:16 -05:00
parent 1e05920742
commit 4b856bea55
No known key found for this signature in database
GPG key ID: 08A3DFFF987B11BF
3 changed files with 1908 additions and 1057 deletions

View file

@ -31,6 +31,8 @@ type Query struct {
lastCond Token
inList bool
callStack []*Call
conditional []string
}
func (q *Query) startCall(name string) {
@ -43,13 +45,52 @@ func (q *Query) startCall(name string) {
calls := q.callStack[len(q.callStack)-2].Children
q.callStack[len(q.callStack)-2].Children = append(calls, newCall)
}
}
func (q *Query) endCall() {
q.callStack = q.callStack[:len(q.callStack)-1]
}
func (q *Query) addPosNum(key, value string) {
q.addField(key)
q.addNumVal(value)
}
func (q *Query) addPosStr(key, value string) {
q.addField(key)
q.addVal(value)
}
func (q *Query) startConditional() {
q.conditional = make([]string, 0)
}
func (q *Query) condAdd(val string) {
q.conditional = append(q.conditional, val)
}
func (q *Query) endConditional() {
// do stuff
if len(q.conditional) != 5 {
panic(fmt.Sprintf("conditional of wrong length: %#v", q.conditional))
}
low, _ := strconv.ParseInt(q.conditional[0], 10, 64)
field := q.conditional[2]
high, _ := strconv.ParseInt(q.conditional[4], 10, 64)
if q.conditional[1] == "<" {
low++
}
if q.conditional[3] == "<=" {
high++
}
call := q.callStack[len(q.callStack)-1]
call.Args[field] = Condition{Op: BETWEEN, Value: []interface{}{low, high}}
q.conditional = nil
}
func (q *Query) addField(field string) {
if q.lastField != "" {
panic(fmt.Sprintf("addField called with '%s' while field is not empty, it's: %s", field, q.lastField))

View file

@ -5,8 +5,14 @@ type PQL Peg {
}
Calls <- Call* !.
Call <- whitesp < IDENT > { p.startCall(buffer[begin:end] ) } open allargs comma? close whitesp { p.endCall() }
Calls <- whitesp (Call whitesp)* !.
Call <- 'Set' {p.startCall("Set")} open uintcol comma args (comma timestamp)? close {p.endCall()}
/ 'SetRowAttrs' {p.startCall("SetRowAttrs")} open posfield comma uintrow comma args close {p.endCall()}
/ 'SetColAttrs' {p.startCall("SetColAttrs")} open posfield comma uintcol comma args close {p.endCall()}
/ 'ClearBit' {p.startCall("ClearBit")} open uintcol comma args close {p.endCall()}
/ 'TopN' {p.startCall("TopN")} open posfield (comma args)? close {p.endCall()}
/ 'Range' {p.startCall("Range")} open (arg / conditional) close {p.endCall()}
/ < IDENT > { p.startCall(buffer[begin:end] ) } open allargs comma? close { p.endCall() }
allargs <- Call (comma Call)* (comma args)? / comma? args / sp
args <- arg (comma args)? sp
arg <- ( field sp '=' sp value
@ -20,6 +26,7 @@ COND <- ( '><' { p.addBTWN() }
/ '<' { p.addLT() }
/ '>' { p.addGT() }
)
conditional <- {p.startConditional()} int ('<=' / '<') fieldExpr ('<=' / '<') int {p.endConditional()}
open <- '(' sp
value <- ( item
/ lbrack { p.startList() } list rbrack { p.endList() }
@ -38,11 +45,20 @@ item <- ( 'null' &(comma / sp close) { p.addVal(nil) }
doublequotedstring <- ( [^"\\\n] / '\\n' / '\\\"' / '\\\'' / '\\\\' )*
singlequotedstring <- ( [^'\\\n] / '\\n' / '\\\"' / '\\\'' / '\\\\' )*
field <- < [[A-Z]] ( [[A-Z]] / [0-9] / '_' )* > { p.addField(buffer[begin:end]) }
fieldExpr <- [[A-Z]] ( [[A-Z]] / [0-9] / '_' )*
field <- <fieldExpr> { p.addField(buffer[begin:end]) }
posfield <- <fieldExpr> { p.addPosStr("_field", buffer[begin:end]) }
uint <- [1-9] [0-9]* / '0'
int <- '-'? [1-9] [0-9]* / '0'
uintrow <- <uint>{p.addPosNum("_row", buffer[begin:end])}
uintcol <- <uint>{p.addPosNum("_col", buffer[begin:end])}
close <- ')' sp
sp <- ( ' ' / '\t' )*
comma <- sp ',' sp
comma <- sp ',' whitesp
lbrack <- '[' sp
rbrack <- sp ']' sp
whitesp <- ( ' ' / '\t' / '\n' )*
IDENT <- [[A-Z]] ([[A-Z]] / [0-9] / '-' / '_' / '.')*
IDENT <- [[A-Z]] ([[A-Z]] / [0-9] / '-' / '_' / '.')*
timestamp <- <[0-9][0-9][0-9][0-9]'-'[01][0-9]'-'[0-3][0-9]'T'[0-9][0-9]':'[0-9][0-9]> {p.addPosStr("_timestamp", buffer[begin:end])}

File diff suppressed because it is too large Load diff