def visitContinue_statement(self, ctx: PlSqlParser.Continue_statementContext): ret = self.visitChildren(ctx) condition = None if not ctx.condition() else ret[0] if not condition: return ast.Continue() return ast.If(test=condition, body=[ast.Continue()], orelse=[])
def cStatementToPyAst(funcEnv, c): body = funcEnv.getBody() if isinstance(c, (CVarDecl, CFunc)): funcEnv.registerNewVar(c.name, c) elif isinstance(c, CStatement): a, t = astAndTypeForCStatement(funcEnv, c) if isinstance(a, ast.expr): a = ast.Expr(value=a) body.append(a) elif isinstance(c, CWhileStatement): body.append(astForCWhile(funcEnv, c)) elif isinstance(c, CForStatement): body.append(astForCFor(funcEnv, c)) elif isinstance(c, CDoStatement): body.append(astForCDoWhile(funcEnv, c)) elif isinstance(c, CIfStatement): body.append(astForCIf(funcEnv, c)) elif isinstance(c, CSwitchStatement): body.append(astForCSwitch(funcEnv, c)) elif isinstance(c, CReturnStatement): body.append(astForCReturn(funcEnv, c)) elif isinstance(c, CBreakStatement): body.append(ast.Break()) elif isinstance(c, CContinueStatement): body.append(ast.Continue()) elif isinstance(c, CCodeBlock): funcEnv.pushScope(body) cCodeToPyAstList(funcEnv, c.body) funcEnv.popScope() else: assert False, "cannot handle " + str(c)
def mutate(cls, node): """ Mutate break and continue statements 1. break to continue 2. continue to break """ if node not in config.visited_nodes: if node.__class__ is ast.Break: config.mutated = True original_node = deepcopy(node) parent = config.parent_dict[node] del config.parent_dict[node] node = ast.Continue() config.parent_dict[node] = parent config.node_pairs[node] = original_node config.current_mutated_node = node elif node.__class__ is ast.Continue: config.mutated = True original_node = deepcopy(node) parent = config.parent_dict[node] del config.parent_dict[node] node = ast.Break() config.parent_dict[node] = parent config.node_pairs[node] = original_node config.current_mutated_node = node return node
def to_node(self, stmt): if isinstance(stmt, Statement): return stmt.to_node() if stmt == 'pass': return ast.Pass() if stmt == 'break': return ast.Break() if stmt == 'continue': return ast.Continue()
def __init__(self, base_node): BaseMutator.__init__(self, base_node) self.original_node = base_node # TODO - This doesn't work - AST node needs replaced if base_node.__class__ is ast.Break: self.mutations.append( ast.Continue(lineno=base_node.lineno, col_offset=base_node.col_offset)) # TODO - This doesn't work - AST node needs replaced if base_node.__class__ is ast.Continue: self.mutations.append( ast.Break(lineno=base_node.lineno, col_offset=base_node.col_offset))
def test_simple_statements(self): # Simple statements can be put on a single line as long as the scope # has not changed. for body, expect in [ (ast.Expr(ast.Num(42)), '42'), (ast.Import([ast.alias('a', None)]), 'import a'), (ast.ImportFrom('b', [ast.alias('a', None)], 1), 'from .b import a'), (ast.Break(), 'break'), (ast.Continue(), 'continue'), (ast.Pass(), 'pass'), (ast.Assign([ast.Name('X', ast.Store())], ast.Num(42)), 'X=42'), (ast.Delete([ast.Name('X', ast.Del())]), 'del X'), (ast.Raise(None, None), 'raise'), (ast.Return(None), 'return'), (ast.AugAssign(ast.Name('X', ast.Store()), ast.Add(), ast.Num(42)), 'X+=42'), (ast.Assert(ast.Num(42), None), 'assert 42'), (ast.Global(['x']), 'global x'), (ast.Nonlocal(['x']), 'nonlocal x'), ]: if_simple = ast.If(ast.Num(42), [body], None) self.verify(if_simple, 'if 42:{}'.format(expect)) if_multiple_simples = ast.If(ast.Num(42), [ast.Pass(), ast.Pass()], None) self.verify(if_multiple_simples, 'if 42:pass;pass') inner_if = ast.If(ast.Num(6), [ast.Pass()], None) funky_if = ast.If(ast.Num(42), [ ast.Break(), ast.Continue(), inner_if, ast.Break(), ast.Continue() ], None) self.verify(funky_if, 'if 42:\n break;continue\n if 6:pass\n break;continue')
def statement_to_node(self, statement): if type(statement) is PrintStatement: node = self.print_to_node(statement) elif type(statement) is AssignmentStatement: node = self.assignment_to_node(statement) elif type(statement) is IfStatement: node = self.if_to_node(statement) elif type(statement) is WhileStatement: node = self.while_to_node(statement) elif type(statement) is BreakStatement: node = ast.Break() elif type(statement) is ContinueStatement: node = ast.Continue() else: raise return node
def _parse_jump_statement(self, env): """ <jump_statement> Parses the <jump_statement> language structure. jump_statement -> 'continue' ';' | 'break' ';' | 'return' ';' | 'return' logical_expression ';' """ if self._accept(lexer.Tag.CONTINUE): return ast.Continue() elif self._accept(lexer.Tag.BREAK): return ast.Break() elif self._accept(lexer.Tag.RETURN): exp = None if not self._check(';'): exp = self._parse_logical_expression(env) self._match(';') return ast.Return(exp)
def astForCDoWhile(funcEnv, stmnt): assert isinstance(stmnt, CDoStatement) assert isinstance(stmnt.whilePart, CWhileStatement) assert stmnt.whilePart.body is None assert len(stmnt.args) == 0 assert len(stmnt.whilePart.args) == 1 assert isinstance(stmnt.whilePart.args[0], CStatement) whileAst = ast.While(body=[], orelse=[], test=ast.Name(id="True", ctx=ast.Load())) funcEnv.pushScope(whileAst.body) if stmnt.body is not None: cCodeToPyAstList(funcEnv, stmnt.body) funcEnv.popScope() ifAst = ast.If(body=[ast.Continue()], orelse=[ast.Break()]) ifAst.test = getAstNode_valueFromObj( funcEnv.globalScope.stateStruct, *astAndTypeForCStatement(funcEnv, stmnt.whilePart.args[0])) whileAst.body.append(ifAst) return whileAst
def statement(self, is_global=False): if self.accept(';'): self.advance() return ast.EmptyStmt() elif self.accept('return'): return self.return_() elif self.accept('break'): self.advance() brk = ast.Break() self.expect(';') return brk elif self.accept('continue'): self.advance() cont = ast.Continue() self.expect(';') return cont elif self.accept('{'): return self.block() elif self.accept('for'): return self.for_() elif self.accept('while'): return self.while_() elif self.accept('if'): return self.if_() elif self.is_declaration(): declr = self.declaration() if (type(declr) == ast.Declaration and type(declr.typ) == ast.Function and self.accept('{')): return self.parse_function(declr) else: self.expect(';') return declr else: expr = self.expression() self.expect(';') return expr
def tct(infunc): """ Transform a recursive call to an iteration... in some cases """ tree = ast.parse(inspect.getsource(infunc)) transformer = ReturnCallTransformer(infunc.func_name, ast.Continue(), tree.body[0].args) trans_tree = transformer.visit(tree) trans_tree.body[0].body = [ ast.While(test=ast.Name(id='True', ctx=ast.Load()), body=trans_tree.body[0].body + [ast.Break()], orelse=[]) ] # remove TCT decorator, so that we only do TCT once trans_tree.body[0].decorator_list = [decorator for decorator in trans_tree.body[0].decorator_list if decorator.id != 'tct'] outfunc_code = compile(ast.fix_missing_locations(trans_tree), inspect.getfile(infunc), 'exec') eval_env = globals().copy() eval(outfunc_code, eval_env) return eval_env[infunc.func_name]
def visit_While(self, node): breakout = ast.If( test=node.test, body=[ast.Expr(value=ast.Continue())], orelse=[ast.Expr(value=ast.Break())] ) body_block = [i for i in node.body] body_block.append(breakout) new_node = ast.For( target=ast.Name("WhileLoop"), iter=ast.Call(func=ast.Name(id="range"), ctx=ast.Load(), args=[ast.Num(n=65534)]), body=body_block ) try: self.indent -= 1 subp = self.sub_parser(new_node) subp.indent -= 1 self.stack.append(subp.format()) finally: self.indent += 1
def p_continue_statement_1(self, p): """continue_statement : CONTINUE SEMI | CONTINUE auto_semi """ p[0] = ast.Continue()
def from_phpast(node): if node is None: return py.Pass(**pos(node)) if isinstance(node, str): return py.Str(node, **pos(node)) if isinstance(node, (int, float)): return py.Num(node, **pos(node)) if isinstance(node, php.Array): if node.nodes: if node.nodes[0].key is not None: keys = [] values = [] for elem in node.nodes: keys.append(from_phpast(elem.key)) values.append(from_phpast(elem.value)) return py.Dict(keys, values, **pos(node)) else: return py.List([from_phpast(x.value) for x in node.nodes], py.Load(**pos(node)), **pos(node)) else: return py.List([], py.Load(**pos(node)), **pos(node)) if isinstance(node, php.InlineHTML): args = [py.Str(node.data, **pos(node))] return py.Call( py.Name('inline_html', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)) if isinstance(node, php.Echo): return py.Call(py.Name('echo', py.Load(**pos(node)), **pos(node)), list(map(from_phpast, node.nodes)), [], None, None, **pos(node)) if isinstance(node, php.Print): return py.Print(None, [from_phpast(node.node)], True, **pos(node)) if isinstance(node, php.Exit): args = [] if node.expr is not None: args.append(from_phpast(node.expr)) return py.Raise( py.Call(py.Name('Exit', py.Load(**pos(node)), **pos(node)), args, [], None, None, **pos(node)), None, None, **pos(node)) if isinstance(node, php.Return): if node.node is None: return py.Return(None, **pos(node)) else: return py.Return(from_phpast(node.node), **pos(node)) if isinstance(node, php.Break): assert node.node is None, 'level on break not supported' return py.Break(**pos(node)) if isinstance(node, php.Continue): assert node.node is None, 'level on continue not supported' return py.Continue(**pos(node)) if isinstance(node, php.Silence): return from_phpast(node.expr) if isinstance(node, php.Block): return from_phpast(php.If(1, node, [], None, lineno=node.lineno)) if isinstance(node, php.Unset): return py.Delete(list(map(from_phpast, node.nodes)), **pos(node)) if isinstance(node, php.IsSet) and len(node.nodes) == 1: if isinstance(node.nodes[0], php.ArrayOffset): return py.Compare(from_phpast(node.nodes[0].expr), [py.In(**pos(node))], [from_phpast(node.nodes[0].node)], **pos(node)) if isinstance(node.nodes[0], php.ObjectProperty): return py.Call( py.Name('hasattr', py.Load(**pos(node)), **pos(node)), [ from_phpast(node.nodes[0].node), from_phpast(node.nodes[0].name) ], [], None, None, **pos(node)) if isinstance(node.nodes[0], php.Variable): return py.Compare(py.Str( node.nodes[0].name[1:], **pos(node)), [py.In(**pos(node))], [ py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)) ], **pos(node)) return py.Compare(from_phpast(node.nodes[0]), [py.IsNot(**pos(node))], [py.Name('None', py.Load(**pos(node)), **pos(node))], **pos(node)) if isinstance(node, php.Empty): return from_phpast( php.UnaryOp('!', php.BinaryOp('&&', php.IsSet([node.expr], lineno=node.lineno), node.expr, lineno=node.lineno), lineno=node.lineno)) if isinstance(node, php.Assignment): if (isinstance(node.node, php.ArrayOffset) and node.node.expr is None): return py.Call( py.Attribute(from_phpast(node.node.node), 'append', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr)], [], None, None, **pos(node)) if (isinstance(node.node, php.ObjectProperty) and isinstance(node.node.name, php.BinaryOp)): return to_stmt( py.Call(py.Name('setattr', py.Load(**pos(node)), **pos(node)), [ from_phpast(node.node.node), from_phpast(node.node.name), from_phpast(node.expr) ], [], None, None, **pos(node))) return py.Assign([store(from_phpast(node.node))], from_phpast(node.expr), **pos(node)) if isinstance(node, php.ListAssignment): return py.Assign([ py.Tuple(list(map(store, list(map(from_phpast, node.nodes)))), py.Store(**pos(node)), **pos(node)) ], from_phpast(node.expr), **pos(node)) if isinstance(node, php.AssignOp): return from_phpast( php.Assignment(node.left, php.BinaryOp(node.op[:-1], node.left, node.right, lineno=node.lineno), False, lineno=node.lineno)) if isinstance(node, (php.PreIncDecOp, php.PostIncDecOp)): return from_phpast( php.Assignment(node.expr, php.BinaryOp(node.op[0], node.expr, 1, lineno=node.lineno), False, lineno=node.lineno)) if isinstance(node, php.ArrayOffset): return py.Subscript(from_phpast(node.node), py.Index(from_phpast(node.expr), **pos(node)), py.Load(**pos(node)), **pos(node)) if isinstance(node, php.ObjectProperty): if isinstance(node.name, (php.Variable, php.BinaryOp)): return py.Call( py.Name('getattr', py.Load(**pos(node)), **pos(node)), [from_phpast(node.node), from_phpast(node.name)], [], None, None, **pos(node)) return py.Attribute(from_phpast(node.node), node.name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Constant): name = node.name if name.lower() == 'true': name = 'True' if name.lower() == 'false': name = 'False' if name.lower() == 'null': name = 'None' return py.Name(name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Variable): name = node.name[1:] if name == 'this': name = 'self' return py.Name(name, py.Load(**pos(node)), **pos(node)) if isinstance(node, php.Global): return py.Global([var.name[1:] for var in node.nodes], **pos(node)) if isinstance(node, php.Include): once = py.Name('True' if node.once else 'False', py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('include', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr), once], [], None, None, **pos(node)) if isinstance(node, php.Require): once = py.Name('True' if node.once else 'False', py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('require', py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr), once], [], None, None, **pos(node)) if isinstance(node, php.UnaryOp): op = unary_ops.get(node.op) assert op is not None, "unknown unary operator: '%s'" % node.op op = op(**pos(node)) return py.UnaryOp(op, from_phpast(node.expr), **pos(node)) if isinstance(node, php.BinaryOp): if node.op == '.': pattern, pieces = build_format(node.left, node.right) if pieces: return py.BinOp( py.Str(pattern, **pos(node)), py.Mod(**pos(node)), py.Tuple(list(map(from_phpast, pieces)), py.Load(**pos(node)), **pos(node)), **pos(node)) else: return py.Str(pattern % (), **pos(node)) if node.op in bool_ops: op = bool_ops[node.op](**pos(node)) return py.BoolOp(op, [from_phpast(node.left), from_phpast(node.right)], **pos(node)) if node.op in cmp_ops: op = cmp_ops[node.op](**pos(node)) return py.Compare(from_phpast(node.left), [op], [from_phpast(node.right)], **pos(node)) op = binary_ops.get(node.op) if node.op == 'instanceof': return py.Call( func=py.Name(id='isinstance', ctx=py.Load(**pos(node))), args=[from_phpast(node.left), from_phpast(node.right)], keywords=[], starargs=None, kwargs=None) assert op is not None, "unknown binary operator: '%s'" % node.op op = op(**pos(node)) return py.BinOp(from_phpast(node.left), op, from_phpast(node.right), **pos(node)) if isinstance(node, php.TernaryOp): return py.IfExp(from_phpast(node.expr), from_phpast(node.iftrue), from_phpast(node.iffalse), **pos(node)) if isinstance(node, php.Cast): return py.Call( py.Name(casts.get(node.type, node.type), py.Load(**pos(node)), **pos(node)), [from_phpast(node.expr)], [], None, None, **pos(node)) if isinstance(node, php.If): orelse = [] if node.else_: for else_ in map(from_phpast, deblock(node.else_.node)): orelse.append(to_stmt(else_)) for elseif in reversed(node.elseifs): orelse = [ py.If( from_phpast(elseif.expr), list( map(to_stmt, list(map(from_phpast, deblock(elseif.node))))), orelse, **pos(node)) ] return py.If( from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), orelse, **pos(node)) if isinstance(node, php.For): assert node.test is None or len(node.test) == 1, \ 'only a single test is supported in for-loops' return from_phpast( php.Block((node.start or []) + [ php.While(node.test[0] if node.test else 1, php.Block(deblock(node.node) + (node.count or []), lineno=node.lineno), lineno=node.lineno) ], lineno=node.lineno)) if isinstance(node, php.Foreach): if node.keyvar is None: target = py.Name(node.valvar.name[1:], py.Store(**pos(node)), **pos(node)) else: target = py.Tuple([ py.Name(node.keyvar.name[1:], py.Store(**pos(node))), py.Name(node.valvar.name[1:], py.Store(**pos(node))) ], py.Store(**pos(node)), **pos(node)) return py.For( target, from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [], **pos(node)) if isinstance(node, php.While): return py.While( from_phpast(node.expr), list(map(to_stmt, list(map(from_phpast, deblock(node.node))))), [], **pos(node)) if isinstance(node, php.DoWhile): condition = php.If(php.UnaryOp('!', node.expr, lineno=node.lineno), php.Break(None, lineno=node.lineno), [], None, lineno=node.lineno) return from_phpast( php.While(1, php.Block(deblock(node.node) + [condition], lineno=node.lineno), lineno=node.lineno)) if isinstance(node, php.Try): return py.TryExcept( list(map(to_stmt, list(map(from_phpast, node.nodes)))), [ py.ExceptHandler( py.Name(catch.class_, py.Load(**pos(node)), **pos(node)), store(from_phpast(catch.var)), list(map(to_stmt, list(map(from_phpast, catch.nodes)))), **pos(node)) for catch in node.catches ], [], **pos(node)) if isinstance(node, php.Throw): return py.Raise(from_phpast(node.node), None, None, **pos(node)) if isinstance(node, php.Function): args = [] defaults = [] for param in node.params: args.append( py.Name(param.name[1:], py.Param(**pos(node)), **pos(node))) if param.default is not None: defaults.append(from_phpast(param.default)) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) if not body: body = [py.Pass(**pos(node))] return py.FunctionDef(node.name, py.arguments(args, None, None, defaults), body, [], **pos(node)) if isinstance(node, php.Method): args = [] defaults = [] decorator_list = [] if 'static' in node.modifiers: decorator_list.append( py.Name('classmethod', py.Load(**pos(node)), **pos(node))) args.append(py.Name('cls', py.Param(**pos(node)), **pos(node))) else: args.append(py.Name('self', py.Param(**pos(node)), **pos(node))) for param in node.params: args.append( py.Name(param.name[1:], py.Param(**pos(node)), **pos(node))) if param.default is not None: defaults.append(from_phpast(param.default)) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) if not body: body = [py.Pass(**pos(node))] return py.FunctionDef(node.name, py.arguments(args, None, None, defaults), body, decorator_list, **pos(node)) if isinstance(node, php.Class): name = node.name bases = [] extends = node.extends or 'object' bases.append(py.Name(extends, py.Load(**pos(node)), **pos(node))) body = list(map(to_stmt, list(map(from_phpast, node.nodes)))) for stmt in body: if (isinstance(stmt, py.FunctionDef) and stmt.name in (name, '__construct')): stmt.name = '__init__' if not body: body = [py.Pass(**pos(node))] return py.ClassDef(name, bases, body, [], **pos(node)) if isinstance(node, (php.ClassConstants, php.ClassVariables)): assert len(node.nodes) == 1, \ 'only one class-level assignment supported per line' if isinstance(node.nodes[0], php.ClassConstant): name = php.Constant(node.nodes[0].name, lineno=node.lineno) else: name = php.Variable(node.nodes[0].name, lineno=node.lineno) initial = node.nodes[0].initial if initial is None: initial = php.Constant('None', lineno=node.lineno) return py.Assign([store(from_phpast(name))], from_phpast(initial), **pos(node)) if isinstance(node, (php.FunctionCall, php.New)): if isinstance(node.name, str): name = py.Name(node.name, py.Load(**pos(node)), **pos(node)) else: name = py.Subscript( py.Call(py.Name('vars', py.Load(**pos(node)), **pos(node)), [], [], None, None, **pos(node)), py.Index(from_phpast(node.name), **pos(node)), py.Load(**pos(node)), **pos(node)) args, kwargs = build_args(node.params) return py.Call(name, args, kwargs, None, None, **pos(node)) if isinstance(node, php.MethodCall): args, kwargs = build_args(node.params) return py.Call( py.Attribute(from_phpast(node.node), node.name, py.Load(**pos(node)), **pos(node)), args, kwargs, None, None, **pos(node)) if isinstance(node, php.StaticMethodCall): class_ = node.class_ if class_ == 'self': class_ = 'cls' args, kwargs = build_args(node.params) return py.Call( py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)), node.name, py.Load(**pos(node)), **pos(node)), args, kwargs, None, None, **pos(node)) if isinstance(node, php.StaticProperty): class_ = node.node name = node.name if isinstance(name, php.Variable): name = name.name[1:] return py.Attribute(py.Name(class_, py.Load(**pos(node)), **pos(node)), name, py.Load(**pos(node)), **pos(node)) return py.Call(py.Name('XXX', py.Load(**pos(node)), **pos(node)), [py.Str(str(node), **pos(node))], [], None, None, **pos(node))
def handle_goto_stmnt(self, stmnt): assert isinstance(stmnt, GotoStatement) a = ast.Assign() a.targets = [ast.Name(id=self.gotoVarName, ctx=ast.Store())] a.value = _ast_for_value(stmnt.label) return [a, ast.Continue()]
def test_Continue(self): self.verify(ast.Continue(), 'continue')
def mutate_Break(self, node): return ast.Continue()
def p_continue(p): '''statement : CONTINUE SEMICOL''' p[0] = ast.Continue().at(loc(p, 1))
import ast import pytest from astvalidate.validators.contextual import ContextualASTValidator @pytest.mark.parametrize( "node, message", [ (ast.Return(), "inside of a function"), ( ast.AsyncFunctionDef(body=[ast.Yield(), ast.Return(1)]), "can't be part of async gen", ), (ast.Continue(), "inside of a loop"), (ast.Break(), "inside of a loop"), (ast.AsyncFor(), "inside of a coroutine"), ( ast.Try(handlers=[ ast.ExceptHandler(type=None), ast.ExceptHandler(type=1), ]), "must be placed last", ), ( ast.Module([1, 2, ast.ImportFrom("__future__")]), "must occur at the top", ), ( ast.Module(
def Continue(draw) -> ast.Continue: return ast.Continue()
def generate(self, element:Element, GC:GenerationContext): self.precheck(element, GC) return ast.Continue()
def p_continue_statement_2(self, p): """continue_statement : CONTINUE identifier SEMI | CONTINUE identifier auto_semi """ p[0] = ast.Continue(p[2])
def trans(return_node): if return_node: return [ast.Expr(value=ast.Yield(value=return_node.value)), ast.Continue()] else: return [ast.Expr(value=ast.Yield(value=None)), ast.Continue()]
def mutate(self, node): """Replace a Break node with a Continue node """ assert isinstance(node, ast.Break) return ast.Continue()
def visitContinue(self, n, *args): return ast.Continue()
def __init__(self): # Notes: # ^ yields the longest match while | yield the first possible match # Enable Caching, otherwise it is super slow!! pp.ParserElement.enablePackrat() # Keywords k_load = pp.Keyword('load') k_section = pp.Keyword('section') k_template = pp.Keyword('template') k_assert = pp.Keyword('assert') k_print = pp.Keyword('print') k_if = pp.Keyword('if') k_else = pp.Keyword('else') k_elif = pp.Keyword('elif') k_for = pp.Keyword('for') k_in = pp.Keyword('in') k_break = pp.Keyword('break') k_continue = pp.Keyword('continue') keyword_list = [ k_load, k_assert, k_print, k_template, k_section, k_if, k_else, k_elif, k_for, k_in, k_break, k_continue ] # Operators plus_op = pp.Literal('+') minus_op = pp.Literal('-') multiply_op = pp.Literal('*') divide_op = pp.Literal('/') modulus_op = pp.Literal('%') power_op = pp.Literal('**') dot_op = pp.Literal('.') colon_op = pp.Literal(':') assign_op = pp.Literal('=') comma_op = pp.Literal(',') lbracket_op = pp.Literal('[') rbracket_op = pp.Literal(']') lcurly_op = pp.Literal('{') rcurly_op = pp.Literal('}') lparen_op = pp.Literal('(') rparen_op = pp.Literal(')') qmark_op = pp.Literal('?') not_bit_op = pp.Literal('~') and_bit_op = pp.Literal('&') or_bit_op = pp.Literal('|') xor_bit_op = pp.Literal('^') lshift_bit_op, rshift_bit_op = pp.Literal('<<'), pp.Literal('>>') not_test_op = pp.Keyword('not') and_test_op = pp.Keyword('and') or_test_op = pp.Keyword('or') comp_op = (pp.Literal('==') ^ pp.Literal('>') ^ pp.Literal('>=') ^ pp.Literal('<') ^ pp.Literal('<=') ^ pp.Literal('!=')) terminate_op = pp.LineEnd() # Number for integer, float and scientific notion number = pp.Combine( pp.Optional(pp.oneOf('+ -')) + ((pp.Word(pp.nums) + pp.Optional(dot_op + pp.Optional(pp.Word(pp.nums)))) | (dot_op + pp.Word(pp.nums))) + pp.Optional( pp.oneOf('e E') + pp.Optional(pp.oneOf('+ -')) + pp.Word(pp.nums))).setParseAction(number_action) dq_string = pp.QuotedString('"', escChar='\\', unquoteResults=False) sq_string = pp.QuotedString("'", escChar='\\', unquoteResults=False) q_string = (dq_string | sq_string) string = pp.Combine(pp.Optional(pp.oneOf('b u')) + q_string).setParseAction(string_action) # Reserve the keywords and ensure they are NOT matched as a regular name # Variable names cannot start with underscore # This is avoid clashing with python internals (double underscore) and # the BPCL internals (single underscore) name = pp.Combine(~pp.MatchFirst(keyword_list) + pp.Word(pp.alphas + '$', pp.alphanums + '_$')).setParseAction(name_action) # Forward declarations argument = pp.Forward() factor = pp.Forward() not_test = pp.Forward() test = pp.Forward() stmt = pp.Forward() # Expressions # TODO: array literal?? may not be necessary atom = (number | string | name | (lparen_op.suppress() + test + rparen_op.suppress())).setParseAction(passby_action) arglist = ( pp.ZeroOrMore(argument + comma_op.suppress()) + argument + pp.Optional(comma_op).suppress()).setParseAction(arglist_action) sliceop = (colon_op.suppress() + pp.Optional(test)).setParseAction(sliceop_action) subscript = (test ^ (pp.Optional(test)('start') + colon_op.suppress() + pp.Optional(test)('stop') + pp.Optional(sliceop) ('step'))('slice')).setParseAction(subscript_action) trailer = ((lparen_op.suppress() + pp.Optional(arglist) + rparen_op.suppress())('func_call_trailer') | (lbracket_op.suppress() + subscript + rbracket_op.suppress())('subscript_trailer') | (dot_op.suppress() + name)('attr_trailer')).setParseAction(trailer_action) power = (atom + pp.ZeroOrMore(trailer)('trailers') + pp.Optional(power_op.suppress() + factor)('exponential') ).setParseAction(power_action) # Match power first so that negative value can be matched instead of unary op, # i.e. -1 is Num(n=-1) instead of UnaryOp(op=USub(), operand=Num(n=1)) factor << (power | ( (plus_op | minus_op | not_bit_op) + factor).setParseAction(unary_action)).setParseAction(factor_action) term = (factor + pp.ZeroOrMore( pp.Group((multiply_op | divide_op | modulus_op) + factor))).setParseAction(binop_action) arith_expr = (term + pp.ZeroOrMore(pp.Group((plus_op | minus_op) + term)) ).setParseAction(binop_action) shift_expr = (arith_expr + pp.ZeroOrMore( pp.Group((lshift_bit_op | rshift_bit_op) + arith_expr))).setParseAction(binop_action) and_expr = (shift_expr + pp.ZeroOrMore( pp.Group(and_bit_op + shift_expr))).setParseAction(binop_action) xor_expr = (and_expr + pp.ZeroOrMore( pp.Group(xor_bit_op + and_expr))).setParseAction(binop_action) expr = (xor_expr + pp.ZeroOrMore( pp.Group(or_bit_op + xor_expr))).setParseAction(binop_action) comparison = (expr + pp.ZeroOrMore( pp.Group(comp_op + expr))).setParseAction(compare_action) not_test << ((not_test_op + not_test).setParseAction(unary_action) | comparison).setParseAction(passby_action) and_test = (not_test + pp.ZeroOrMore(and_test_op.suppress() + not_test) ).setParseAction(and_test_action) or_test = (and_test + pp.ZeroOrMore(or_test_op.suppress() + and_test) ).setParseAction(or_test_action) test << (or_test + pp.Optional(qmark_op.suppress() + or_test + colon_op.suppress() + test)).setParseAction(test_action) kwarg = (name + assign_op.suppress() + test).setParseAction(kwarg_action) argument << (test ^ kwarg).setParseAction(passby_action) # Statements expr_stmt = (test + pp.ZeroOrMore(assign_op.suppress() + test) ).setParseAction(expr_stmt_action) assert_stmt = (k_assert.suppress() + test + pp.Optional(comma_op.suppress() + test)).setParseAction(assert_stmt_action) print_stmt = ( k_print.suppress() + pp.Optional(test + pp.ZeroOrMore(comma_op.suppress() + test) + pp.Optional(comma_op).suppress()) ).setParseAction(print_stmt_action) break_stmt = k_break.setParseAction(lambda tokens: ast.Break()) continue_stmt = k_continue.setParseAction( lambda tokens: ast.Continue()) template_verb = (pp.Literal('build') | pp.Literal('dump') | pp.Literal('lint') | pp.Literal('compile') | pp.Literal('recompile')) template_stmt = (k_template.suppress() + template_verb + pp.ZeroOrMore(comma_op.suppress() + template_verb) + pp.Optional(comma_op).suppress() ).setParseAction(template_stmt_action) load_stmt = (k_load.suppress() + string).setParseAction(load_stmt_action) simple_stmt = (assert_stmt | print_stmt | break_stmt | continue_stmt | expr_stmt | template_stmt | load_stmt).setParseAction(passby_action) suite = (lcurly_op.suppress() + pp.ZeroOrMore(stmt) + rcurly_op.suppress()) if_stmt = (k_if.suppress() + test + pp.Group(suite) + pp.ZeroOrMore( pp.Group(k_elif.suppress() + test + pp.Group(suite)))('elif') + pp.Optional(k_else.suppress() + pp.Group(suite))('else') ).setParseAction(if_stmt_action) for_stmt = (k_for.suppress() + expr + k_in.suppress() + test + pp.Group(suite)).setParseAction(for_stmt_action) section_stmt = (k_section.suppress() + number + pp.Group(suite)).setParseAction(section_stmt_action) compound_stmt = (if_stmt | for_stmt | section_stmt) # TODO: This allows multiple stmts to be written on the same line with only whitespaces # as separators. Tried to enforce newline as separator between stmts and did NOT work. stmt << (compound_stmt | simple_stmt | terminate_op.suppress()) self.file_input = pp.ZeroOrMore(stmt).ignore( pp.pythonStyleComment).setParseAction(file_input_action)
def make_continue(): return ast.Continue()
def p_continue(p): #added continue parser '''statement : CONTINUE SEMICOL''' p[0] = ast.Continue()
def as_ast(dct): """See https://docs.python.org/2/library/ast.html""" if dct['ast_type'] == "Module": return ast.Module(dct["body"]) elif dct['ast_type'] == "Interactive": return ast.Interactive(dct["body"]) elif dct['ast_type'] == "Expression": return ast.Expression(dct["body"]) elif dct['ast_type'] == "Suite": return ast.Suite(dct["body"]) elif dct['ast_type'] == "FunctionDef": return ast.FunctionDef(dct["name"], dct["args"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "ClassDef": return ast.ClassDef(dct["name"], dct["bases"], dct["body"], dct["decorator_list"]) elif dct['ast_type'] == "Return": return ast.Return(dct["value"]) elif dct['ast_type'] == "Delete": return ast.Delete(dct["targets"]) elif dct['ast_type'] == "Assign": return ast.Assign(dct["targets"], dct["value"]) elif dct['ast_type'] == "AugAssign": return ast.AugAssign(dct["target"], dct["op"], dct["value"]) elif dct['ast_type'] == "Print": return ast.Print(dct["dest"], dct["values"], dct["nl"]) elif dct['ast_type'] == "For": return ast.For(dct["target"], dct["iter"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "While": return ast.While(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "If": return ast.If(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "With": return ast.With(dct["context_expr"], dct["optional_vars"], dct["body"]) elif dct['ast_type'] == "Raise": return ast.Raise(dct["type"], dct["inst"], dct["tback"]) elif dct['ast_type'] == "TryExcept": return ast.TryExcept(dct["body"], dct["handlers"], dct["orelse"]) elif dct['ast_type'] == "TryFinally": return ast.TryFinally(dct["body"], dct["finalbody"]) elif dct['ast_type'] == "Assert": return ast.Assert(dct["test"], dct["msg"]) elif dct['ast_type'] == "Import": return ast.Import(dct["names"]) elif dct['ast_type'] == "ImportFrom": return ast.ImportFrom(dct["module"], dct["names"], dct["level"]) elif dct['ast_type'] == "Exec": return ast.Exec(dct["body"], dct["globals"], dct["locals"]) elif dct['ast_type'] == "Global": return ast.Global(dct["names"]) elif dct['ast_type'] == "Expr": return ast.Expr(dct["value"]) elif dct['ast_type'] == "Pass": return ast.Pass() elif dct['ast_type'] == "Break": return ast.Break() elif dct['ast_type'] == "Continue": return ast.Continue() elif dct['ast_type'] == "BoolOp": return ast.BoolOp(dct["op"], dct["values"]) elif dct['ast_type'] == "BinOp": return ast.BinOp(dct["left"], dct["op"], dct["right"]) elif dct['ast_type'] == "UnaryOp": return ast.UnaryOp(dct["op"], dct["operand"]) elif dct['ast_type'] == "Lambda": return ast.Lambda(dct["args"], dct["body"]) elif dct['ast_type'] == "IfExp": return ast.IfExp(dct["test"], dct["body"], dct["orelse"]) elif dct['ast_type'] == "Dict": return ast.Dict(dct["keys"], dct["values"]) elif dct['ast_type'] == "Set": return ast.Set(dct["elts"]) elif dct['ast_type'] == "ListComp": return ast.ListComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "SetComp": return ast.SetComp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "DictComp": return ast.DictComp(dct["key"], dct["value"], dct["generators"]) elif dct['ast_type'] == "GeneratorExp": return ast.GeneratorExp(dct["elt"], dct["generators"]) elif dct['ast_type'] == "Yield": return ast.Yield(dct["value"]) elif dct['ast_type'] == "Compare": return ast.Compare(dct["left"], dct["ops"], dct["comparators"]) elif dct['ast_type'] == "Call": return ast.Call(dct["func"], dct["args"], dct["keywords"], dct["starargs"], dct["kwargs"]) elif dct['ast_type'] == "Repr": return ast.Repr(dct["value"]) elif dct['ast_type'] == "Num": return ast.Num(dct["n"]) elif dct['ast_type'] == "Str": # Converting to ASCII return ast.Str(dct["s"].encode('ascii', 'ignore')) elif dct['ast_type'] == "Attribute": return ast.Attribute(dct["value"], dct["attr"], dct["ctx"]) elif dct['ast_type'] == "Subscript": return ast.Subscript(dct["value"], dct["slice"], dct["ctx"]) elif dct['ast_type'] == "Name": return ast.Name(dct["id"], dct["ctx"]) elif dct['ast_type'] == "List": return ast.List(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Tuple": return ast.Tuple(dct["elts"], dct["ctx"]) elif dct['ast_type'] == "Load": return ast.Load() elif dct['ast_type'] == "Store": return ast.Store() elif dct['ast_type'] == "Del": return ast.Del() elif dct['ast_type'] == "AugLoad": return ast.AugLoad() elif dct['ast_type'] == "AugStore": return ast.AugStore() elif dct['ast_type'] == "Param": return ast.Param() elif dct['ast_type'] == "Ellipsis": return ast.Ellipsis() elif dct['ast_type'] == "Slice": return ast.Slice(dct["lower"], dct["upper"], dct["step"]) elif dct['ast_type'] == "ExtSlice": return ast.ExtSlice(dct["dims"]) elif dct['ast_type'] == "Index": return ast.Index(dct["value"]) elif dct['ast_type'] == "And": return ast.And() elif dct['ast_type'] == "Or": return ast.Or() elif dct['ast_type'] == "Add": return ast.Add() elif dct['ast_type'] == "Sub": return ast.Sub() elif dct['ast_type'] == "Mult": return ast.Mult() elif dct['ast_type'] == "Div": return ast.Div() elif dct['ast_type'] == "Mod": return ast.Mod() elif dct['ast_type'] == "Pow": return ast.Pow() elif dct['ast_type'] == "LShift": return ast.LShift() elif dct['ast_type'] == "RShift": return ast.RShift() elif dct['ast_type'] == "BitOr": return ast.BitOr() elif dct['ast_type'] == "BitXor": return ast.BitXor() elif dct['ast_type'] == "BitAnd": return ast.BitAnd() elif dct['ast_type'] == "FloorDiv": return ast.FloorDiv() elif dct['ast_type'] == "Invert": return ast.Invert() elif dct['ast_type'] == "Not": return ast.Not() elif dct['ast_type'] == "UAdd": return ast.UAdd() elif dct['ast_type'] == "USub": return ast.USub() elif dct['ast_type'] == "Eq": return ast.Eq() elif dct['ast_type'] == "NotEq": return ast.NotEq() elif dct['ast_type'] == "Lt": return ast.Lt() elif dct['ast_type'] == "LtE": return ast.LtE() elif dct['ast_type'] == "Gt": return ast.Gt() elif dct['ast_type'] == "GtE": return ast.GtE() elif dct['ast_type'] == "Is": return ast.Is() elif dct['ast_type'] == "IsNot": return ast.IsNot() elif dct['ast_type'] == "In": return ast.In() elif dct['ast_type'] == "NotIn": return ast.NotIn() elif dct['ast_type'] == "comprehension": return ast.comprehension(dct["target"], dct["iter"], dct["ifs"]) elif dct['ast_type'] == "ExceptHandler": return ast.ExceptHandler(dct["type"], dct["name"], dct["body"]) elif dct['ast_type'] == "arguments": return ast.arguments(dct["args"], dct["vararg"], dct["kwarg"], dct["defaults"]) elif dct['ast_type'] == "keyword": return ast.keyword(dct["arg"], dct["value"]) elif dct['ast_type'] == "alias": return ast.alias(dct["name"], dct["asname"]) else: return dct
def p_jump_statement_3(self, p): """ jump_statement : CONTINUE SEMI """ p[0] = ast.Continue()