예제 #1
0
    def _create_parser() -> ParserElement:
        # operators in the format later used by infixNotation
        operator_list = [
            (None, 2, opAssoc.LEFT, BooleanAndOperation._create_from_implicit_tokens),
            (CaselessKeyword('not') | "~" | "!", 1, opAssoc.RIGHT, BooleanNotOperation._create_from_tokens),
            (CaselessKeyword('and') | "&", 2, opAssoc.LEFT, BooleanAndOperation._create_from_tokens),
            (CaselessKeyword('xor') | "^", 2, opAssoc.LEFT, BooleanXorOperation._create_from_tokens),
            (CaselessKeyword('or') | "|", 2, opAssoc.LEFT, BooleanOrOperation._create_from_tokens),
        ]

        # terms (atoms) that will be combined with the boolean operators
        term_list = [
            (CaselessKeyword('tag'), TagFilterTerm._create_from_tokens),
            (CaselessKeyword('ingr'), IngredientFilterTerm._create_from_tokens),
            (CaselessKeyword('unit'), UnitFilterTerm._create_from_tokens),
            (None, AnyFilterTerm._create_from_tokens),
        ]

        # extract keywords that can
        operator_expressions = [om[0] for om in operator_list if om[0] is not None]
        term_expressions = [tm[0] for tm in term_list if tm[0] is not None]
        reserved_expressions = operator_expressions + term_expressions

        # quoted string indicates exact macthc
        quoted_filter_string = (QuotedString('"', escChar='\\') | QuotedString("'", escChar='\\')).setResultsName('string')
        # quoted_filter_string.setDebug(True)
        quoted_filter_string.setName("quoted_filter_string")
        quoted_filter_string.setParseAction(ExactFilterString._create_from_tokens)

        # not quoted string is inexact match, can't contain whitespace or be an operator
        unquoted_filter_string = ~MatchFirst(reserved_expressions) + Regex(r'[^\s\(\)]+', flags=re.U).setResultsName('string')
        # unquoted_filter_string.setDebug(True)
        unquoted_filter_string.setName("unquoted_filter_string")
        unquoted_filter_string.setParseAction(FuzzyFilterString._create_from_tokens)

        # regular expressions aren't parsed in the grammar but delegated to python re.compile in the parser action
        regex_filter_string = QuotedString('/', escChar='\\')
        regex_filter_string.setName("regex_filter_string")
        regex_filter_string.setParseAction(RegexFilterString._create_from_tokens)

        # unquoted_filter_string must be last, so that initial quotes are handled correctly
        filter_string = regex_filter_string | quoted_filter_string | unquoted_filter_string
        filter_string.setParseAction(lambda toks: toks[0])

        filter_terms = []
        for prefix_expression, term_action in term_list:
            if prefix_expression is not None:
                filter_term = Combine(prefix_expression + ':' + filter_string.setResultsName("filter_string"))
                filter_term.setName("filter_term_"+str(prefix_expression.match))
            else:
                filter_term = filter_string.setResultsName("filter_string")
                filter_term.setName("filter_term_None")
            # filter_term.setDebug(True)
            filter_term.addParseAction(term_action)
            filter_terms.append(filter_term)
        filter_term = MatchFirst(filter_terms)
        filter_expr = infixNotation(filter_term, operator_list)

        return filter_expr
예제 #2
0
파일: assembler.py 프로젝트: skaven81/mycpu
labeloffset.setName('labeloffset')
# Bytes can be represented in binary, hex, char, or a number (0-255 or -128-127)
# and may include embedded arithmetic
#  OPCODE 0b00001100
#  OPCODE 0x0b
#  OPCODE 'a'
#  OPCODE 254-0x0a
#  OPCODE 'a'&0b00001111
binbyte = Combine(Literal('0b') + Char('01') * 8)
binbyte.setName('binbyte')
binbyte.setParseAction(lambda t: [int(t[0], 2)])
hexbyte = Combine(Literal('0x') + Char(srange("[0-9a-fA-F]")) * 2)
hexbyte.setName('hexbyte')
hexbyte.setParseAction(lambda t: [int(t[0], 16)])
chrbyte = QuotedString(quoteChar="'", unquoteResults=True)
chrbyte.setName('char')
chrbyte.setParseAction(lambda t: [ord(t[0])])
number = Word(nums + '-')
number.setName('number')
number.setParseAction(lambda t: [int(t[0])])
allbytes = binbyte | hexbyte | chrbyte | number
mathtoken = Combine(oneOf('+ - & |') + allbytes)
bytemathexpression = Combine(allbytes + OneOrMore(mathtoken))
bytemathexpression.setParseAction(lambda t: [eval(t[0])])
byte = bytemathexpression | allbytes
byte.setName('byte')
# Words can be represented in binary, hex, label, or number (0-65535 or -32768-32767)
#  OPCODE 0b0000111100001111
#  OPCODE 0x2911
#  OPCODE .label
#  OPCODE .label+4