如何解析RPLY中的多行?

2024-05-17 07:15:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图用RPLY创建一种虚构的语言,但当我试图解析语言中的多行代码时遇到了麻烦

我搜索了一下,发现我的问题出在语言的语法上。但我对RPLY不是很有经验,我一直在解决这个问题

我无法在parser.py文件中构造正确的代码(定义语法规则时调用什么函数)

我看到了一些建议,比如创建规则'program : program statement''program : statement',但是我如何为上面的规则定义下面的函数呢

AST.py

class Integer():
    def __init__(self, valor):
        self.valor = valor

    def eval(self):
        return int(self.valor)
    
class OpBinarios():
    def __init__(self, esquerda, direita):
        self.esquerda = esquerda
        self.direita = direita

class Subtracao(OpBinarios):
    def eval(self):
        return self.esquerda.eval() - self.direita.eval()

class Soma(OpBinarios):
    def eval(self):
        return self.esquerda.eval() + self.direita.eval()

class Mult(OpBinarios):
    def eval(self):
        return self.esquerda.eval() * self.direita.eval()

class Div(OpBinarios):
    def eval(self):
        return self.esquerda.eval() / self.direita.eval()

class Mod(OpBinarios):
    def eval(self):
        return self.esquerda.eval() % self.direita.eval()

class Left_Shift(OpBinarios):
    def eval(self):
        return self.esquerda.eval() << self.direita.eval()

class Right_Shift(OpBinarios):
    def eval(self):
        return self.esquerda.eval() >> self.direita.eval()

class Unsigned_Right_Shift(OpBinarios):
    def eval(self):
        return (self.esquerda.eval() % 0x100000000) >> self.direita.eval()

class And(OpBinarios):
    def eval(self):
        return self.esquerda.eval() and self.direita.eval()

class Write(OpBinarios):
    def __init__(self, valor):
        self.valor = valor
    
    def eval(self):
        print(self.valor.eval())

parser.py

def parse(self):
        @self.pg.production('program : WRITE OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
        def write(p):
            return Write(p[2])

        @self.pg.production('expression : expression SOMA expression')
        @self.pg.production('expression : expression SUBTRACAO expression')
        @self.pg.production('expression : expression MULT expression')
        @self.pg.production('expression : expression DIV expression')
        @self.pg.production('expression : expression MOD expression')
        @self.pg.production('expression : expression LEFT_SHIFT expression')
        @self.pg.production('expression : expression RIGHT_SHIFT expression')
        @self.pg.production('expression : expression >>> expression')
        def operacoes(p):
            esquerda = p[0]
            direita = p[2]
            operator = p[1]

            if operator.gettokentype() == 'SOMA':
                print()
                return Soma(esquerda, direita)
            
            elif operator.gettokentype() == 'SUBTRACAO':
                return Subtracao(esquerda, direita)
            
            elif operator.gettokentype() == 'MULT':
                return Mult(esquerda, direita)
            
            elif operator.gettokentype() == 'DIV':
                return Div(esquerda, direita)
            
            elif operator.gettokentype() == 'MOD':
                return Mod(esquerda, direita)

            elif operator.gettokentype() == 'LEFT_SHIFT':
                return Left_Shift(esquerda, direita)
            
            elif operator.gettokentype() == 'RIGHT_SHIFT':
                return Right_Shift(esquerda, direita)

            elif operator.gettokentype() == '>>>':
                return Unsigned_Right_Shift(esquerda, direita)
            else:
                raise AssertionError('Opa, isso não é possível!')
        
        @self.pg.production('expression : INTEGER')
        def numero(p):
            return Integer(int(p[0].value))
        
        @self.pg.error
        def error_handler(token):
            raise ValueError(f'Encontrou um {token.gettokentype()} onde não era esperado')

    def get_parser(self):
        return self.pg.build()

代码的某些部分是葡萄牙语的,因为我是巴西人,如果有人不懂,请告诉我


Tags: selfreturndefevaloperatorclassvalorproduction