Skip to content

Commit

Permalink
Add a support with string
Browse files Browse the repository at this point in the history
  • Loading branch information
streetartist authored Sep 5, 2020
1 parent 44bed55 commit a0ce00f
Showing 1 changed file with 42 additions and 22 deletions.
64 changes: 42 additions & 22 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ def run(string: str) -> str:
'''

from rply import LexerGenerator

lg = LexerGenerator()

lg.add('NUMBER', r'\d+')
lg.add('PLUS', r'\+')
lg.add('MINUS', r'-')
Expand All @@ -23,51 +23,58 @@ def run(string: str) -> str:
lg.add('OPEN_PARENS', r'\(')
lg.add('CLOSE_PARENS', r'\)')
lg.add('PRINT',r'print')

lg.add('STRING',r'"\w"')

lg.ignore('\s+')

lexer = lg.build()

from rply.token import BaseBox

class Number(BaseBox):
def __init__(self, value):
self.value = value

def eval(self):
return self.value


class String(BaseBox):
def __init__(self, value):
self.value = value

def eval(self):
return self.value

class BinaryOp(BaseBox):
def __init__(self, left, right):
self.left = left
self.right = right

class Add(BinaryOp):
def eval(self):
return self.left.eval() + self.right.eval()

class Sub(BinaryOp):
def eval(self):
return self.left.eval() - self.right.eval()

class Mul(BinaryOp):
def eval(self):
return self.left.eval() * self.right.eval()

class Div(BinaryOp):
def eval(self):
return self.left.eval() / self.right.eval()

class Print(BinaryOp):
def eval(self):
print(self.right.eval())

return self.right.eval()
from rply import ParserGenerator

pg = ParserGenerator(
# A list of all token names, accepted by the parser.
['NUMBER', 'OPEN_PARENS', 'CLOSE_PARENS',
['NUMBER','STRING', 'OPEN_PARENS', 'CLOSE_PARENS',
'PLUS', 'MINUS', 'MUL', 'DIV','PRINT'
],
# A list of precedence rules with ascending precedence, to
Expand All @@ -78,17 +85,23 @@ def eval(self):
('right',['PRINT'])
]
)

@pg.production('expression : NUMBER')
def expression_number(p):
# p is a list of the pieces matched by the right hand side of the
# rule
return Number(int(p[0].getstr()))

@pg.production('expression : STRING')
def expression_number(p):
# p is a list of the pieces matched by the right hand side of the
# rule
return String(p[0].getstr())

@pg.production('expression : OPEN_PARENS expression CLOSE_PARENS')
def expression_parens(p):
return p[1]

@pg.production('expression : expression PLUS expression')
@pg.production('expression : expression MINUS expression')
@pg.production('expression : expression MUL expression')
Expand All @@ -106,15 +119,22 @@ def expression_binop(p):
return Div(left, right)
else:
raise AssertionError('Oops, this should not be possible!')

@pg.production('expression : PRINT expression')
def expression_func(p):
right = p[1]
if p[0].gettokentype() == 'PRINT':
return Print(None, right)

parser = pg.build()

@pg.error
def error_handler(token):
raise ValueError("Ran into a %s where it wasn't expected" % token.gettokentype())


while(True):
try:
print(parser.parse(lexer.lex(input(">>>"))).eval())
except Exception as e:
print(e)

0 comments on commit a0ce00f

Please sign in to comment.