def test_full_expression(): # 27 + (43 / 36 - 48) * 51 tokens = [ Token(TokenType.NUMBER, 27), Token(TokenType.PLUS), Token(TokenType.LPAREN), Token(TokenType.NUMBER, 43), Token(TokenType.DIVIDE), Token(TokenType.NUMBER, 36), Token(TokenType.MINUS), Token(TokenType.NUMBER, 48), Token(TokenType.RPAREN), Token(TokenType.MULTIPLY), Token(TokenType.NUMBER, 51), ] node = Parser(tokens).parse() assert node == BinNode( NumberNode(27), TokenType.PLUS, BinNode( BinNode( BinNode( NumberNode(43), TokenType.DIVIDE, NumberNode(36), ), TokenType.MINUS, NumberNode(48), ), TokenType.MULTIPLY, NumberNode(51), ))
def test_unary(): node = UnaryNode(TokenType.PLUS, NumberNode(1)) value = Interpreter().visit(node) assert value == Number(1) node = UnaryNode(TokenType.MINUS, NumberNode(1)) value = Interpreter().visit(node) assert value == Number(-1)
def test_plus(): tokens = [ Token(TokenType.NUMBER, 1), Token(TokenType.PLUS), Token(TokenType.NUMBER, 2), ] node = Parser(tokens).parse() assert node == BinNode(NumberNode(1), TokenType.PLUS, NumberNode(2))
def test_unary(): tokens = [ Token(TokenType.PLUS), Token(TokenType.NUMBER, 1), ] node = Parser(tokens).parse() assert node == UnaryNode(TokenType.PLUS, NumberNode(1)) tokens = [ Token(TokenType.MINUS), Token(TokenType.NUMBER, 1), ] node = Parser(tokens).parse() assert node == UnaryNode(TokenType.MINUS, NumberNode(1))
def makeifcond(self): self.advance() ret=[] cond = self.cmp() if str(self.cur_tok) not in (TTTHEN): self.tot+=MAKEPERROR return ret self.advance() self.tot+=1 cons = self.cmp() ret.append((cond,cons)) #print(cond,cons,self.cur_tok) while(str(self.cur_tok)==TTELIF): self.advance() self.tot+=1 cond = self.cmp() if str(self.cur_tok) != TTTHEN: self.tot+=MAKEPERROR return ret self.advance() self.tot+=1 cons = self.cmp() ret.append((cond,cons)) if(str(self.cur_tok)==TTELSE): self.advance() self.tot+=1 cons= self.cmp() ret.append((NumberNode(Token(TT_INT,1)),cons)) return UnaryOpNode(TTIF,ret)
def atom(self): res = ParseResult() tok = self.current_token if tok.type in (TT_INT, TT_FLOAT): res.register(self.advance()) return res.success(NumberNode(tok)) elif tok.type == TT_LPAREN: res.register(self.advance()) expr = res.register(self.expr()) if res.error: return res if self.current_token.type == TT_RPAREN: res.register(self.advance()) return res.success(expr) else: return res.failure(InvalidSyntaxError( self.current_token.pos_start, self.current_token.pos_end, "Expected ')'" )) return res.failure(InvalidSyntaxError( tok.pos_start, tok.pos_end, "Expected INT, FLOAT, '+', '-' or '('" ))
def factor(self): '''factor: number | LPAREN expr RPAREN''' token = self.current_token # for parentheses if token.type == TokenType.LPAREN: self._advance() # recursive call to restart from expression result = self.expr() if self.current_token.type != TokenType.RPAREN: self.raise_error() self._advance() return result # for simple number if token.type == TokenType.NUMBER: self._advance() return NumberNode(token.value) # for unary operations elif token.type in [TokenType.PLUS, TokenType.MINUS]: self._advance() return UnaryNode(token.type, self.factor()) self.raise_error()
def test_individual_operations(): left = NumberNode(27) right = NumberNode(14) value = Interpreter().visit(BinNode(left, TokenType.PLUS, right)) assert value == Number(41) value = Interpreter().visit(BinNode(left, TokenType.MINUS, right)) assert value == Number(13) value = Interpreter().visit(BinNode(left, TokenType.MULTIPLY, right)) assert value == Number(378) value = Interpreter().visit(BinNode(left, TokenType.DIVIDE, right)) assert value.value == pytest.approx(1.92857, 5) with pytest.raises(Exception): Interpreter().visit(BinNode(left, TokenType.DIVIDE, NumberNode(0)))
def test_full_expression(): tree = BinNode( NumberNode(27), TokenType.PLUS, BinNode( BinNode( BinNode( NumberNode(43), TokenType.DIVIDE, NumberNode(36), ), TokenType.MINUS, NumberNode(48), ), TokenType.MULTIPLY, NumberNode(51), )) result = Interpreter().visit(tree) assert result.value == pytest.approx(-2360.08, 2)
def factor(self): if self.current is not None: if self.current.type == "LPAREN": self.next() res = self.add_subtract() if (self.current is None) or (self.current.type != "RPAREN"): raise SyntaxError("Invalid Syntax") self.next() return res if self.current.type in ("NUMBER"): cur = self.current self.next() return NumberNode(cur.value) raise SyntaxError("Invalid Syntax")
def expression(self): #print(self.cur_tok.type) if str(self.cur_tok.type) in (TTVAR): ######################################### MADE CHANGES self.advance() self.tot+=1 id=self.cur_tok #self.op_tok if self.cur_tok.type != TTIDENTIFIER: self.tot+=len(self.tokens) #ERROR else: self.advance() self.tot+=1 if(self.cur_tok.type!= TTEQ): self.tot+=len(self.tokens)#ERROR else: self.advance() self.tot+=1 return BinOpNode(NumberNode(id,True),TTEQ,self.expression()) return self.ops(self.term,(TTPLUS,TTMINUS,TTEQ,TTAND,TTOR))
def factor(self): self.tot+=1 tok=self.cur_tok if tok.type in (TTPLUS,TTMINUS,TTNOT): self.advance() factor= self.factor() return UnaryOpNode(tok,factor) elif tok.type in (TT_INT,TTIDENTIFIER): self.advance() return NumberNode(tok) elif tok.type in (TTLPAREN): self.advance() expr = self.cmp() if self.cur_tok.type in (TTRPAREN): self.tot+=1 self.advance() return expr else: self.tot+=len(self.tokens) elif tok.type in (TTLBRACE): self.advance() multiexpr= self.statements() if self.cur_tok.type in (TTRBRACE): self.tot+=1 self.advance() return multiexpr return multiexpr elif tok.type in(TTIF): return self.makeifcond() elif tok.type in(TTWHILE): return self.makewhile() elif tok.type in (TTINPUT,TTOUTPUT): self.advance() if(self.cur_tok.type != TTIDENTIFIER): print("Only input single variables") self.tot+=MAKEPERROR self.advance() return else: val=self.cur_tok self.tot+=1 self.advance() return UnaryOpNode(tok,val)
def test_individual_operations(): tokens = [ Token(TokenType.NUMBER, 27), Token(TokenType.PLUS), Token(TokenType.NUMBER, 14), ] node = Parser(tokens).parse() assert node == BinNode(NumberNode(27), TokenType.PLUS, NumberNode(14)) tokens = [ Token(TokenType.NUMBER, 27), Token(TokenType.MINUS), Token(TokenType.NUMBER, 14), ] node = Parser(tokens).parse() assert node == BinNode(NumberNode(27), TokenType.MINUS, NumberNode(14)) tokens = [ Token(TokenType.NUMBER, 27), Token(TokenType.MULTIPLY), Token(TokenType.NUMBER, 14), ] node = Parser(tokens).parse() assert node == BinNode(NumberNode(27), TokenType.MULTIPLY, NumberNode(14)) tokens = [ Token(TokenType.NUMBER, 27), Token(TokenType.DIVIDE), Token(TokenType.NUMBER, 14), ] node = Parser(tokens).parse() assert node == BinNode(NumberNode(27), TokenType.DIVIDE, NumberNode(14))
def factor(self): token = self.currentToken if isinstance(token, OpeningBracket): self.advance() result = self.expression() if not isinstance(self.currentToken, ClosingBracket): self.raiseError() self.advance() return result elif isinstance(token, Operand): self.advance() return NumberNode(token.value) elif isinstance(token, Plus): self.advance() return PlusNode(self.factor()) elif isinstance(token, Minus): self.advance() return MinusNode(self.factor()) self.raiseError()
def test_numbers(): value = Interpreter().visit(NumberNode(51.2)) assert value == Number(51.2)
def test_number(): tokens = [Token(TokenType.NUMBER, 51.2)] node = Parser(tokens).parse() assert node == NumberNode(51.2)