- 16 Eki 2020
- 442
- 20
Merhabalar, bugün sizlere Python programlama dili ile nasıl programlama dili oluşturulur, bunun hakkında size bilgi vermeye çalışacağım.
Çalışma şekli
Yorumlayıcı sizin yazdığınız kaynak kodu alır ve Lexer kısmında (yani söz dizilimi) kısmında işleme sokar, lexer kuralları oluşturur ve sizin oluşturduğunuz kurallara göre kodu parçalara böler, eğer kurallar aşılırsa hata verdirilir.
Lexer'de işlem bittikten sonra oluşturulan token'ler parser kısmında yeniden işleme sokulur ve parser ile kodlar ağaç yapısı şeklinde gruplara bölünür.
Lexer'de işlem bittikten sonra oluşturulan token'ler parser kısmında yeniden işleme sokulur ve parser ile kodlar ağaç yapısı şeklinde gruplara bölünür.
Önce kendi lexerimizi yazacağız.
Önce içe aktarma işlemlerini yapalım:
Önce içe aktarma işlemlerini yapalım:
Kod:
from sly import Lexer
Daha sonra lexerimizi oluşturalım:
Kod:
class BasicLexer(Lexer):
tokens = { NAME, NUMBER, STRING }
ignore = '\t '
literals = { '=', '+', '-', '/',
'*', '(', ')', ',', ';'}
# Define tokens as regular expressions
# (stored as raw strings)
NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
STRING = r'\".*?\"'
# Number token
@_(r'\d+')
def NUMBER(self, t):
# convert it into a python integer
t.value = int(t.value)
return t
# Comment token
@_(r'//.*')
def COMMENT(self, t):
pass
# Newline token(used only for showing
# errors in new line)
@_(r'\n+')
def newline(self, t):
self.lineno = t.value.count('\n')
Şimdi parser oluşturalım, fakat önce aktarma işlemlerini yapalım:
Kod:
from sly import Parser
Şimdi parserimizi oluşturalım:
Kod:
class BasicParser(Parser):
#tokens are passed from lexer to parser
tokens = BasicLexer.tokens
precedence = (
('left', '+', '-'),
('left', '*', '/'),
('right', 'UMINUS'),
)
def __init__(self):
self.env = { }
@_('')
def statement(self, p):
pass
@_('var_assign')
def statement(self, p):
return p.var_assign
@_('NAME "=" expr')
def var_assign(self, p):
return ('var_assign', p.NAME, p.expr)
@_('NAME "=" STRING')
def var_assign(self, p):
return ('var_assign', p.NAME, p.STRING)
@_('expr')
def statement(self, p):
return (p.expr)
@_('expr "+" expr')
def expr(self, p):
return ('add', p.expr0, p.expr1)
@_('expr "-" expr')
def expr(self, p):
return ('sub', p.expr0, p.expr1)
@_('expr "*" expr')
def expr(self, p):
return ('mul', p.expr0, p.expr1)
@_('expr "/" expr')
def expr(self, p):
return ('div', p.expr0, p.expr1)
@_('"-" expr %prec UMINUS')
def expr(self, p):
return p.expr
@_('NAME')
def expr(self, p):
return ('var', p.NAME)
@_('NUMBER')
def expr(self, p):
return ('num', p.NUMBER)
Şimdi yorumlayıcımızı yazalım ve daha sonra dilimizi çalıştıralım:
Kod:
class BasicExecute:
def __init__(self, tree, env):
self.env = env
result = self.walkTree(tree)
if result is not None and isinstance(result, int):
print(result)
if isinstance(result, str) and result[0] == '"':
print(result)
def walkTree(self, node):
if isinstance(node, int):
return node
if isinstance(node, str):
return node
if node is None:
return None
if node[0] == 'program':
if node[1] == None:
self.walkTree(node[2])
else:
self.walkTree(node[1])
self.walkTree(node[2])
if node[0] == 'num':
return node[1]
if node[0] == 'str':
return node[1]
if node[0] == 'add':
return self.walkTree(node[1]) + self.walkTree(node[2])
elif node[0] == 'sub':
return self.walkTree(node[1]) - self.walkTree(node[2])
elif node[0] == 'mul':
return self.walkTree(node[1]) * self.walkTree(node[2])
elif node[0] == 'div':
return self.walkTree(node[1]) / self.walkTree(node[2])
if node[0] == 'var_assign':
self.env[node[1]] = self.walkTree(node[2])
return node[1]
if node[0] == 'var':
try:
return self.env[node[1]]
except LookupError:
print("Undefined variable '"+node[1]+"' found!")
return 0
Çıkışı Görüntüleme:
Yorumlayıcıdan gelen çıktıyı görüntülemek için bazı kodlar yazmalıyız. Kod önce lexeri, sonra parseri ve ardından yorumlayıcıyı çağırmalı ve son olarak çıktıyı almalıdır. Çıkış, daha sonra kabukta görüntülenir.
Yorumlayıcıdan gelen çıktıyı görüntülemek için bazı kodlar yazmalıyız. Kod önce lexeri, sonra parseri ve ardından yorumlayıcıyı çağırmalı ve son olarak çıktıyı almalıdır. Çıkış, daha sonra kabukta görüntülenir.
Son komutlarımızı yazalım ve daha sonra dilimizi çalıştıralım:
Kod:
if __name__ == '__main__':
lexer = BasicLexer()
parser = BasicParser()
print('GFG Language')
env = {}
while True:
try:
text = input('GFG Language > ')
except EOFError:
break
if text:
tree = parser.parse(lexer.tokenize(text))
BasicExecute(tree, env)
Herhangi bir hatayı ele almadığımızı bilmemiz gerekir, bu sebepten yazdığınız kurallarda belirtilmeyen bir şey yaptığınızda hata mesajı gösterilecek.
Şimdi programlama dilimizi çalıştıralım:
Şimdi programlama dilimizi çalıştıralım:
Dipnotlar:
Oluşturduğumuz tercüman çok basit. Elbette bu, daha fazlasını yapmak için genişletilebilir. Döngüler ve koşul ifadeleri eklenebilir. Modüller veya nesneye yönelik tasarım özellikleri uygulanabilir. Modül entegrasyonu, yöntem tanımları, parametrelerden yöntemlere aynı şekilde genişletilebilecek özelliklerden bazılarıdır. Hayırlı günler.
Oluşturduğumuz tercüman çok basit. Elbette bu, daha fazlasını yapmak için genişletilebilir. Döngüler ve koşul ifadeleri eklenebilir. Modüller veya nesneye yönelik tasarım özellikleri uygulanabilir. Modül entegrasyonu, yöntem tanımları, parametrelerden yöntemlere aynı şekilde genişletilebilecek özelliklerden bazılarıdır. Hayırlı günler.
alıntıdır//
Moderatör tarafında düzenlendi: