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)
'return': s_ast.Return, 'relprop': s_ast.RelProp, 'relpropcond': s_ast.RelPropCond, 'relpropvalu': s_ast.RelPropValue, 'relpropvalue': s_ast.RelPropValue, 'setitem': s_ast.SetItemOper, 'setvar': s_ast.SetVarOper, 'stormcmd': lambda kids: s_ast.CmdOper(kids=kids if len(kids) == 2 else (kids[0], s_ast.Const(tuple()))), 'stormfunc': s_ast.Function, 'tagcond': s_ast.TagCond, 'tagprop': s_ast.TagProp, 'tagvalu': s_ast.TagValue, 'tagpropvalu': s_ast.TagPropValue, 'tagvalucond': s_ast.TagValuCond, 'tagpropcond': s_ast.TagPropCond, 'valulist':
def query(self): self.ignore(whitespace) query = s_ast.Query() query.text = self.text while True: self.ignorespace() if not self.more(): break # if we are sub-query, time to go... if self.nextstr('}'): break # | <command> syntax... if self.nextstr('|'): self.offs += 1 # trailing | case... self.ignore(whitespace) if not self.more(): break # switch to command interpreter... name = self.cmdname() argv = self.cmdargv() oper = s_ast.CmdOper(kids=(name, argv)) query.addKid(oper) # command is last query text case... if not self.more(): break self.ignorespace() # End of subquery if self.nextstr('}'): continue # back to storm mode... if self.nextstr('|'): self.offs += 1 continue self._raiseSyntaxError('expected | or end of input for cmd') # parse a query option: %foo=10 if self.nextstr('%'): self.offs += 1 self.ignore(whitespace) name = self.noms(optset) self.ignore(whitespace) self.nextmust('=') valu = self.noms(alphanum) cast = optcast.get(name) if cast is None: raise s_exc.NoSuchOpt(name=name) try: valu = cast(valu) except Exception: raise s_exc.BadOptValu(name=name, valu=valu) query.opts[name] = valu continue # edit operations... if self.nextstr('['): self.offs += 1 self.ignore(whitespace) while not self.nextstr(']'): oper = self.editoper() query.kids.append(oper) self.ignore(whitespace) self.offs += 1 continue oper = self.oper() query.addKid(oper) self.ignorespace() return query