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
示例#2
0
    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