Esempio n. 1
0
class FormatTextParsers(TextParsers, whitespace=None):
    integer = reg(r'[0-9]+') > int
    dense = lit('d') > constant(Mode.dense)
    compressed = lit('s') > constant(Mode.compressed)
    mode = dense | compressed

    # Use eof to ensure each parser goes to end
    format_without_orderings = rep(mode) << eof > (
        lambda modes: Format(tuple(modes), tuple(range(len(modes)))))
    format_with_orderings = rep(mode
                                & integer) << eof > make_format_with_orderings

    format = format_without_orderings | format_with_orderings
Esempio n. 2
0
File: day18.py Progetto: knkski/aoc
class Homework(TextParsers):
    number = reg(r"\d+") > int
    plus = lit("+") > constant(add)
    times = lit("*") > constant(mul)
    operator = plus | times

    # No precedence
    base = "(" >> unprecedented << ")" | number
    unprecedented = base & rep(operator & base) > reduce

    # Addition first, then multiplication
    base = "(" >> multiplication << ")" | number
    addition = base & rep(plus & base) > reduce
    multiplication = addition & rep(times & addition) > reduce
Esempio n. 3
0
class JsonParsers(TextParsers, whitespace=r'[ \t\n\r]*'):
    number = reg(r'-?(0|[1-9][0-9]*)(\.[0-9]+)?([eE][-+]?[0-9]+)?')

    false = lit('false')
    true = lit('true')
    null = lit('null')

    string = JsonStringParsers.string

    array = '[' >> repsep(value, ',') << ']'

    entry = string << ':' & value
    obj = '{' >> repsep(entry, ',') << '}'

    value = (number
             | false
             | true
             | null
             | string
             | array
             | obj)
Esempio n. 4
0
class JsonStringParsers(TextParsers, whitespace=None):
    quote = lit(r'\"')
    reverse_solidus = lit(r'\\')
    solidus = lit(r'\/')
    backspace = lit(r'\b')
    form_feed = lit(r'\f')
    line_feed = lit(r'\n')
    carriage_return = lit(r'\r')
    tab = lit(r'\t')
    uni = reg(r'\\u([0-9a-fA-F]{4})')

    escaped = (quote | reverse_solidus | solidus | backspace | form_feed |
               line_feed | carriage_return | tab | uni)
    unescaped = reg(r'[\u0020-\u0021\u0023-\u005B\u005D-\U0010FFFF]+')

    string = '"' >> rep(escaped | unescaped) << '"' > ''.join
Esempio n. 5
0
class TensorExpressionParsers(TextParsers):
    name = reg(r'[A-Za-z][A-Za-z0-9]*')

    # taco does not support negatives or exponents
    floating_point = reg(r'[0-9]+\.[0-9]+') > (lambda x: Float(float(x)))
    integer = reg(r'[0-9]+') > (lambda x: Integer(int(x)))
    number = floating_point | integer

    # taco requires at least one index; scalar tensors are not parsed as `a()`
    # taco also allows for `y_{i}` and `y_i` to mean `y(i)`, but that is not supported here
    tensor = name & '(' >> rep1sep(name, ',') << ')' > splat(Tensor)
    scalar = name > Scalar
    variable = tensor | scalar

    parentheses = '(' >> expression << ')'  # noqa: F821
    factor = variable | number | parentheses

    term = rep1sep(factor, '*') > (lambda x: reduce(Multiply, x))
    expression = term & rep(lit('+', '-') & term) > splat(make_expression)

    simple_assignment = variable & '=' >> expression > splat(Assignment)
    add_assignment = variable & '+=' >> expression > splat(lambda v, e: Assignment(v, Add(v, e)))

    assignment = simple_assignment | add_assignment
Esempio n. 6
0
class ProgramParser(TextParsers):

    # Actual grammar
    split1 = lambda item, separator: item & rep(separator & item)
    split = lambda item, separator: opt(split1(item, separator))

    identifier = reg(r"[a-zA-Z]\w*")

    string = reg(r'".*?(?<!\\)(\\\\)*?"') | reg(r"'.*?(?<!\\)(\\\\)*?'") > (
        lambda s: TokenString(s[1:-1])
    )

    num_int = reg(r"\d+") > int
    num_float = reg(r"(\d*\.\d+|\d+\.\d*)") > float
    num_positive = num_float | num_int
    num_negative = "-" >> num > (lambda x: -x)
    num = num_negative | num_positive
    number = num > TokenNumber

    op_eq = lit("==") > constant(Operator.EQ)
    op_ne = lit("!=") > constant(Operator.NE)
    op_ge = lit(">=") > constant(Operator.GE)
    op_gt = lit(">") > constant(Operator.GT)
    op_le = lit("<=") > constant(Operator.LE)
    op_lt = lit("<") > constant(Operator.LT)
    op_and = lit("&") > constant(Operator.AND)
    op_or = lit("|") > constant(Operator.OR)
    op_add = lit("+") > constant(Operator.ADD)
    op_sub = lit("-") > constant(Operator.SUB)
    op_mul = lit("*") > constant(Operator.MUL)
    op_div = lit("/") > constant(Operator.DIV)
    op_pow = lit("^") > constant(Operator.POW)
    op_not = lit("!") > constant(Operator.NOT)
    op_neg = lit("-") > constant(Operator.NEG)

    equality_op = op_eq | op_ne
    comparison_op = op_ge | op_gt | op_le | op_lt
    logic_op = op_and | op_or
    term_op = op_add | op_sub
    factor_op = op_mul | op_div
    power_op = op_pow
    unary_op = op_neg | op_not

    case_pair = expr << "->" & expr

    assignment = identifier << "=" & expr
    let_stmt = "^" >> rep1sep(assignment, ";") << "$" & expr > let

    anon_func = (lit("\\") | lit("\\\\")) >> rep1(identifier) & "->" >> expr > anon

    variable = identifier > TokenVariable

    expr = rep1sep(equality, reg(r"\s*")) > maybe_application
    equality = split1(comparison, equality_op) > bin_operator
    comparison = split1(logic, comparison_op) > bin_operator
    logic = split1(term, logic_op) > bin_operator
    term = split1(factor, term_op) > bin_operator
    factor = split1(power, factor_op) > bin_operator
    power = split1(ternary, power_op) > bin_operator_right
    ternary = case & opt("?" >> expr << ":" & expr) > maybe_ternary
    case = dice & opt(lit("$") >> "(" >> rep1sep(case_pair, ";") << ")") > maybe_case
    dice = unary & opt("d" >> unary) > maybe_dice
    unary = unary_op & unary | primary > mon_operator
    primary = number | string | bracketed | let_stmt | anon_func | variable
    bracketed = "(" >> expr << ")"

    func = identifier & "=" >> expr > function

    program = repsep("@" >> func | expr, ";") << opt(";") > Program

    main = program
Esempio n. 7
0
class DiceParser(TextParsers):

    split1 = lambda item, separator: item & rep(separator & item)
    split = lambda item, separator: opt(split1(item, separator))

    comment = "/*" >> expr << "*/" > constant(None)

    string = reg(r'".*?(?<!\\)(\\\\)*?"') > (lambda s: ValueString(s[1:-1]))

    num_int = reg(r"\d+") > int
    num_float = reg(r"(\d*\.\d+|\d+\.\d*)") > float
    num_positive = num_float | num_int
    num_negative = "-" >> num > (lambda x: -x)
    num = num_negative | num_positive
    number = num > ValueNumber

    # set = "(" >> repsep(expr, ",") << ")" > ValueSet

    op_eq = lit("==") > constant(Operator.EQ)
    op_ne = lit("!=") > constant(Operator.NE)
    op_ge = lit(">=") > constant(Operator.GE)
    op_gt = lit(">") > constant(Operator.GT)
    op_le = lit("<=") > constant(Operator.LE)
    op_lt = lit("<") > constant(Operator.LT)
    op_and = lit("&") > constant(Operator.AND)
    op_or = lit("|") > constant(Operator.OR)
    op_add = lit("+") > constant(Operator.ADD)
    op_sub = lit("-") > constant(Operator.SUB)
    op_mul = lit("*") > constant(Operator.MUL)
    op_div = lit("/") > constant(Operator.DIV)
    op_pow = lit("^") > constant(Operator.POW)
    op_not = lit("!") > constant(Operator.NOT)
    op_neg = lit("-") > constant(Operator.NEG)

    equality_op = op_eq | op_ne
    comparison_op = op_ge | op_gt | op_le | op_lt
    logic_op = op_and | op_or
    term_op = op_add | op_sub
    factor_op = op_mul | op_div
    power_op = op_pow
    unary_op = op_neg | op_not

    case_pair = expr << "," & expr

    program = repsep(expr, ";") > Program
    expr = equality
    equality = split1(comparison, equality_op) > bin_operator
    comparison = split1(logic, comparison_op) > bin_operator
    logic = split1(term, logic_op) > bin_operator
    term = split1(factor, term_op) > bin_operator
    factor = split1(power, factor_op) > bin_operator
    power = split1(dice, power_op) > bin_operator_right
    dice = opt(opt(ternary) << "d") & ternary > maybe_dice
    ternary = case & opt("?" >> expr << ":" & expr) > maybe_ternary
    case = unary & opt(
        lit(":") >> "(" >> repsep(case_pair, ";") << ")") > maybe_case
    unary = unary_op & unary | primary > mon_operator
    primary = number | string | bracketed
    bracketed = "(" >> expr << ")"

    parse_all = program
Esempio n. 8
0
class ModelParsers(TextParsers, whitespace=r'[ \t]*'):
    number = reg(r'[+-]?\d+(\.\d+)?([Ee][+-]?\d+)?') > float
    name = reg(r'[A-Za-z_][A-Za-z_0-9]*')
    symbol = name > sy.Symbol

    def make_function(x):
        func_name, arguments = x
        if func_name in sy.functions.__dict__:
            func_handle = sy.__dict__[func_name]
        else:
            raise ValueError(f'Function "{func_name}" not found. Only functions in sympy.* may be used.')
        return func_handle(*arguments)

    function = name & '(' >> repsep(expression, ',') << ')' > make_function

    factor = number | function | symbol | '(' >> expression << ')'

    def make_exponent(x):
        x = list(reversed(x))  # Exponentiation is right associative so reverse the list
        value = x[0]
        rest = x[1:]
        for item in rest:
            value = sy.Pow(item, value)
        return value

    exponent = rep1sep(factor, '^') > make_exponent

    def make_term(x):
        first, rest = x
        value = first
        for op, exponent in rest:
            if op == '/':
                exponent = sy.Pow(exponent, -1)  # This is how sympy handles divide
            value = sy.Mul(value, exponent)
        return value

    term = exponent & rep(lit('*', '/') & exponent) > make_term

    def make_unary_term(x):
        ops, value = x
        for op in ops:
            if op == '-':
                value = -value
        return value

    unary_term = rep(lit('+', '-')) & term > make_unary_term

    def make_expression(x):
        first, rest = x
        value = first
        for op, term in rest:
            if op == '-':
                term = sy.Mul(-1, term)  # This is how sympy handles minus
            value = sy.Add(value, term)
        return value

    expression = unary_term & rep(lit('+', '-') & unary_term) > make_expression

    def make_one_sided_time_constant(x):
        direction, time = x
        if direction == '<':
            return -inf, time
        else:
            return time, inf

    one_sided_time = '(' >> lit('t') >> lit('<', '>') & number << ')' > make_one_sided_time_constant

    two_sided_time = '(' >> number << '<' << 't' << '<' & number << ')'

    time_range = one_sided_time | two_sided_time

    def make_constant(x):
        name, op, value = x
        if op == '+=':
            additive = True
        else:
            additive = False
        return name, Constant(name, value, additive)

    constant = name & lit('=', '+=') & number > make_constant

    def make_rule(x):
        name, domain, op, expr = x
        if not domain:
            first = -inf
            last = inf
        else:
            first, last = domain[0]
        if op == '+=':
            additive = True
        else:
            additive = False
        return name, Rule(name, AnalyticSegment(first, last, expr), additive)

    rule = name & opt(time_range) & lit('=', '+=') & expression > make_rule

    def make_initial(x):
        name, op, value = x
        if op == '+=':
            additive = True
        else:
            additive = False
        return name, Initial(value, additive)

    initial = name << '*' & lit('=', '+=') & expression > make_initial

    def make_ode(x):
        name, domain, op, expr = x
        if not domain:
            first = -inf
            last = inf
        else:
            first, last = domain[0]
        if op == '+=':
            additive = True
        else:
            additive = False
        return name, Ode(AnalyticSegment(first, last, expr), additive)

    ode = name << "'" & opt(time_range) & lit('=', '+=') & expression > make_ode

    def make_dose(x):
        name, time, op, value = x
        if op == '+=':
            value += sy.Symbol(name)
        return name, Dose(time, value)

    dose = name << "(" & number << ")" & lit('=', '+=') & expression > make_dose

    def make_effect(x):
        name, op, value = x
        if op == '+=':
            value += sy.Symbol(name)
        return Effect(name, value)

    effect = name & lit('=', '+=') & expression > make_effect

    def make_event(x):
        left, direction, right, effects = x
        trigger = left - right
        if direction == '<':
            effect_direction = EventDirection.down
        else:
            effect_direction = EventDirection.up
        return Event(trigger, effect_direction, True, effects)

    event = lit('@') >> '(' >> expression & lit('<', '>') & expression << ")" & rep1sep(effect, ',') > make_event

    component = constant | rule | initial | ode | dose | event

    eol = reg(r'(((#.*)?\n)+)|(((#.*)?\n)*(#.*)?\Z)')
    options_section = '%' >> lit('options') >> eol >> rep(failure('not implemented') << eol)
    components_section = '%' >> lit('components') >> eol >> rep(component << eol)

    def make_model(x):
        maybe_options, components = x

        if maybe_options:
            raise NotImplementedError

        parts, events = collapse_components(components)

        new_model = Model(parts, events)
        return new_model

    model = opt(options_section) & components_section > make_model