def __init__(self, grammar, ruleName, callback=None, globals=None): self.grammar = grammar self.position = 0 self.callback = callback self.globals = globals or {} self.rules = decomposeGrammar(grammar) self.next = self.apply(ruleName, None, ()) self._localsStack = [] self.currentResult = None self.input = InputStream([], 0) self.ended = False
v, err = self._eval(run, args[1]) self._localsStack[-1][args[0].data] = v return v, err elif name == "Predicate": val, err = self._eval(run, args[0]) if not val: raise err else: return True, err elif name == "List": v, e = run.rule_anything() oldInput = run.input try: run.input = InputStream.fromIterable(v) except TypeError: raise e.withMessage(expected("an iterable")) self._eval(run, args[0]) run.end() run.input = oldInput return v, e elif name in ("Action", "Python"): lo = self._localsStack[-1] val = eval(args[0].data, self._globals, lo) return (val, run.input.nullError()) elif name == "ConsumedBy": oldInput = run.input _, err = self._eval(run, args[0])
def _eval(self, run, expr): name = expr.tag.name args = expr.args if name == "Apply": ruleName = args[0].data return self._apply(run, ruleName, args[2].args) elif name == "Exactly": return run.exactly(args[0].data) elif name == "Label": label = args[1].data try: val, err = self._eval(run, args[0]) return val, err.withMessage([("Custom Exception:", label, None)]) except ParseError as err: e=err raise e.withMessage([("Custom Exception:", label, None)]) elif name == "Token": if run.tree: return run._apply(run.rule_exactly, "exactly", [args[0].data]) else: return run._apply(run.rule_token, "token", [args[0].data]) elif name in ("Many", "Many1"): ans = [self._eval(run, args[0])[0]] if name == "Many1" else [] err = None while True: try: m = run.input v, _ = self._eval(run, args[0]) ans.append(v) except ParseError as e: err = e run.input = m break return ans, err elif name == "Repeat": if args[0].tag.name == '.int.': min = args[0].data else: min = self._localsStack[-1][args[0].data] if args[1].tag.name == '.int.': max = args[1].data elif args[1].tag.name == 'null': max = None else: max = self._localsStack[-1][args[1].data] if min == max == 0: return "", None ans = [] e = None for i in range(min): v, e = self._eval(run, args[2]) ans.append(v) for i in range(min, max): try: m = run.input v, e = self._eval(run, args[2]) ans.append(v) except ParseError as err: e = err run.input = m break return ans, e elif name == "Optional": i = run.input try: return self._eval(run, args[0]) except ParseError: run.input = i return (None, run.input.nullError()) elif name == "Or": errors = [] for e in args[0].args: try: m = run.input x = self._eval(run, e) ret, err = x errors.append(err) return ret, joinErrors(errors) except ParseError as err: errors.append(err) run.input = m raise joinErrors(errors) elif name == "Not": m = run.input try: self._eval(run, args[0]) except ParseError as err: run.input = m return True, run.input.nullError() else: raise run.input.nullError() elif name == "Lookahead": try: m = run.input return self._eval(run, args[0]) finally: run.input = m elif name == "And": v = None, run.input.nullError() for e in args[0].args: v = self._eval(run, e) return v elif name == "Bind": v, err = self._eval(run, args[1]) if args[0].data: self._localsStack[-1][args[0].data] = v else: for n, val in zip(args[0].args, v): self._localsStack[-1][n.data] = val return v, err elif name == "Predicate": val, err = self._eval(run, args[0]) if not val: raise err else: return True, err elif name == "List": v, e = run.rule_anything() oldInput = run.input try: run.input = InputStream.fromIterable(v) except TypeError: raise e.withMessage(expected("an iterable")) self._eval(run, args[0]) run.end() run.input = oldInput return v, e elif name in ("Action", "Python"): lo = self._localsStack[-1] val = eval(args[0].data, self._globals, lo) return (val, run.input.nullError()) elif name == "ConsumedBy": oldInput = run.input _, err = self._eval(run, args[0]) slice = oldInput.data[oldInput.position:run.input.position] return slice, err else: raise ValueError("Unrecognized term: %r" % (name,))
def makeTokenStream(text, origin="<string>"): lexer = MonteLexer(StringFeeder(text, origin)) toks = [tok for tok in lexer if tok.tag.name != '#' and tok.tag.name != 'UPDOC'] return InputStream.fromIterable(toks)
def _eval(self, run, expr): name = expr.tag.name args = expr.args if name == "Apply": ruleName = args[0].data return self._apply(run, ruleName, args[2].args) elif name == "Exactly": return run.exactly(args[0].data) elif name == "Label": label = args[1].data try: val, err = self._eval(run, args[0]) return val, err.withMessage([("Custom Exception:", label, None) ]) except ParseError as err: e = err raise e.withMessage([("Custom Exception:", label, None)]) elif name == "Token": if run.tree: return run._apply(run.rule_exactly, "exactly", [args[0].data]) else: return run._apply(run.rule_token, "token", [args[0].data]) elif name in ("Many", "Many1"): ans = [self._eval(run, args[0])[0]] if name == "Many1" else [] err = None while True: try: m = run.input v, _ = self._eval(run, args[0]) ans.append(v) except ParseError as e: err = e run.input = m break return ans, err elif name == "Repeat": if args[0].tag.name == '.int.': min = args[0].data else: min = self._localsStack[-1][args[0].data] if args[1].tag.name == '.int.': max = args[1].data elif args[1].tag.name == 'null': max = None else: max = self._localsStack[-1][args[1].data] if min == max == 0: return "", None ans = [] e = None for i in range(min): v, e = self._eval(run, args[2]) ans.append(v) for i in range(min, max): try: m = run.input v, e = self._eval(run, args[2]) ans.append(v) except ParseError as err: e = err run.input = m break return ans, e elif name == "Optional": i = run.input try: return self._eval(run, args[0]) except ParseError: run.input = i return (None, run.input.nullError()) elif name == "Or": errors = [] for e in args[0].args: try: m = run.input x = self._eval(run, e) ret, err = x errors.append(err) return ret, joinErrors(errors) except ParseError as err: errors.append(err) run.input = m raise joinErrors(errors) elif name == "Not": m = run.input try: self._eval(run, args[0]) except ParseError as err: run.input = m return True, run.input.nullError() else: raise run.input.nullError() elif name == "Lookahead": try: m = run.input return self._eval(run, args[0]) finally: run.input = m elif name == "And": v = None, run.input.nullError() for e in args[0].args: v = self._eval(run, e) return v elif name == "Bind": v, err = self._eval(run, args[1]) if args[0].data: self._localsStack[-1][args[0].data] = v else: for n, val in zip(args[0].args, v): self._localsStack[-1][n.data] = val return v, err elif name == "Predicate": val, err = self._eval(run, args[0]) if not val: raise err else: return True, err elif name == "List": v, e = run.rule_anything() oldInput = run.input try: run.input = InputStream.fromIterable(v) except TypeError: raise e.withMessage(expected("an iterable")) self._eval(run, args[0]) run.end() run.input = oldInput return v, e elif name in ("Action", "Python"): lo = self._localsStack[-1] val = eval(args[0].data, self._globals, lo) return (val, run.input.nullError()) elif name == "ConsumedBy": oldInput = run.input _, err = self._eval(run, args[0]) slice = oldInput.data[oldInput.position:run.input.position] return slice, err else: raise ValueError("Unrecognized term: %r" % (name, ))