Created
January 8, 2018 14:35
-
-
Save calmery/9a38ccd9619fe30f322d456400e42810 to your computer and use it in GitHub Desktop.
Four arithmetic operations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def is_digit( num ) : | |
if num in list( map( lambda n: str( n ), range( 10 ) ) ) : | |
return True | |
return False | |
class Tokenizer : | |
def __init__( self, formula ) : | |
self.formula = formula | |
self.tokens = [] | |
self.position = 0 | |
token = '' | |
character = '' | |
while True : | |
character = self.peek() | |
if character == None : | |
break | |
if character == ' ' : | |
self.next() | |
continue | |
if is_digit( character ) or character == '.' : | |
token = token + character | |
self.next() | |
continue | |
if token != '' : | |
self.tokens.append( token ) | |
token = '' | |
self.tokens.append( character ) | |
self.next() | |
if token != '' : | |
self.tokens.append( token ) | |
def peek( self ) : | |
if self.position < len( self.formula ) : | |
return self.formula[self.position] | |
return None | |
def next( self ) : | |
self.position = self.position + 1 | |
def get_tokens( self ) : | |
return self.tokens | |
class Parser : | |
def __init__( self, tokens ) : | |
self.tokens = tokens | |
self.position = 0 | |
def peek( self ) : | |
if self.position < len( self.tokens ) : | |
return self.tokens[self.position] | |
return None | |
def poll( self ) : | |
position = self.position | |
self.position = self.position + 1 | |
return self.tokens[position] | |
def parse( self ) : | |
return self.expression() | |
def expression( self ) : | |
n = self.term() | |
if self.peek() == '+' or self.peek() == '-' : | |
n = { | |
'type': 'BinaryExpression', | |
'operator': self.poll(), | |
'left': n, | |
'right': self.term() | |
} | |
return n | |
def term( self ) : | |
n = self.factor() | |
if self.peek() == '*' or self.peek() == '/' : | |
n = { | |
'type': 'BinaryExpression', | |
'operator': self.poll(), | |
'left': n, | |
'right': self.factor() | |
} | |
return n | |
def factor( self ) : | |
if self.peek() == '(' : | |
self.poll() | |
n = self.expression() | |
self.poll() | |
return n | |
else : | |
return { | |
'type': 'Literal', | |
'value': self.poll() | |
} | |
def evaluate( tree ) : | |
if tree['type'] == 'BinaryExpression' : | |
left = evaluate( tree['left'] ) | |
right = evaluate( tree['right'] ) | |
if tree['operator'] == '+' : | |
return left + right | |
if tree['operator'] == '-' : | |
return left - right | |
if tree['operator'] == '*' : | |
return left * right | |
if tree['operator'] == '/' : | |
return left / right | |
if tree['type'] == 'Literal' : | |
if tree['value'].find( '.' ) == -1 : | |
return int( tree['value'] ) | |
else : | |
return float( tree['value'] ) | |
formula = '((2 + 5.1) + 2) * 2' | |
tokens = Tokenizer( formula ).get_tokens() | |
parsed = Parser( tokens ).parse() | |
result = evaluate( parsed ) | |
print( result ) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment