<commit_before>from parsy import *

match_one = lambda i1: item_matcher(lambda i2: i1 == i2)

def lexer(code):
    whitespace = regex(r'\s*')
    integer = digit.at_least(1).map(''.join).map(int)
    float_ = (
        digit.many() + string('.').result(['.']) + digit.many()
        ).map(''.join).map(float)
    parser = whitespace >> ((
        integer | float_ | regex(r'[()*/+-]')
        ) << whitespace).many()
    return parser.parse(code)

def syntactic_analysis(tokens):
    lparen = match_one('(')
    rparen = match_one(')')

    @generate
    def additive():
        res = yield multiplicative
        sign = match_one('+') | match_one('-')
        while True:
            operation = yield sign|success('')
            if not operation:
                break
            operand = yield multiplicative
            if operation == '+':
                res += operand
            elif operation == '-':
                res -= operand
        return res

    @generate
    def multiplicative():
        res = yield simple
        sign = match_one('*') | match_one('/')
        while True:
            operation = yield sign|success('')
            if not operation:
                break
            operand = yield simple
            if operation == '*':
                res *= operand
            elif operation == '/':
                res /= operand
        return res

    @generate
    def number():
        sign = yield match_one('+') | match_one('-') | success('+')
        value = yield item_matcher(
            lambda x: isinstance(x, (int, float)), 'number')
        return value if sign == '+' else -value

    expr = additive
    simple = (lparen >> expr << rparen) | number

    return expr.parse(tokens)

def simple_eval(expr):
    return syntactic_analysis(lexer(expr))

if __name__ == '__main__':
    print(simple_eval(input()))<commit_msg>Updated example code for modern parsy<commit_after>from parsy import digit, generate, regex, string, success, test_char

test_item = test_char

match_one = lambda i1: test_item(lambda i2: i1 == i2, str(i1))


def lexer(code):
    whitespace = regex(r'\s*')
    integer = digit.at_least(1).map(''.join).map(int)
    float_ = (
        digit.many() + string('.').result(['.']) + digit.many()
    ).map(''.join).map(float)
    parser = whitespace >> ((
        integer | float_ | regex(r'[()*/+-]')
    ) << whitespace).many()
    return parser.parse(code)


def syntactic_analysis(tokens):
    lparen = match_one('(')
    rparen = match_one(')')

    @generate
    def additive():
        res = yield multiplicative
        sign = match_one('+') | match_one('-')
        while True:
            operation = yield sign | success('')
            if not operation:
                break
            operand = yield multiplicative
            if operation == '+':
                res += operand
            elif operation == '-':
                res -= operand
        return res

    @generate
    def multiplicative():
        res = yield simple
        op = match_one('*') | match_one('/')
        while True:
            operation = yield op | success('')
            if not operation:
                break
            operand = yield simple
            if operation == '*':
                res *= operand
            elif operation == '/':
                res /= operand
        return res

    @generate
    def number():
        sign = yield match_one('+') | match_one('-') | success('+')
        value = yield test_item(
            lambda x: isinstance(x, (int, float)), 'number')
        return value if sign == '+' else -value

    expr = additive
    simple = (lparen >> expr << rparen) | number

    return expr.parse(tokens)


def simple_eval(expr):
    return syntactic_analysis(lexer(expr))


if __name__ == '__main__':
    print(simple_eval(input()))
{'fraction_non_alphanumeric': 0.14102898929224342, 'fraction_numerical': 0.002872812744841995, 'mean_word_length': 1.937116564417178, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3675025', 'n_tokens_mistral': 1113, 'n_tokens_neox': 1084, 'n_words': 289}