mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-05 08:10:50 +00:00
This modifies the parser to properly "unquote" incoming strings. So if a string comes in double or single quoted, we approximately follow Go rules for removing the quotes and processing escape sequences. The differences from Go are: 1. we only support backslash, quote, tab and newline escape sequenences. 2. Single quoted strings are supported and work just like double quoted strings. 3. The peg parser won't actually accept backquoted strings (I don't think) Fixes: #411
105 lines
4.5 KiB
Text
105 lines
4.5 KiB
Text
package pql
|
|
|
|
type PQL Peg {
|
|
Query
|
|
}
|
|
|
|
|
|
Calls <- sp (Call sp)* !.
|
|
Call <- 'Set' {p.startCall("Set")} open col comma dargs (comma timestamp)? close {p.endCall()}
|
|
/ 'SetRowAttrs' {p.startCall("SetRowAttrs")} open posfield comma row comma fargs close {p.endCall()}
|
|
/ 'SetColumnAttrs' {p.startCall("SetColumnAttrs")} open col comma fargs close {p.endCall()}
|
|
/ 'Clear' {p.startCall("Clear")} open col comma dargs close {p.endCall()}
|
|
/ 'ClearRow' {p.startCall("ClearRow")} open darg close {p.endCall()}
|
|
/ 'Store' {p.startCall("Store")} open Call comma darg close {p.endCall()}
|
|
/ 'TopN' {p.startCall("TopN")} open posfield (comma allargs)? close {p.endCall()}
|
|
/ 'Rows' {p.startCall("Rows")} open posfield (comma allargs)? close {p.endCall()}
|
|
/ 'Range' {p.startCall("Range")} open field sp '=' sp fvalue comma 'from='? {p.addField("from")} timestampfmt {p.addVal(buffer[begin:end])} comma 'to='? sp {p.addField("to")} timestampfmt {p.addVal(buffer[begin:end])} close {p.endCall()}
|
|
/ < IDENT > { p.startCall(buffer[begin:end] ) } open allargs comma? close { p.endCall() }
|
|
allargs <- Call (comma Call)* (comma dargs)? / dargs / sp
|
|
fargs <- farg (comma fargs)? sp
|
|
farg <- ( field sp '=' sp fvalue
|
|
/ field sp COND sp fvalue
|
|
/ conditional
|
|
)
|
|
dargs <- darg (comma dargs)? sp
|
|
darg <- ( field sp '=' sp dvalue
|
|
/ field sp COND sp dvalue
|
|
/ conditional
|
|
)
|
|
COND <- ( '><' { p.addBTWN() }
|
|
/ '<=' { p.addLTE() }
|
|
/ '>=' { p.addGTE() }
|
|
/ '==' { p.addEQ() }
|
|
/ '!=' { p.addNEQ() }
|
|
/ '<' { p.addLT() }
|
|
/ '>' { p.addGT() }
|
|
)
|
|
|
|
conditional <- {p.startConditional()} condint condLT condfield condLT condint {p.endConditional()}
|
|
condint <- < '-'? [0-9]* '.' [0-9]+ / '0' / '-'? [1-9] [0-9]* > sp {p.condAdd(buffer[begin:end])}
|
|
condLT <- <('<=' / '<')> sp {p.condAdd(buffer[begin:end])}
|
|
condfield <- <fieldExpr> sp {p.condAdd(buffer[begin:end])}
|
|
|
|
dvalue <- ( ditem
|
|
/ lbrack { p.startList() } dlist rbrack { p.endList() }
|
|
)
|
|
fvalue <- ( fitem
|
|
/ lbrack { p.startList() } flist rbrack { p.endList() }
|
|
)
|
|
dlist <- ditem (comma dlist)?
|
|
flist <- fitem (comma flist)?
|
|
ditem <- ( itema
|
|
/ decimal
|
|
/ itemb
|
|
)
|
|
fitem <- ( itema
|
|
/ float
|
|
/ itemb
|
|
)
|
|
itema <- ( 'null' &(comma / sp close) { p.addVal(nil) }
|
|
/ 'true' &(comma / sp close) { p.addVal(true) }
|
|
/ 'false' &(comma / sp close) { p.addVal(false) }
|
|
/ timestampfmt { p.addVal(buffer[begin:end]) }
|
|
)
|
|
itemb <- ( < IDENT > { p.startCall(buffer[begin:end]) } open allargs comma? close { p.addVal(p.endCall()) }
|
|
/ < ([[A-Z]] / [0-9] / '-' / '_' / ':')+ > { p.addVal(buffer[begin:end]) }
|
|
/ < '"' doublequotedstring '"' > { p.addVal(buffer[begin:end]) }
|
|
/ < '\'' singlequotedstring '\'' > { p.addVal(buffer[begin:end]) }
|
|
)
|
|
float <- ( < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(buffer[begin:end], true) }
|
|
/ < '-'? '.'[0-9]+ > { p.addNumVal(buffer[begin:end], true) }
|
|
)
|
|
decimal <- ( < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(buffer[begin:end], false) }
|
|
/ < '-'? '.'[0-9]+ > { p.addNumVal(buffer[begin:end], false) }
|
|
)
|
|
|
|
doublequotedstring <- ( '\\"' / '\\\\' / '\\n' / '\\t' / [^"\\] )*
|
|
singlequotedstring <- ( '\\\'' / '\\\\' / '\\n' / '\\t' / [^'\\] )*
|
|
|
|
fieldExpr <- ( [[A-Z]] / '_' ) ( [[A-Z]] / [0-9] / '_' / '-' )*
|
|
field <- <fieldExpr / reserved> { p.addField(buffer[begin:end]) }
|
|
reserved <- ('_row' / '_col' / '_start' / '_end' / '_timestamp' / '_field')
|
|
posfield <- <fieldExpr> { p.addPosStr("_field", buffer[begin:end]) }
|
|
uint <- [1-9] [0-9]* / '0'
|
|
col <- ( <uint> {p.addPosNum("_col", buffer[begin:end])}
|
|
/ < '\'' singlequotedstring '\'' > {p.addPosStr("_col", buffer[begin:end])}
|
|
/ < '"' doublequotedstring '"' > {p.addPosStr("_col", buffer[begin:end])}
|
|
)
|
|
row <- ( <uint> {p.addPosNum("_row", buffer[begin:end])}
|
|
/ < '\'' singlequotedstring '\'' > {p.addPosStr("_row", buffer[begin:end])}
|
|
/ < '"' doublequotedstring '"' > {p.addPosStr("_row", buffer[begin:end])}
|
|
)
|
|
|
|
open <- '(' sp
|
|
close <- ')' sp
|
|
sp <- ( ' ' / '\t' / '\n' )*
|
|
comma <- sp ',' sp
|
|
lbrack <- '[' sp
|
|
rbrack <- sp ']' sp
|
|
IDENT <- [[A-Z]] ([[A-Z]] / [0-9])*
|
|
|
|
|
|
timestampbasicfmt <- [0-9][0-9][0-9][0-9]'-'[01][0-9]'-'[0-3][0-9]'T'[0-9][0-9]':'[0-9][0-9]
|
|
timestampfmt <- '"' <timestampbasicfmt> '"' / '\'' <timestampbasicfmt> '\'' / <timestampbasicfmt>
|
|
timestamp <- <timestampfmt> {p.addPosStr("_timestamp", buffer[begin:end])}
|