def check_expression(self, tokens, each=False): line_num = tokens.current.line exp = self.parse_expression(tokens) if exp is not None: if tokens.is_end(): return exp if tokens.now.name == 'ASSIGN': left = exp return self.assignment_expression(tokens, left) elif tokens.current.name == 'COMMA': others = self.list_expression(tokens) left = exp left = [left] + others if tokens.now.name == 'ASSIGN': return self.assignment_expression(tokens, left) if tokens.prev.name == "DEDENT": # there is one undetected bug now, use this to solve it pass else: self.eat(tokens, "NEWLINE") return exp if tokens.current.name == "INDENT": raise ParserError('unexpected indent', tokens.current)
def compare_expression(self, tokens, left): # ==,>,< , <=, >=, + ,-, op = 'OPERATOR' pre = self.get_precedence(tokens.current) token = self.eat(tokens, op) right = self.parse_expression(tokens, pre) if right is None: raise ParserError('Expected right expression', tokens.current) current_pre = self.get_precedence(tokens.current) if current_pre != -1 and current_pre > pre: left = ast.BinaryOperator(token.value, left, right, token.line) parser = self.get_infix_parser(tokens.current.name) if parser: return parser(tokens, left) return ast.BinaryOperator(token.value, left, right, token.line)
def call_expression(self, tokens, left): keyword = {} line_num = left.line func_name = left.value if not isinstance(left, ast.Identifier): raise ParserError("SyntaxError: ", tokens.current) self.eat(tokens, 'LPAREN') arguments = self.list_expression(tokens) if tokens.current.name == "ASSIGN": keyword = self.function_keys(tokens, func_name) if keyword: # del last item, it is part of keywords del arguments[-1] self.eat(tokens, 'RPAREN') return ast.Call(func_name, arguments, keyword, line_num)
def assignment_expression(self, tokens, left): multiple = False if not isinstance( left, (ast.Identifier, ast.SubscriptOperator, ast.Objcall, list)): raise ParserError("SyntaxError: cant assign to %s" % left._name, tokens.current) self.eat(tokens, 'ASSIGN') line_num = left[0].line if isinstance(left, list) else left.line test, right2 = None, None right = self.parse_expression(tokens) if not right: raise ParserError('SyntaxError: expected assignment value', tokens.current) if tokens.current.name == 'COMMA': multiple = True # left, right # r,t,m = 9,0,6 right = [right] + self.list_expression(tokens) if not isinstance(left, list): #left is not list , right is list # a = 9,2,3,4,5 # convert it to array right = ast.Array(right, line_num) else: # both are list # assert number of left items equals right assert_expression( len(left) == len(right), 'assignment items count not equal to right', line_num) else: #right item is not list # assert left item also is not list assert_expression( not isinstance(left, list), 'cant assign multiple value to single expression', line_num) if tokens.check_expected("QUE"): # a = 9 ? 6==9:8 self.eat(tokens, 'QUE') test = self.parse_expression(tokens) if not test: raise ParserError('Syntax Error: expected comparism operator', tokens.current) self.eat(tokens, "COLON") right2 = self.parse_expression(tokens) # check if right-2 is also multiple value eg, va1,val2 if tokens.current.name == 'COMMA': right2 = [right2] + self.list_expression(tokens) if not isinstance(left, list): right2 = ast.Array(right2, line_num) else: assert_expression( len(left) == len(right2), 'assignment items count not equal to right', line_num) else: assert_expression(not isinstance(left, list), 'assignment errors', line_num) if not right2: raise ParserError('Syntax Error: expect a value', tokens.current) self.eat(tokens, 'NEWLINE') return ast.Assignment(left, right, test, right2, line_num)
def math_expression(self, tokens): raise ParserError( 'this is not supported yet "-x or + x", use x - y instead', tokens.current) pass
def err_expression(self, tokens): raise ParserError("SyntaxError: unexpected tokens", tokens.current)