Skip to content

Instantly share code, notes, and snippets.

@calmery
Created January 8, 2018 14:35
Show Gist options
  • Save calmery/9a38ccd9619fe30f322d456400e42810 to your computer and use it in GitHub Desktop.
Save calmery/9a38ccd9619fe30f322d456400e42810 to your computer and use it in GitHub Desktop.
Four arithmetic operations
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