assert isinstance(ret, str) return ret # For AstConverter, one-to-one replacements from lark to synapse AST terminalClassMap = { 'ABSPROP': s_ast.AbsProp, 'ABSPROPNOUNIV': s_ast.AbsProp, 'ALLTAGS': lambda _: s_ast.TagMatch(''), 'BREAK': lambda _: s_ast.BreakOper(), 'CONTINUE': lambda _: s_ast.ContinueOper(), 'DOUBLEQUOTEDSTRING': lambda x: s_ast.Const(unescape(x) ), # drop quotes and handle escape characters 'NUMBER': lambda x: s_ast.Const(s_ast.parseNumber(x)), 'SINGLEQUOTEDSTRING': lambda x: s_ast.Const(x[1:-1]), # drop quotes 'TAGMATCH': lambda x: s_ast.TagMatch(kids=AstConverter._tagsplit(x)), 'VARTOKN': lambda x: s_ast.Const(x[1:-1] if len(x) and x[0] in ("'", '"') else x) } # For AstConverter, one-to-one replacements from lark to synapse AST ruleClassMap = {
evalcache = s_cache.FixedCache(_forkedParseEval, size=100) querycache = s_cache.FixedCache(_forkedParseQuery, size=100) def massage_vartokn(x): return s_ast.Const('' if not x else (x[1:-1] if x[0] == "'" else ( unescape(x) if x[0] == '"' else x))) # For AstConverter, one-to-one replacements from lark to synapse AST terminalClassMap = { 'ABSPROP': s_ast.AbsProp, 'ABSPROPNOUNIV': s_ast.AbsProp, 'ALLTAGS': lambda _: s_ast.TagMatch(''), 'BREAK': lambda _: s_ast.BreakOper(), 'CONTINUE': lambda _: s_ast.ContinueOper(), 'DEREFMATCHNOSEP': massage_vartokn, 'DOUBLEQUOTEDSTRING': lambda x: s_ast.Const(unescape( x)), # drop quotes and handle escape characters 'TRIPLEQUOTEDSTRING': lambda x: s_ast.Const(x[3:-3]), # drop the triple 's 'NUMBER': lambda x: s_ast.Const(s_ast.parseNumber(x)), 'HEXNUMBER': lambda x: s_ast.Const(s_ast.parseNumber(x)), 'BOOL': lambda x: s_ast.Bool(x == 'true'), 'SINGLEQUOTEDSTRING': lambda x: s_ast.Const(x[1:-1]), # drop quotes 'TAGMATCH': lambda x: s_ast.TagMatch(kids=AstConverter._tagsplit(x)), 'VARTOKN': massage_vartokn, } # For AstConverter, one-to-one replacements from lark to synapse AST ruleClassMap = { 'abspropcond':
def oper(self): ''' ''' self.ignore(whitespace) if not self.more(): self._raiseSyntaxError('unexpected end of query text') if self.nextstr('{'): return self.subquery() # some syntax elements prior to a prop/oper name... if self.nextstr('->'): return self.formpivot() if self.nextstr('-+>'): return self.formjoin() if self.nextstr('<-'): return self.formpivotin() if self.nextstr('<+-'): return self.formjoinin() if self.nextstr('##'): return self.lifttagtag() char = self.nextchar() # var list assignment # ($foo, $bar) = $baz if char == '(': varl = self.varlist() self.ignore(whitespace) self.nextmust('=') self.ignore(whitespace) valu = self.valu() return s_ast.VarListSetOper(kids=(varl, valu)) # $foo = valu var assignment if char == '$': varn = self.varname() self.ignore(whitespace) self.nextmust('=') self.ignore(whitespace) valu = self.valu() kids = (varn, valu) return s_ast.VarSetOper(kids=kids) if char in ('+', '-'): return self.filtoper() if char == '#': return self.liftbytag() # :foo:bar relative property if char == ':': prop = self.relprop() # :foo=10 here could be assignment... self.ignore(whitespace) if self.nextstr('->'): return self.proppivot(prop) if self.nextstr('-+>'): return self.propjoin(prop) if self.nextstrs('<-', '<+-'): self._raiseSyntaxError('Pivot in syntax does not currently support relative properties.') tokn = self.peek(varset) if tokn == 'for': return self.forloop() if tokn == 'switch': return self.switchcase() if tokn == 'break': self.offs += 5 return s_ast.BreakOper() if tokn == 'continue': self.offs += 8 return s_ast.ContinueOper() noff = self.offs name = self.noms(varset) if not name: self._raiseSyntaxError('unknown query syntax') if self.modelinfo.isprop(name): # before ignoring more whitespace, check for form#tag[=time] if self.nextstr('#'): tag = self.tagname() form = s_ast.Const(name) self.ignore(whitespace) kids = [form, tag] if self.nextchar() in cmprstart: kids.append(self.cmpr()) kids.append(self.valu()) return s_ast.LiftFormTag(kids=kids) self.ignore(whitespace) if self.nextchar() in cmprstart: cmpr = self.cmpr() valu = self.valu() kids = (s_ast.Const(name), cmpr, valu) return s_ast.LiftPropBy(kids=kids) # lift by prop only return s_ast.LiftProp(kids=(s_ast.Const(name),)) if name in self.stormcmds: argv = self.cmdargv() self.ignore(whitespace) # eat a trailing | from a command at the beginning if self.nextstr('|'): self.offs += 1 return s_ast.CmdOper(kids=(s_ast.Const(name), argv)) # rewind and noms until whitespace self.offs = noff tokn = self.noms(until=whitespace) ndefs = list(s_scrape.scrape(tokn)) if ndefs: return s_ast.LiftByScrape(ndefs) self.offs = noff raise s_exc.NoSuchProp(name=name)