def _parse_func_call_args(self, is_stmt=True): self._publish_event(ParserEventType.BEFORE_FUNC_ARGS) symbol_nodes = [] arg_nodes = [] kwarg_nodes = [] while self._peek_token().ttype is not EOF: if self._peek_token().ttype is BlankLine: self._consume_token(BlankLine) if is_stmt: break elif self._peek_token().ttype is ParenRight: if is_stmt: raise PeekSyntaxError( self.text, self._peek_token(), message= 'Found function expression while parsing for function stmt' ) else: break elif self._peek_token().ttype is Name: self._publish_event(ParserEventType.FUNC_OPTION_NAME_OR_ARG) n = NameNode(self._consume_token(Name)) if self._peek_token().ttype is Assign: self._consume_token(Assign) self._publish_event( ParserEventType.BEFORE_FUNC_OPTION_VALUE) kwarg_nodes.append(KeyValueNode(n, self._parse_expr())) self._publish_event( ParserEventType.AFTER_FUNC_OPTION_VALUE) elif self._peek_token( ).ttype is ParenLeft: # nested function expr self._consume_token(ParenLeft) sub_symbol_nodes, sub_arg_nodes, sub_kwarg_nodes = self._parse_func_call_args( is_stmt=False) arg_nodes.append( FuncCallNode(n, ArrayNode(sub_symbol_nodes), ArrayNode(sub_arg_nodes), DictNode(sub_kwarg_nodes), is_stmt=False)) self._consume_token(ParenRight) else: arg_nodes.append(self._parse_expr_after_left_operand(n)) elif self._peek_token().ttype is At: self._publish_event(ParserEventType.BEFORE_FUNC_SYMBOL_ARG) self._consume_token(At) symbol_nodes.append(SymbolNode(self._consume_token(Literal))) self._publish_event(ParserEventType.AFTER_FUNC_SYMBOL_ARG) else: self._publish_event(ParserEventType.BEFORE_FUNC_REGULAR_ARG) arg_nodes.append(self._parse_expr()) self._publish_event(ParserEventType.AFTER_FUNC_REGULAR_ARG) self._publish_event(ParserEventType.AFTER_FUNC_ARGS) return symbol_nodes, arg_nodes, kwarg_nodes
def _parse_array(self): value_nodes = [] self._consume_token(BracketLeft) while self._peek_token().ttype is not BracketRight: value_nodes.append(self._parse_expr()) if self._peek_token().ttype is Comma: self._consume_token(Comma) else: break self._consume_token(BracketRight) return ArrayNode(value_nodes)
def _parse_expr_after_left_operand(self, n, unary_op_token=None, last_bin_op=None): while True: if self._peek_token().ttype is BinOp: op_token = self._peek_token() if _BIN_OP_ORDERS[last_bin_op] >= _BIN_OP_ORDERS[ op_token.value]: return n if unary_op_token is None else UnaryOpNode( unary_op_token, n) else: self._consume_token(op_token.ttype) right_node = self._parse_expr(last_bin_op=op_token.value) n = n if unary_op_token is None else UnaryOpNode( unary_op_token, n) n = BinOpNode(op_token, n, right_node) elif self._peek_token().ttype is ParenLeft: # func call if last_bin_op == '.': return n if unary_op_token is None else UnaryOpNode( unary_op_token, n) else: self._consume_token(ParenLeft) symbol_nodes, arg_nodes, kwarg_nodes = self._parse_func_call_args( is_stmt=False) self._consume_token(ParenRight) n = FuncCallNode(n, ArrayNode(symbol_nodes), ArrayNode(arg_nodes), DictNode(kwarg_nodes), is_stmt=False) n = n if unary_op_token is None else UnaryOpNode( unary_op_token, n) else: return n if unary_op_token is None else UnaryOpNode( unary_op_token, n) unary_op_token = None
def _parse_func_call(self): self._publish_event(ParserEventType.FUNC_STMT) name_node = NameNode(self._consume_token(FuncName)) symbol_nodes, arg_nodes, kwarg_nodes = self._parse_func_call_args() return FuncCallNode(name_node, ArrayNode(symbol_nodes), ArrayNode(arg_nodes), DictNode(kwarg_nodes))
def visit_array_node(self, node: ArrayNode): values = [] with self.consumer(lambda v: values.append(v)): for node in node.value_nodes: node.accept(self) self.consume(values)