def _parse_es_api_call(self): self._publish_event(ParserEventType.ES_METHOD) method_token = self._consume_token(HttpMethod) method_node = NameNode(method_token) if method_token.value.upper() not in HTTP_METHODS: raise PeekSyntaxError( self.text, method_token, title='Invalid HTTP method', message= f'Expect HTTP method of value in {HTTP_METHODS!r}, got {method_token.value!r}' ) if self._peek_token().ttype is Literal: self._publish_event(ParserEventType.ES_URL) path_node = TextNode(self._consume_token(Literal)) elif self._peek_token().ttype is ParenLeft: self._publish_event(ParserEventType.BEFORE_ES_URL_EXPR) path_node = self._parse_expr() self._publish_event(ParserEventType.AFTER_ES_URL_EXPR) else: raise PeekSyntaxError( self.text, self._peek_token(), message= 'HTTP path must be either text literal or an expression enclosed by parenthesis' ) option_nodes = [] while self._peek_token().ttype is OptionName: self._publish_event(ParserEventType.ES_OPTION_NAME) n = NameNode(self._consume_token(OptionName)) self._consume_token(Assign) self._publish_event(ParserEventType.BEFORE_ES_OPTION_VALUE) option_nodes.append(KeyValueNode(n, self._parse_expr())) self._publish_event(ParserEventType.AFTER_ES_OPTION_VALUE) if self._peek_token().ttype is At: self._publish_event(ParserEventType.ES_PAYLOAD_FILE_AT) self._consume_token(At) return EsApiCallFilePayloadNode( method_node, path_node, DictNode(option_nodes), TextNode(self._consume_token(Literal))) else: dict_nodes = [] while self._peek_token().ttype is not EOF: if self._peek_token().ttype is CurlyLeft: self._publish_event( ParserEventType.BEFORE_ES_PAYLOAD_INLINE) dict_nodes.append(self._parse_dict()) self._publish_event( ParserEventType.AFTER_ES_PAYLOAD_INLINE) else: break return EsApiCallInlinePayloadNode(method_node, path_node, DictNode(option_nodes), dict_nodes)
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_for_stmt(self): self._publish_event(ParserEventType.FOR) self._consume_token(For) item = NameNode(self._consume_token(Name)) self._consume_token(In) items = self._parse_expr() self._publish_event(ParserEventType.BEFORE_FOR_SUITE) self._consume_token(CurlyLeft) suite = [] while self._peek_token().ttype is not CurlyRight: token = self._peek_token() if token.ttype is BlankLine: self._consume_token(BlankLine) else: suite.append(self._parse_stmt()) self._consume_token(CurlyRight) self._publish_event(ParserEventType.AFTER_FOR_SUITE) return ForInNode(item, items, suite)
def _parse_expr(self, last_bin_op=None): if self._peek_token().ttype is UnaryOp: unary_op_token = self._consume_token(UnaryOp) else: unary_op_token = None if self._peek_token().ttype is ParenLeft: pl = self._consume_token(ParenLeft) n = self._parse_expr() pr = self._consume_token(ParenRight) n = GroupNode(n, pl, pr) elif self._peek_token().ttype is Name: n = NameNode(self._consume_token(Name)) elif self._peek_token().ttype is At: self._consume_token(At) n = SymbolNode(self._consume_token(Literal)) else: n = self._parse_value() return self._parse_expr_after_left_operand( n, unary_op_token=unary_op_token, last_bin_op=last_bin_op)
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))