def parse_let_family(tp: ast.Tuple) -> ast.Node: if len(tp.elements) < 3: raise ParseError( f'{tp.elements[0]}: bad syntax, no expression in body') elem = tp.elements[1] if not isinstance(elem, ast.Tuple): raise ParseError( f'{tp.elements[0]}: bad syntax, expected bindings, given: {elem}') bindings: List[Node] = elem.elements patterns: List[ast.Name] = [] exprs: List[Node] = [] for i, binding in enumerate(bindings): if isinstance(binding, ast.Tuple): if len(binding.elements) == 2: if isinstance(binding.elements[0], ast.Name): patterns.append(binding.elements[0]) exprs.append(parse_node(binding.elements[1])) continue raise ParseError( f'{tp.elements[0]}: bad syntax, not an identifer and expression for a binding {binding}' ) body = ast.Block(parse_list(tp.elements[2:])) name = tp.elements[0] if not isinstance(name, ast.Name): raise ParseError(f'expected a Name, given {name}') if name.identifier == constants.LET: return ast.Let(patterns, exprs, body) elif name.identifier == constants.LET_STAR: return ast.LetStar(patterns, exprs, body) elif name.identifier == constants.LET_REC: return ast.LetRec(patterns, exprs, body) else: raise ParseError(f'{tp.elements[0]}: should not be here')
def p_ifstmt(p): '''ifstmt : TKIF '(' cond_expr ')' block TKELSE block | TKIF '(' cond_expr ')' block ''' if len(p) == 8: p[0] = ast.IfStmt(p[3], p[5], p[7]).addloc(p.lineno(1)) else: p[0] = ast.IfStmt(p[3], p[5], ast.Block()).addloc(p.lineno(1))
def parse_block(self): stats = self.parse_stats() block = ast.Block(stats) if self.lex.look_ahead().kind == lexer.TokenKind.KW_RETURN: retstat = self.parse_retstat() block.append_stat(retstat) return block
def block(self): self.expect('{') stmts = [] while not self.accept('}'): stmts.append(self.statement()) self.expect('}') return ast.Block(stmts)
def parse_block(self): if not isinstance(self.current, tokens.LBRACE): raise ParserError( f"Expected {'{'} after function, found `{self.current}`") self.step() statements = [] while not isinstance(self.current, tokens.EOF): if isinstance(self.current, tokens.SEMICOLON): self.step() continue if isinstance(self.current, tokens.LET): stmt = self.parse_let() elif isinstance(self.current, tokens.FUNC): stmt = self.parse_function_literal() elif isinstance(self.current, tokens.RETURN): stmt = self.parse_return() elif isinstance(self.current, tokens.IF): stmt = self.parse_conditional() elif isinstance(self.current, tokens.LBRACE): stmt = self.parse_block() elif isinstance(self.current, tokens.RBRACE): break else: stmt = self.parse_expr() statements.append(stmt) self.step() return ast.Block(statements)
def parse_block_expression(self, expect_delim): self.expect_word('bk') name = self.expect_type(Token.IDENTIFIER) subject = [self.get_functino_subject()] signature = self.parse_functino_signature(subject, False) methods = self.parse_functino_tail(signature, subject) self.expect_word('in') body = self.parse_word_expression(expect_delim) return ast.Block(name, methods, body)
def block(self): """block : declarations compound_statement """ # declarations declaration_nodes = self.declarations() # compound BEGIN...END compound_statement_node = self.compound_statement() node = ast.Block(declaration_nodes, compound_statement_node) return node
def block(self): if self.currtok[0] == "PCTLBRA": self.currtok = next(self.tokens) b = self.statements() if self.currtok[0] == "PCTRBRA": self.currtok = next(self.tokens) return ast.Block(b) else: raise CLiteSyntaxError("Right Brace expected", self.currtok[1]) else: raise CLiteSyntaxError("Left brace expected", self.currtok[1])
def block(self): self.expect(T.LEFT_BRACE) self.root.push_scope() stmts = [] while self.peek().type != T.RIGHT_BRACE: stmts.append(self.statement()) self.expect(T.RIGHT_BRACE) self.root.pop_scope() return ast.Block(stmts)
def semiAsExpr(block): ''' Convert a list of expressions to a single expression, possibly a Block ''' block = list(filter(lambda x: x is not None, block)) if len(block) == 0: return ast.Value(None) elif len(block) == 1: return block[0] else: return ast.Block(block)
def parse_loop(self, cur): always = self.block() if self.maybe("while"): cond, bl, th, el = self.parse_while() return ast.Loop(ast.Block([ always, ast.If(cond, bl, semiAsExpr([th, ast.Branch("break")])) ]), el=el).set_origin(cur) else: return ast.Loop(always).set_origin(cur)
def parse_define(tp: ast.Tuple) -> ast.Define: elements = tp.elements if len(elements) < 3: raise ParseError(f'define: bad syntax (missing expressions) {tp}') if isinstance(elements[1], ast.Name): if len(elements) > 3: raise ParseError(f'define: bad syntax (multiple expressions) {tp}') return ast.Define(elements[1], parse_node(elements[2])) elif isinstance(elements[1], ast.Tuple): tail = ast.Block(parse_list(elements[2:])) function = parse_function(elements[1], tail) return ast.Define(function.caller, function) else: raise ParseError(f'Unsupported ast node type: {elements[1]}')
def parse_lambda(tp: ast.Tuple) -> ast.Lambda: elements = tp.elements if len(elements) < 3: raise ParseError(f'lambda: bad syntax: {tp}') pattern = elements[1] body = ast.Block(parse_list(elements[2:])) if isinstance(pattern, ast.Name): return ast.Lambda(pattern, body) elif isinstance(pattern, ast.Tuple): formals = expand_formals(pattern.elements) if isinstance(formals, ast.Pair) or formals is ast.NULL_PAIR: return ast.Lambda(formals, body) else: raise ParseError('lambda: illegal use of \'.\'') else: raise ParseError(f'Unsupported ast node type: {pattern}')
def block(self): ''' Block -> '{' Statements '}' :return: a Block object ''' # match/consume the opening brace self.curr_tok = self.lex_gen.__next__() stmts = self.statements() if self.curr_tok[0] != values.RBRACE: raise CliteSyntaxError('} expected') self.curr_tok = self.lex_gen.__next__() return ast.Block(stmts)
def p_block(p): '''block : '{' vardecllist stmtlist '}' | '{' vardecllist '}' | '{' stmtlist '}' | '{' '}' ''' p[0] = ast.Block().addloc(p.lineno(1)) if len(p) == 4: for y in p[2]: if isinstance(y, ast.VarDecl): p[0].addVardecl(y) else: p[0].addStatement(y) elif len(p) == 5: for vd in p[2]: p[0].addVardecl(vd) for st in p[3]: p[0].addStatement(st)
def block(self, level): """ Block -> '{' Statements '}' :param level: indicates level of statements in block; type(level) - int :return: An ast.Block object :raise CliteSyntaxError if an unexpected token is seen """ # Consume the opening brace identifying the start of a block self.curr_tok = self.lex.__next__() statements = self.statements(level) # Match right closing brace if self.curr_tok[self.CODE] != tokens.SINGLE_TOKENS[tokens.RBRACE][self.CODE]: raise errors.CliteSyntaxError("'}' expected!", self.curr_tok[self.LINE]) # Consume right closing brace self.curr_tok = self.lex.__next__() return ast.Block(statements, level)
def block_stmt(self) -> ast.Block: self.check_eof("Expected { for block statement.") toks = TokenList() if not toks.add(self.match(token.LBRACE)): raise ParseException("Expected { for block statement.") # Snapshot the current scope (before block) previous_scope = self.symbol_tree.take_snapshot() # Parse all block statments statements : typing.List[ast.BaseNode] = [] while self.peek().type != token.RBRACE: self.check_eof("Expected statement for block body.") statements.append(self.stmt()) self.check_eof("missing } for block statement") if not toks.add(self.match(token.RBRACE)): raise ParseException("Missing } for block statement.") # Store block scope and ... # leave block scope == restore scope snapshot block_scope = self.symbol_tree.take_snapshot() self.symbol_tree.restore_snapshot(previous_scope) return ast.Block(toks, statements)
def block(self): ''' Parses a "block", which is an expression which prioritizes curly-brace blocks over object literals and considers the semicolon to end the expression rather than continue it. ''' cur = self.cur if self.maybe("{"): vars = [] with common.stack(self.scope, vars): b = self.semichain() self.expect("}") if len(vars) > 0: return ast.Block(b, vars).set_origin(cur) else: return semiAsExpr(b) else: x = self.expr() self.maybe(";") return x
def block(self): ''' Block --> { Statement } :return: ast.Block ''' # need '{' if self.curr_tok[0] != lexer.Lexer.LCBRACK: print("Error: '{' expected found:", self.curr_tok[1], "on line", self.curr_tok[2]) sys.exit(1) self.curr_tok = next(self.lex) stmt = self.statements() # need '}' if self.curr_tok[0] != lexer.Lexer.RCBRACK: print("Error: '}' expected found:", self.curr_tok[1], "on line", self.curr_tok[2]) sys.exit(1) self.curr_tok = next(self.lex) return ast.Block(stmt)
def p_block(self, p): """block : LBRACE source_elements RBRACE""" p[0] = ast.Block(p[2])
def p_expression_block(self, parse): """ expression : LBRACE block_list RBRACE """ parse[0] = AST.Block(expr_list=parse[2])
def block(stat): if isinstance(stat, ast.Block): return stat assert isinstance(stat, ast.Statement) return ast.Block([stat]).at(stat)
def p_block(p): '''statement : LBRACE RBRACE | LBRACE statements RBRACE''' stat = [] if len(p) == 3 else p[2] p[0] = ast.Block(stat).at(loc(p))
def statements_statement(s): return ast.Block([s[0]])
def p_expression_block(self, parse): ''' expression : LBRACE block_list RBRACE ''' parse[0] = AST.Block(expression_list=parse[2])
def statements(s): return ast.Block(s[0].getastlist() + [s[1]])
def p_fundef(p): '''fundef : funheader LBRACE RBRACE | funheader LBRACE statements RBRACE''' name, _type = p[1] body = ast.Block(p[3] if len(p) == 5 else []) p[0] = ast.FunDef(False, name, _type, body).at(loc(p, 1))
def parse_begin(tp: ast.Tuple) -> ast.Begin: return ast.Begin(ast.Block(parse_list(tp.elements[1:])))
def parse_block(tp: ast.Tuple) -> ast.Block: return ast.Block(parse_list(tp.elements))
def p_fundef_static(p): '''fundef : STATIC funheader LBRACE RBRACE | STATIC funheader LBRACE statements RBRACE''' name, _type = p[2] body = ast.Block(p[4] if len(p) == 6 else []) p[0] = ast.FunDef(True, name, _type, body).at(loc(p, 2))