Пример #1
0
    def _tagsplit(cls, tag):
        if '$' not in tag:
            return [s_ast.Const(tag)]

        segs = tag.split('.')
        kids = [
            s_ast.VarValue(kids=[s_ast.Const(seg[1:])])
            if seg[0] == '$' else s_ast.Const(seg) for seg in segs
        ]
        return kids
Пример #2
0
    def cmdargv(self):

        argv = []
        while self.more():

            self.ignore(whitespace)

            # if we hit a | or a } we're done
            if self.nextstr('|'):
                break

            if self.nextstr('}'):
                break

            if not self.nextstr('{'):
                valu = self.cmdvalu()
                argv.append(valu)
                continue

            start = self.offs
            query = self.subquery()

            text = self.text[start:self.offs]

            argv.append(text)

        return s_ast.Const(tuple(argv))
Пример #3
0
    def casevalu(self):

        self.ignorespace()

        if self.nextstr('"'):
            text = self.quoted()
            self.ignorespace()
            self.nextmust(':')
            return s_ast.Const(text)

        text = self.noms(until=':').strip()
        if not text:
            self._raiseSyntaxError('empty case statement')

        self.nextmust(':')
        return s_ast.Const(text)
Пример #4
0
    def casevalu(self, kids):
        assert len(kids) == 1
        kid = kids[0]

        if kid.type == 'DOUBLEQUOTEDSTRING':
            return self._convert_child(kid)

        return s_ast.Const(kid.value[:-1])  # drop the trailing ':'
Пример #5
0
    def cmpr(self):

        self.ignore(whitespace)

        if self.nextstr('*'):

            text = self.expect('=')
            if text is None:
                raise self._raiseSyntaxError('comparison with * but not =')

            return s_ast.Const(text)

        if self.nextchar() not in cmprset:
            self._raiseSyntaxError('expected valid comparison char')

        text = self.noms(cmprset)
        return s_ast.Const(text)
Пример #6
0
    def cmdname(self):

        self.ignore(whitespace)

        name = self.noms(cmdset)
        if not name:
            self._raiseSyntaxError(f'expected cmd name')

        return s_ast.Const(name)
Пример #7
0
    def vartokn(self):

        self.ignore(whitespace)

        name = self.noms(varchars)
        if not name:
            self._raiseSyntaxError('expected variable name')

        return s_ast.Const(name)
Пример #8
0
    def stormcmdargs(self, kids):
        kids = self._convert_children(kids)
        argv = []

        for kid in kids:
            if isinstance(kid, s_ast.SubQuery):
                argv.append(s_ast.Const(kid.text))
            else:
                argv.append(self._convert_child(kid))

        return s_ast.List(kids=argv)
Пример #9
0
    def stormcmdargs(self, kids):
        kids = self._convert_children(kids)
        argv = []

        for kid in kids:
            if isinstance(kid, s_ast.Const):
                newkid = kid.valu
            elif isinstance(kid, s_ast.SubQuery):
                newkid = kid.text
            else:
                assert False, 'Unexpected rule'  # pragma: no cover
            argv.append(newkid)

        return s_ast.Const(tuple(argv))
Пример #10
0
    def valu(self):

        self.ignore(whitespace)

        # a simple whitespace separated string
        nexc = self.nextchar()
        if nexc in alphanum or nexc in ('-', '?'):
            text = self.noms(until=mustquote)
            return s_ast.Const(text)

        if self.nextstr('('):
            kids = self.valulist()
            # TODO Value() ctor convention...
            return s_ast.List(None, kids=kids)

        if self.nextstr(':'):
            return self.relpropvalu()

        if self.nextstr('.'):
            return self.univpropvalu()

        if self.nextstr('#'):
            tag = self.tagname()
            return s_ast.TagPropValue(kids=(tag,))

        if self.nextstr('$'):
            return self.varvalu()

        if self.nextstr('"'):
            text = self.quoted()
            return s_ast.Const(text)

        if self.nextstr("'"):
            text = self.singlequoted()
            return s_ast.Const(text)

        self._raiseSyntaxError('unrecognized value prefix')
Пример #11
0
    def filtoper(self):

        self.ignore(whitespace)

        pref = self.nextchar()
        if pref not in ('+', '-'):
            self._raiseSyntaxError('expected: + or -')

        self.offs += 1

        cond = self.cond()

        kids = (
            s_ast.Const(pref),
            cond,
        )
        return s_ast.FiltOper(kids=kids)
Пример #12
0
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)))
Пример #13
0

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':
    s_ast.AbsPropCond,
    'arraycond':
    s_ast.ArrayCond,
Пример #14
0

# 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 = {
    'abspropcond':
    s_ast.AbsPropCond,
    'andexpr':
Пример #15
0
    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)
Пример #16
0
 s_ast.VarListSetOper,
 'orexpr':
 s_ast.OrCond,
 'query':
 s_ast.Query,
 'relprop':
 s_ast.RelProp,
 'relpropcond':
 s_ast.RelPropCond,
 'relpropvalu':
 s_ast.RelPropValue,
 'relpropvalue':
 s_ast.RelPropValue,
 'stormcmd':
 lambda kids: s_ast.CmdOper(kids=kids if len(kids) == 2 else
                            (kids[0], s_ast.Const(tuple()))),
 'tagcond':
 s_ast.TagCond,
 'tagpropvalue':
 s_ast.TagPropValue,
 'tagvalucond':
 s_ast.TagValuCond,
 'valuvar':
 s_ast.VarSetOper,
 'varderef':
 s_ast.VarDeref,
 'vareval':
 s_ast.VarEvalOper,
 'varvalue':
 s_ast.VarValue,
 'univprop':