From a0ce00f1245aeabfc83c0d962e3b3b6b43bc2246 Mon Sep 17 00:00:00 2001 From: streetartist <60282562+streetartist@users.noreply.github.com> Date: Sun, 6 Sep 2020 06:53:52 +0800 Subject: [PATCH] Add a support with string --- src/main.py | 64 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/src/main.py b/src/main.py index 9ea4c3f..8d6b2c9 100644 --- a/src/main.py +++ b/src/main.py @@ -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'-') @@ -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 @@ -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') @@ -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)