def _create_parser(self): def xo_yo(fo1, fo2): if not fo1: return fo2 return fo1[1](fo1[0], fo2[0]), fo2[1] def xo_x(fo1, fo2): if not fo1: return fo2 return fo1[1](fo1[0], fo2) fnumber = Regex( re.compile(r"[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?")).value(float) plus, minus, mult, div = map(Terminal, '+-*/') addop = (plus | minus).value(lambda o: self._opn[o]) multop = (mult | div).value(lambda o: self._opn[o]) expr = Forward() sub_expr = Terminal('(').then(expr).skip(')') factor = Terminal('-').repeat(0, 1).then(fnumber | sub_expr, lambda x, y: -y if x else y) term = factor.then(multop, lambda f, o: (f, o)).repeat(0, None, xo_yo).then(factor, xo_x) expr.is_( term.then(addop, lambda f, o: (f, o)).repeat(0, None, xo_yo).then(term, xo_x)) self.parser = expr
def setUp(self): # Translated from https://github.com/gvanrossum/pegen/blob/ec2b354f64f6dbfcb46133757fe4c0e07880f526/test/test_pegen.py#L232 ident = Alpha + Alnum.repeat() atom = (ident.value(lambda v: ast.Name(id=v, ctx=ast.Load())) | Digit.repeat(1).value( lambda v: ast.Constant(value=ast.literal_eval(v)))) expr = Forward() factor = (Terminal('(').then(expr).skip(')') | atom) term = Forward() term.is_( term.skip('*').then( factor, lambda l, r: ast.BinOp(l, ast.Mult(), r)) ^ term.skip( '/').then(factor, lambda l, r: ast.BinOp(l, ast.Div(), r)) ^ factor) expr.is_( expr.skip('+').then(term, lambda l, r: ast.BinOp(l, ast.Add(), r)) ^ expr.skip('-').then( term, lambda l, r: ast.BinOp(l, ast.Sub(), r)) ^ term) start = expr.skip(Terminal('\n').repeat(0, 1)).filter( lambda r: not r.remain).value(lambda v: ast.fix_missing_locations( ast.Expression(v, lineno=1, col_offset=0))) self.parser = start