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. """
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)
) 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
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
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)
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
#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 +
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,
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)
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')
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()
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
# 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"))
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,
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 # ==================
# 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'))
) 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)
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
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')
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
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
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
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')
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") +