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 parse_left(self, required=True): result = self.hooks.unary_prehook() if self.hooks != None else None if result != None: return result unary = self.reader.read_any_of(self.config.unary) if unary != None: right = self.parse(self.prefix_precedence) return exprs.UnaryExpression(exprs.UNARY_TYPE.PREFIX, unary, right) id = self.reader.read_identifier() if id != None: return exprs.Identifier(id) num = self.reader.read_number() if num != None: return exprs.NumericLiteral(num) str = self.reader.read_string() if str != None: return exprs.StringLiteral(str) if self.reader.read_token("("): expr = self.parse() self.reader.expect_token(")") return exprs.ParenthesizedExpression(expr) if required: self.reader.fail( f'''unknown (literal / unary) token in expression''') return None