def matrix_parser(): cell = many1(digit()).parsecmap(''.join).parsecmap(int) height = yield cell yield (string(",") << spaces()) width = yield cell yield string('\n') row = separated(cell, string(",") << spaces(), mint=width, maxt=width) rows = separated(row, string('\n'), mint=height, maxt=height) return rows
def ratio(): [num, den] = yield (separated(number, string("/"), 2, maxt=2, end=False) | na.result([0, 0])) if den: return num / den else: return None
def parser_by_count(value): try: num_cells = int(value) return separated(cell, string(",") << spaces(), mint=num_cells, maxt=num_cells) except ValueError: return Parser( lambda index, text: Value.failure(index, "expected a number"))
parse_meta = parsec.spaces().parsecmap(lambda _: CodeGenKind('meta')) parse_plain = (parsec.spaces() >> (name_pattern + star_pattern) << parsec.spaces() ).parsecmap(lambda value: CodeGenKind('plain', value)) parse_list = (parsec.string('[') >> (name_pattern + star_pattern) << parsec.string(']') ).parsecmap(lambda value: CodeGenKind('list', value)) parse_dlist = (parsec.string('[[') >> (name_pattern + star_pattern) << parsec.string(']]') ).parsecmap(lambda value: CodeGenKind('dlist', value)) parse_set = (parsec.string('{') >> (name_pattern + star_pattern) << parsec.string('}') ).parsecmap(lambda value: CodeGenKind('set', value)) parse_dict = (parsec.string('{') >> parsec.separated( (name_pattern + star_pattern), parsec.string(':'), 2, 2) << parsec.string('}') ).parsecmap(lambda values: CodeGenKind('dict', tuple(values))) codegen_spec_parser = parse_dict ^ parse_set ^ parse_dlist ^ parse_list ^ parse_plain ^ parse_meta def parse_codegen_spec(kind): if kind.startswith('vineyard'): kind = kind[len('vineyard'):] if kind.startswith('codegen'): kind = kind[len('codegen'):] if kind.startswith(':'): kind = kind[1:] return codegen_spec_parser.parse(kind)
return '[reg %s]' % self.reg class Computer: def __init__(self, program, registers): self.program = program self.registers = registers self.ip = 0 def run_program(self): while self.ip < len(self.program): self.program[self.ip].apply(self) self.ip = self.ip + 1 parse_value = parsec.choice(parsec.letter().parsecmap(Register), parsec.regex(r'-?\d+').parsecmap(int).parsecmap(Literal)) parse_args = parsec.separated(parse_value, parsec.space(), 1, maxt=2) instructions = {'cpy': Cpy, 'inc': Inc, 'dec': Dec, 'jnz': Jnz} parse_instr = reduce(parsec.choice, [parsec.string(k).result(v) for (k, v) in instructions.items()]) def apply_args(ctor): return (parsec.space() .compose(parse_args.parsecmap(lambda args: ctor(*args)))) parse_line = parse_instr.bind(apply_args) def regex_parse(line): def arg(x): m = regex.match(r'-?\d+', x) if m: return Literal(int(x)) return Register(x)
def words(self, n=1): return psc.separated(self.word(), psc.spaces(), n, n, end=False).parsecmap(lambda x: ' '.join(x))