Я работаю над созданием нового языка и использую библиотеку RPLY для целей лексического анализа и анализа. Теперь я застреваю при получении ошибки, когда использую более одной строки в файле кода.
вот мои файлы: -
mylexer.py
from rply import LexerGenerator
class Lexer():
def __init__(self):
self.lexer = LexerGenerator()
def _add_tokens(self):
# Print
self.lexer.add('PRINT', r'print')
# Parenthesis
self.lexer.add('OPEN_PAREN', r'\(')
self.lexer.add('CLOSE_PAREN', r'\)')
# Semi Colon
self.lexer.add('SEMI_COLON', r'\;')
# Operators
self.lexer.add('SUM', r'\+')
self.lexer.add('SUB', r'\-')
self.lexer.add('DIV', r'\/')
self.lexer.add('MUL', r'\*')
self.lexer.add('MOD', r'\%')
# Number
#self.lexer.add('INT', r'^[-+]?\d+$')
self.lexer.add('NUMBER',r'[-+]?[0-9]*\.?[0-9]+')
# Ignore spaces
self.lexer.ignore('\s+')
#self.lexer.ignore('\n+')
#self.lexer.ignore('\\*.*?\\*/')
def get_lexer(self):
self._add_tokens()
return self.lexer.build()
myparser.py
from rply import ParserGenerator
from ast import *
class Parser():
def __init__(self):
self.pg = ParserGenerator(
# A list of all token names accepted by the parser.
['NUMBER', 'PRINT', 'OPEN_PAREN', 'CLOSE_PAREN',
'SEMI_COLON', 'SUM', 'SUB','MUL','DIV','MOD']
)
def parse(self):
@self.pg.production('program : PRINT OPEN_PAREN expression CLOSE_PAREN SEMI_COLON')
def program(p):
return Print(p[2])
@self.pg.production('expression : expression SUM expression')
@self.pg.production('expression : expression SUB expression')
@self.pg.production('expression : expression MUL expression')
@self.pg.production('expression : expression DIV expression')
@self.pg.production('expression : expression MOD expression')
def expression(p):
left = p[0]
right = p[2]
operator = p[1]
if operator.gettokentype() == 'SUM':
return Sum(left, right)
elif operator.gettokentype() == 'SUB':
return Sub(left, right)
elif operator.gettokentype() == 'MUL':
return Mul(left, right)
elif operator.gettokentype() == 'DIV':
return Div(left, right)
elif operator.gettokentype() == 'MOD':
return Mod(left, right)
@self.pg.production('expression : NUMBER')
def number(p):
return Number(p[0].value)
@self.pg.error
def error_handle(token):
raise ValueError(token)
def get_parser(self):
return self.pg.build()
ast.py
class Number():
def __init__(self, value):
self.value = value
def eval(self):
try:
return int(self.value)
except ValueError:
return float(self.value)
class BinaryOp():
def __init__(self, left, right):
self.left = left
self.right = right
class Sum(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 Mod(BinaryOp):
def eval(self):
return self.left.eval() % self.right.eval()
class Print():
def __init__(self, value):
self.value = value
def eval(self):
print(self.value.eval())
main.py
from mylexer import Lexer
from myparser import Parser
data=""""""
with open('test.vlj', 'r') as file:
data = file.read()
lexer = Lexer().get_lexer()
tokens = lexer.lex(data)
# print(type(tokens))
# for token in tokens:
# print(token)
pg = Parser()
pg.parse()
parser = pg.get_parser()
parser.parse(tokens).eval()
test.vlj
print(12.5*2);
print(150+17.5);
Когда я пишу только одну строку в test.vlj, он оценивается, но проблема возникает при использовании более линия. Как мне написать свою продукцию для анализа нескольких строк кода? Также, если возможно, вы можете дать мне несколько ссылок на учебники и документы для изучения RPLY.