def parse(self, precedence=0, required=True): self.reader.skip_whitespace() left_start = self.reader.offset left = self.parse_left(required) if left == None: return None self.add_node(left, left_start) while True: if self.hooks != None: parsed = self.hooks.infix_prehook(left) if parsed != None: left = parsed self.add_node(left, left_start) continue op = self.parse_operator() if op == None or op.precedence <= precedence: break self.reader.expect_token(op.text) op_text = self.config.aliases.get( op.text) if op.text in self.config.aliases else op.text if op.is_binary: right = self.parse(op.precedence - 1 if op.is_right_assoc else op.precedence) left = exprs.BinaryExpression(left, op_text, right) elif op.is_postfix: left = exprs.UnaryExpression(exprs.UNARY_TYPE.POSTFIX, op_text, left) elif op.text == "?": when_true = self.parse() self.reader.expect_token(":") when_false = self.parse(op.precedence - 1) left = exprs.ConditionalExpression(left, when_true, when_false) elif op.text == "(": args = self.parse_call_arguments() left = exprs.UnresolvedCallExpression(left, [], args) elif op.text == "[": element_expr = self.parse() self.reader.expect_token("]") left = exprs.ElementAccessExpression(left, element_expr) elif op.text in self.config.property_access_ops: prop = self.reader.expect_identifier( "expected identifier as property name") left = exprs.PropertyAccessExpression(left, prop) else: self.reader.fail( f'''parsing \'{op.text}\' is not yet implemented''') self.add_node(left, left_start) if isinstance(left, exprs.ParenthesizedExpression) and isinstance( left.expression, exprs.Identifier): expr = self.parse(0, False) if expr != None: return exprs.CastExpression( astTypes.UnresolvedType(left.expression.text, []), expr) return left
def visit_expression(self, expr): orig_expr = expr expr = super().visit_expression(expr) if isinstance(expr, exprs.BinaryExpression) and expr.operator == "in": expr = exprs.UnresolvedCallExpression( exprs.PropertyAccessExpression(expr.right, "hasKey"), [], [expr.left]) expr.parent_node = orig_expr.parent_node return expr
def infix_prehook(self, left): if isinstance( left, exprs.PropertyAccessExpression ) and self.reader.peek_regex("<[A-Za-z0-9_<>]*?>\\(") != None: type_args = self.parse_type_args() self.reader.expect_token("(") args = self.expression_parser.parse_call_arguments() return exprs.UnresolvedCallExpression(left, type_args, args) elif self.reader.read_token("instanceof"): type = self.parse_type() return exprs.InstanceOfExpression(left, type) elif isinstance(left, exprs.Identifier) and self.reader.read_token("=>"): block = self.parse_lambda_block() return types.Lambda( [types.MethodParameter(left.text, None, None, None)], block) return None