featurebase/pql/pql.peg
Seebs c19d571112 more consistent spacing
We still prohibit a space before a leading '(', which maybe we shouldn't,
but we now allow spaces on both sides of a closing ')' more consistently.
Drop the unneeded "sp" before "close" in the special handling after
null, true, and false, because close now implies that.

Also, refactored the two instances of "sp '=' sp" into a thing called eq,
which may not be worth it.
2020-10-19 13:35:49 -05:00

77 lines
3.6 KiB
Text

package pql
type PQL Peg {
Query
}
Calls <- sp (Call sp)* !.
Call <- "Set" {p.startCall("Set")} open col comma args (comma timestamp)? close {p.endCall()}
/ "SetRowAttrs" {p.startCall("SetRowAttrs")} open posfield comma row comma args close {p.endCall()}
/ "SetColumnAttrs" {p.startCall("SetColumnAttrs")} open col comma args close {p.endCall()}
/ "Clear" {p.startCall("Clear")} open col comma args close {p.endCall()}
/ "ClearRow" {p.startCall("ClearRow")} open arg close {p.endCall()}
/ "Store" {p.startCall("Store")} open Call comma arg 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 eq value comma 'from='? {p.addField("from")} timestampfmt {p.addVal(text)} comma 'to='? sp {p.addField("to")} timestampfmt {p.addVal(text)} close {p.endCall()}
/ < IDENT > { p.startCall(text) } open allargs comma? close { p.endCall() }
allargs <- Call (comma Call)* (comma args)? / args / sp
args <- arg (comma args)? sp
arg <- field eq value
/ field sp COND sp value
/ 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(text)}
condLT <- <('<=' / '<')> sp {p.condAdd(text)}
condfield <- <fieldExpr> sp {p.condAdd(text)}
value <- item
/ lbrack { p.startList() } list rbrack { p.endList() }
list <- item (comma list)?
item <- 'null' &(comma / close) { p.addVal(nil) }
/ 'true' &(comma / close) { p.addVal(true) }
/ 'false' &(comma / close) { p.addVal(false) }
/ timestampfmt { p.addVal(text) }
/ < '-'? [0-9]+ ('.'[0-9]*)? > { p.addNumVal(text) }
/ < '-'? '.'[0-9]+ > { p.addNumVal(text) }
/ < IDENT > { p.startCall(text) } open allargs comma? close { p.addVal(p.endCall()) }
/ < ([[A-Z]] / [0-9] / '-' / '_' / ':')+ > { p.addVal(text) }
/ < '"' doublequotedstring '"' > { p.addVal(text) }
/ < '\'' singlequotedstring '\'' > { p.addVal(text) }
doublequotedstring <- ( '\\"' / '\\\\' / '\\n' / '\\t' / [^"\\] )*
singlequotedstring <- ( '\\\'' / '\\\\' / '\\n' / '\\t' / [^'\\] )*
fieldExpr <- ( [[A-Z]] / '_' ) ( [[A-Z]] / [0-9] / '_' / '-' )*
field <- <fieldExpr / reserved> { p.addField(text) }
reserved <- '_row' / '_col' / '_start' / '_end' / '_timestamp' / '_field'
posfield <- <fieldExpr> { p.addPosStr("_field", text) }
uint <- [1-9] [0-9]* / '0'
col <- <uint> {p.addPosNum("_col", text)}
/ < '\'' singlequotedstring '\'' > {p.addPosStr("_col", text)}
/ < '"' doublequotedstring '"' > {p.addPosStr("_col", text)}
row <- <uint> {p.addPosNum("_row", text)}
/ < '\'' singlequotedstring '\'' > {p.addPosStr("_row", text)}
/ < '"' doublequotedstring '"' > {p.addPosStr("_row", text)}
open <- '(' sp
close <- sp ')' sp
sp <- [ \t\n]*
eq <- sp '=' sp
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", text)}