def _build_filter_parser(field_names): field = _build_field_expr(field_names) negation = CaselessKeyword('not') negation.setParseAction(lambda x: Negation(x[0])) comparison_operator = Group( Keyword('=') ^ Keyword('!=') ^ Keyword('>=') ^ Keyword('<=') ^ Keyword('<') ^ Keyword('>') ^ Keyword('lte') # match before lt ^ Keyword('lt') ^ Keyword('gte') # match before gt ^ Keyword('gt') ^ (Optional(negation) + (CaselessKeyword('contains') ^ CaselessKeyword('icontains') ^ CaselessKeyword('startswith') ^ CaselessKeyword('istartswith') ^ CaselessKeyword('endswith') ^ CaselessKeyword('iendswith') ^ CaselessKeyword('eq')))) comparison_operator.setParseAction(lambda x: Operator(x)) single_value_operator = Group( CaselessKeyword('isnull') ^ (Optional(negation) + CaselessKeyword('isnull'))) single_value_operator.setParseAction(lambda x: Operator(x)) plusorminus = Literal('+') | Literal('-') num_integer = Combine(Optional(plusorminus) + Word(nums)) num_integer.setParseAction(lambda x: Integer(x[0])) num_float = Combine(Optional(plusorminus) + Word(nums) + '.' + Word(nums)) num_float.setParseAction(lambda x: Float(x[0])) quoted_string = (QuotedString("'") ^ QuotedString('"')) quoted_string.setParseAction(lambda x: String(x[0])) boolean = Or([ CaselessKeyword(v) for v in BOOLEAN_TRUE_VALUES + BOOLEAN_FALSE_VALUES ]) boolean.setParseAction(lambda x: Boolean(x[0])) value = (quoted_string ^ num_integer ^ boolean) comparison = Group((field + comparison_operator + value) ^ (value + comparison_operator + field) ^ (field + comparison_operator + field) ^ (field + single_value_operator)) comparison.setParseAction(lambda x: Comparison(x)) invalid_comparison = Group( (value + comparison_operator + value).setParseAction(lambda x: fail( "Value may not be compared with values: {0}".format(' '.join(x))))) logical_op = Group(CaselessKeyword("and") | CaselessKeyword("or")) logical_op.setParseAction(lambda x: LogicalOp(x[0][0])) statement = Optional(comparison | invalid_comparison) + ZeroOrMore( logical_op + (comparison | invalid_comparison)) return statement
def _angular_distance(): _m = (usn + Literal("\'").leaveWhitespace()) _s = (usn + Literal("\"").leaveWhitespace()) ms = Or([_m + Optional(_s), _s]) ms = ms.setParseAction(lambda s, l, tok: AngularDistance(tok)) return ms
def _angular_distance(): _m = (usn + Literal("\'").leaveWhitespace()) _s = (usn + Literal("\"").leaveWhitespace()) ms = Or([_m + Optional(_s), _s]) ms = ms.setParseAction(lambda s, l, tok: AngularDistance(tok)) return ms
return x[0] else: return query_ast.Function(x[0], x[2]) code_single.setParseAction(lambda x: query_ast.Code(x[2])) code_list.setParseAction(lambda x: query_ast.Code(*x[3::2])) serial_single.setParseAction(lambda x: query_ast.Serial(x[2])) serial_list.setParseAction(lambda x: query_ast.Serial(*x[3::2])) type_single.setParseAction(lambda x: query_ast.Type(x[2])) type_list.setParseAction(lambda x: query_ast.Type(*x[3::2])) cond_single.setParseAction(lambda x: query_ast.Condition(x[2])) cond_list.setParseAction(lambda x: query_ast.Condition(*x[3::2])) path_single.setParseAction(lambda x: query_ast.Path(x[2])) path_list.setParseAction(lambda x: query_ast.Path(*x[3::2])) tristate_expr.setParseAction(lambda x: query_ast.TriState(*x[0::2])) label_expr.setParseAction(lambda x: query_ast.Labelled(x[2])) assy_expr.setParseAction(lambda x: query_ast.Assy(x[2])) or_expr.setParseAction(_pa_or_expr) and_expr.setParseAction(_pa_and_expr) func_expr.setParseAction(_pa_func_expr) not_expr.setParseAction(lambda x: query_ast.Not(x[1])) paren_expr.setParseAction(lambda x: x[1]) def search_tree(query): """ Create a search tree for a query string. :param str query: The query string to generate the search tree for. :returns: A new search tree.
def look_at_something(tokens): d = {'action': 'look'} target = tokens[0][1] if target['target'] == "around": target['target'] = "CURRENT_ROOM" d.update(target) return d def move_somewhere(tokens): ele = tokens[0] if isinstance(ele, dict): ele = [ ele, ] d = {'action': 'move'} d.update(ele[-1]) return d take_command.setParseAction(take_something) wear_command.setParseAction(wear_something) look_command.setParseAction(look_at_something) move_command.setParseAction(move_somewhere) command = MatchFirst([take_command, wear_command, look_command, move_command]) print(command.parseString("go n")) print(command.parseString("n")) # elementRef.setParseAction( computeElementWeight ) print("OK??")
if len(x) == 1: return x[0] else: return query_ast.Function(x[0], x[2]) code_single.setParseAction(lambda x: query_ast.Code(x[2])) code_list.setParseAction(lambda x: query_ast.Code(*x[3::2])) serial_single.setParseAction(lambda x: query_ast.Serial(x[2])) serial_list.setParseAction(lambda x: query_ast.Serial(*x[3::2])) type_single.setParseAction(lambda x: query_ast.Type(x[2])) type_list.setParseAction(lambda x: query_ast.Type(*x[3::2])) cond_single.setParseAction(lambda x: query_ast.Condition(x[2])) cond_list.setParseAction(lambda x: query_ast.Condition(*x[3::2])) path_single.setParseAction(lambda x: query_ast.Path(x[2])) path_list.setParseAction(lambda x: query_ast.Path(*x[3::2])) tristate_expr.setParseAction(lambda x: query_ast.TriState(*x[0::2])) label_expr.setParseAction(lambda x: query_ast.Labelled(x[2])) assy_expr.setParseAction(lambda x: query_ast.Assy(x[2])) or_expr.setParseAction(_pa_or_expr) and_expr.setParseAction(_pa_and_expr) func_expr.setParseAction(_pa_func_expr) not_expr.setParseAction(lambda x: query_ast.Not(x[1])) paren_expr.setParseAction(lambda x: x[1]) def search_tree(query): """ Create a search tree for a query string. :param str query: The query string to generate the search tree for. :returns: A new search tree.
numsign = oneOf('+ -') integer = Combine(Optional(numsign) + Word(nums)) integer.setParseAction(lambda s, l, t: int(t[0])) decimal = Combine( Optional(numsign) + Word(nums) + Optional(Literal('.') + Word(nums)) \ + Optional( oneOf('e E') + Optional(numsign) + Word(nums) ) ) decimal.setParseAction(lambda s, l, t: float(t[0])) nbprintables = translate(printables, None, '{}') string = Or([ QuotedString("'", escChar='\\', multiline=True), QuotedString('"', escChar='\\', multiline=True), Word(nbprintables) ]) string.setParseAction(lambda s, l, t: str(t[0])) braced_string = Forward() braced_string = OneOrMore(nestedExpr("{", "}", content=braced_string) | string) braced_string.setParseAction(lambda s, l, t: t) decimal_list = nestedExpr("{", "}", content=decimal) decimal_list.setParseAction(lambda s, l, t: t.asList()[0] if len(t[0]) == 1 else t.asList()) integer_list = nestedExpr("{", "}", content=integer) integer_list.setParseAction(lambda s, l, t: t.asList()[0] if len(t[0]) == 1 else t.asList()) string_list = nestedExpr("{", "}", content=braced_string) string_list.setParseAction(lambda s, l, t: t.asList()[0] if len(t[0]) == 1 else t.asList())
def ruleParser(): global typedversion # ------------------------------------------------------ # Atomic # ------------------------------------------------------ # Tokens lbrX = Literal("(") rbrX = Literal(")") commaX = Literal(",") lbr = Literal("(").suppress() rbr = Literal(")").suppress() comma = Literal(",").suppress() hash = Literal("#") equ = Literal("=") implies = Literal("=>").suppress() dot = Literal(".").suppress() eol = Literal("\n").suppress() # Basic constructors Alfabet = alphas + nums + "_$" Number = Word(nums) # Typeinfo/Constant TypeInfo = oneOf("mr nonce pk sk fu table") Constant = Word(alphas, Alfabet) # Time nTime = Number xTime = Literal("xTime") sTime = Literal("s") + lbrX + Number + rbrX Time = Or([nTime, xTime, sTime]) # Const Const = Forward() ConstC = Literal("c") + lbrX + Constant + commaX + Time + rbrX ConstF = Literal("c(ni,ni)") Const << Or([Constant, ConstC, ConstF]) def stringize(s, l, t): return ["".join(t)] Const.setParseAction(stringize) # Optional prime def optprimeaction(s, l, t): if len(t) == 0: return [""] else: return t optprime = Optional(Literal("'")) optprime.setParseAction(optprimeaction) # Two versions if typedversion: Variable = Word("x", Alfabet) Variable = TypeInfo + lbr + Variable + rbr + optprime Variable.setParseAction( lambda s, l, t: [If.Variable(t[0], t[1], t[2])]) else: Variable = Word("x", Alfabet) + optprime Variable.setParseAction( lambda s, l, t: [If.Variable("untyped", t[0], t[1])]) # Atomic ## DEVIANT : below there is an optprime after the atom. This ## is not in the BNF. TypedConstant = TypeInfo + lbr + Const + rbr + optprime TypedConstant.setParseAction( lambda s, l, t: [If.Constant(t[0], t[1], t[2])]) Atomic = Or(TypedConstant, Variable) ### TEST #print Atomic.parseString("mr(Cas)'") #print Atomic.parseString("nonce(Koen)") # ------------------------------------------------------ # Messages # ------------------------------------------------------ # Base forward declaration Message = Forward() # Agents etc AgentMr = Literal("mr") + lbr + Const + rbr AgentMr.setParseAction(lambda s, l, t: [If.Constant(t[0], t[1])]) Agent = Or([AgentMr, Variable]) # TODO Not implemented yet KeyTable = Or([Literal("table") + lbr + Const + rbr, Variable]) KeyTableApp = Literal( "tb") + lbr + KeyTable + comma + Agent + rbr + optprime # Crypto pkterm = Literal("pk") + lbr + Const + rbr + optprime pkterm.setParseAction(lambda s, l, t: [If.PublicKey(t[0], t[1], t[2])]) ##varterm = Variable + optprime ### Variable already has an optprime varterm = Variable Invertible = Or([pkterm, KeyTableApp, varterm]) PublicCypher = Literal("crypt") + lbr + Invertible + comma + Message + rbr PublicCypher.setParseAction(lambda s, l, t: [If.PublicCrypt(t[1], t[2])]) XOR = Literal("rcrypt") + lbr + Message + comma + Message + rbr XOR.setParseAction(lambda s, l, t: [If.XOR(t[1], t[2])]) SymmetricCypher = Literal("scrypt") + lbr + Message + comma + Message + rbr SymmetricCypher.setParseAction( lambda s, l, t: [If.SymmetricCrypt(t[1], t[2])]) # TODO Not implemented yet futerm = Or([Literal("fu") + lbr + Const + rbr, Variable]) Function = Literal("funct") + lbr + futerm + comma + Message + rbr Concatenation = Literal( "c").suppress() + lbr + Message + comma + Message + rbr Concatenation.setParseAction(lambda s, l, t: [If.Composed(t[0], t[1])]) # Message composition Composed = Or([ Concatenation, SymmetricCypher, XOR, PublicCypher, Function, KeyTable, KeyTableApp ]) Message << Or([Composed, Atomic]) ### TEST #print Message.parseString("nonce(c(Na,xTime))") # ------------------------------------------------------ # Model of honest agents # ------------------------------------------------------ Boolean = Or([Literal("true"), Literal("false"), Variable]) Session = Forward() Session << Or([Literal("s") + lbr + Session + rbr, Number, Variable]) MsgEtc = Literal("etc") MsgEtc.setParseAction( lambda s, l, t: [If.MsgList([If.Constant("special", "etc")])]) MsgVar = Group(Variable) MsgVar.setParseAction(lambda s, l, t: [If.MsgList(t)]) MsgList = Forward() MsgComp = Literal("c") + lbr + Message + comma + MsgList + rbr MsgComp.setParseAction( lambda s, l, t: [If.MsgList([t[1]] + t[2].getList())]) MsgList << Or([MsgEtc, Variable, MsgComp]) Step = Or([Number, Variable]) ### TEST #print Message.parseString("xKb") #print Message.parseString("mr(Cas)") #print MsgList.parseString("etc") #print MsgList.parseString("c(xKb,etc)") #print MsgList.parseString("c(xA,c(xB,c(xKa,c(xKa',c(xKb,etc)))))") # Principal fact Principal = Literal( "w" ) + lbr + Step + comma + Agent + comma + Agent + comma + MsgList + comma + MsgList + comma + Boolean + comma + Session + rbr Principal.setParseAction(lambda s, l, t: [If.PrincipalFact(t[1:])]) # Message fact MessageFact = Literal( "m" ) + lbr + Step + comma + Agent + comma + Agent + comma + Agent + comma + Message + comma + Session + rbr MessageFact.setParseAction(lambda s, l, t: [If.MessageFact(t[1:])]) # Goal fact Secret = Literal("secret") + lbr + Message + Literal( "f") + lbr + Session + rbr + rbr Give = Literal("give") + lbr + Message + Literal( "f") + lbr + Session + rbr + rbr Witness = Literal( "witness" ) + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr Request = Literal( "request" ) + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr GoalFact = Or([Secret, Give, Witness, Request]) GoalFact.setParseAction(lambda s, l, t: [If.GoalFact(t)]) # Goal State # It actually yields a rule (not a state per se) Correspondence = Principal + dot + Principal Correspondence.setParseAction(lambda s, l, t: [If.CorrespondenceRule(t)]) Secrecy = Literal("secret") + lbr + Literal("xsecret") + comma + Literal( "f") + lbr + Session + rbr + rbr + dot + Literal("i") + lbr + Literal( "xsecret") + rbr Secrecy.setParseAction(lambda s, l, t: [If.SecrecyRule(t)]) STSecrecy = Literal("give(xsecret,f(xc)).secret(xsecret,f(xc))" ) + implies + Literal("i(xsecret)") STSecrecy.setParseAction(lambda s, l, t: [If.STSecrecyRule(t)]) Authenticate = Literal( "request" ) + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr Authenticate.setParseAction(lambda s, l, t: [If.AuthenticateRule(t)]) GoalState = Or([Correspondence, Secrecy, STSecrecy, Authenticate]) # TimeFact TimeFact = Literal("h") + lbr + Message + rbr TimeFact.setParseAction(lambda s, l, t: [If.TimeFact(t[1])]) # Intruder knowledge IntruderKnowledge = Literal("i") + lbr + Message + rbr # Facts and states Fact = Or([ Principal, MessageFact, IntruderKnowledge, TimeFact, Secret, Give, Witness, Request ]) Fact.setParseAction(lambda s, l, t: [If.Fact(t)]) State = Group(delimitedList( Fact, ".")) ## From initial part of document, not in detailed BNF State.setParseAction(lambda s, l, t: [If.State(t)]) # Rules MFPrincipal = Or([MessageFact + dot + Principal, Principal]) mr1 = Literal("h") + lbr + Literal("s") + lbr + Literal( "xTime") + rbr + rbr + dot + MFPrincipal mr2 = implies mr3 = Literal("h") + lbr + Literal( "xTime") + rbr + dot + MFPrincipal + Optional( dot + delimitedList(GoalFact, ".")) MessageRule = Group(mr1) + mr2 + Group( mr3) ## DEVIANT : BNF requires newlines MessageRule.setParseAction( lambda s, l, t: [If.MessageRule(t[0][3:], t[1][2:])]) InitialState = Literal("h") + lbr + Literal( "xTime") + rbr + dot + State ## DEVIANT : BNF requires newlines InitialState.setParseAction(lambda s, l, t: [If.InitialRule(t[2])]) # Intruder IntruderRule = Literal("nogniet") # Simplification f_simplif = Literal("f") + lbr + Literal("s") + lbr + Literal( "xc") + rbr + rbr + implies + Literal("f") + lbr + Literal( "xc") + rbr ## DEVIANT : EOL removed matching_request = Witness + dot + Request + implies no_auth_intruder = Request + implies SimplificationRule = Or([f_simplif, matching_request, no_auth_intruder]) # Compose all rules Rule = Or([ InitialState, MessageRule, IntruderRule, GoalState, SimplificationRule ]) return Rule
valexpr << Group(QuotedString("\"") | nums | attrexpr) """ provides_decl = Keyword("provides") - Suppress(open_block) - Group(ZeroOrMore(Word(printables, excludeChars="{}"))) - Suppress(close_block) requires_decl = Keyword("requires") - Suppress(open_block) - Group(ZeroOrMore(Word(printables, excludeChars="{}"))) - Suppress(close_block) agent_decl = Keyword("agent") + Suppress(open_block) + Group(ZeroOrMore(Word(printables, excludeChars="{}"))) + Suppress(close_block) script_decl = Keyword("script") + Suppress(open_block) + QuotedString("\"", multiline=True) + Suppress(close_block) tool_decl = Keyword("tool") + Suppress(open_block) + QuotedString("\"", multiline=True) + Suppress(close_block) action_contents = Group(provides_decl ^ requires_decl ^ agent_decl ^ script_decl ^ tool_decl) action_decl = Group(Keyword("action") + name.setResultsName("actionName") + Optional(action_keywords) + Suppress(open_block) - ZeroOrMore(action_contents) - Suppress(close_block)).setParseAction(add_action) primary_decl = Forward() block = Forward() primary_keyword = Or([Keyword("branch"), Keyword("iteration"), Keyword("selection"), Keyword("sequence"), Keyword("task")]) primary_decl << Group(primary_keyword.setParseAction(add_primary) - Optional(name)("name") - Suppress(open_block).setParseAction(start_prim) - ZeroOrMore( (action_decl ^ primary_decl) ) - Suppress(close_block).setParseAction(stop_prim)) process_decl = (Keyword("process") + name.setResultsName("processName").setParseAction(process_name) + Suppress(open_block) - ZeroOrMore( (primary_decl ^ action_decl )).setResultsName("block") - Suppress(close_block)) def arr_to_json(orig_arr): arr = copy.deepcopy(orig_arr) global glob_cur_path global glob_d d = copy.deepcopy(glob_d) cur_path = d["process"]["contains"] glob_d = {"process": {"contains": {}, "type": "process", "name": ""}} glob_cur_path = glob_d["process"]["contains"] stack = [] count = -1 for item in arr:
def make_grammar_2(): """ Construct the BBDB grammar. See grammar.ebnf for the specification. """ # Helper functions for the brace types. LP, RP, LB, RB = map(Suppress, "()[]") Paren = lambda arg: LP + Group(arg) + RP Bracket = lambda arg: LB + Group(arg) + RB # Helper functions for constructing return types. def make_list(t): return t.asList() def make_dict(t): return {k: v for k, v in t[0] or []} def make_address_entry(t): return t[0].tag, { "location": list(t[0].location or []), "city": t[0].city or "", "state": t[0].state or "", "zipcode": t[0].zipcode or "", "country": t[0].country or "" } def make_record(t): return { "firstname": t[0].firstname, "lastname": t[0].lastname, "aka": t[0].aka or [], "company": t[0].company or "", "phone": t[0].phone or {}, "address": t[0].address or {}, "net": t[0].net or [], "fields": t[0].fields or {} } def make_string(t): return t[0][1:-1].replace(r'\"', '"') # Define the low-level entities. string = QuotedString(quoteChar='"', escChar='\\', unquoteResults=False) string.setParseAction(make_string) nil = Keyword("nil") nil.setParseAction(lambda t: [None]) atom = Word(alphanums + '-') dot = Suppress(Keyword(".")) integer = Word(nums) integer.setParseAction(lambda t: int(t[0])) # Phone. phone_usa = Group(OneOrMore(integer)) phone_nonusa = string phone_entry = Bracket(string("tag") + Or([phone_usa, phone_nonusa])) phone = Or([Paren(OneOrMore(phone_entry)), nil])("phone") phone.setParseAction(make_dict) # Address. location = Paren(OneOrMore(string))("location") location.setParseAction(make_list) address_entry = Bracket( string("tag") + location + string("city") + string("state") + string("zipcode") + string("country")) address_entry.setParseAction(make_address_entry) address = Or([Paren(OneOrMore(address_entry)), nil])("address") address.setParseAction(make_dict) # Field. field = Paren(atom + dot + string) fields = Or([Paren(OneOrMore(field)), nil])("fields") fields.setParseAction(make_dict) # Other parts of an entry. name = string("firstname") + Or([string("lastname"), nil]) company = Or([string, nil])("company") aka = Or([Paren(OneOrMore(string)), nil])("aka") aka.setParseAction(make_list) net = Or([Paren(OneOrMore(string)), nil])("net") net.setParseAction(make_list) cache = nil("cache") # A single record. record = Bracket(name + aka + company + phone + address + net + fields + cache) record.setParseAction(make_record) # All the records. bbdb = ZeroOrMore(record) bbdb.setParseAction(make_list) # Define comment syntax. comment = Regex(r";.*") bbdb.ignore(comment) return bbdb
expression = operatorPrecedence(term, [(oneOf("* /"), 2, opAssoc.LEFT, parse_expression), (oneOf("+ -"), 2, opAssoc.LEFT, parse_expression)] ) assignment_stmt = variable + equals + expression + StringEnd() assignment_stmt.setParseAction(parse_assignment_stmt) output_stmt = output_fn + expression + StringEnd() output_stmt.setParseAction(parse_output_stmt) input_stmt = input_fn + term + StringEnd() input_stmt.setParseAction(parse_input_stmt) stmt = Or([assignment_stmt, input_stmt, output_stmt]) stmt.setParseAction(print_tree) def parser_init(): global symbol_table symbol_table = {} def test_negative(): parser_init() test_negative_string("x=1 +") test_negative_string("x==1 ** x /") test_negative_string("z 1 3 + 4") test_negative_string("z =1 3 + 4") test_negative_string("z =1 3 + 4;") def test_negative_string(expr): try:
four_digits_year.setResultsName("y") ])) date_month = Or([ four_digits_year + year_month_separator + month, month + year_month_separator + four_digits_year ]) two_dates_separator = oneOf("- /") time_expression = Or([ (date + Optional(two_dates_separator.suppress() + date) ).setParseAction(lambda _s, l, t: { 'type': 'time', 'dates': [{k: int(v) for k, v in d.items()} for d in t] }), period_name.setParseAction(lambda _s, l, t: { 'type': 'time', 'period': t[0] }) ]) # RULES: "Relative to" factor_unit = ( simple_h_name.setResultsName("factor") + Optional(Regex(".*").setResultsName("unparsed_unit"))).setParseAction( lambda _s, l, t: { 'type': 'factor_unit', 'factor': t.factor, 'unparsed_unit': t.unparsed_unit if t.unparsed_unit else "" }) # #### URL Parser ################################################################
equationName = QuotedString(quoteChar="\"") # What word to use to include another file's contents? # http://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28syntax%29#Libraries # Python: import # OpenSCAD: include (also use, but that's slightly different) # C etc: #include # LaTeX: \input, \include # Java: import # Modelica: import # OK, let's go for import then... importkeyword = Keyword("import").suppress() # Constants constantMap = {"pi": Constant("pi", math.pi), "e": Constant("e", math.e)} constant = Or([CaselessKeyword(constantName) for constantName in constantMap]) constant.setParseAction(lambda s, l, t: [constantMap[t[0]]]) # Parse numbers into floats straight away fNumber.setParseAction(lambda s, l, t: [float(t[0])]) # Binary operators binaryOperator = Word( '+-*/^', exact=1 ) # N.B. To-the-power-of is ^ in this grammar at the moment - TODO make it accept Python syntax ** # Define mapping from binary operator symbols to composite expression classes binaryOperatorMap = { '+': SumExpression, '-': DifferenceExpression, '*': ProductExpression, '/': QuotientExpression, '^': PowerExpression
def ruleParser(): global typedversion # ------------------------------------------------------ # Atomic # ------------------------------------------------------ # Tokens lbrX = Literal("(") rbrX = Literal(")") commaX = Literal(",") lbr = Literal("(").suppress() rbr = Literal(")").suppress() comma = Literal(",").suppress() hash = Literal("#") equ = Literal("=") implies = Literal("=>").suppress() dot = Literal(".").suppress() eol = Literal("\n").suppress() # Basic constructors Alfabet = alphas + nums + "_$" Number = Word(nums) # Typeinfo/Constant TypeInfo = oneOf("mr nonce pk sk fu table") Constant = Word(alphas, Alfabet) # Time nTime = Number xTime = Literal("xTime") sTime = Literal("s") + lbrX + Number + rbrX Time = Or([nTime, xTime, sTime]) # Const Const = Forward() ConstC = Literal("c") + lbrX + Constant + commaX + Time + rbrX ConstF = Literal("c(ni,ni)") Const << Or([Constant, ConstC, ConstF]) def stringize(s, l, t): return ["".join(t)] Const.setParseAction(stringize) # Optional prime def optprimeaction(s, l, t): if len(t) == 0: return [""] else: return t optprime = Optional(Literal("'")) optprime.setParseAction(optprimeaction) # Two versions if typedversion: Variable = Word("x", Alfabet) Variable = TypeInfo + lbr + Variable + rbr + optprime Variable.setParseAction(lambda s, l, t: [If.Variable(t[0], t[1], t[2])]) else: Variable = Word("x", Alfabet) + optprime Variable.setParseAction(lambda s, l, t: [If.Variable("untyped", t[0], t[1])]) # Atomic ## DEVIANT : below there is an optprime after the atom. This ## is not in the BNF. TypedConstant = TypeInfo + lbr + Const + rbr + optprime TypedConstant.setParseAction(lambda s, l, t: [If.Constant(t[0], t[1], t[2])]) Atomic = Or(TypedConstant, Variable) ### TEST # print Atomic.parseString("mr(Cas)'") # print Atomic.parseString("nonce(Koen)") # ------------------------------------------------------ # Messages # ------------------------------------------------------ # Base forward declaration Message = Forward() # Agents etc AgentMr = Literal("mr") + lbr + Const + rbr AgentMr.setParseAction(lambda s, l, t: [If.Constant(t[0], t[1])]) Agent = Or([AgentMr, Variable]) # TODO Not implemented yet KeyTable = Or([Literal("table") + lbr + Const + rbr, Variable]) KeyTableApp = Literal("tb") + lbr + KeyTable + comma + Agent + rbr + optprime # Crypto pkterm = Literal("pk") + lbr + Const + rbr + optprime pkterm.setParseAction(lambda s, l, t: [If.PublicKey(t[0], t[1], t[2])]) ##varterm = Variable + optprime ### Variable already has an optprime varterm = Variable Invertible = Or([pkterm, KeyTableApp, varterm]) PublicCypher = Literal("crypt") + lbr + Invertible + comma + Message + rbr PublicCypher.setParseAction(lambda s, l, t: [If.PublicCrypt(t[1], t[2])]) XOR = Literal("rcrypt") + lbr + Message + comma + Message + rbr XOR.setParseAction(lambda s, l, t: [If.XOR(t[1], t[2])]) SymmetricCypher = Literal("scrypt") + lbr + Message + comma + Message + rbr SymmetricCypher.setParseAction(lambda s, l, t: [If.SymmetricCrypt(t[1], t[2])]) # TODO Not implemented yet futerm = Or([Literal("fu") + lbr + Const + rbr, Variable]) Function = Literal("funct") + lbr + futerm + comma + Message + rbr Concatenation = Literal("c").suppress() + lbr + Message + comma + Message + rbr Concatenation.setParseAction(lambda s, l, t: [If.Composed(t[0], t[1])]) # Message composition Composed = Or([Concatenation, SymmetricCypher, XOR, PublicCypher, Function, KeyTable, KeyTableApp]) Message << Or([Composed, Atomic]) ### TEST # print Message.parseString("nonce(c(Na,xTime))") # ------------------------------------------------------ # Model of honest agents # ------------------------------------------------------ Boolean = Or([Literal("true"), Literal("false"), Variable]) Session = Forward() Session << Or([Literal("s") + lbr + Session + rbr, Number, Variable]) MsgEtc = Literal("etc") MsgEtc.setParseAction(lambda s, l, t: [If.MsgList([If.Constant("special", "etc")])]) MsgVar = Group(Variable) MsgVar.setParseAction(lambda s, l, t: [If.MsgList(t)]) MsgList = Forward() MsgComp = Literal("c") + lbr + Message + comma + MsgList + rbr MsgComp.setParseAction(lambda s, l, t: [If.MsgList([t[1]] + t[2].getList())]) MsgList << Or([MsgEtc, Variable, MsgComp]) Step = Or([Number, Variable]) ### TEST # print Message.parseString("xKb") # print Message.parseString("mr(Cas)") # print MsgList.parseString("etc") # print MsgList.parseString("c(xKb,etc)") # print MsgList.parseString("c(xA,c(xB,c(xKa,c(xKa',c(xKb,etc)))))") # Principal fact Principal = ( Literal("w") + lbr + Step + comma + Agent + comma + Agent + comma + MsgList + comma + MsgList + comma + Boolean + comma + Session + rbr ) Principal.setParseAction(lambda s, l, t: [If.PrincipalFact(t[1:])]) # Message fact MessageFact = ( Literal("m") + lbr + Step + comma + Agent + comma + Agent + comma + Agent + comma + Message + comma + Session + rbr ) MessageFact.setParseAction(lambda s, l, t: [If.MessageFact(t[1:])]) # Goal fact Secret = Literal("secret") + lbr + Message + Literal("f") + lbr + Session + rbr + rbr Give = Literal("give") + lbr + Message + Literal("f") + lbr + Session + rbr + rbr Witness = Literal("witness") + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr Request = Literal("request") + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr GoalFact = Or([Secret, Give, Witness, Request]) GoalFact.setParseAction(lambda s, l, t: [If.GoalFact(t)]) # Goal State # It actually yields a rule (not a state per se) Correspondence = Principal + dot + Principal Correspondence.setParseAction(lambda s, l, t: [If.CorrespondenceRule(t)]) Secrecy = ( Literal("secret") + lbr + Literal("xsecret") + comma + Literal("f") + lbr + Session + rbr + rbr + dot + Literal("i") + lbr + Literal("xsecret") + rbr ) Secrecy.setParseAction(lambda s, l, t: [If.SecrecyRule(t)]) STSecrecy = Literal("give(xsecret,f(xc)).secret(xsecret,f(xc))") + implies + Literal("i(xsecret)") STSecrecy.setParseAction(lambda s, l, t: [If.STSecrecyRule(t)]) Authenticate = Literal("request") + lbr + Agent + comma + Agent + comma + Constant + comma + Message + rbr Authenticate.setParseAction(lambda s, l, t: [If.AuthenticateRule(t)]) GoalState = Or([Correspondence, Secrecy, STSecrecy, Authenticate]) # TimeFact TimeFact = Literal("h") + lbr + Message + rbr TimeFact.setParseAction(lambda s, l, t: [If.TimeFact(t[1])]) # Intruder knowledge IntruderKnowledge = Literal("i") + lbr + Message + rbr # Facts and states Fact = Or([Principal, MessageFact, IntruderKnowledge, TimeFact, Secret, Give, Witness, Request]) Fact.setParseAction(lambda s, l, t: [If.Fact(t)]) State = Group(delimitedList(Fact, ".")) ## From initial part of document, not in detailed BNF State.setParseAction(lambda s, l, t: [If.State(t)]) # Rules MFPrincipal = Or([MessageFact + dot + Principal, Principal]) mr1 = Literal("h") + lbr + Literal("s") + lbr + Literal("xTime") + rbr + rbr + dot + MFPrincipal mr2 = implies mr3 = Literal("h") + lbr + Literal("xTime") + rbr + dot + MFPrincipal + Optional(dot + delimitedList(GoalFact, ".")) MessageRule = Group(mr1) + mr2 + Group(mr3) ## DEVIANT : BNF requires newlines MessageRule.setParseAction(lambda s, l, t: [If.MessageRule(t[0][3:], t[1][2:])]) InitialState = Literal("h") + lbr + Literal("xTime") + rbr + dot + State ## DEVIANT : BNF requires newlines InitialState.setParseAction(lambda s, l, t: [If.InitialRule(t[2])]) # Intruder IntruderRule = Literal("nogniet") # Simplification f_simplif = ( Literal("f") + lbr + Literal("s") + lbr + Literal("xc") + rbr + rbr + implies + Literal("f") + lbr + Literal("xc") + rbr ) ## DEVIANT : EOL removed matching_request = Witness + dot + Request + implies no_auth_intruder = Request + implies SimplificationRule = Or([f_simplif, matching_request, no_auth_intruder]) # Compose all rules Rule = Or([InitialState, MessageRule, IntruderRule, GoalState, SimplificationRule]) return Rule
# Python: import # OpenSCAD: include (also use, but that's slightly different) # C etc: #include # LaTeX: \input, \include # Java: import # Modelica: import # OK, let's go for import then... importkeyword = Keyword("import").suppress() # Constants constantMap = { "pi": Constant("pi", math.pi), "e": Constant("e", math.e) } constant = Or([CaselessKeyword(constantName) for constantName in constantMap]) constant.setParseAction(lambda s, l, t: [constantMap[t[0]]]) # Parse numbers into floats straight away fNumber.setParseAction(lambda s, l, t: [float(t[0])]) # Binary operators binaryOperator = Word('+-*/^', exact=1) # N.B. To-the-power-of is ^ in this grammar at the moment - TODO make it accept Python syntax ** # Define mapping from binary operator symbols to composite expression classes binaryOperatorMap = { '+': SumExpression, '-': DifferenceExpression, '*': ProductExpression, '/': QuotientExpression, '^': PowerExpression } # Now make binary operators get turned into classes straight away