def __init__(self, probability, emojis, channels, target, dead_user, death_date, slack=None): self.channels = channels self.pig_name = 'Pig Latin' self.pig_expr = CaselessLiteral('pig') + symbols.tail('message') + StringEnd() self.pig_doc = ('Translate a message to pig latin:\n' '\tpig <message>') self.hankey_name = 'Hankey' self.hankey_expr = CaselessLiteral('hankey') + White() + symbols.user_name.setResultsName('target') + StringEnd() self.hankey_doc = ('Target a user for hankeying:\n' '\thankey <user>') self.hankeycost_name = 'Hankey Cost' self.hankeycost_expr = CaselessLiteral('hankeycost') + StringEnd() self.hankeycost_doc = ('Check the current price of the hankey command:\n' '\thankeycost') self.rip_name = 'RIP' self.rip_expr = CaselessLiteral('rip') + StringEnd() self.rip_doc = ('Check time since %s\'s last appearance:\n' '\trip' % dead_user) self.dead_user = dead_user self.death_date = datetime.strptime(death_date, "%m/%d/%Y") self.target = target self.ramoji = emojis self.probability = probability if os.path.exists(SAVE_FILE): with open(SAVE_FILE, 'rb') as f: self.cost = pickle.load(f) else: self.cost = 1 with open(SAVE_FILE, 'wb') as f: pickle.dump(self.cost, f)
def __init__(self): ints = Word(nums) EOL = LineEnd().suppress() # ip address of device ipAddress = Optional( delimitedList(ints, ".", combine=True) + Suppress(":")) # priority priority = Suppress("<") + ints + Suppress(">") # timestamp month = Word(string.uppercase, string.lowercase, exact=3) day = ints hour = Combine(ints + ":" + ints + ":" + ints) timestamp = month + day + hour # hostname hostname = Word(alphas + nums + "_" + "-" + ".") # daemon daemon = Word(alphas + nums + "/" + "-" + "_" + ".") + Optional(Suppress("[") + ints + Suppress("]")) + Suppress(":") # message message = Regex(".*") # pattern build self.__pattern = ipAddress + priority + timestamp + \ hostname + daemon + message + StringEnd() | EOL self.__pattern_without_daemon = ipAddress + priority + \ timestamp + hostname + message + StringEnd() | EOL
def build_parser(): """ Build a pyparsing parser for our custom topology description language. :rtype: pyparsing.MatchFirst :return: A pyparsing parser. """ from pyparsing import (Word, Literal, QuotedString, StringStart, StringEnd, alphas, nums, alphanums, Group, OneOrMore, Optional) number = Word(nums) text = QuotedString('"') identifier = Word(alphas, alphanums + '_') attribute = (identifier('key') + Literal('=') + (text | number | identifier)('value')) attributes = (Literal('[') + OneOrMore(Group(attribute))('attributes') + Literal(']')) node = identifier('node') port = node + Literal(':') + (identifier | number)('port') link = port('endpoint_a') + Literal('--') + port('endpoint_b') nodes_spec = (StringStart() + Optional(attributes) + OneOrMore(Group(node))('nodes') + StringEnd()) ports_spec = (StringStart() + Optional(attributes) + OneOrMore(Group(port))('ports') + StringEnd()) link_spec = (StringStart() + Optional(attributes) + link('link') + StringEnd()) statement = link_spec | ports_spec | nodes_spec return statement
def __init__(self, currency_name, slack=None): self.currency_name = currency_name self.slots_name = 'Slot machine' self.slots_expr = CaselessLiteral( 'slots') + symbols.int_num.setResultsName('bet') + StringEnd() self.slots_doc = ( 'Gamble away your hard earned {0}:\n\tslots <currency bet>'.format( currency_name)) self.slots_jackpot_symbol = ':moneybag:' self.slots_sym = [ ':peach:', ':tangerine:', ':cherries:', ':watermelon:', ':banana:', self.slots_jackpot_symbol ] self.slots_contribution = .45 self.slots_rig = 'Rig the slot machine' self.slots_rig_expr = CaselessLiteral( 'slots') + symbols.int_num.setResultsName( 'bet') + symbols.emoji.setResultsName( '1') + symbols.emoji.setResultsName( '2') + symbols.emoji.setResultsName('3') + StringEnd() self.slots_rig_doc = 'slots <currency bet> <emoji1> <emoji2> <emoji3>' self.stats_name = 'Gambling stats' self.stats_expr = CaselessLiteral('casino') + CaselessLiteral( 'stats') + StringEnd() self.stats_doc = ( 'Information on your filthy gambling habits.\n\tcasino stats')
def __init__(self, max_len, admins=set(), slack=None): self.max_len = max_len self.admins = admins key_expr = Word(alphanums + '{}').setResultsName('key') self.bind_name = 'Make Bind' self.bind_expr = CaselessLiteral('bind') + key_expr + symbols.tail( 'output') + StringEnd() self.bind_doc = 'Bind a word to an output: bind <word> <output>.' self.unbind_name = 'Remove Bind' self.unbind_expr = CaselessLiteral('unbind') + key_expr + StringEnd() self.unbind_doc = 'Unbind a bound word: unbind <word>' self.list_name = 'List Binds' self.list_expr = CaselessLiteral('list_binds') + StringEnd() self.list_doc = 'List the current binds: list_binds' self.print_bind_name = 'Display Bind' # Use a forward to allow updating expression # Expression which is a MatchFirst of bound keys self.print_bind_forward = Forward().setResultsName('key') self.load_binds()
def __init__(self, session, slack): self.name = 'Sentiment Stats' self.expr = (CaselessLiteral('feels') + Optional(symbols.user_name.setResultsName('user')) + StringEnd()) self.doc = ('Show someone\'s feels:\n' '\tfeels [<user>]') self.extrema_name = 'Emotional Moments' self.extrema_expr = ( (CaselessLiteral('grumpy') | CaselessLiteral('happy') | CaselessLiteral('meh')).setResultsName('emotion') + Optional(symbols.user_name.setResultsName('user')) + StringEnd()) self.extrema_doc = ('Show a particularly grumpy, happy or meh quote:\n' '\t(grumpy|happy|meh) <user>') self.judge_name = 'Measure sentiment' self.judge_expr = (CaselessLiteral('lyte') + ( (Optional(symbols.flag_with_arg('decimals', Word(nums))) + symbols.tail('text')) | symbols.tail('text')) + StringEnd()) self.judge_doc = ('Evaluate the sentiment of a piece of text:\n' '\tlyte [--decimals <decimals>] <message>') self.sentiments = defaultdict(list) self.cooldowns = defaultdict(int) self.monitor_channels = config.SENTIMENT_MONITOR_CHANNELS model = lstm.load_model(session) self.predict = partial(model.predict, session)
def term(): """ """ token = ( StringStart() + operand() + StringEnd() ^ StringStart() + Group(operand() + operator() + operand()) + StringEnd() ) token.setName("term") return token
def makeParser(patterns=None): from pyparsing import ( Word, QuotedString, Keyword, Literal, SkipTo, StringEnd, ZeroOrMore, Optional, Combine, alphas, alphanums, printables ) dblQuotedString = QuotedString(quoteChar='"', escChar='\\', unquoteResults=False) sglQuotedString = QuotedString(quoteChar="'", escChar='\\', unquoteResults=False) value = dblQuotedString | sglQuotedString | Word(printables) tag_name = Word(alphas + "_", alphanums + "_-") tag_expression = Combine(tag_name + ZeroOrMore('&' + tag_name)) values = value + ZeroOrMore(tag_expression + value) identifier = Word(alphas + "_", alphanums + "_") variable = Combine(identifier + '=' + value) constituent_option = (Keyword('-no_share') | Keyword('-no_static') | Keyword('-prototypes') | Keyword('-no_prototypes') | Keyword('-check') | Keyword('-target_tag') | Combine('-group=' + value) | Combine('-suffix=' + value) | Combine('-import=' + value) | variable | Keyword('-OS9') | Keyword('-windows')) source = (Word(alphanums + "_*./$()") | Combine('-s=' + value) | Combine('-k=' + value) | Combine('-x=' + value)) # statements comment = (Literal("#") + SkipTo(StringEnd())).suppress() package = Keyword('package') + Word(printables) version = Keyword("version") + Word(printables) use = Keyword("use") + identifier + Word(printables) + Optional(identifier) + Optional(Keyword("-no_auto_imports")) constituent = ((Keyword('library') | Keyword('application') | Keyword('document')) + identifier + ZeroOrMore(constituent_option | source)) macro = (Keyword('macro') | Keyword('macro_append')) + identifier + values setenv = (Keyword('set') | Keyword('path_append') | Keyword('path_prepend')) + identifier + values alias = Keyword('alias') + identifier + values apply_pattern = Keyword("apply_pattern") + identifier + ZeroOrMore(variable) if patterns: direct_patterns = reduce(operator.or_, map(Keyword, set(patterns))) # add the implied 'apply_pattern' to the list of tokens direct_patterns.addParseAction(lambda toks: toks.insert(0, 'apply_pattern')) apply_pattern = apply_pattern | (direct_patterns + ZeroOrMore(variable)) statement = (package | version | use | constituent | macro | setenv | alias | apply_pattern) return Optional(statement) + Optional(comment) + StringEnd()
def _define_vs(): KEY = Word(alphas + '_$', alphanums + '_$').setName('identifier').setResultsName('key') # noqa VALUE = originalTextFor(_define_json()).setResultsName('value') # validator name, eg: int NAME = Optional( Optional(Suppress('?')) + pyparsing_common.identifier.setResultsName('name')) # noqa # refers, eg: @xx@yy REFERS = Group(ZeroOrMore(Suppress('@') + pyparsing_common.identifier)).setResultsName( 'refers') # noqa # args, eg: (), (1), (1,2,3), ([1,2], {"key":"value"}, "Any JSON") ARGS = Group( Optional( Suppress('(') + Optional(delimitedList(VALUE)) + Suppress(')'))).setResultsName('args') # noqa # key-value, eg: key, key=True, key=[1,2,3] KW = Group(KEY + Optional(Suppress('=') + VALUE)) # kwargs, eg: &key1&key2=True&key3=[1,2,3] KWARGS = Group(ZeroOrMore(Suppress('&') + KW)).setResultsName('kwargs') # lead xxx is key: xxx@yyy, xxx?yyy, $self&abc # lead xxx except '$self' is validator name: xxx(1,2), xxx&abc, xxx SELF = Literal('$self').setResultsName('key') VS_KEY = Optional((KEY + FollowedBy(Word('@?'))) | SELF) VS_DEF = REFERS + NAME + ARGS + KWARGS return StringStart() + VS_KEY + VS_DEF + StringEnd()
def _make_grammar(): """Make a grammar for parsing a sanitized F5 config The syntax is Tcl, except for a 'Sanitized out =' string at the top. We only parse enough to find commands and their arguments. Return a ParseResult where 'prog' is a list of commands. Each command has a name and some arguments. These arguments can be further nested lists in case of '{ ... }' and '[ ... ]' blocks. """ ParserElement.setDefaultWhitespaceChars(' ') white = Suppress(Optional(White())) comment = white + '#' - restOfLine lbrace, rbrace = Suppress('{'), Suppress('}') lbracket, rbracket = Suppress('['), Suppress(']') cmds = Forward() braces = Group(lbrace - white - Optional(cmds) - white - rbrace) brackets = Group(lbracket - white - Optional(cmds) - white - rbracket) string = QuotedString(quoteChar='"', escChar='\\', multiline=True) word = string | braces | brackets | Word(alphanums + '-:()_./<>%*$|!=&?') cmd = Group(word('name') + ZeroOrMore(word)('args')) cmd_sep = OneOrMore(Literal('\n') | ';') cmds << (cmd + ZeroOrMore(Suppress(cmd_sep) + cmd)) prog_end = Suppress(Optional(cmd_sep)) + StringEnd() prog = cmds + prog_end sanitized_begin = Suppress(Optional(White())) sanitized = sanitized_begin + Optional('Sanitized out =') + prog('prog') sanitized.ignore(comment) return sanitized
def get_idl_line_parser(): """ Based on http://pyparsing.wikispaces.com/file/view/parsePythonValue.py """ from pyparsing import \ Word, ZeroOrMore, OneOrMore, Optional, oneOf, StringEnd, Suppress, Group, Combine, \ nums, dblQuotedString, removeQuotes s = Suppress int_number = Combine(Optional(oneOf("+ -")) + Word(nums)).setParseAction( lambda tokens: int(tokens[0])).setName("integer") float_number = \ Combine(Optional(oneOf("+ -")) + Word(nums) + Optional("." + Optional(Word(nums)) + Optional(oneOf("e E")+Optional(oneOf("+ -")) +Word(nums)))) \ .setName("float") \ .setParseAction( lambda tokens: float(tokens[0]) ) bounding_box = s('(') + OneOrMore(int_number | s(',')) + s(')') bounding_box_with_score = Group(bounding_box + Optional((s(":") | s("~")) + float_number)) #filename = s('"') + Word(alphanums + "/_.~") + s('"') quoted = dblQuotedString.setParseAction(removeQuotes) filename = quoted idl_line = filename + Optional( s(':') + ZeroOrMore(bounding_box_with_score | s(','))) + ( s(";") | s(".")) + StringEnd() #print( filename.parseString("\"left/image_00000004_0.png\"") ) #print( bounding_box.parseString("(221, 183, 261, 289)") ) return idl_line.parseString
def __grammar(self): """ Pyparsing grammar to parse the filter string. """ float_ = Combine(Word(nums) + Literal(".") + Word(nums)).setParseAction( lambda x, y, z: float(z[0])) sci = Combine( Word(nums) + Optional(".") + Optional(Word(nums)) + oneOf("e E") + Optional("-") + Word(nums)).setParseAction(lambda x, y, z: float(z[0])) int_ = Word(nums).setParseAction(lambda x, y, z: int(z[0])) comp = oneOf("in eq gt lt ge le < > = like", caseless=True).setResultsName("comp") op = oneOf("and or", caseless=True).setResultsName("op") lhs = Word(alphanums + "_").setResultsName("lhs") element = sci | float_ | int_ | quotedString.setParseAction( removeQuotes) | Word(alphanums) rhs = (element + ZeroOrMore(Suppress(",") + element)).setResultsName("rhs") stmt = Group(lhs + comp + rhs).setResultsName("statement") expr = stmt + ZeroOrMore(op + stmt) + StringEnd() self.grammar = expr
def __init__(self, *args, **kwargs): super(BonusPointCalculator, self).__init__(*args, **kwargs) self.Operators.update({ "=": operator.eq, ">": operator.gt, "<": operator.lt, ">=": operator.ge, "<=": operator.le, ",": operator.and_, "[": lambda a, b: a and b or Zero, "]": lambda a, b: a and b or Zero, }) BonusPointAddition = Addition | Comparison Expression = Forward() Atom = ((Identifier | Integer).setParseAction(self._push) | (LeftParenthesis + Expression.suppress() + RightParenthesis)) Terminal = Atom + ZeroOrMore( (Multiplication + Atom).setParseAction(self._push)) Expression << Terminal + ZeroOrMore( (BonusPointAddition + Terminal).setParseAction(self._push)) Condition = Expression + ZeroOrMore( (Comma + Expression).setParseAction(self._push)) Rule = (LeftBracket + Condition + Colon + Expression + RightBracket).setParseAction(self._push) Chain = Rule + ZeroOrMore((Addition + Rule).setParseAction(self._push)) self.pattern = Chain + StringEnd()
def __init__(self): ParserElement.enablePackrat() hexadecimal_integer = Combine(CaselessLiteral('0x') + Word(hexnums)) \ .setName('hexadecimal integer') \ .setParseAction(lambda *t: int(t[2][0][2:], 16)) decimal_integer = Word(nums) \ .setName('decimal integer') \ .setParseAction(lambda t: int(''.join(t))) identifier = Word(alphanums + '_$') \ .setName('identifier') baseExpr = (hexadecimal_integer | decimal_integer | identifier) operators = [ (oneOf('+ - ~ !'), 1, opAssoc.RIGHT, self.nest_operand_pairs), (oneOf('* /'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('+ -'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('<< >>'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('<= < > >='), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('== !='), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('&'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('^'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('|'), 2, opAssoc.LEFT, self.nest_operand_pairs), ] self.expr = infixNotation(baseExpr, operators) + StringEnd()
def parse_kernel(line): from pyparsing import Group, Forward, Word, Combine, Literal, Optional, Suppress, ZeroOrMore, OneOrMore, StringEnd, delimitedList, nestedExpr, alphanums # letter = (* any alphanumeric character *) # identifier = letter, {letter}, [*] # pattern = expression, {space, expression} # expression = domain | loop | wildcard | break # domain = identifier # loop = identifier, "(", [pattern] ,")" # wildcard = "?" | "_" | "~" (* ... etc.*) # break = "+" identifier = Word(alphanums + "_-").setName("identifier") domain = Combine(identifier + Optional(Literal("^")) + Optional(Literal("*"))).setName("domain") sbreak = Literal("+").setName("strand break") wildcard = Literal("?").setName("wildcard") pattern = Forward() expression = Forward() loop = (domain + Suppress("(") + Group(Optional(pattern)) + Suppress(")")).setName("loop") expression << (loop | wildcard | sbreak | domain) pattern << OneOrMore(expression) rule = pattern + StringEnd() return rule.parseString(line)
def dom_document_setup(): crn_DWC = "".join( [x for x in ParseElementEnhance.DEFAULT_WHITE_CHARS if x != "\n"]) ParseElementEnhance.setDefaultWhitespaceChars(crn_DWC) W = Word G = Group S = Suppress O = Optional L = Literal identifier = W(alphas, alphanums + "_") number = W(nums, nums) domain = G(OneOrMore((G(identifier + O("*")) | "?" | "+"))) dotparen = G(OneOrMore(W("().+", max=1))) structure = domain + OneOrMore(LineEnd().suppress()) + dotparen sequence = G( S("sequence") + identifier + S(":") + number + OneOrMore(LineEnd().suppress())) molecule = G(identifier + S(":") + OneOrMore(LineEnd().suppress()) + structure) document = StringStart() + ZeroOrMore(LineEnd().suppress()) + G( ZeroOrMore(sequence)) + G( OneOrMore(molecule + OneOrMore(LineEnd().suppress()))) + StringEnd() document.ignore(pythonStyleComment) return document
def __init__(self): ParserElement.enablePackrat() decimal_integer = Word(nums).setName('decimal integer') \ .setParseAction(lambda t: int(''.join(t))) hexadecimal_integer = Combine(Word(nums, hexnums) + Word('hH')) \ .setName('hexadecimal integer') \ .setParseAction(lambda t: int((''.join(t))[:-1], 16)) identifier = Word(alphas, alphanums + '_@?') \ .setName('identifier') # XXX and maybe dollar sign? baseExpr = (hexadecimal_integer | decimal_integer | identifier) operators = [ (oneOf('+ - ~'), 1, opAssoc.RIGHT, self.nest_operand_pairs), (oneOf('* /'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('+ -'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('<< >>'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('&'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('^'), 2, opAssoc.LEFT, self.nest_operand_pairs), (oneOf('|'), 2, opAssoc.LEFT, self.nest_operand_pairs), ] self.expr = infixNotation(baseExpr, operators) + StringEnd()
def _compile_grammar(self): # type: () -> ParserElement """ Takes the individual grammars from each registered directive and compiles them into a full test fixture grammar whose callback methods are the bound methods on this class instance. :return: The full PyParsing grammar for test fixture files. """ grammars = [ (LineEnd().suppress()).setParseAction( functools.partial(self._finalize_test_case) ) ] # directives for directive_class in get_all_directives(): grammars.append( LineStart() + directive_class.get_full_grammar().setParseAction( functools.partial(self._ingest_directive, directive_class) ) + LineEnd() ) return StringStart() + OneOrMore(MatchFirst(grammars)) + StringEnd()
def compare_parse(parser, input, *, expected): total_parser = parser + StringEnd() if expected is ParseException: with raises(ParseException): total_parser.parseString(input) else: compare(total_parser.parseString(input), expected=expected)
def __init__(self) -> None: self.__specifications: Dict[str, Specification] = {} self.__messages: Dict[str, Message] = {} self.__refinements: List[Refinement] = [] self.__grammar = self.specification() + StringEnd() self.__grammar.setParseAction(self.__evaluate_specification) self.__grammar.ignore(Regex(r"--.*"))
def clear_sql(sql: str) -> str: ''' remove comments from sql TODO current implementation is not remove /**/ from mid of string: select a, /*comment*/ from b ''' # remove /*comment*/ ParserElement.defaultWhitespaceChars = (" \t") comment = nestedExpr('/*', '*/').suppress() starting = ZeroOrMore(comment.suppress()) ending = ZeroOrMore(comment | ';').suppress() + StringEnd() expr = starting + SkipTo(ending) + ending sql = expr.transformString(sql) # remove -- and # comments oracleSqlComment = Literal("--") + restOfLine mySqlComment = Literal("#") + restOfLine expr = (originalTextFor(QuotedString("'")) | originalTextFor(QuotedString('"')) | originalTextFor(QuotedString('`')) | (oracleSqlComment | mySqlComment).suppress()) sql = expr.transformString(sql) sql = sql.strip(' \n\t') return sql
def __init__(self): family = Regex(r'([^%s]|(\\[%s]))*' % (family_punc, family_punc)) \ .setParseAction(self._family) size = Regex(r"([0-9]+\.?[0-9]*|\.[0-9]+)") \ .setParseAction(self._size) name = Regex(r'[a-z]+') \ .setParseAction(self._name) value = Regex(r'([^%s]|(\\[%s]))*' % (value_punc, value_punc)) \ .setParseAction(self._value) families = (family + ZeroOrMore(Literal(',') + family)).setParseAction( self._families) point_sizes = (size + ZeroOrMore(Literal(',') + size)).setParseAction( self._point_sizes) property = ((name + Suppress(Literal('=')) + value + ZeroOrMore(Suppress(Literal(',')) + value)) | name).setParseAction(self._property) pattern = (Optional(families) + Optional(Literal('-') + point_sizes) + ZeroOrMore(Literal(':') + property) + StringEnd()) self._parser = pattern self.ParseException = ParseException
def create_arg_parser(): from pyparsing import Literal, Word, delimitedList, Group, \ StringStart, StringEnd, Optional, nums, alphas, alphanums ident = Word(alphas, alphanums + "_") inumber = Word("+-" + nums, nums) history = Optional(Literal('[').suppress() + inumber + Literal(']').suppress(), default=0)("history") history.setParseAction(lambda str, loc, toks: int(toks[0])) variable = Group(Word(alphas, alphanums + '._') + history) derivative = Group(Literal('d') + variable\ + Literal('/').suppress() + Literal('dt')) trace = Group( Literal('tr') + Literal('(').suppress() + Optional(ident + Literal(',').suppress(), default=None) + variable + Literal(')').suppress()) generalized_var = derivative | trace | variable args = StringStart() + delimitedList(generalized_var) + StringEnd() return args
def wildcard(str): parsed = parse(str, mask) if not parsed: return parsed return StringStart() + \ Regex(''.join([wild_to_match(x) for x in parsed])) + \ StringEnd()
class NLPyParser(NLBaseParser): """pyparsing--based implementation of the NLBaseParser """ notSpace = CharsNotIn(" \n") eq = Literal('=').suppress() value = (QuotedString('"', escChar=chr(92), unquoteResults=False) \ ^ OneOrMore(notSpace)) ts = Group(Literal('ts') + eq + value) event = Group(Literal('event') + eq + value) name = ~oneOf("ts event") + Word(alphanums + '-_.') nv = ZeroOrMore(Group(name + eq + value)) nvp = Each([ts, event, nv]) + White('\n').suppress() + StringEnd() def parseLine(self, line): try: rlist = self.nvp.parseString(line).asList() except ParseException as E: raise ValueError(E) result = {} for a in rlist: if self.parse_date and a[0] == 'ts': result[a[0]] = parse_ts(a[1]) else: result[a[0]] = a[1] return result
class TestHexUnicode(unittest.TestCase): parser = (identifier.hex_unicode.copy() + Regex(".+") + StringEnd()).leaveWhitespace() def testUnicodeConversion(self): self.assertEqual( "&", identifier.hex_unicode.parseString(r"\000026")[0] ) self.assertEqual( "&", identifier.hex_unicode.parseString(r"\26")[0] ) def testDoesntEatMoreThan6Chars(self): self.assertEqual( ["&", "B"], list(self.parser.parseString(r"\000026B")) ) def testConsumesFinalSpaceWith6Chars(self): self.assertEqual( ["&", "B"], list(self.parser.parseString(r"\000026 B")) ) def testConsumesFinalSpaceWithShortChars(self): self.assertEqual( ["&", "B"], list(self.parser.parseString(r"\26 B")) ) def testDoesntConsumeMoreThanOneSpace(self): self.assertEqual( ["&", " B"], list(self.parser.parseString(r"\26 B")) )
def __init__(self): from pyparsing import (ParserElement, StringEnd, LineEnd, Literal, pythonStyleComment, ZeroOrMore, Suppress, Optional, Combine, OneOrMore, Regex, oneOf, QuotedString, Group, ParseException) ParserElement.setDefaultWhitespaceChars("\t ") EOF = StringEnd() EOL = ~EOF + LineEnd() # EOL must not match on EOF escape = Literal("\\") comment = pythonStyleComment junk = ZeroOrMore(comment | EOL).suppress() # word (i.e: single argument string) word = Suppress(escape + EOL + Optional(comment)) \ | Combine(OneOrMore( escape.suppress() + Regex(".") | QuotedString("'", escChar='\\', multiline=True) | QuotedString('"', escChar='\\', multiline=True) | Regex("[^ \t\r\n\f\v\\\\$&<>();\|\'\"`]+") | Suppress(escape + EOL))) # redirector (aka bash file redirectors, such as "2>&1" sequences) fd_src = Regex("[0-2]").setParseAction(lambda t: int(t[0])) fd_dst = Suppress("&") + fd_src # "[n]<word" || "[n]<&word" || "[n]<&digit-" fd_redir = (Optional(fd_src, 0) + Literal("<") | Optional(fd_src, 1) + Literal(">")) + \ (word | (fd_dst + Optional("-"))) # "&>word" || ">&word" obj = (oneOf("&> >&") + word) full_redir = obj.setParseAction(lambda t: ("&", ">", t[-1])) # "<<<word" || "<<[-]word" here_doc = Regex("<<(<|-?)") + word # "[n]>>word" add_to_file = (Optional(fd_src | Literal("&"), 1) + Literal(">>") + word) # "[n]<>word" fd_bind = Optional(fd_src, 0) + Literal("<>") + word obj = (fd_redir | full_redir | here_doc | add_to_file | fd_bind) redirector = obj.setParseAction(lambda token: tuple(token)) # single command (args/redir list) command = Group(OneOrMore(redirector | word)) # logical operators (section splits) semicolon = Suppress(";") + junk connector = (oneOf("&& || |") + junk) | semicolon # pipeline, aka logical block of interconnected commands pipeline = junk + Group(command + ZeroOrMore(connector + command) + Optional(semicolon)) # define object attributes self.LEXER = pipeline.ignore(comment) + EOF self.parseException = ParseException
def build(parsers: dict): comma = Literal(",") rb = Literal(")") lb = Literal("(") srb = Literal("]") slb = Literal("[") number = Regex(r"0|[1-9][0-9]*") string = quotedString() name = Word(alphanums) label = Keyword(STRONG) | Keyword(WEAK) | Literal(SHORT_WEAK) param = Combine(Keyword(PARAM) + slb + number + srb) marker = Keyword(RESULT) | Keyword(TRUE) | Keyword(FALSE) | Keyword( THIS) | Keyword(_THIS) | param function = Keyword(GET) get = Literal(GETATTR) operator1 = Literal(MUL) | Literal(DIV) | Literal(MOD) operator2 = Literal(ADD) | Literal(SUB) operator3 = Literal(EQUAL) | Literal(NOT_EQUAL) operator3 |= And(Keyword(word) for word in IS_NOT.split(" ")) | Keyword(IS) operator4 = Literal(GREATER_OR_EQUAL) | Literal(GREATER) | Literal( LOWER_OR_EQUAL) | Literal(LOWER) operator5 = Keyword(AND) operator6 = Keyword(OR) operator7 = Keyword(FOLLOW) expression = Forward() string_st = string.setParseAction(parsers[STRING]) name_st = name.setParseAction(parsers[STRING]) marker_st = marker.setParseAction(parsers[MARKER]) tuple_st = expression + ZeroOrMore(comma + expression) round_invocation_st = (lb + Optional(tuple_st) + rb).setParseAction( parsers[INVOCATION]) function_st = (function + Suppress(round_invocation_st)).setParseAction( parsers[FUNCTION]) getattr_st = (marker_st | name_st) + OneOrMore( (get + Suppress(name_st)).setParseAction(parsers[OPERATOR])) atom_st = (lb + expression + rb) | function_st | string_st | getattr_st | marker_st operator_st = atom_st + ZeroOrMore( (operator1 + Suppress(atom_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator2 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator3 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator4 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator5 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator6 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) operator_st = operator_st + ZeroOrMore( (operator7 + Suppress(operator_st)).setParseAction(parsers[OPERATOR])) expression << operator_st getattr_st.enablePackrat() statement = (Optional(label, STRONG) + Suppress(expression)).setParseAction(parsers[LABEL]) return ZeroOrMore(statement) + StringEnd()
def create_bnf(term_descs): """term_descs .. list of TermParse objects (sign, term_name, term_arg_names), where sign can be real or complex multiplier""" lc = ['+'] # Linear combination context. equal = Literal("=").setParseAction(rhs(lc)) zero = Literal("0").suppress() point = Literal(".") e = CaselessLiteral("E") inumber = Word("+-" + nums, nums) fnumber = Combine(Word("+-" + nums, nums) + Optional(point + Optional(Word(nums))) + Optional(e + Word("+-" + nums, nums))) number = fnumber + Optional(Literal('j'), default='') add_op = oneOf('+ -') number_expr = Forward() number_expr << ZeroOrMore('(') + number \ + ZeroOrMore(add_op + number_expr) \ + ZeroOrMore(')') ident = Word(alphas, alphanums + "_") integral = Combine((Literal('i') + Word(alphanums)) | Literal('i') | Literal('a') | Word(nums))("integral") history = Optional('[' + inumber + ']', default='')("history") variable = Combine(Word(alphas, alphanums + '._') + history) derivative = Combine(Literal('d') + variable \ + Literal('/') + Literal('dt')) trace = Combine(Literal('tr') + '(' + variable + ')') generalized_var = derivative | trace | variable args = Group(delimitedList(generalized_var)) flag = Literal('a') term = Optional(Literal('+') | Literal('-'), default='+')("sign") \ + Optional(number_expr + Literal('*').suppress(), default=['1.0', ''])("mul") \ + Combine(ident("name") \ + Optional("." + (integral + "." + ident("region") + "." + flag("flag") | integral + "." + ident("region") | ident("region") )))("term_desc") + "(" \ + Optional(args, default=[''])("args") + ")" term.setParseAction(collect_term(term_descs, lc)) rhs1 = equal + OneOrMore(term) rhs2 = equal + zero equation = StringStart() + OneOrMore(term) \ + Optional(rhs1 | rhs2) + StringEnd() ## term.setDebug() return equation
def _define_grammar(): """ Creates and returns a copy of the selector grammar. Wrapped in a function to avoid polluting the module namespace. """ expr = Forward() label_name = Word(LABEL_CHARS) label_name.setParseAction(LabelNode) string_literal = QuotedString('"') | QuotedString("'") string_literal.setParseAction(LiteralNode) set_literal = (Suppress("{") + delimitedList(QuotedString('"') | QuotedString("'"), ",") + Suppress("}")) set_literal.setParseAction(SetLiteralNode) eq_comparison = label_name + Suppress("==") + string_literal eq_comparison.setParseAction(LabelToLiteralEqualityNode) not_eq_comparison = label_name + Suppress("!=") + string_literal not_eq_comparison.setParseAction(InequalityNode) in_comparison = label_name + Suppress(Keyword("in")) + set_literal in_comparison.setParseAction(LabelInSetLiteralNode) not_in = Suppress(Keyword("not") + Keyword("in")) not_in_comparison = label_name + not_in + set_literal not_in_comparison.setParseAction(NotInNode) has_check = (Suppress("has(") + Word(LABEL_CHARS) + Suppress(")")) has_check.setParseAction(HasNode) # For completeness, we allow an all() to occur in an expression like # "! all()". Note: we special-case the trivial selectors "" and # "all()" below for efficiency. all_op = (Suppress("all()")) all_op.setParseAction(AllNode) comparison = (eq_comparison | not_eq_comparison | in_comparison | not_in_comparison | has_check | all_op) paren_expr = (Suppress("(") + expr + Suppress(")")) value = ZeroOrMore("!") + (comparison | paren_expr) value.setParseAction(simplify_negation_node) and_expr = value + ZeroOrMore(Suppress("&&") + value) and_expr.setParseAction(simplify_and_node) or_expr = and_expr + ZeroOrMore(Suppress("||") + and_expr) or_expr.setParseAction(simplify_or_node) expr << or_expr grammar = expr + StringEnd() return grammar