예제 #1
0
from parsy import string, decimal_digit, generate, char_from

from math import prod

number = decimal_digit.at_least(1).concat().map(int)
operator = string('*') | string('+')
lparen = string('(')
rparen = string(')')
eol = string('\n')
space = string(' ')


@generate
def calc_num():
    next_val = yield lparen | number
    if next_val == '(':
        # do not return since (5 + 3) * 4  -> after getting 5 + 3, still possible to have a * 4 after
        lnum = yield calc_num
    else:
        lnum = next_val
    space_or_end = yield space | char_from(
        ')\n')  # number is definitely there, but operator may not be there
    if space_or_end in ')\n':
        return [lnum]
    else:
        op = yield operator
        yield space
        rnum = yield calc_num
        return [lnum, op] + rnum

예제 #2
0
 def test_decimal_digit(self):
     self.assertEqual(decimal_digit.at_least(1).concat().parse("9876543210"),
                      "9876543210")
     self.assertRaises(ParseError, decimal_digit.parse, "¹")
예제 #3
0
from basic import Sym, WS, Punc
from parsy import alt, decimal_digit, regex, seq, string

def make_number(sign, int_part, frac_part):
    result = float(int_part + '.' + frac_part) if frac_part else int(int_part)
    return result * -1 if sign else result

number_literal = seq(string('-').optional(), decimal_digit.at_least(1).concat(), string('.').then(decimal_digit.at_least(1).concat()).optional()).combine(make_number)

string_literal = string('"') >> regex(r'[^"]*') << string('"')

operator = regex(r'[]+*^/.\\@d_:!-]').map(Sym)

func = regex(r'sin|cos|tan|asin|acos|atan|deg|rad|pi|e|ln|log').map(Sym)

variable = regex(r'[A-Z]').map(Sym)

punc = regex(r'[\[]').map(Punc)

whitespace = string(' ').at_least(1).map(WS)

stacky_parser = alt(number_literal, operator, punc, func, variable, whitespace).many()
예제 #4
0
from datetime import datetime
from typing import Callable, List, Optional, Tuple

from .core import Model
from parsy import (
    Parser,
    any_char,
    decimal_digit,
    generate,
    letter,
    seq,
    string,
    whitespace,
)

some_digits = decimal_digit.at_least(1).concat()

integer = some_digits.map(int).desc("integer")

floating = ((some_digits + string(".") +
             some_digits).map(float).desc("floating-point number"))

newline = string("\n")

dash = string("-")


def line_with(p: Parser) -> Parser:
    return whitespace.optional() >> p << newline