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
def parse_block(self, indent_len = 0): block = nodes.TemplateBlock([]) indent_man = BlockIndentManager(block, indent_len) while not self.reader.get_eof(): if self.reader.peek_exactly("{{/"): break if self.reader.read_exactly("${"): expr = self.parser.parse_expression() block.items.append(nodes.ExpressionNode(expr)) self.reader.expect_token("}") elif self.reader.read_exactly("$"): id = self.reader.expect_identifier() block.items.append(nodes.ExpressionNode(exprs.Identifier(id))) elif self.reader.read_exactly("{{"): block_indent_len = indent_man.remove_prev_indent() if self.reader.read_token("for"): var_name = self.reader.expect_identifier() self.reader.expect_token("of") items_expr = self.parser.parse_expression() attrs = self.parse_attributes() self.reader.expect_token("}}") body = self.parse_block(block_indent_len) self.reader.expect_token("{{/for}}") block.items.append(nodes.ForNode(var_name, items_expr, body, attrs.get("joiner"))) else: expr = self.parser.parse_expression() block.items.append(nodes.ExpressionNode(expr)) self.reader.expect_token("}}") else: literal = self.reader.read_regex("([^\\\\]\\\\(\\{\\{|\\$)|\r|\n|(?!\\{\\{|\\$\\{|\\$).)*")[0] if literal == "": raise Error("This should not happen!") block.items.append(indent_man.deindent(nodes.LiteralNode(literal))) if indent_len != 0: indent_man.remove_prev_indent() return block
def unary_prehook(self): if self.reader.read_token("null"): return exprs.NullLiteral() elif self.reader.read_token("true"): return exprs.BooleanLiteral(True) elif self.reader.read_token("false"): return exprs.BooleanLiteral(False) elif self.reader.read_token("`"): parts = [] lit_part = "" while True: if self.reader.read_exactly("`"): if lit_part != "": parts.append( exprs.TemplateStringPart.literal(lit_part)) lit_part = "" break elif self.reader.read_exactly("${"): if lit_part != "": parts.append( exprs.TemplateStringPart.literal(lit_part)) lit_part = "" expr = self.parse_expression() parts.append(exprs.TemplateStringPart.expression(expr)) self.reader.expect_token("}") elif self.allow_dollar_ids and self.reader.read_exactly("$"): if lit_part != "": parts.append( exprs.TemplateStringPart.literal(lit_part)) lit_part = "" id = self.reader.read_identifier() parts.append( exprs.TemplateStringPart.expression( exprs.Identifier(id))) elif self.reader.read_exactly("\\"): chr = self.reader.read_char() if chr == "n": lit_part += "\n" elif chr == "r": lit_part += "\r" elif chr == "t": lit_part += "\t" elif chr == "`": lit_part += "`" elif chr == "$": lit_part += "$" elif chr == "\\": lit_part += "\\" else: self.reader.fail("invalid escape", self.reader.offset - 1) else: chr = self.reader.read_char() chr_code = ord(chr[0]) if not (32 <= chr_code and chr_code <= 126) or chr == "`" or chr == "\\": self.reader.fail( f'''not allowed character (code={chr_code})''', self.reader.offset - 1) lit_part += chr return exprs.TemplateString(parts) elif self.reader.read_token("new"): type = self.parse_type() if isinstance(type, astTypes.UnresolvedType): self.reader.expect_token("(") args = self.expression_parser.parse_call_arguments() return exprs.UnresolvedNewExpression(type, args) else: raise Error( f'''[TypeScriptParser2] Expected UnresolvedType here!''') elif self.reader.read_token("<"): new_type = self.parse_type() self.reader.expect_token(">") expression = self.parse_expression() return exprs.CastExpression(new_type, expression) elif self.reader.read_token("/"): pattern = "" while True: chr = self.reader.read_char() if chr == "\\": chr2 = self.reader.read_char() pattern += "/" if chr2 == "/" else "\\" + chr2 elif chr == "/": break else: pattern += chr modifiers = self.reader.read_modifiers(["g", "i"]) return exprs.RegexLiteral(pattern, "i" in modifiers, "g" in modifiers) elif self.reader.read_token("typeof"): expr = self.expression_parser.parse( self.expression_parser.prefix_precedence) self.reader.expect_token("===") check = self.reader.expect_string() ts_type = None if check == "string": ts_type = "TsString" elif check == "boolean": ts_type = "TsBoolean" elif check == "object": ts_type = "Object" elif check == "function": # TODO: ??? ts_type = "Function" elif check == "undefined": # TODO: ??? ts_type = "Object" else: self.reader.fail("unexpected typeof comparison") return exprs.InstanceOfExpression( expr, astTypes.UnresolvedType(ts_type, [])) elif self.reader.peek_regex("\\([A-Za-z0-9_]+\\s*[:,]|\\(\\)") != None: params = self.parse_lambda_params() self.reader.expect_token("=>") block = self.parse_lambda_block() return types.Lambda(params, block) elif self.reader.read_token("await"): expression = self.parse_expression() return exprs.AwaitExpression(expression) map_literal = self.expression_parser.parse_map_literal() if map_literal != None: return map_literal array_literal = self.expression_parser.parse_array_literal() if array_literal != None: return array_literal return None