コード例 #1
0
not_.setName("not")
filterlist = OneOrMore(filter_)
or_ = Suppress(Literal("|")) + filterlist
or_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_or(t))
or_.setName("or")
and_ = Suppress(Literal("&")) + filterlist
and_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_and(t))
and_.setName("and")
filtercomp = and_ | or_ | not_ | item
filtercomp.setName("filtercomp")
filter_ << (
    Suppress(Literal("(").leaveWhitespace())
    + filtercomp
    + Suppress(Literal(")").leaveWhitespace())
)
filter_.setName("filter")
filtercomp.leaveWhitespace()
filter_.leaveWhitespace()

toplevel = StringStart().leaveWhitespace() + filter_ + StringEnd().leaveWhitespace()
toplevel.leaveWhitespace()
toplevel.setName("toplevel")


def parseFilter(s):
    """
    Converting source string to pureldap.LDAPFilter

    Source string is converted to unicode as pyparsing cannot parse bytes
    objects with the rules declared in this module.
    """
コード例 #2
0
    def __init__(self, simulation):
        #
        # NOTE(smari):
        # This is a really lousy parser, but it gets the job done.
        # In particular, we're ignoring a lot of Abaqus's actual
        # syntax and just parsing out the bits that seem meaningful.
        # This is bad form and will probably lead to me being put
        # against the wall when the revolution comes.
        #
        self.simulation = simulation
        self.debug = False

        self.expr_stack = []
        self.var_stack = []

        # NOTE(smari): Floating point numbers. I have no idea if Abaqus
        #              actually supports 4.29E-12 format, but we might
        #              as well since it's easy.
        point = Literal('.')
        e = CaselessLiteral('E')
        plusorminus = Literal('+') | Literal('-')
        number = Word(nums)
        integer = Combine(Optional(plusorminus) + number)
        floatnumber = Combine(integer + Optional(point + Optional(number)) +
                              Optional(e + integer))

        plus = Literal("+")
        minus = Literal("-")
        mult = Literal("*")
        div = Literal("/")
        lpar = Literal("(").suppress()
        rpar = Literal(")").suppress()
        addop = plus | minus
        addop.setName("addop")
        mulop = mult | div
        mulop.setName("multop")
        op = addop | mulop
        expop = Literal("^")
        assign = Literal("=").suppress()
        declare = Literal(":").suppress()

        # NOTE(smari):
        # Identifiers in the model often contain periods. It is unclear if
        # the periods mean anything in particular.
        ident = Word(alphas, alphanums + '_' + '.')
        ident_subscript = (ident + lpar + integer + rpar
                           )  #.setParseAction(self.ident_subscript_handle)

        # NOTE(smari): It appears that mathematical operations can be done
        # on both sides of a definition expression, such as:
        #   CJ: CJ/GDPN = A.CJ + B.CJ*(CJ(-1)/GDPN(-1)) + C.CJ*GAPAV + Q1.CJ*Q1
        #                   + Q2.CJ*Q2 + Q3.CJ*Q3 + D091.CJ*D091 + R_CJ,
        # ... which explains the distinction between declaring and defining.
        expr = Forward()
        term = Forward()

        atom = ((ident_subscript | ident).setParseAction(self.add_ref) |
                (floatnumber | integer).setParseAction(self.add_const))
        atom.setName("atom")

        #factor = Forward()
        #factor << (atom + ZeroOrMore(
        #        (expop + factor)).setParseAction(self.add_factor))

        def termfail(s, loc, expr, err):
            print "ERROR: %s / %s " % (expr, err)
            print "Failed on term '%s' at %s" % (s.strip(), loc)
            print '               ' + ' ' * loc + '^'

        term = ((atom + ZeroOrMore(mulop + expr)) | atom |
                (lpar + expr + rpar))
        term.setName("term")

        expr << (
            (term + ZeroOrMore(addop + expr)).setParseAction(self.add_expr) |
            (lpar + expr + rpar))
        expr.setName("expr")
        expr.setFailAction(termfail)

        coefficient_set_value = ((ident + assign + expr).setParseAction(
            self.define_coefficient).setName("def(coefficient)"))

        timeseries_define = (
            ident + declare + ident + assign + expr).setParseAction(
                self.define_timeseries).setName("def(time series)")

        expression = ((coefficient_set_value | timeseries_define) +
                      Literal(",").suppress())
        expression.setName("expression")

        #expression = ( Optional(ident + declare) +
        #               Optional((ident + assign).setParseAction(self.assign_var)) +
        #               expr
        #             )

        # TODO(smari): Use these declarations as initializers for coefficients
        #              or time series in the simulation.
        # NOTE(smari): "ENDROGENOUS", "EXOGENOUS" and "COEFFICIENT" tell us
        #              what kind of situation we're talking about.
        #              Coefficients will end up as scalars in the simulation,
        #              whereas the others are either derived time series or
        #              time series loaded from the "database" (read: Excel file)
        #
        declaration = ((Literal("ENDOGENOUS") | Literal("EXOGENOUS")
                        | Literal("COEFFICIENT")) + ZeroOrMore(ident) +
                       Optional(Literal(",")).suppress()).setParseAction(
                           self.declare_variable).setName("declaration")

        # Junk that we're ignoring for now... it's probably super important!
        ignore = (Literal("Dofile") | Literal(";") | Literal("usemod;")
                  | Literal("ADDSYM") | Literal("filemod cbiq;")
                  | Literal("ADDEQ BOTTOM")).setName("ignore").suppress()

        self.pattern = (expression | declaration | ignore | StringEnd())
        self.pattern.ignore(cppStyleComment)
コード例 #3
0
ファイル: sql_parser.py プロジェクト: jcfrank/moz-sql-parser
)

join = ((CROSSJOIN | INNERJOIN | JOIN)("op") + tableName("join") + Optional(ON + expr("on"))).addParseAction(to_join_call)

sortColumn = expr("value").setName("sort1").setDebugActions(*debug) + Optional(DESC("sort")) | \
             expr("value").setName("sort2").setDebugActions(*debug)

# define SQL tokens
selectStmt << Group(
    Group(Group(
        delimitedList(
            Group(
                SELECT.suppress().setDebugActions(*debug) + delimitedList(selectColumn)("select") +
                Optional(
                    FROM.suppress().setDebugActions(*debug) + (delimitedList(Group(tableName)) + ZeroOrMore(join))("from") +
                    Optional(WHERE.suppress().setDebugActions(*debug) + expr.setName("where"))("where") +
                    Optional(GROUPBY.suppress().setDebugActions(*debug) + delimitedList(Group(selectColumn))("groupby").setName("groupby")) +
                    Optional(HAVING.suppress().setDebugActions(*debug) + expr("having").setName("having")) +
                    Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit"))
                )
            ),
            delim=UNION
        )
    )("union"))("from") +
    Optional(ORDERBY.suppress().setDebugActions(*debug) + delimitedList(Group(sortColumn))("orderby").setName("orderby")) +
    Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit"))
).addParseAction(to_union_call)


SQLParser = selectStmt
コード例 #4
0
def model_grammar():
    """
    Construct a parser for winBugs/openBugs/JAGS models.

    Returns *parser*, which is a *pyaparsing.ParserElement, with the
    *parser.parserString()* method.

    Be sure to strip comments from the string prior to parsing, so that the
    grammar can be a little simpler.
    """
    ###factor = Forward().setName('factor') # for right-to-left parsing
    expression = Forward().setName('expr')
    group = Forward().setName('group')

    # start:stop used for indexing and for loops
    inner_range = Optional (expression + Optional(Literal(":") + expression))
    paren_range = Literal("(").suppress() + inner_range + Literal(")").suppress()
    slice =  inner_range | paren_range

    paren_range.setName('(slice)')
    inner_range.setName('slice').setParseAction(
        lambda s,l,t: [(SLICE,(NONE,),(NONE,)) if len(t)==0 else (SLICE,t[0],t[2]) if len(t)>1 else t[0]])

    # indexing
    subscripts = slice + ZeroOrMore(Literal(',').suppress() + slice)
    index = Literal('[').suppress() + subscripts + Literal(']').suppress()
    indexed_variable = variable + Optional(index)

    subscripts.setName('subs')
    index.setName('index')
    indexed_variable.setName('deref').setParseAction(
        lambda s,l,t: [(DEREF,t[0],t[1:])])

    # arithmetic
    muldiv = Literal('*') | Literal('/')
    addsub = Literal('+') | Literal('-')
    ###exponent = Literal('^')

    pars = expression + ZeroOrMore(Literal(',').suppress() + expression)
    function = variable + Literal('(') + Optional(pars) + Literal(')')
    paren = Literal('(') + expression + Literal(')')
    value = constant + Empty()
    atom = Optional("-") + (function | indexed_variable | value | paren )
    ###factor << (atom | ZeroOrMore (exponent + factor))
    ###term = factor + ZeroOrMore(muldiv + factor)
    term = atom + ZeroOrMore(muldiv + atom)
    expression << (term + ZeroOrMore(addsub + term))

    paren.setName('paren').setParseAction(
        lambda s,l,t: [t[1]])
    value.setName('value').setParseAction(
        lambda s,l,t: [(CONST, t[0])])
    function.setName('apply').setParseAction(
        lambda s,l,t: [(APPLY, t[0], t[2:-1])])
    atom.setName('atom').setParseAction(
        lambda s,l,t: [(UNARY, t[0], t[1]) if len(t)>1 else t[0]])
    ###factor.setName('factor').setParseAction(lambda s,l,t: [_binop(t)])
    term.setName('term').setParseAction(
        lambda s,l,t: [_binop(t)])
    expression.setName('expr').setParseAction(
        lambda s,l,t: [_binop(t)])

    # priors look like dname(p1,p2,...) with optional qualifier T(left,right)
    # to set the bounds on the prior.   Since left/right are optional, the
    # function parser can't be used, and we need a special bounds term to
    # parse this form.
    bounds_limit = expression | Empty()
    bounds_function = (variable + Literal('(') + bounds_limit
                           + Literal(',') + bounds_limit + Literal(')'))
    bounds = bounds_function | Empty()
    bounds_limit.setName('limit').setParseAction(
        lambda s,l,t: [(t[0] if len(t) else (NONE,))])
    bounds.setName('trunc').setParseAction(
        lambda s,l,t: [(APPLY,t[0],[t[2],t[4]]) if len(t) else (NONE,)])

    # Funky assignment lhs functions, such as:
    #    logit(t) <- alpha; D(C[5],t) <- PER1 * C[7] - R*kT1*C[1]
    lhs_function = variable + Literal('(') + indexed_variable \
                   + ZeroOrMore(Literal(',') + indexed_variable) + Literal(')')
    lhs_function.setName('f(lhs)').setParseAction(
        lambda s,l,t: [(APPLY, t[0], t[2::2])])

    # statements
    assignment = (lhs_function | indexed_variable) + Literal("<-") + expression
    prior = indexed_variable + Literal("~") + function + bounds
    loop = (Keyword("for")  + Literal("(") + variable + Keyword("in")
            + expression + Literal(":") + expression + Literal(")") + group)

    assignment.setName('assign').setParseAction(
        lambda s,l,t: [(ASSIGN, t[0], t[2])])
    prior.setName('prior').setParseAction(
        lambda s,l,t: [(PRIOR, t[0], t[2], t[3])])
    loop.setName('loop').setParseAction(
        lambda s,l,t: [(LOOP, t[2], t[4], t[6], t[8:])])

    # Note: line breaks are ignored.  That means the following are valid:
    #     statement\n
    #     statement;\n
    #     statement; statement\n
    #     statement statement\n
    #     partial statement\n statement completion
    # Indeed, all of these forms exist in the openBugs example models.
    #comment = Literal("#[^\n]*")
    statement = (loop | assignment | prior) + Optional(Literal(';')).suppress()
    body = ZeroOrMore(statement)
    group << (Literal("{").suppress() + body + Literal("}").suppress())
    model = Keyword("model") + group + StringEnd()

    model.setName('model').setParseAction(
        lambda s,l,t: [(MODEL, t[1:])])

    if 0: # Debug
        all_terms = (
            model, group, body, statement, loop, prior, assignment,
            expression, term, atom, muldiv, addsub,
            value, constant, paren, function, pars,
            indexed_variable, variable, index, subscripts,
            slice, inner_range, paren_range,
        )
        for s in all_terms: s.setDebug(True)
    return model
コード例 #5
0
        Optional((ON + expr("on"))
                 | (USING + expr("using")))).addParseAction(to_join_call)

sortColumn = expr("value").setName("sort1").setDebugActions(*debug) + Optional(DESC("sort") | ASC("sort")) | \
             expr("value").setName("sort2").setDebugActions(*debug)

# define SQL tokens
selectStmt << Group(
    Group(
        Group(
            delimitedList(Group(SELECT.suppress().setDebugActions(
                *debug) + delimitedList(selectColumn)("select") + Optional(
                    (FROM.suppress().setDebugActions(*debug) + delimitedList(
                        Group(table_source)) + ZeroOrMore(join))("from") +
                    Optional(WHERE.suppress().setDebugActions(*debug) +
                             expr.setName("where"))
                    ("where") + Optional(GROUP_BY.suppress().setDebugActions(
                        *debug) + delimitedList(Group(selectColumn))
                                         ("groupby").setName("groupby")) +
                    Optional(HAVING.suppress().setDebugActions(*debug) +
                             expr("having").setName("having")) +
                    Optional(LIMIT.suppress().setDebugActions(*debug) +
                             expr("limit")) + Optional(OFFSET.suppress(
                             ).setDebugActions(*debug) + expr("offset")))),
                          delim=(UNION | UNION_ALL)))("union"))("from") +
    Optional(ORDER_BY.suppress().setDebugActions(*debug) +
             delimitedList(Group(sortColumn))("orderby").setName("orderby")) +
    Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit")) +
    Optional(OFFSET.suppress().setDebugActions(*debug) +
             expr("offset"))).addParseAction(to_union_call)
コード例 #6
0
join = ((CROSSJOIN | INNERJOIN | JOIN)("op") + Group(tableName)("join") +
        Optional(ON + expr("on"))).addParseAction(to_join_call)

sortColumn = expr("value").setName("sort1").setDebugActions(*debug) + Optional(DESC("sort") | ASC("sort")) | \
             expr("value").setName("sort2").setDebugActions(*debug)

# define SQL tokens
selectStmt << Group(
    Group(
        Group(
            delimitedList(Group(SELECT.suppress().setDebugActions(
                *debug) + delimitedList(selectColumn)("select") + Optional(
                    FROM.suppress().setDebugActions(*debug) +
                    (delimitedList(Group(tableName)) + ZeroOrMore(join)
                     )("from") + Optional(WHERE.suppress().setDebugActions(
                         *debug) + expr.setName("where"))
                    ("where") + Optional(GROUPBY.suppress().setDebugActions(
                        *debug) + delimitedList(Group(selectColumn))
                                         ("groupby").setName("groupby")) +
                    Optional(HAVING.suppress().setDebugActions(*debug) +
                             expr("having").setName("having")) +
                    Optional(LIMIT.suppress().setDebugActions(*debug) +
                             expr("limit")))),
                          delim=UNION))("union"))("from") +
    Optional(ORDERBY.suppress().setDebugActions(*debug) +
             delimitedList(Group(sortColumn))("orderby").setName("orderby")) +
    Optional(LIMIT.suppress().setDebugActions(*debug) +
             expr("limit"))).addParseAction(to_union_call)

SQLParser = selectStmt
コード例 #7
0
#Defining the AND expression body
AndExpr <<= ((AndExpr + Word("e") + EqExpr) | EqExpr).setName("AND Expression")

#Defining the OR expression body
OrExpr <<= ((OrExpr + Word("ou") + AndExpr) | AndExpr).setName("OR Expression")

#Defining the conditional expression body
CondExpr <<= (OrExpr | (OrExpr + Word("?") + Expr + Word(":") +
                        CondExpr)).setName("Conditional Expression")

#defining the assigned expresion's body
AssignExpr <<= (CondExpr | (LValueExpr + Word("=") +
                            AssignExpr)).setName("Assigned Expression")

#Defining the expression's body
Expr <<= AssignExpr.setName("Expression")

#<<<<<<<<<<<<<<< EXPRESSIONS DEFINITIONS<<<<<<<<<<<<<<<<<<

#>>>>>>>>>>>>>>> VARIABLES DEFINITIONS>>>>>>>>>>>>>>>>>>>>

#Variable declaration definition
DeclVar <<= ((Word(",") + identifier + DeclVar) |
             (Word(",") + identifier + Word("[") + intNum + Word("") +
              DeclVar)).setName("Variable Declaration")

#Defining the ListDeclVar's body
ListDeclVar <<= (
    # ZeroOrMore(
    (Type + identifier + DeclVar + TERMINATOR + ListDeclVar) |
    (Type + identifier + Word("[") + intNum + Word("]") + DeclVar +
コード例 #8
0
ファイル: ldapfilter.py プロジェクト: cwaldbieser/ldaptor
not_ = Suppress(Literal('!')) + filter_
not_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_not(t[0]))
not_.setName('not')
filterlist = OneOrMore(filter_)
or_ = Suppress(Literal('|')) + filterlist
or_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_or(t))
or_.setName('or')
and_ = Suppress(Literal('&')) + filterlist
and_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_and(t))
and_.setName('and')
filtercomp = and_ | or_ | not_ | item
filtercomp.setName('filtercomp')
filter_ << (Suppress(Literal('(').leaveWhitespace())
            + filtercomp
            + Suppress(Literal(')').leaveWhitespace()))
filter_.setName('filter')
filtercomp.leaveWhitespace()
filter_.leaveWhitespace()

toplevel = (StringStart().leaveWhitespace()
            + filter_
            + StringEnd().leaveWhitespace())
toplevel.leaveWhitespace()
toplevel.setName('toplevel')


def parseFilter(s):
    try:
        x = toplevel.parseString(s)
    except ParseException as e:
        raise InvalidLDAPFilter(e.msg,
コード例 #9
0
    def __init__(self, basedir: str = '.') -> None:
        self.__basedir = basedir
        self.__specifications: Dict[str, Specification] = {}
        self.__pdus: Dict[str, PDU] = {}
        self.__refinements: Dict[str, Refinement] = {}

        # Generic
        comma = Suppress(Literal(','))
        comma.setName('","')
        semicolon = Suppress(Literal(';'))
        semicolon.setName('";"')

        # Comments
        comment = Regex(r'--.*')

        # Names
        identifier = WordStart(alphanums) + Word(alphanums +
                                                 '_') + WordEnd(alphanums +
                                                                '_')
        identifier.setParseAction(verify_identifier)
        identifier.setName('Identifier')
        qualified_identifier = Optional(identifier + Literal('.')) - identifier
        qualified_identifier.setParseAction(lambda t: ''.join(t.asList()))
        attribute_designator = Keyword('First') | Keyword('Last') | Keyword(
            'Length')
        attribute_reference = identifier + Literal('\'') - attribute_designator
        attribute_reference.setParseAction(parse_attribute)
        attribute_reference.setName('Attribute')
        name = attribute_reference | identifier
        name.setName('Name')

        # Literals
        numeral = Word(nums) + ZeroOrMore(Optional(Word('_')) + Word(nums))
        numeral.setParseAction(
            lambda t: int(''.join(t.asList()).replace('_', '')))
        extended_digit = Word(nums + 'ABCDEF')
        based_numeral = extended_digit + ZeroOrMore(
            Optional('_') + extended_digit)
        based_literal = numeral + Literal('#') - based_numeral - Literal('#')
        based_literal.setParseAction(
            lambda t: int(t[2].replace('_', ''), int(t[0])))
        numeric_literal = based_literal | numeral
        numeric_literal.setParseAction(lambda t: Number(t[0]))
        numeric_literal.setName('Number')
        literal = numeric_literal

        # Operators
        mathematical_operator = (Literal('**') | Literal('+') | Literal('-')
                                 | Literal('*')
                                 | Literal('/'))
        relational_operator = (Keyword('<=') | Keyword('>=') | Keyword('=')
                               | Keyword('/=')
                               | Keyword('<') | Keyword('>'))
        logical_operator = Keyword('and') | Keyword('or')

        # Expressions
        mathematical_expression = Forward()
        relation = mathematical_expression + relational_operator - mathematical_expression
        relation.setParseAction(parse_relation)
        relation.setName('Relation')
        logical_expression = infixNotation(
            relation,
            [(logical_operator, 2, opAssoc.LEFT, parse_logical_expression)])
        logical_expression.setName('LogicalExpression')
        term = Keyword('null') | literal | name
        term.setParseAction(parse_term)
        mathematical_expression << infixNotation(
            term, [(mathematical_operator, 2, opAssoc.LEFT,
                    parse_mathematical_expression)])
        mathematical_expression.setName('MathematicalExpression')

        # Type Refinement
        value_constraint = Keyword('if') - logical_expression
        value_constraint.setParseAction(lambda t: t[1])
        type_refinement_definition = (
            Keyword('new') - qualified_identifier - Suppress(Literal('(')) -
            identifier - Suppress(Literal('=>')) -
            (Keyword('null') | qualified_identifier) - Suppress(Literal(')')) -
            Optional(value_constraint))
        type_refinement_definition.setName('Refinement')

        # Integer Types
        size_aspect = Keyword('Size') - Keyword('=>') - mathematical_expression
        size_aspect.setParseAction(parse_aspect)
        range_type_aspects = Keyword('with') - size_aspect
        range_type_aspects.setParseAction(parse_aspects)

        range_type_definition = (Keyword('range') - mathematical_expression -
                                 Suppress(Literal('..')) -
                                 mathematical_expression - range_type_aspects)
        range_type_definition.setName('RangeInteger')
        modular_type_definition = Keyword('mod') - mathematical_expression
        modular_type_definition.setName('ModularInteger')
        integer_type_definition = range_type_definition | modular_type_definition

        # Enumeration Types
        enumeration_literal = name
        positional_enumeration = enumeration_literal + ZeroOrMore(
            comma - enumeration_literal)
        positional_enumeration.setParseAction(
            lambda t: [(k, Number(v)) for v, k in enumerate(t.asList())])
        element_value_association = enumeration_literal + Keyword(
            '=>') - numeric_literal
        element_value_association.setParseAction(lambda t: (t[0], t[2]))
        named_enumeration = (element_value_association +
                             ZeroOrMore(comma - element_value_association))

        boolean_literal = Keyword('True') | Keyword('False')
        boolean_literal.setParseAction(lambda t: t[0] == 'True')
        boolean_aspect_definition = Optional(Keyword('=>') - boolean_literal)
        boolean_aspect_definition.setParseAction(lambda t:
                                                 (t if t else ['=>', True]))
        always_valid_aspect = Literal(
            'Always_Valid') - boolean_aspect_definition
        always_valid_aspect.setParseAction(parse_aspect)
        enumeration_aspects = Keyword('with') - delimitedList(
            size_aspect | always_valid_aspect)
        enumeration_aspects.setParseAction(parse_aspects)

        enumeration_type_definition = (
            Literal('(') - (named_enumeration | positional_enumeration) -
            Literal(')') - enumeration_aspects)
        enumeration_type_definition.setName('Enumeration')

        # Array Type
        unconstrained_array_definition = Keyword('array of') + name
        array_type_definition = unconstrained_array_definition
        array_type_definition.setName('Array')

        # Message Type
        first_aspect = Keyword('First') - Keyword(
            '=>') - mathematical_expression
        first_aspect.setParseAction(parse_aspect)
        length_aspect = Keyword('Length') - Keyword(
            '=>') - mathematical_expression
        length_aspect.setParseAction(parse_aspect)
        component_aspects = Keyword('with') - delimitedList(first_aspect
                                                            | length_aspect)
        component_aspects.setParseAction(parse_aspects)

        then = (Keyword('then') - (Keyword('null') | identifier) -
                Group(Optional(component_aspects)) -
                Group(Optional(value_constraint)))
        then.setParseAction(parse_then)
        then_list = then + ZeroOrMore(comma - then)
        then_list.setParseAction(lambda t: [t.asList()])
        component_list = Forward()
        message_type_definition = Keyword(
            'message') - component_list - Keyword('end message')
        message_type_definition.setName('Message')
        component_item = (~Keyword('end') + ~CaselessKeyword('Message') -
                          identifier + Literal(':') - name -
                          Optional(then_list) - semicolon)
        component_item.setParseAction(lambda t: Component(t[0], t[2], t[3]) if
                                      len(t) >= 4 else Component(t[0], t[2]))
        component_item.setName('Component')
        null_component_item = Keyword('null') - then - semicolon
        null_component_item.setParseAction(
            lambda t: Component(t[0], '', [t[1]]))
        null_component_item.setName('NullComponent')
        component_list << (Group(
            Optional(null_component_item) - component_item -
            ZeroOrMore(component_item)))
        component_list.setParseAction(lambda t: t.asList())

        # Types
        type_definition = (enumeration_type_definition
                           | integer_type_definition
                           | message_type_definition
                           | type_refinement_definition
                           | array_type_definition)
        type_declaration = (Keyword('type') - identifier - Keyword('is') -
                            type_definition - semicolon)
        type_declaration.setParseAction(parse_type)

        # Package
        basic_declaration = type_declaration
        package_declaration = (Keyword('package') - identifier -
                               Keyword('is') -
                               Group(ZeroOrMore(basic_declaration)) -
                               Keyword('end') - name - semicolon)
        package_declaration.setParseAction(
            lambda t: Package(t[1], t[3].asList()))

        # Context
        context_item = Keyword('with') - identifier - semicolon
        context_item.setParseAction(lambda t: t[1])
        context_clause = ZeroOrMore(context_item)
        context_clause.setParseAction(lambda t: Context(t.asList()))

        # Specification
        specification = Optional(context_clause + package_declaration)
        specification.setParseAction(lambda t: Specification(t[0], t[1])
                                     if len(t) == 2 else None)

        # Grammar
        self.__grammar = specification + StringEnd()
        self.__grammar.setParseAction(self.__evaluate_specification)
        self.__grammar.ignore(comment)
コード例 #10
0
ファイル: parsemath.py プロジェクト: matutter/parsemath
    def __init__(self):
        self.stack = []
        self.dice_roles = []

        self.binary_ops = {
            '+': operator.add,
            '-': operator.sub,
            '*': operator.mul,
            '/': operator.truediv,
            '^': operator.pow,
            '>': operator.gt,
            '>=': operator.ge,
            '<': operator.lt,
            '<=': operator.le,
            '!=': operator.ne,
            '==': operator.eq,
            'or': operator.or_,
            'and': operator.and_
        }

        self.constants = {'PI': math.pi, 'E': math.e}

        self.functions = {
            'sum': lambda *a: sum(a),
            'sin': math.sin,
            'cos': math.cos,
            'tan': math.tan,
            'exp': math.exp,
            'hypot': math.hypot,
            'abs': abs,
            'trunc': int,
            'round': round,
            'sgn': lambda a: -1 if a < -math.e else 1 if a > math.e else 0,
            'multiply': lambda a, b: a * b,
            'all': lambda *a: all(a),
            'any': lambda *a: any(a)
        }

        # lang vars
        e = CaselessKeyword("E")
        pi = CaselessKeyword("PI")
        number = Regex(r"[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?")
        number.setName('Number')
        ident = Word(alphas, alphanums + "_$")
        ident.setName('Ident')
        dice = Regex(r'\d?[dD]\d+')
        dice.setName('Dice')
        plus, minus, lt, le, gt, ge, eq, ne, or_, and_ = map(
            Literal, ['+', '-', '<', '<=', '>', '>=', '==', '!=', 'or', 'and'])
        bi_op = plus | minus | lt | le | gt | ge | eq | ne | or_ | and_
        bi_op.setName('LowBinaryOp')
        mult = Literal('*')
        div = Literal('/')
        multop = mult | div
        multop.setName('MediumBinaryOp')
        expop = Literal('^')
        expop.setName('HighBinaryOp')
        lpar = Suppress('(')
        rpar = Suppress(')')
        factor = Forward()
        expr = Forward()
        expr_list = delimitedList(Group(expr))
        expr_list.setName('ExpressionList')

        def dice_role(s: str) -> int:
            rolls = DiceRolls(roll=s, results=[])
            s = s.lower()
            if s.startswith('d'):
                count = 1
                limit = s[1:]
            else:
                count, limit = s.lower().split('d')
            count = int(count)
            limit = int(limit)
            for _ in range(0, count):
                roll = random.randint(1, limit)
                rolls.results.append(roll)
            self.dice_roles.append(rolls)
            return rolls.sum

        def insert_fn_arg_count_tuple(t: Tuple) -> None:
            fn = t.pop(0)
            argc = len(t[0])
            t.insert(0, (fn, argc))

        def push(tokens) -> None:
            self.stack.append(tokens[0])

        def push_unary_minus(tokens) -> None:
            if '-' in tokens:
                push('unary -')

        def push_dice(t: ParseResults) -> None:
            self.stack.append(functools.partial(dice_role, t[0]))

        dice.setParseAction(push_dice)

        fn_call = ((ident + lpar - Group(expr_list) +
                    rpar).setParseAction(insert_fn_arg_count_tuple))

        atom = dice | (bi_op[...] + (
            ((fn_call | pi | e | number | ident).setParseAction(push))
            | Group(lpar + expr + rpar)).setParseAction(push_unary_minus))

        factor <<= atom + (expop + factor).setParseAction(push)[...]
        term = factor + (multop + factor).setParseAction(push)[...]
        expr <<= term + (bi_op + term).setParseAction(push)[...]

        self.expr = expr
        expr.setName('Expression')
        factor.setName('Factor')
        atom.setName('Atom')
        term.setName('Term')
コード例 #11
0
m_or.setName('OR')
m_not = K('not')
m_not.setName('NOT')

test('m_and', 'and')
test('m_or', 'or')

m_logical_operator = m_and ^ m_or

test('m_logical_operator', '''
and
or
''')

m_expression = Forward()
m_expression.setName('EXPR')
m_infix_operator = m_logical_operator
m_prefix_operator = m_not
m_subexpression = nestedExpr(content=m_expression)

m_term = m_literal ^ m_identifier ^ m_subexpression

m_infix_expression = ((m_term + m_infix_operator + m_expression)
                      #^
                      #(m_expression + m_infix_operator + m_term)
                      ^ (m_term + m_infix_operator + m_term))

m_prefix_expression = m_prefix_operator + m_expression

m_expression << (m_term ^ m_prefix_expression
                 ^ m_infix_expression) + StringEnd()
コード例 #12
0
ファイル: has_comps.py プロジェクト: AndreaCensi/typsy
from .interface import TypsyType
from contracts import ContractsMeta, contract
from contracts.backported import getfullargspec
from contracts.interface import describe_type
from contracts.main import get_all_arg_names
from contracts.pyparsing_utils import myOperatorPrecedence
from contracts.utils import indent
from pyparsing import Forward, ParserElement, opAssoc, Suppress, Literal
from typsy.pyparsing_add import MyOr, wrap_parse_action
import traceback

ParserElement.enablePackrat()
# ParserElement.verbose_stacktrace = True

sts_type = Forward()
sts_type.setName('sts_type')
sts_type_final = None

simple_sts_type = Forward()

def get_sts_type():
    global sts_type_final
    if sts_type_final is not None:
        # print('reusing')
        return sts_type_final
    else:
        simple_exprs = []
        complex_exprs = []
        operators = []
        
        S = Suppress
コード例 #13
0
ファイル: parser.py プロジェクト: jbofill/rdflib
# VarOrIRIref:
VarOrIRIref = Var | IRIref
if DEBUG:
    VarOrIRIref.setName("VarOrIRIref")

# Verb:
Verb = VarOrIRIref | Keyword("a").setParseAction(refer_component(getattr, [rdflib.namespace.RDF, "type"], [0, 1]))
if DEBUG:
    Verb.setName("Verb")


# Expression:
Expression = Forward()
if DEBUG:
    Expression.setName("Expression")

# BuiltInCall:
STR = Suppress(CaselessKeyword("STR"))
LANG = Suppress(CaselessKeyword("LANG"))
LANGMATCHES = Suppress(CaselessKeyword("LANGMATCHES"))
DATATYPE = Suppress(CaselessKeyword("DATATYPE"))
BOUND = Suppress(CaselessKeyword("BOUND"))
isIRI = Suppress(CaselessKeyword("isIRI"))
isURI = Suppress(CaselessKeyword("isURI"))
isBLANK = Suppress(CaselessKeyword("isBLANK"))
isLITERAL = Suppress(CaselessKeyword("isLITERAL"))
sameTerm = Suppress(CaselessKeyword("sameTERM"))

# RegexExpression
REGEX = Suppress(CaselessKeyword("REGEX"))
コード例 #14
0
ファイル: graph_parser_pp.py プロジェクト: Mause/circuitry
CustomComponent = CustomComponentHeader + CustomComponentBody('contents')
CustomComponent.addParseAction(build_component)

ComponentDeclarationComponents = WordOrWords()
ComponentDeclaration = (OPEN + ComponentDeclarationComponents('components') +
                        WORD('ttype') + CLOSE)
ComponentDeclaration.setName('ComponentDeclaration')
ComponentDeclaration.addParseAction(build_declaration)

Import = (Literal('@import') + WordOrWords + Literal('from') +
          WORD('filename') + Literal('@'))
Import.addParseAction(lambda tok: ImportFile(tok.filename, tok[1:-3]))

SubGrammar = ComponentDeclaration | Connector | Import | CustomComponent
Grammar <<= (SubGrammar + Grammar) | SubGrammar
Grammar.setName('Grammar')

Header = (OPEN + WORD('filename').setName('filename') + WordOrWords('inputs') +
          WordOrWords('outputs') + CLOSE)

Header.addParseAction(lambda tok: (tok.filename, tok.inputs, tok.outputs))


def build_file(tok):
    return tok[1:]
    # filename, inputs, outputs = tok[0]

    # from .graph import Graph
    # return Graph(
    #     connectable_impls.CustomComponent(
    #         filename,
コード例 #15
0
ファイル: grammar.py プロジェクト: a-recknagel/stenotype
    MatchFirst,
)

from . import elements as ste

__all__ = ["parse"]


def unpack(results: ParseResults) -> tuple:
    """Unpack the members of a :py:class:`~.ParseResults` to a :py:class:`tuple`"""
    return tuple(item[0] for item in results)


#: Words that are not valid identifiers
KEYWORDS = Forward()
KEYWORDS.setName("KEYWORD")
KEYWORDS << MatchFirst(tuple(map(Keyword, kwlist)))

#: literal `...`, e.g. in `typing.Tuple[int, ...]`, not an `Ellipsis`
DOTS = Literal("...").setParseAction(lambda: ste.Dots())
KEYWORDS << MatchFirst((*KEYWORDS.expr.exprs, DOTS))

#: any valid typing or stenotype expression, such as `List`, `typing.List`, `?List`, ...
TYPE = Forward()
TYPE.setName("TYPE")
TYPE_exclude_UNION = Forward()
TYPE_exclude_UNION.setName("TYPE_exclude_UNION")

# typing expressions
# ==================
コード例 #16
0
ファイル: parser.py プロジェクト: gjhiggins/django-rdflib
# VarOrIRIref:
VarOrIRIref = Var | IRIref
if DEBUG:
    VarOrIRIref.setName('VarOrIRIref')

# Verb:
Verb = (VarOrIRIref | Keyword('a').setParseAction(
  refer_component(getattr, [rdflib.namespace.RDF, 'type'], [0, 1])))
if DEBUG:
    Verb.setName('Verb')


# Expression:
Expression = Forward()
if DEBUG:
    Expression.setName('Expression')

# BuiltInCall:
STR = Suppress(CaselessKeyword('STR'))
LANG = Suppress(CaselessKeyword('LANG'))
LANGMATCHES = Suppress(CaselessKeyword('LANGMATCHES'))
DATATYPE = Suppress(CaselessKeyword('DATATYPE'))
BOUND = Suppress(CaselessKeyword('BOUND'))
isIRI = Suppress(CaselessKeyword('isIRI'))
isURI = Suppress(CaselessKeyword('isURI'))
isBLANK = Suppress(CaselessKeyword('isBLANK'))
isLITERAL = Suppress(CaselessKeyword('isLITERAL'))
sameTerm = Suppress(CaselessKeyword('sameTERM'))

# RegexExpression
REGEX = Suppress(CaselessKeyword('REGEX'))
コード例 #17
0
ファイル: parser.py プロジェクト: ishanthilina/cc.libreoffice
# VarOrIRIref:
VarOrIRIref = Var | IRIref
if DEBUG:
    VarOrIRIref.setName('VarOrIRIref')

# Verb:
Verb = (VarOrIRIref | Keyword('a').setParseAction(
    refer_component(getattr, [rdflib.namespace.RDF, 'type'], [0, 1])))
if DEBUG:
    Verb.setName('Verb')

# Expression:
Expression = Forward()
if DEBUG:
    Expression.setName('Expression')

# BuiltInCall:
STR = Suppress(CaselessKeyword('STR'))
LANG = Suppress(CaselessKeyword('LANG'))
LANGMATCHES = Suppress(CaselessKeyword('LANGMATCHES'))
DATATYPE = Suppress(CaselessKeyword('DATATYPE'))
BOUND = Suppress(CaselessKeyword('BOUND'))
isIRI = Suppress(CaselessKeyword('isIRI'))
isURI = Suppress(CaselessKeyword('isURI'))
isBLANK = Suppress(CaselessKeyword('isBLANK'))
isLITERAL = Suppress(CaselessKeyword('isLITERAL'))
sameTerm = Suppress(CaselessKeyword('sameTERM'))

# RegexExpression
REGEX = Suppress(CaselessKeyword('REGEX'))
コード例 #18
0
ファイル: sql_parser.py プロジェクト: klahnakoski/pyLibrary
)

join = ((CROSSJOIN | FULLJOIN | FULLOUTERJOIN | INNERJOIN | JOIN | LEFTJOIN | LEFTOUTERJOIN | RIGHTJOIN | RIGHTOUTERJOIN)("op") + Group(tableName)("join") + Optional(ON + expr("on"))).addParseAction(to_join_call)

sortColumn = expr("value").setName("sort1").setDebugActions(*debug) + Optional(DESC("sort") | ASC("sort")) | \
             expr("value").setName("sort2").setDebugActions(*debug)

# define SQL tokens
selectStmt << Group(
    Group(Group(
        delimitedList(
            Group(
                SELECT.suppress().setDebugActions(*debug) + delimitedList(selectColumn)("select") +
                Optional(
                    FROM.suppress().setDebugActions(*debug) + (delimitedList(Group(tableName)) + ZeroOrMore(join))("from") +
                    Optional(WHERE.suppress().setDebugActions(*debug) + expr.setName("where"))("where") +
                    Optional(GROUPBY.suppress().setDebugActions(*debug) + delimitedList(Group(selectColumn))("groupby").setName("groupby")) +
                    Optional(HAVING.suppress().setDebugActions(*debug) + expr("having").setName("having")) +
                    Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit")) +
                    Optional(OFFSET.suppress().setDebugActions(*debug) + expr("offset"))
                )
            ),
            delim=(UNION | UNIONALL)
        )
    )("union"))("from") +
    Optional(ORDERBY.suppress().setDebugActions(*debug) + delimitedList(Group(sortColumn))("orderby").setName("orderby")) +
    Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit")) +
    Optional(OFFSET.suppress().setDebugActions(*debug) + expr("offset"))
).addParseAction(to_union_call)

コード例 #19
0
ファイル: sql_parser.py プロジェクト: javatreble/ActiveData
            ident.setName("table_name2").setDebug(DEBUG)

join = ((CROSSJOIN | INNERJOIN | JOIN)("op") + tableName("join") + Optional(ON + expr("on"))).addParseAction(to_join_call)

sortColumn = expr("value").setName("sort1").setDebug(DEBUG) + Optional(DESC("sort")) | \
             expr("value").setName("sort2").setDebug(DEBUG)

# define SQL tokens
selectStmt << Group(
    Group(Group(
        delimitedList(
            Group(
                SELECT.suppress().setDebug(DEBUG) + delimitedList(selectColumn)("select") +
                Optional(
                    FROM.suppress().setDebug(DEBUG) + (delimitedList(Group(tableName)) + ZeroOrMore(join))("from") +
                    Optional(WHERE.suppress().setDebug(DEBUG) + expr.setName("where"))("where") +
                    Optional(GROUPBY.suppress().setDebug(DEBUG) + delimitedList(Group(selectColumn))("groupby").setName("groupby")) +
                    Optional(HAVING.suppress().setDebug(DEBUG) + expr("having").setName("having")) +
                    Optional(LIMIT.suppress().setDebug(DEBUG) + expr("limit"))
                )
            ),
            delim=UNION
        )
    )("union"))("from") +
    Optional(ORDERBY.suppress().setDebug(DEBUG) + delimitedList(Group(sortColumn))("orderby").setName("orderby")) +
    Optional(LIMIT.suppress().setDebug(DEBUG) + expr("limit"))
).addParseAction(to_union_call)


SQLParser = selectStmt
コード例 #20
0
ファイル: syntax.py プロジェクト: Xion/contracts
O = Optional
S = Suppress

number = Word(nums)
point = Literal('.')
e = CaselessLiteral('E')
plusorminus = Literal('+') | Literal('-')
integer = Combine(O(plusorminus) + number)
floatnumber = Combine(integer + (point + O(number)) ^ (e + integer))
integer.setParseAction(lambda tokens: SimpleRValue(int(tokens[0])))
floatnumber.setParseAction(lambda tokens: SimpleRValue(float(tokens[0])))
pi = Keyword('pi').setParseAction(lambda tokens: SimpleRValue(math.pi, 'pi')) #@UnusedVariable
isnumber = lambda x: isinstance(x, Number)

rvalue = Forward()
rvalue.setName('rvalue')
contract_expression = Forward()
contract_expression.setName('contract')
simple_contract = Forward()
simple_contract.setName('simple_contract')

# Import all expressions -- they will call add_contract()
from .library import (EqualTo, Unary, Binary, composite_contract,
                      identifier_contract, misc_variables_contract,
                      int_variables_contract, int_variables_ref,
                      misc_variables_ref, SimpleRValue)


number = pi | floatnumber | integer
operand = number | int_variables_ref | misc_variables_ref
operand.setName('r-value')
コード例 #21
0
ファイル: sed.py プロジェクト: iiSeymour/sedpy
    def parser(self):
        """
        Sed Parser Generator
        """
        # Forward declaration of the pattern and replacemnt text as the delimter
        # can be any character and will we not know it's value until parse time
        # https://pythonhosted.org/pyparsing/pyparsing.Forward-class.html
        text = Forward()

        def define_text(token):
            """
            Closes round the scope of the text Forward and defines the
            pattern and replacement tokens after the delimter is known

            https://pythonhosted.org/pyparsing/pyparsing.ParserElement-class.html#setParseAction
            """
            text << Word(printables + ' \t', excludeChars=token[0])

        flags = oneOf('g p i d').setName('flags')('flags')

        delimiter = Word(printables, exact=1).setName('delimiter')('delimiter')
        delimiter.setParseAction(define_text)

        step = Regex('~[0-9]+').setName('step')('step')

        num_address = (Word(nums + '$') + Optional(step)).setName('num_address')('num_address')

        regex_address = reduce(operator.add, [
            Suppress(Literal('/')),
            Word(printables, excludeChars='/').setName('regex')('regex*'),
            Suppress(Literal('/'))
        ])

        address = reduce(operator.add, [
            (num_address ^ regex_address).setName('address1')('address1'),
            Optional(Suppress(Literal(',')) + (num_address ^ regex_address).setName('address2')('address2')),
        ])

        address.setParseAction(self.check_condition)

        subsitution = reduce(operator.add, [
            Literal('s').setName('sflag')('sflag'),
            delimiter,
            Optional(text, '').setName('pattern')('pattern'),
            delimiter,
            Optional(text, '').setName('replacement')('replacement'),
            delimiter,
            ZeroOrMore(flags).setName('flags')('flags')
        ]).leaveWhitespace()('subsitution')

        subsitution.setParseAction(self.compileRegex)

        translate = reduce(operator.add, [
            Literal('y').setName('translate')('translate'),
            delimiter,
            text.setName('pattern')('pattern'),
            delimiter,
            text.setName('replacement')('replacement'),
            delimiter,
        ]).leaveWhitespace()('translateF')

        translate.setParseAction(self.translateF)

        actions = (subsitution | translate)
        return Optional(address) + actions
コード例 #22
0
item.leaveWhitespace()
not_ = Suppress(Literal('!')) + filter_
not_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_not(t[0]))
not_.setName('not')
filterlist = OneOrMore(filter_)
or_ = Suppress(Literal('|')) + filterlist
or_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_or(t))
or_.setName('or')
and_ = Suppress(Literal('&')) + filterlist
and_.setParseAction(lambda s, l, t: pureldap.LDAPFilter_and(t))
and_.setName('and')
filtercomp = and_ | or_ | not_ | item
filtercomp.setName('filtercomp')
filter_ << (Suppress(Literal('(').leaveWhitespace()) + filtercomp +
            Suppress(Literal(')').leaveWhitespace()))
filter_.setName('filter')
filtercomp.leaveWhitespace()
filter_.leaveWhitespace()

toplevel = (StringStart().leaveWhitespace() + filter_ +
            StringEnd().leaveWhitespace())
toplevel.leaveWhitespace()
toplevel.setName('toplevel')


def parseFilter(s):
    """
    Converting source string to pureldap.LDAPFilter

    Source string is converted to unicode for Python 3
    as pyparsing cannot parse Python 3 byte strings with
コード例 #23
0
ファイル: boolean.py プロジェクト: sjbrown/misc_work
m_not = K('not')
m_not.setName('NOT')

test('m_and', 'and')
test('m_or', 'or')

m_logical_operator = m_and ^ m_or

test('m_logical_operator', '''
and
or
''')


m_expression = Forward()
m_expression.setName('EXPR')
m_infix_operator = m_logical_operator
m_prefix_operator = m_not
m_subexpression = nestedExpr(content=m_expression)

m_term = m_literal ^ m_identifier ^ m_subexpression

m_infix_expression = (
    (m_term + m_infix_operator + m_expression)
    #^
    #(m_expression + m_infix_operator + m_term)
    ^
    (m_term + m_infix_operator + m_term)
)

m_prefix_expression = m_prefix_operator + m_expression
コード例 #24
0
    numpy = None


def isnumber(x):
    # These are scalar quantities that we can compare (=,>,>=, etc.)
    if isinstance(x, Number):
        return True

    if numpy is not None and isinstance(x, numpy.number):
        return True

    return False


rvalue = Forward()
rvalue.setName('rvalue')
contract_expression = Forward()
contract_expression.setName('contract')
simple_contract = Forward()
simple_contract.setName('simple_contract')

# Import all expressions -- they will call add_contract()
from .library import (EqualTo, Unary, Binary, composite_contract,
                      identifier_contract, misc_variables_contract,
                      scoped_variables_ref, int_variables_contract,
                      int_variables_ref, misc_variables_ref, SimpleRValue)

number = pi | floatnumber | integer
operand = number | int_variables_ref | misc_variables_ref | scoped_variables_ref
operand.setName('r-value')
コード例 #25
0
to_app = expr("value").setName("app").setDebugActions(*debug)

# define SQL tokens
selectStmt <<= delimitedList(
    #delimitedList(
        Group(
            Group(
                Group(
                    delimitedList(
                        Group(
                            SELECT.suppress().setDebugActions(*debug) + delimitedList(selectColumn)("select") +
                            Optional(TIME.suppress().setDebugActions(*debug) + expr("time"))+
                            Optional(
                                (FROM.suppress().setDebugActions(*debug) + delimitedList(Group(table_source)) + ZeroOrMore(join))("from") +
                                Optional(WHERE.suppress().setDebugActions(*debug) + expr.setName("where"))("where") +
                                Optional(GROUPBY.suppress().setDebugActions(*debug) + delimitedList(Group(selectColumn))("groupby").setName("groupby")) +
                                Optional(HAVING.suppress().setDebugActions(*debug) + expr("having").setName("having")) +
                                Optional(LIMIT.suppress().setDebugActions(*debug) + expr("limit")) +
                                Optional(OFFSET.suppress().setDebugActions(*debug) + expr("offset")) +
                                Optional(ADD.suppress().setDebugActions(*debug) + expr("add")) +
                                Optional(AVG.suppress().setDebugActions(*debug) + expr("avg")) +
                                Optional(DIVIDE.suppress().setDebugActions(*debug) + expr("divide")) +
                                Optional(MINUS.suppress().setDebugActions(*debug) + expr("minus")) +
                                Optional(MULTIPLY.suppress().setDebugActions(*debug) + expr("multiply")) +
                                Optional(TOP.suppress().setDebugActions(
                                    *debug) + expr("top"))
                            )
                        ), delim=(UNION | UNIONALL)
                    )
                )("union"))("from") +