def if_expr(self): res = ParseResult() cases = [] else_case = None if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Ketika_nada'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Ketika_nada'")) res.register_advancement() self.advance() condition = res.register(self.expr()) if res.error: return res if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Maka_cakrawala'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Maka_cakrawala'")) res.register_advancement() self.advance() expr = res.register(self.expr()) if res.error: return res cases.append((condition, expr)) while self.current_tok.matches(Lexer.TT_KEYWORD, 'Lain_jika'): res.register_advancement() self.advance() condition = res.register(self.expr()) if res.error: return res if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Maka_cakrawala'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Maka_cakrawala'" )) res.register_advancement() self.advance() expr = res.register(self.expr()) if res.error: return res cases.append((condition, expr)) if self.current_tok.matches(Lexer.TT_KEYWORD, 'Lainnya'): res.register_advancement() self.advance() else_case = res.register(self.expr()) if res.error: return res return res.success(Lexer.IfNode(cases, else_case))
def while_expr(self): res = ParseResult() if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Sedangkan'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Sedangkan'")) res.register_advancement() self.advance() condition = res.register(self.expr()) if res.error: return res if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Maka_cakrawala'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Maka_cakrawala'")) res.register_advancement() self.advance() body = res.register(self.expr()) if res.error: return res return res.success(Lexer.WhileNode(condition, body))
def comp_expr(self): res = ParseResult() if self.current_tok.matches(Lexer.TT_KEYWORD, 'Tak_dapat'): op_tok = self.current_tok res.register_advancement() self.advance() node = res.register(self.comp_expr()) if res.error: return res return res.success(Lexer.UnaryOpNode(op_tok, node)) node = res.register( self.bin_op(self.arith_expr, (Lexer.TT_EE, Lexer.TT_NE, Lexer.TT_LT, Lexer.TT_GT, Lexer.TT_LTE, Lexer.TT_GTE))) if res.error: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) int, float, identifier, '+', '-', '(', '[', 'Ketika_nada', 'Untuk_kita', 'Sedangkan', 'Fungsi' or 'Tak_dapat'" )) return res.success(node)
def list_expr(self): res = ParseResult() element_nodes = [] pos_start = self.current_tok.pos_start.copy() if self.current_tok.type != Lexer.TT_LSQUARE: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) '['")) res.register_advancement() self.advance() if self.current_tok.type == Lexer.TT_RSQUARE: res.register_advancement() self.advance() else: element_nodes.append(res.register(self.expr())) if res.error: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) ']', 'Sajak', 'Ketika_nada', 'Untuk_kita', 'Sedangkan', 'Fungsi', int, float, identifier, '+', '-', '(', '[' or 'Tak_dapat'" )) while self.current_tok.type == Lexer.TT_COMMA: res.register_advancement() self.advance() element_nodes.append(res.register(self.expr())) if res.error: return res if self.current_tok.type != Lexer.TT_RSQUARE: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) ',' or ']'")) res.register_advancement() self.advance() return res.success( Lexer.ListNode(element_nodes, pos_start, self.current_tok.pos_end.copy()))
def parse(self): res = self.expr() if not res.error and self.current_tok.type != Lexer.TT_EOF: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) '+', '-', '*', '/', '^', '==', '!=', '<', '>', <=', '>=', 'Dan_waktu' or 'Atau'" )) return res
def call(self): res = ParseResult() atom = res.register(self.atom()) if res.error: return res if self.current_tok.type == Lexer.TT_LPAREN: res.register_advancement() self.advance() arg_nodes = [] if self.current_tok.type == Lexer.TT_RPAREN: res.register_advancement() self.advance() else: arg_nodes.append(res.register(self.expr())) if res.error: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) ')', 'Sajak', 'Ketika_nada', 'Untuk_kita', 'Sedangkan', 'Fungsi', int, float, identifier, '+', '-', '(', '[' or 'Tak_dapat'" )) while self.current_tok.type == Lexer.TT_COMMA: res.register_advancement() self.advance() arg_nodes.append(res.register(self.expr())) if res.error: return res if self.current_tok.type != Lexer.TT_RPAREN: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) ',' or ')'" )) res.register_advancement() self.advance() return res.success(Lexer.CallNode(atom, arg_nodes)) return res.success(atom)
def expr(self): res = ParseResult() if self.current_tok.matches(Lexer.TT_KEYWORD, 'Sajak'): res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_IDENTIFIER: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) identifier")) var_name = self.current_tok res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_EQ: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) '='")) res.register_advancement() self.advance() expr = res.register(self.expr()) if res.error: return res return res.success(Lexer.VarAssignNode(var_name, expr)) node = res.register( self.bin_op(self.comp_expr, ((Lexer.TT_KEYWORD, 'Dan_waktu'), (Lexer.TT_KEYWORD, 'Atau')))) if res.error: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) 'Sajak', 'Ketika_nada', 'Untuk_kita', 'Sedangkan', 'Fungsi', int, float, identifier, '+', '-', '(', '[' or 'Tak_dapat'" )) return res.success(node)
def func_def(self): res = ParseResult() if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Fungsi'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Fungsi'")) res.register_advancement() self.advance() if self.current_tok.type == Lexer.TT_IDENTIFIER: var_name_tok = self.current_tok res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_LPAREN: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) '('")) else: var_name_tok = None if self.current_tok.type != Lexer.TT_LPAREN: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) identifier or '('" )) res.register_advancement() self.advance() arg_name_toks = [] if self.current_tok.type == Lexer.TT_IDENTIFIER: arg_name_toks.append(self.current_tok) res.register_advancement() self.advance() while self.current_tok.type == Lexer.TT_COMMA: res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_IDENTIFIER: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) identifier" )) arg_name_toks.append(self.current_tok) res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_RPAREN: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) ',' or ')'")) else: if self.current_tok.type != Lexer.TT_RPAREN: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) identifier or ')'" )) res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_ARROW: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) '->'")) res.register_advancement() self.advance() node_to_return = res.register(self.expr()) if res.error: return res return res.success( Lexer.FuncDefNode(var_name_tok, arg_name_toks, node_to_return))
def for_expr(self): res = ParseResult() if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Untuk_kita'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Untuk_kita'")) res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_IDENTIFIER: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) identifier")) var_name = self.current_tok res.register_advancement() self.advance() if self.current_tok.type != Lexer.TT_EQ: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) '='")) res.register_advancement() self.advance() start_value = res.register(self.expr()) if res.error: return res if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Ke'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Ke'")) res.register_advancement() self.advance() end_value = res.register(self.expr()) if res.error: return res if self.current_tok.matches(Lexer.TT_KEYWORD, 'Melangkah'): res.register_advancement() self.advance() step_value = res.register(self.expr()) if res.error: return res else: step_value = None if not self.current_tok.matches(Lexer.TT_KEYWORD, 'Maka_cakrawala'): return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, f"Mengharapkan seperti (senja kala itu) 'Maka_cakrawala'")) res.register_advancement() self.advance() body = res.register(self.expr()) if res.error: return res return res.success( Lexer.ForNode(var_name, start_value, end_value, step_value, body))
def atom(self): res = ParseResult() tok = self.current_tok if tok.type in (Lexer.TT_INT, Lexer.TT_FLOAT): res.register_advancement() self.advance() return res.success(Lexer.NumberNode(tok)) elif tok.type == Lexer.TT_STRING: res.register_advancement() self.advance() return res.success(Lexer.StringNode(tok)) elif tok.type == Lexer.TT_IDENTIFIER: res.register_advancement() self.advance() return res.success(Lexer.VarAccessNode(tok)) elif tok.type == Lexer.TT_LPAREN: res.register_advancement() self.advance() expr = res.register(self.expr()) if res.error: return res if self.current_tok.type == Lexer.TT_RPAREN: res.register_advancement() self.advance() return res.success(expr) else: return res.failure( Lexer.InvalidSyntaxError( self.current_tok.pos_start, self.current_tok.pos_end, "Mengharapkan seperti (senja kala itu) ')'")) elif tok.type == Lexer.TT_LSQUARE: list_expr = res.register(self.list_expr()) if res.error: return res return res.success(list_expr) elif tok.matches(Lexer.TT_KEYWORD, 'Ketika_nada'): if_expr = res.register(self.if_expr()) if res.error: return res return res.success(if_expr) elif tok.matches(Lexer.TT_KEYWORD, 'Untuk_kita'): for_expr = res.register(self.for_expr()) if res.error: return res return res.success(for_expr) elif tok.matches(Lexer.TT_KEYWORD, 'Sedangkan'): while_expr = res.register(self.while_expr()) if res.error: return res return res.success(while_expr) elif tok.matches(Lexer.TT_KEYWORD, 'Fungsi'): func_def = res.register(self.func_def()) if res.error: return res return res.success(func_def) return res.failure( Lexer.InvalidSyntaxError( tok.pos_start, tok.pos_end, "Mengharapkan seperti (senja kala itu) int, float, identifier, '+', '-', '(', '[', 'Ketika_nada', 'Untuk_kita', 'Sedangkan', 'Fungsi'" ))