#! /usr/bin/python3
#-*- coding: utf-8 -*-
import argparse
import re
import os
from data import symbol_to_sort_map, max_length_symbol
import logging
from colorlog import ColoredFormatter
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = ColoredFormatter(
"%(log_color)s%(levelname)-8s %(message)s",
datefmt=None,
reset=True,
log_colors={
'DEBUG': 'cyan',
'INFO': 'green',
'WARNING': 'yellow',
'ERROR': 'red',
'CRITICAL': 'red,bg_white',
},
secondary_log_colors={},
style='%'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.DEBUG)
class SymbolTable:
def __init__(self):
self.symbol = {}
def create(self, symbol):
if symbol not in self.symbol:
self.symbol[symbol] = {}
class LexicalAnalysis:
def __init__(self, filename):
'''
äºå
å¼:
åè¯ç¬¦å·[space]ç§å«
16 1 2
'''
self.filename = filename + '.dyd'
self.errorfile = filename + '.err'
@classmethod
def is_const(cls, symbol):
if re.match('^\d+$', symbol):
return True
def error(self, text):
open(self.errorfile, 'a').write(text)
def is_identify(self, symbol, line=0):
if symbol in symbol_to_sort_map:
return False
elif re.match('^[a-zA-Z_]+[a-zA-Z0-9_]*$', symbol):
if len(str(symbol)) <= 16:
return True
else:
e = '***LINE:%02d overlength symbol "%s"' % (line, symbol)
errorMsg = 'LexicalAnalysis.is_identify(1): %s' % e
logger.error(errorMsg)
self.error(e)
return None
else:
return False
def write(self, symbol, sort):
text = '%16s %02d' % (symbol, sort)
logger.debug('LexicalAnalysis.write: %s' % text)
open(self.filename, 'a').write(text + '\n')
def writeEOLN(self):
text = '%16s %02d' % ('EOLN', 24)
logger.debug('LexicalAnalysis.writeEOLN: %s' % text)
open(self.filename, 'a').write(text + '\n')
def writeEOF(self):
text = '%16s %02d' % ('EOF', 24)
logger.debug('LexicalAnalysis.writeEOF: %s' % text)
open(self.filename, 'a').write(text + '\n')
def do(self, source_code, line=1):
# _ = re.findall('<\s+=', source_code)
# for i in _:
# source_code = source_code.replace(i, '<=')
# _ = re.findall('<\s+>', source_code)
# for i in _:
# source_code = source_code.replace(i, '<>')
# _ = re.findall('>\s+=', source_code)
# for i in _:
# source_code = source_code.replace(i, '>=')
# _ = re.findall(':\s+=', source_code)
# for i in _:
# source_code = source_code.replace(i, ':=')
source_code_split = source_code.replace('\n', ' \n ').split(' ')
for k in source_code_split:
if k == '\n':
line += 1
self.writeEOLN()
continue
if k == '':
continue
try:
code, token = self.check_defines(k, line)
except TypeError:
continue
# if code is None:
# continue
self.write(code, token)
if len(code) < len(k):
self.do(k[len(code):], line)
def check_defines(self, code, line=0):
l = len(code)
for i in range(max_length_symbol, 0, -1):
if code[0:i] in symbol_to_sort_map:
return (code[0:i], symbol_to_sort_map.get(code[0:i]))
if self.is_const(code):
return (code, 11)
if self.is_identify(code, line=line) is None:
return None
elif self.is_identify(code, line=line):
return (code, 10)
else:
pass
if l > 1:
return self.check_defines(code[0:-1], line)
else:
criticalMsg = '***LINE:%02d invalid symbol "%s"' % (line, code)
logger.critical('LexicalAnalysis.do(1): %s' % criticalMsg)
self.error(criticalMsg + '\n')
# exit(0)
# return (-1, -1)
class Var:
def __init__(self):
self.vname = '' # åéå
self.vproc = '' # æå±è¿ç¨
self.vkind = -1 # åç±» 0åé 1å½¢å
self.vtype = int # åéç±»å
self.vlev = -1 # åé屿¬¡
self.vadr = 0 # åéå¨åé表ä¸çä½ç½® ç¸å¯¹ç¬¬ä¸ä¸ªåéèè¨
class Pro:
def __init__(self):
self.pname = '' # è¿ç¨å
self.ptype = int # è¿ç¨ç±»å
self.plev = 0 # è¿ç¨å±æ¬¡
self.varNum = 0 # åéæ°é
self.fadr = 0 # 第ä¸ä¸ªåéä½ç½®
self.ladr = 0 # æåä¸ä¸ªåéä½ç½®
self.parameter = -1
self.parameterIsDefined = False
class GrammarAnalysis:
def __init__(self, filename):
'''
'''
self.filename = filename + '.dyd'
self.dysfilename = filename + '.dys'
self.errorfile = filename + '.err'
self.varfile = filename + '.var'
self.profile = filename + '.pro'
self.line = 1
self.token_index = 0
self.var = []
self.pro = []
self.currentVar = Var()
self.currentPro = Pro()
self.char_index = 0
self.error_cnt = 0
pass
def init(self):
logger.debug('GrammarAnalysis.init(1)')
logger.info('GrammarAnalysis.init(2): read file %s' % self.filename)
os.system('cp %s %s' % (self.filename, self.dysfilename))
self.tokens = open(self.filename, 'r').readlines()
def check(self, currentVar=None):
print('total error: %d ' % self.error_cnt)
print('----')
# print('list is:')
# for i in range(0, len(self.tokens), 1):
# print('<%d>%s' % (i, self.tokens[i]), end='')
print('now read:')
print(self.token_index, self.tokens[self.token_index])
print('var[]:')
for i in self.var:
print('vname=%s, vproc=%s, vkind=%d, vlev=%d, vadr=%d' % (i.vname, i.vproc, i.vkind, i.vlev, i.vadr))
print('pro[]:')
for i in self.pro:
print('pname=%s, ptype=%s, plev=%d, varNum=%d, fadr=%d, ladr=%d, parameter=%d, parameterIsDefined=%s' % (i.pname, i.ptype, i.plev, i.varNum, i.fadr, i.ladr, i.parameter, i.parameterIsDefined))
if currentVar is not None:
print('currentVar')
i = currentVar
print('vname=%s, vproc=%s, vkind=%d, vlev=%d, vadr=%d' % (i.vname, i.vproc, i.vkind, i.vlev, i.vadr))
print('currentPro:')
i = self.currentPro
print('pname=%s, ptype=%s, plev=%d, varNum=%d, fadr=%d, ladr=%d, parameter=%d, parameterIsDefined=%s' % (i.pname, i.ptype, i.plev, i.varNum, i.fadr, i.ladr, i.parameter, i.parameterIsDefined))
print('----')
def get_token(self, index=-1, code=False, change=True):
if index == -1:
index = self.token_index
d = ''.join(self.tokens[index].strip('\n')[0:16].split())
c = int(''.join(self.tokens[index].strip('\n')[17:19].split()))
if d == 'EOLN':
logger.info('get EOLN')
if change:
self.line += 1
logger.info('now line is %d, ->%s %d' % (self.line, d, c))
self.set_token_offset(1)
return self.get_token(index+1)
# logger.debug('-> %s' % d)
if code:
return c
else:
return d
def set_token_offset(self, offset=0, absolute=0):
self.char_index = 0
if offset != 0:
logger.debug('GrammarAnalysis.set_token_offset(1): get next %d' % offset)
self.token_index += offset
elif absolute != 0:
logger.debug('GrammarAnalysis.set_token_offset(1): turn to %d' % absolute)
self.token_index = absolute
else:
pass
logger.info('now token offset is %d' % self.token_index)
def error(self, text):
logger.error(text)
open(self.errorfile, 'a').write(text + '\n')
self.error_cnt += 1
def do(self):
self.init()
logger.debug('GrammarAnalysis.do(1)')
self.A()
self.check()
self.writeVar()
self.writePro()
def writeVar(self):
line = '%16s %16s %1d %s %d %d\n'
for i in self.var:
if i.vtype == int:
types = 'integer'
else:
types = ''
open(self.varfile, 'a').write(line % (i.vname, i.vproc, i.vkind, types, i.vlev, i.vadr))
def writePro(self):
line = '%16s %s %d %d %d\n'
for i in self.pro:
if i.ptype == int:
types = 'integer'
else:
types = ''
open(self.profile, 'a').write(line % (i.pname, types, i.plev, i.fadr, i.ladr))
def A(self):
logger.debug('GrammarAnalysis.A(1)')
self.B()
def B(self):
logger.debug('GrammarAnalysis.B(1)')
if self.get_token() == 'begin':
logger.debug('GrammarAnalysis.B(2): get <begin>')
self.set_token_offset(offset=1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'begin'))
if self.get_token() != 'integer':
self.set_token_offset(1)
self.C()
if self.get_token() == ';':
logger.debug('GrammarAnalysis.B(3): get <;>')
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
if self.get_token() != 'integer' and self.get_token() != 'read' and self.get_token() != 'write' and self.get_token(code=True) != 10:
self.set_token_offset(1)
self.M()
if self.get_token() == 'end':
logger.debug('GrammarAnalysis.B(4): get <end>')
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'end'))
def C(self):
logger.debug('GrammarAnalysis.C(1)')
self.D()
self.C_()
def C_(self):
logger.debug('GrammarAnalysis.C_(1)')
self.get_token()
if self.get_token() == ';' and self.get_token(self.token_index + 1, change=False) == 'integer':
logger.info('GrammarAnalysis.C(1): get ";" and next is "integer"')
self.set_token_offset(1)
self.D()
self.C_()
else:
if self.get_token() == 'integer':
logger.info('GrammarAnalysis.C(1): get "integer"')
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
self.D()
self.C_()
def D(self):
logger.debug('GrammarAnalysis.D(1)')
self.get_token()
if self.get_token(self.token_index + 1, change=False) == 'function':
logger.info('GrammarAnalysis.D(2): next is "function"')
self.J()
else:
logger.info('GrammarAnalysis.D(3): next is %s NOT "function"' % self.get_token())
self.E()
def is_var_exists(self, vname, vproc, vkind):
for i in self.var:
logger.info('GrammarAnalysis.is_var_exists(1): check this <%s, %s, %s> == <%s, %s, %s>' % (vname, vproc, vkind, i.vname, i.vproc, i.vkind))
if i.vname == vname and i.vproc == vproc and i.vkind == vkind:
return True
for i in self.pro:
logger.info('GrammarAnalysis.is_var_exists(1): check this <%s> == <%s>' % (vname, i.pname))
if i.pname == vname:
return True
if vproc != '':
return self.is_var_exists(vname, '', vkind)
else:
return False
def is_pro_exists(self, vname):
for i in self.var:
if vname == i.vname:
return True
for i in self.pro:
if vname == i.pname:
return True
return False
def E(self):
logger.debug('GrammarAnalysis.E(1)')
currentVar = Var()
if self.get_token() == 'integer':
logger.info('GrammarAnalysis.E(2): get "%s"' % self.get_token())
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'integer'))
self.set_token_offset(1)
currentVar.vname = self.get_token()
currentVar.vproc = self.currentPro.pname
# if self.token_index == self.currentPro.parameter:
if currentVar.vproc != '':
currentVar.vkind = 1
self.currentPro.parameterIsDefined = 1
else:
currentVar.vkind = 0
currentVar.vtype = int
currentVar.vlev = self.currentPro.plev
currentVar.vadr = len(self.var)
if self.is_var_exists(self.get_token(), self.currentPro.pname, currentVar.vkind):
self.error('***LINE:%02d Redifine var "%s"' % (self.line, self.get_token()))
else:
if self.currentPro.varNum == 0:
self.currentPro.fadr = currentVar.vadr
self.currentPro.ladr = currentVar.vadr
self.currentPro.varNum += 1
self.var.append(currentVar)
self.F();
def F(self):
logger.debug('GrammarAnalysis.F(1)')
self.G()
def G(self):
logger.debug('GrammarAnalysis.G(1)')
if self.get_token(code=True) == 10:
logger.info('GrammarAnalysis.G(2): get const "%s"' % self.get_token())
self.set_token_offset(1)
def J(self):
logger.debug('GrammarAnalysis.J(1)')
pro_bak = self.currentPro
if self.get_token() == 'integer':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'integer'))
if self.get_token() != 'function':
self.set_token_offset(1)
if self.get_token() == 'function':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'function'))
if self.get_token(code=True) != 10:
self.set_token_offset(1)
self.currentPro.pname = self.get_token()
self.currentPro.ptype = int
self.currentPro.plev += 1
self.currentPro.varNum = 0
self.currentPro.parameterIsDefined = False
if self.is_pro_exists(self.get_token()):
self.error('***LINE:%02d Redefine "%s"' % (self.line, self.get_token()))
self.G()
if self.get_token() == '(':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, '('))
if self.get_token(code=True) != 10:
self.set_token_offset(1)
self.currentPro.parameter = self.token_index
self.K()
if self.get_token() == ')':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ')'))
if self.get_token() != ';':
self.set_token_offset(1)
if self.get_token() == ';':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
if self.get_token() != 'begin':
self.set_token_offset(1)
self.L()
self.currentPro = pro_bak
def K(self):
logger.debug('GrammarAnalysis.K(1)')
self.F()
def L(self):
logger.debug('GrammarAnalysis.L(1)')
if self.get_token() == 'begin':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'begin'))
if self.get_token() != 'integer':
self.set_token_offset(1)
self.C()
if not self.currentPro.parameterIsDefined:
self.error('***LINE:%02d No Para "%s"' % (self.line, self.get_token()))
_ = self.currentPro
self.pro.append(_)
if self.get_token() == ';':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
if self.get_token() != 'integer' and self.get_token() != 'read' and self.get_token() != 'write' and self.get_token(code=True) != 10:
self.set_token_offset(1)
self.M()
if self.get_token() == 'end':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'end'))
if self.get_token() != ';' and self.get_token() != 'end':
self.set_token_offset(1)
def M(self):
logger.debug('GrammarAnalysis.M(1)')
self.N()
self.M_()
def M_(self):
logger.debug('GrammarAnalysis.M_(1)')
if self.get_token() == ';':
logger.info('GrammarAnalysis.M_(2): get "%s"' % self.get_token())
self.set_token_offset(1)
self.N()
self.M_()
else:
if self.get_token() != 'end' and self.get_token() != 'EOF':
logger.info('GrammarAnalysis.M_(3): get "%s"' % self.get_token())
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
self.N()
self.M_()
def N(self):
logger.debug('GrammarAnalysis.N(1)')
logger.info('GrammarAnalysis.N(2): get "%s"' % self.get_token())
if self.get_token() == 'read':
self.O()
elif self.get_token() == 'write':
self.P()
elif self.get_token() == 'if':
self.W()
elif self.get_token(code=True) == 10:
logger.info('GrammarAnalysis.N(2): get const "%s"' % self.get_token())
self.Q()
else:
self.error('***LINE:%02d Symbol exec error "%s"' % (self.line, self.get_token()))
self.set_token_offset(1)
def O(self):
logger.debug('GrammarAnalysis.O(1)')
if self.get_token() == 'read':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ';'))
if self.get_token() != '(':
self.set_token_offset(1)
if self.get_token() == '(':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, '('))
if self.get_token(code=True) != 10:
self.set_token_offset(1)
if not self.is_var_exists(self.get_token(), self.currentPro.pname, False) and not self.is_var_exists(self.get_token(), self.currentPro.pname, True):
self.error('***LINE:%02d Undefined Symbol "%s"' % (self.line, self.get_token()))
self.F()
if self.get_token() == ')':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ')'))
if self.get_token() != ';' and self.get_token() != 'end':
self.set_token_offset()
def P(self):
logger.debug('GrammarAnalysis.P(1)')
if self.get_token() == 'write':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'write'))
if self.get_token() != '(':
self.set_token_offset(1)
if self.get_token() == '(':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ')'))
if self.get_token(code=True) != 10:
self.set_token_offset(1)
if not self.is_var_exists(self.get_token(), self.currentPro.pname, False) and not self.is_var_exists(self.get_token(), self.currentPro.pname, True):
self.error('***LINE:%02d Undefined Symbol "%s"' % (self.line, self.get_token()))
self.F()
if self.get_token() == ')':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ')'))
if self.get_token() != ';' and self.get_token() != 'end':
self.set_token_offset(1)
def Q(self):
logger.debug('GrammarAnalysis.Q(1)')
if not self.is_var_exists(self.get_token(), self.currentPro.pname, False) and not self.is_var_exists(self.get_token(), self.currentPro.pname, True):
logger.info('GrammarAnalysis.Q(2): get "%s"' % self.get_token())
self.error('***LINE:%02d Undefined Symbol "%s"' % (self.line, self.get_token()))
self.F()
if self.get_token() == ':=':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ':='))
if self.get_token(code=True) != 10 and self.get_token(code=True) != 11:
self.set_token_offset(1)
self.R()
def R(self):
logger.debug('GrammarAnalysis.R(1)')
self.S()
self.R_()
def R_(self):
logger.debug('GrammarAnalysis.R_(1)')
if self.get_token() == '-':
logger.info('GrammarAnalysis.R_(2): get "%s"' % self.get_token())
self.set_token_offset(1)
self.S()
self.R_()
else:
if self.get_token(code=True) == 10 or self.get_token(code=True) == 11:
logger.info('GrammarAnalysis.R_(3): get const "%s"' % self.get_token())
self.S()
self.R_()
def S(self):
logger.debug('GrammarAnalysis.S(1)')
self.T()
self.S_()
def S_(self):
logger.debug('GrammarAnalysis.S_(1)')
if self.get_token() == '*':
logger.info('GrammarAnalysis.S_(2): get const "*"')
self.set_token_offset(1)
self.T()
self.S_()
else:
if self.get_token(code=True) == 10 or self.get_token(code=True) == 11:
logger.info('GrammarAnalysis.S_(3): get const "%s"' % self.get_token())
self.T()
self.S_()
def T(self):
logger.debug('GrammarAnalysis.T(1)')
if ord('0') <= ord(self.get_token()[self.char_index]) <= ord('9'):
logger.info('GrammarAnalysis.T(2): get const "%s"' % self.get_token())
self.U()
elif self.get_token(self.token_index + 1, change=False) == '(':
logger.info('GrammarAnalysis.T(3): get "("')
self.Z()
else:
if not self.is_var_exists(self.get_token(), self.currentPro.pname, False) and not self.is_var_exists(self.get_token(), self.currentPro.pname, True):
self.error('***LINE:%02d Undefined Symbol "%s"' % (self.line, self.get_token()))
self.F()
def U(self):
logger.debug('GrammarAnalysis.U(1)')
if self.get_token(code=True) == 11:
self.set_token_offset(1)
def W(self):
logger.debug('GrammarAnalysis.W(1)')
if self.get_token() == 'if':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'if'))
if self.get_token(code=True) != 10 and self.get_token(code=True) != 11:
self.set_token_offset(1)
self.X()
if self.get_token() == 'then':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'then'))
if self.get_token() != 'integer' and self.get_token() != 'read' and self.get_token() != 'write' and self.get_token(code=True) != 10:
self.set_token_offset(1)
self.N()
if self.get_token() == 'else':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'else'))
if self.get_token() != 'integer' and self.get_token() != 'read' and self.get_token() != 'write' and self.get_token(code=True) != 10:
self.set_token_offset(1)
self.N()
def X(self):
logger.debug('GrammarAnalysis.X(1)')
self.R()
self.Y()
self.R()
def Y(self):
logger.debug('GrammarAnalysis.Y(1)')
if self.get_token() == '<' or self.get_token() == '<=' or self.get_token() == '>' or self.get_token() == '>=' or self.get_token() == '=' or self.get_token() == '<>':
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, 'compair symbol'))
if self.get_token(code=True) != 10 and self.get_token(code=True) != 11:
self.set_token_offset(1)
def Z(self):
logger.debug('GrammarAnalysis.Z(1)')
if not self.is_pro_exists(self.get_token()):
self.error('***LINE:%02d Undefined Symbol "%s"' % (self.line, self.get_token()))
self.G()
if self.get_token() == '(':
logger.info('GrammarAnalysis.Z(2): get "("')
self.set_token_offset(1)
else:
self.error('***LINE:%02d No Symbol "%s"' % (self.line, '('))
if self.get_token(code=True) != 10 and self.get_token(code) != 11:
logger.info('GrammarAnalysis.Z(3): get "%s"' % self.get_token())
self.set_token_offset(1)
self.R()
if self.get_token() == ')':
logger.info('GrammarAnalysis.Z(4): get "%s"' % self.get_token())
self.currentPro = Pro()
self.set_token_offset(1)
else:
logger.info('GrammarAnalysis.Z(5): get "%s"' % self.get_token())
self.error('***LINE:%02d No Symbol "%s"' % (self.line, ')'))
if self.get_token() != '-' and self.get_token() != '*' and self.get_token() != ';' and self.get_token() != 'end':
self.set_token_offset(1)
class ReadFile:
def __init__(self, input_file):
self.input_file = input_file
try:
source_lines = open(input_file, 'r').readlines()
except FileNotFoundError as e:
logger.error('FileNotFound: %s' % input_file)
exit(0)
self.source_code = ''.join(source_lines)
def get_source_code(self):
return self.source_code
if __name__ == '__main__':
# a = LexicalAnalysis('test')
# a.write('begin', 1)
parser = argparse.ArgumentParser(description='little exp')
parser.add_argument('-f', '--file', help='source code file')
parser.add_argument('-c', '--clean', help='clean mid code', action='store_true')
parser.add_argument('-l', '--lexical', help='LexicalAnalysis', action='store_true')
parser.add_argument('-g', '--grammer', help='GrammarAnalysis', action='store_true')
#
source_code = ''
args = parser.parse_args()
if args.clean:
logger.info('main: delete files')
os.system('rm -f *.dyd *.err *.var *.pro *.dys')
elif args.file is None:
parser.print_help()
else:
logger.info('Read file from %s' % args.file)
source_code = ReadFile(args.file).get_source_code()
if args.lexical:
la = LexicalAnalysis('.'.join(args.file.split('.')[:-1]))
la.do(source_code)
la.writeEOF()
if args.grammer:
ga = GrammarAnalysis('.'.join(args.file.split('.')[:-1]))
ga.do()
from tokens.token import TokenType, Token
from error import SyntaxError
import parser_objects
class Parser:
def __init__(self, tokens):
self.tokens = tokens
self.current_token = -1
self.tree = self.create_tree()
# get next token from token list
def get_token(self):
self.current_token += 1
return self.tokens[self.current_token]
# compare token with expected token
def compare_tokens(self, token, type, msg=""):
if token.token_type != type:
raise SyntaxError(token, msg)
# get all token parsed and return AST
def create_tree(self):
model_description, model_content = self.parse_model()
model = parser_objects.Model(model_content[0], model_content[1], model_content[2],
model_content[3], model_description[0], model_description[1])
return model
# parse all tokens
def parse_model(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET, "Model does not start with '<'")
token = self.get_token()
self.compare_tokens(token, TokenType.T_UML_MODEL, "Model not defined")
model_description = self.parse_model_description() # [id, name]
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET, "Model description does not end with '>'")
model_content = self.parse_model_content() # [file_description, imports, elements, profiles]
self.parse_model_end()
return model_description, model_content
# parse model description
# model description = 'xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI"
# xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" ,
# ['xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation"'] ,
# xmlns:uml="http://www.eclipse.org/uml2/3.0.0/UML" xmlns:umlnotation="http://www.ibm.com/xtools/1.5.3/Umlnotation"
# xmi:id=', string value, ' name=', string value;
def parse_model_description(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_VERSION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMLNS_XMI)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMLNS_XSI)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMLNS_ECORE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
if token.token_type == TokenType.T_XMLNS_NOTATION:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMLNS_UML)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMLNS_UML_NOTATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
# model id
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
# model name
name = token.value
return [id, name]
# parse everything after model description
# model contents = file description,{ package import },{ packaged element },{ profile application };
def parse_model_content(self):
file_description = self.parse_file_description()
imports = []
pckg_import = self.parse_package_import()
while pckg_import != None:
imports.append(pckg_import)
pckg_import = self.parse_package_import()
elements = []
pckg_element = self.parse_packaged_element()
while pckg_element != None:
elements.append(pckg_element)
pckg_element = self.parse_packaged_element()
profiles = []
profile_application = self.parse_profile_application()
while profile_application != None:
profiles.append(profile_application)
profile_application = self.parse_profile_application()
return [file_description, imports, elements, profiles]
# file description = "<eAnnotations xmi:id=", string value, 'source="uml2.diagrams"', ['references=', string value]
# ,'>', file name, "</eAnnotations>";
def parse_file_description(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EANNOTATIONS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SOURCE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
source = token.value
token = self.get_token()
if token.token_type == TokenType.T_REFERENCES:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
graphics = self.parse_file_name()
file_description = parser_objects.FileDescription(graphics.graphic, id, source)
return file_description
# file name = "<contents xmi:type="umlnotation:UMLDiagram" xmi:id=", string value, ' type="Class" name=',
# string value, ">", graphic description, "</contents>";
def parse_file_name(self):
token = self.get_token()
graphics = parser_objects.GraphicDescription()
while type(token) is not Token:
# skip graphic description
# append all tokens to GraphicDescription class
graphics.graphic.append(token)
token = self.get_token()
self.current_token -= 1
return graphics
# package import = "<packageImport xmi:id=", id, ">", package, "</packageImport>";
def parse_package_import(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type == TokenType.T_PACKAGED_ELEMENT:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_PACKAGE_IMPORT)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
type, href = self.parse_package()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_PACKAGE_IMPORT)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
package = parser_objects.ImportedPackage(id, type, href)
return package
# package = '<importedPackage xmi:type="uml:Model" href=', string value, "/>";
def parse_package(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_IMPORTED_PACKAGE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_HREF)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
href = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return type, href
# packaged element = "<packagedElement xmi:type=", ( class | association ), "</packagedElement>";
def parse_packaged_element(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_PACKAGED_ELEMENT:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_PACKAGED_ELEMENT)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if token.value == '"uml:Class"':
return self.parse_class()
elif token.value == '"uml:Association"':
return self.parse_association()
else:
raise SyntaxError(token, "Unrecognised packaged element, xmi:type expected: uml:Class or uml:Association")
# class = '"uml:Class" xmi:id=', string value, " name=", string value, visibility, ['isLeaf="true"'],
# ['isAbstract="true"'], ">", [ stereotype ], [ generalization ], {attribute}, {operation};
def parse_class(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
name = token.value
visibility = self.parse_visibility()
is_abstract = '"false"'
is_leaf = '"false"'
token = self.get_token()
if token.token_type != TokenType.T_RIGHT_BRACKET or token.token_type != TokenType.T_SLASH:
while token.token_type == TokenType.T_IS_LEAF or token.token_type == TokenType.T_IS_ABSTRACT:
option_type = token.token_type
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if token.value != '"true"' and token.value != '"false"':
raise SyntaxError(token, "Unexpected value, expected true or false value")
else:
if option_type == TokenType.T_IS_LEAF:
is_leaf = token.value
elif option_type == TokenType.T_IS_ABSTRACT:
is_abstract = token.value
token = self.get_token()
if token.token_type == TokenType.T_SLASH:
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
parsed_class = parser_objects.Class(id, name, visibility, is_leaf, is_abstract, None, [], [], [])
return parsed_class
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
stereotype = self.parse_stereotype()
generalizations = []
generalization = self.parse_generalization()
while generalization != None:
generalizations.append(generalization)
generalization = self.parse_generalization()
attributes = []
attribute = self.parse_attribute()
while attribute != None:
attributes.append(attribute)
attribute = self.parse_attribute()
operations = []
operation = self.parse_operation()
while operation != None:
operations.append(operation)
operation = self.parse_operation()
self.parse_packaged_element_end()
parsed_class = parser_objects.Class(id, name, visibility, is_leaf, is_abstract, stereotype, generalizations, attributes, operations)
return parsed_class
# visibility = " visibility=", visibility type;
# visibility type = "public" | "private" | "protected" | "package";
def parse_visibility(self):
token = self.get_token()
if token.token_type != TokenType.T_VISIBILITY:
self.current_token -= 1
return '"public"'
self.compare_tokens(token, TokenType.T_VISIBILITY)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if token.value == '"public"' or token.value == '"private"' or token.value == '"protected"' \
or token.value == '"package"':
return token.value
else:
raise SyntaxError(token, "Unexpected visibility")
# stereotype = "<eAnnotations xmi:id=", string value, " source=", string value, ">", stereotype description,
# {stereotype description}, "</eAnnotations>";
def parse_stereotype(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_EANNOTATIONS:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_EANNOTATIONS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SOURCE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
source = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
stereotypes = []
stereotype = self.parse_stereotype_description()
while stereotype != None:
stereotypes.append(stereotype)
stereotype = self.parse_stereotype_description()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EANNOTATIONS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
stereotypes_obj = parser_objects.Stereotype(id, source, stereotypes)
return stereotypes_obj
# stereotype description = "<details xmi:id=", string value, " key=", string value, "/>";
def parse_stereotype_description(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_DETAILS:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_DETAILS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_KEY)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
key = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return [id, key]
# generalization = "<generalization xmi:id=", string value, " general=", string value, "/>";
def parse_generalization(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_GENERALIZATION:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_GENERALIZATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_GENERAL)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
general = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
generalization = parser_objects.Generalization(id, general)
return generalization
# attribute = "<ownedAttribute xmi:id=", string value, " name=", string value, attribute parameters,
# ( "/>" | attribute description );
# attribute description = ">", [type], [limit], [default value], "</ownedAttribute>";
def parse_attribute(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_OWNED_ATTRIBUTE:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_OWNED_ATTRIBUTE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
name = token.value
parameters = self.parse_attribute_parameters()
token = self.get_token()
if token.token_type == TokenType.T_SLASH:
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
attribute = parser_objects.Attribute(id, name, parameters, None, None, None, None)
return attribute
elif token.token_type == TokenType.T_RIGHT_BRACKET:
type = self.parse_type()
upper_limit = self.parse_upper_limit()
lower_limit = self.parse_lower_limit()
default_value = self.parse_default_value()
if type is None and default_value[1] is not None:
type = default_value[1]
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_OWNED_ATTRIBUTE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
attribute = parser_objects.Attribute(id, name, parameters, type, upper_limit, lower_limit, default_value[0])
return attribute
else:
raise SyntaxError(token, "Unexpected OwnedAttribute ending, expected '/' or '>'")
# type = "<type xmi:type=", string value, "href=", string value,"/>";
def parse_type(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_TYPE:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_HREF)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
href = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return type, href
# default value = "<defaultValue xmi:type=", string value, " xmi:id=", string value, " value=", string value,
# ( default value type | "/>" );
# default value type = type, "</defaultValue>";
def parse_default_value(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_DEFAULT_VALUE:
self.current_token -= 2
return [None, None]
self.compare_tokens(token, TokenType.T_DEFAULT_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
value = token.value
token = self.get_token()
default_type = None
if token.token_type != TokenType.T_SLASH:
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
default_type = self.parse_type()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_DEFAULT_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
default_value = parser_objects.Limit(type, id, value)
return [default_value, default_type]
# attribute parameters = visibility, ['isLeaf="true"'], ['isStatic="true"'], ['isOrdered="true"'],
# ['isReadOnly="true"'], ['isDerived="true"'], ['isDerivedUnion="true"'], [short type], [association type];
# association type = [ 'aggregation="composite"' | 'aggregation="shared"' ], "association=", string value;
def parse_attribute_parameters(self):
visibility = self.parse_visibility()
token = self.get_token()
aggregation = None
association = None
type = None
options = ['"false"', '"false"', '"false"', '"true"', '"false"', '"false"', '"false"']
if token.token_type != TokenType.T_RIGHT_BRACKET and token.token_type != TokenType.T_SLASH:
while token.token_type == TokenType.T_IS_LEAF or token.token_type == TokenType.T_IS_STATIC \
or token.token_type == TokenType.T_IS_ORDERED or token.token_type == TokenType.T_IS_READ_ONLY \
or token.token_type == TokenType.T_IS_DERIVED or token.token_type == TokenType.T_IS_DERIVED_UNION \
or token.token_type == TokenType.T_IS_UNIQUE:
type = token.token_type
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if type == TokenType.T_IS_LEAF:
options[0] = token.value
elif type == TokenType.T_IS_STATIC:
options[1] = token.value
elif type == TokenType.T_IS_ORDERED:
options[2] = token.value
elif type == TokenType.T_IS_UNIQUE:
options[3] = token.value
elif type == TokenType.T_IS_READ_ONLY:
options[4] = token.value
elif type == TokenType.T_IS_DERIVED:
options[5] = token.value
elif type == TokenType.T_IS_DERIVED_UNION:
options[6] = token.value
type = None
token = self.get_token()
if token.token_type == TokenType.T_TYPE:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
if token.token_type == TokenType.T_AGGREGATION:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
aggregation = token.value
token = self.get_token()
if token.token_type == TokenType.T_ASSOCIATION:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
association = token.value
token = self.get_token()
self.current_token -= 1
parameters = parser_objects.AttributeParameters(visibility, options[0], options[1], options[2], options[3], options[4], options[5], options[6], aggregation, association, type)
return parameters
# operation = "<ownedOperation xmi:id=", string value, " name=", string value, [ operation parameters ],
# ("/>" | parameter );
def parse_operation(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_OWNED_OPERATION:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_OWNED_OPERATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
name = token.value
parameters = self.parse_operation_parameters()
token = self.get_token()
owned_parameters = []
if token.token_type != TokenType.T_SLASH:
owned_parameter = self.parse_owned_parameter()
while owned_parameter != None:
owned_parameters.append(owned_parameter)
owned_parameter = self.parse_owned_parameter()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_OWNED_OPERATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
operation = parser_objects.Operation(id, name, parameters[0], parameters[1], parameters[2], parameters[3], parameters[4], owned_parameters)
return operation
# operation parameters = visibility, ['isLeaf="true"'], ['isStatic="true"'], ['isQuery="true"'];
def parse_operation_parameters(self):
visibility = self.parse_visibility()
isLeaf = '"false"'
isStatic = '"false"'
isAbstract = '"false"'
isQuery = '"false"'
token = self.get_token()
while token.token_type == TokenType.T_IS_LEAF or token.token_type == TokenType.T_IS_STATIC \
or token.token_type == TokenType.T_IS_QUERY or token.token_type == TokenType.T_IS_ABSTRACT:
type = token.token_type
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if type == TokenType.T_IS_LEAF:
isLeaf = token.value
elif type == TokenType.T_IS_STATIC:
isStatic = token.value
elif type == TokenType.T_IS_QUERY:
isQuery = token.value
elif type == TokenType.T_IS_ABSTRACT:
isAbstract = token.value
token = self.get_token()
self.current_token -= 1
return [visibility, isLeaf, isStatic, isAbstract, isQuery]
# parameter = owned parameter, {owned parameter}, "</ownedOperation>";
# owned parameter = "<ownedParameter xmi:id=", string value, " name=", string value, [owned parameter parameters],
# ("/>" | owned parameter description);
# owned parameter parameters = short type, ['isOrdered="true"'], ['isUnique="false"'], [parameter direction];
def parse_owned_parameter(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_OWNED_PARAMETER:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_OWNED_PARAMETER)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
name = token.value
short_type = self.parse_short_type()
token = self.get_token()
isOrdered = '"false"'
isUnique = '"true"'
while token.token_type == TokenType.T_IS_ORDERED or token.token_type == TokenType.T_IS_UNIQUE:
token_type = token.token_type
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
if token_type == TokenType.T_IS_ORDERED:
isOrdered = token.value
elif token_type == TokenType.T_IS_UNIQUE:
isUnique = token.value
token = self.get_token()
direction = self.parse_parameter_direction(token)
token = self.get_token()
if token.token_type != TokenType.T_SLASH:
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
description = self.parse_owned_parameter_description()
owned_parameter = parser_objects.OwnedParameter(id, name, description[0], isOrdered, isUnique, direction, description[1], description[2], description[3], short_type)
return owned_parameter
else:
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
owned_parameter = parser_objects.OwnedParameter(id, name, None, isOrdered, isUnique, direction, None, None, None, short_type)
return owned_parameter
# owned parameter description = ">", [type], [upper limit], [lower limit], [default value], "</ownedParameter>";
def parse_owned_parameter_description(self):
type = self.parse_type()
upper_limit = self.parse_upper_limit()
lower_limit = self.parse_lower_limit()
default_value = self.parse_default_value()
if type is None and default_value[1] is not None:
type = default_value[1]
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_OWNED_PARAMETER)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return [type, upper_limit, lower_limit, default_value[0]]
# parameter direction = " direction=", direction type;
# direction type = "return" | "out" | "inout";
def parse_parameter_direction(self, tok):
if tok.token_type != TokenType.T_DIRECTION:
self.current_token -= 1
return '"in"'
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
return token.value
# association = '"uml:Association"', " xmi:id=", string value, " memberEnd=", double string value, ">", owned end;
def parse_association(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_MEMBER_END)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_DOUBLE_STRING_VALUE)
member_end = token.value
token = self.get_token()
if token.token_type == TokenType.T_SLASH:
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
association = parser_objects.Association(id, member_end, None)
return association
elif token.token_type == TokenType.T_RIGHT_BRACKET:
owned_end = self.parse_owned_end()
association = parser_objects.Association(id, member_end, owned_end)
return association
else:
raise SyntaxError(token, "Invalid association ending, expected '/' or '>'")
# owned end = "<ownedEnd xmi:id=", string value, " name=", string value, visibility, short type, "association=",
# string value, ">", upper limit, lower limit, "</ownedEnd>";
def parse_owned_end(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_OWNED_END)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_NAME)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
name = token.value
visibility = self.parse_visibility()
type = self.parse_short_type()
token = self.get_token()
self.compare_tokens(token, TokenType.T_ASSOCIATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
association = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
upper_limit = self.parse_upper_limit()
lower_limit = self.parse_lower_limit()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_OWNED_END)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
self.parse_packaged_element_end()
owned_end = parser_objects.OwnedEnd(id, name, visibility, type, association, upper_limit, lower_limit)
return owned_end
# upper limit = "<upperValue xmi:type=", string value, " xmi:id=", string value, [" value=", ("1" | "*")] ,"/>";
def parse_upper_limit(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_UPPER_VALUE:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_UPPER_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
value = None
if token.token_type == TokenType.T_VALUE:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
value = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
upper_limit = parser_objects.Limit(type, id, value)
return upper_limit
# lower limit = "<lowerValue xmi:type=", string value, " xmi:id=", string value, [" value=", ("1" | "*")] ,"/>";
def parse_lower_limit(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_LOWER_VALUE:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_LOWER_VALUE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
value = None
if token.token_type == TokenType.T_VALUE:
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
value = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
lower_limit = parser_objects.Limit(type, id, value)
return lower_limit
# short type = " type=", string value;
def parse_short_type(self):
token = self.get_token()
if token.token_type != TokenType.T_TYPE:
self.current_token -= 1
return None
self.compare_tokens(token, TokenType.T_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
return token.value
# "</packagedElement>"
def parse_packaged_element_end(self):
msg = "Packaged element ended incorrectly!"
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_PACKAGED_ELEMENT, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET, msg)
# profile application = "<profileApplication xmi:id=", id, ">", eannotation,
# applied profile, "</profileApplication>";
def parse_profile_application(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
if token.token_type != TokenType.T_PROFILE_APPLICATION:
self.current_token -= 2
return None
self.compare_tokens(token, TokenType.T_PROFILE_APPLICATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
eannotation = self.parse_eannotation()
href = self.parse_applied_profile()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_PROFILE_APPLICATION)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
profile_application = parser_objects.ProfileApplication(eannotation, id, href)
return profile_application
# eannotation = "<eAnnotations xmi:id=", string value, " source=", string value, ">", references, "</eAnnotations>";
def parse_eannotation(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EANNOTATIONS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_ID)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
id = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SOURCE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
source = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
type, href = self.parse_references()
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EANNOTATIONS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
eannotation = parser_objects.EAnnotation(id, source, type, href)
return eannotation
# references = '<references xmi:type="ecore:EPackage" href=', string value, "/>";
def parse_references(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_REFERENCES)
token = self.get_token()
self.compare_tokens(token, TokenType.T_XMI_TYPE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
type = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_HREF)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
href = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return type, href
# applied profile = "<appliedProfile href=", path, "/>";
def parse_applied_profile(self):
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET)
token = self.get_token()
self.compare_tokens(token, TokenType.T_APPLIED_PROFILE)
token = self.get_token()
self.compare_tokens(token, TokenType.T_HREF)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EQUALS)
token = self.get_token()
self.compare_tokens(token, TokenType.T_STRING_VALUE)
href = token.value
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET)
return href
# parse </uml:Model> expression
def parse_model_end(self):
msg = "Model ended incorrectly!"
token = self.get_token()
self.compare_tokens(token, TokenType.T_LEFT_BRACKET, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_SLASH, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_UML_MODEL, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_RIGHT_BRACKET, msg)
token = self.get_token()
self.compare_tokens(token, TokenType.T_EOF, msg)
from os import linesep, pipe
from sys import exec_prefix
from analisador_lexico import *
import re
#Verificação da entrada
if(len(sys.argv) > 2):
print("Numero de argumentos invalido!")
sys.exit(1)
#Verificação da abertura do arquivo
try:
f = open(sys.argv[1], "r")
except:
print("Nao foi possivel abrir o arquivo!")
sys.exit(2)
output = open('output.txt', 'w')
token = ''
linha = f.readline()
cont_linha = 1
def error_func(S):
while(token not in S):
get_token()
erro_regex = 'erro\\(\\"(.*)\\"\\)'
def get_token():
global linha
global cont_linha
global token
fim = False
while(True):
cadeia = analisador_lexico(linha)
if(cadeia != ''):
break
linha = f.readline()
cont_linha += 1
if(len(linha) == 0):
exit()
cadeia = cadeia.split(', ')
token = cadeia[1].replace('\n', '')
var = re.match(erro_regex, cadeia[1])
if(var):
print('Erro léxico na linha {}: '.format(cont_linha), var.groups()[0])
if(var.groups()[0] == 'comentario nao finalizado'):
exit()
elif(var.groups()[0] == 'numero real mal formado'):
token = 'num_real'
linha = linha.replace(cadeia[0],'', 1)
linha = linha.strip()
''' if(linha):
if(linha[0]=='{' and linha[len(linha)-1]=='}'):
linha=''
if(not linha):
linha = f.readline()
cont_linha += 1
if(not linha):
fim = True'''
def programa(S):
if(token == 'simb_program'):
get_token()
else:
print("Erro sintático na linha {}: 'program' esperado".format(cont_linha), file=output)
error_func(['id'] + S)
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(P['corpo'] + ['simb_p'] + S)
corpo(['simb_p'] + S)
if(token == 'simb_p'):
get_token()
else:
print("Erro sintático na linha {}: '.' esperado".format(cont_linha), file=output)
error_func(S)
def corpo(S):
dc(['simb_begin'] + S)
if(token == 'simb_begin'):
get_token()
else:
print("Erro sintático na linha {}: 'begin' esperado".format(cont_linha), file=output)
error_func(P['comandos'] + ['simb_end'] + S)
comandos(['simb_end'] + S)
if(token == 'simb_end'):
get_token()
else:
print("Erro sintático na linha {}: 'end' esperado".format(cont_linha))
error_func(S)
def dc(S):
dc_c(P['dc_v'] + P['dc_p'] + S)
dc_v(P['dc_p'] + S)
dc_p(S)
def dc_c(S):
if(token == 'simb_const'):
get_token()
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(['simb_igual'] + S)
if(token == 'simb_igual'):
get_token()
else:
print("Erro sintático na linha {}: '=' esperado".format(cont_linha), file=output)
error_func(P['numero'] + S)
numero(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(P['dc_c'] + S)
dc_c(S)
else:
return
def dc_v(S):
if(token == 'simb_var'):
get_token()
variaveis(['simb_dp'] + S)
if(token == 'simb_dp'):
get_token()
else:
if(token == 'id'):
print("Erro sintático na linha {}: ',' esperado".format(cont_linha), file=output)
else:
print("Erro sintático na linha {}: ':' esperado".format(cont_linha), file=output)
error_func(P['tipo_var'] + S)
tipo_var(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(P['dc_v'] + S)
dc_v(S)
else:
return
def tipo_var(S):
if(token == 'simb_tipo'):
get_token()
else:
print("Erro sintático na linha {}: tipo da variável esperado".format(cont_linha), file=output)
error_func(S)
def variaveis(S):
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(P['mais_var'] + S)
mais_var(S)
def mais_var(S):
if(token == 'simb_virg'):
get_token()
else:
return
variaveis(S)
def dc_p(S):
if(token == 'simb_procedure'):
get_token()
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(P['parametros'] + ['simb_pv'] + S)
parametros(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(P['corpo_p'] + P['dc_p'] + S)
corpo_p(P['dc_p'] + S)
dc_p(S)
else:
return
def parametros(S):
if(token == 'simb_apar'):
get_token()
lista_par(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
print("Erro sintático na linha {}: ')' esperado".format(cont_linha), file=output)
error_func(S)
else:
return
def lista_par(S):
variaveis(['simb_dp'] + S)
if(token == 'simb_dp'):
get_token()
else:
print("Erro sintático na linha {}: ':' esperado".format(cont_linha), file=output)
error_func(P['tipo_var'] + S)
tipo_var(P['mais_par'] + S)
mais_par(S)
def mais_par(S):
if(token == 'simb_pv'):
get_token()
lista_par(S)
else:
return
def corpo_p(S):
dc_loc(['simb_begin'] + S)
if(token == 'simb_begin'):
get_token()
else:
print("Erro sintático na linha {}: 'begin' esperado".format(cont_linha), file=output)
error_func(P['comandos'] + ['simb_end'] + S)
comandos(['simb_end'] + S)
if(token == 'simb_end'):
get_token()
else:
print("Erro sintático na linha {}: 'end' esperado".format(cont_linha), file=output)
error_func(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(S)
def dc_loc(S):
dc_v(S)
def lista_arg(S):
if(token == 'simb_apar'):
get_token()
argumentos(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
print("Erro sintático na linha {}: ')' esperado".format(cont_linha), file=output)
error_func(S)
else:
return
def argumentos(S):
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(P['mais_ident'] + S)
mais_ident(S)
def mais_ident(S):
if(token == 'simb_pv'):
get_token()
argumentos(S)
else:
return
def pfalsa(S):
if(token == 'simb_else'):
get_token()
cmd(S)
else:
return
def comandos(S):
if(token in P['cmd']):
cmd(['simb_pv'] + S)
if(token == 'simb_pv'):
get_token()
else:
print("Erro sintático na linha {}: ';' esperado".format(cont_linha), file=output)
error_func(P['comandos'] + S)
comandos(S)
else:
return
def cmd(S):
if(token == 'simb_read'):
get_token()
if(token == 'simb_apar'):
get_token()
else:
print("Erro sintático na linha {}: '(' esperado".format(cont_linha), file=output)
error_func(P['variaveis'] + S)
variaveis(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
print("Erro sintático na linha {}: ')' esperado".format(cont_linha), file=output)
error_func(S)
elif(token == 'simb_write'):
get_token()
if(token == 'simb_apar'):
get_token()
else:
print("Erro sintático na linha {}: '(' esperado".format(cont_linha), file=output)
error_func(P['variaveis'] + S)
variaveis(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
print("Erro sintático na linha {}: ')' esperado".format(cont_linha), file=output)
error_func(S)
elif(token == 'simb_while'):
get_token()
if(token == 'simb_apar'):
get_token()
else:
print("Erro sintático na linha {}: '(' esperado".format(cont_linha), file=output)
error_func(P['condicao'] + S)
condicao(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
print("Erro sintático na linha {}: ')' esperado".format(cont_linha), file=output)
error_func(['simb_do'] + S)
if(token == 'simb_do'):
get_token()
else:
print("Erro sintático na linha {}: 'do' esperado".format(cont_linha), file=output)
error_func(P['cmd'] + S)
cmd(S)
elif(token == 'simb_if'):
get_token()
condicao(['simb_then'] + S)
if(token == 'simb_then'):
get_token()
else:
print("Erro sintático na linha {}: 'then' esperado".format(cont_linha), file=output)
error_func(P['cmd'] + S)
cmd(P['pfalsa'] + S)
pfalsa(S)
elif(token == 'id'):
get_token()
ident(S)
elif(token == 'simb_begin'):
get_token()
comandos(['simb_end'] + S)
if(token == 'simb_end'):
get_token()
else:
print("Erro sintático na linha {}: 'end' esperado".format(cont_linha), file=output)
error_func(S)
elif(token == 'simb_for'):
get_token()
if(token == 'id'):
get_token()
else:
print("Erro sintático na linha {}: identificador esperado".format(cont_linha), file=output)
error_func(['simb_atrib'] + S)
if(token == 'simb_atrib'):
get_token()
else:
print("Erro sintático na linha {}: ':=' esperado".format(cont_linha), file=output)
error_func(P['expressao'] + S)
expressao(['simb_to'] + S)
if(token == 'simb_to'):
get_token()
else:
print("Erro sintático na linha {}: 'to' esperado".format(cont_linha), file=output)
error_func(P['expressao'] + S)
expressao(['simb_do'] + S)
if(token == 'simb_do'):
get_token()
else:
print("Erro sintático na linha {}: 'do' esperado".format(cont_linha), file=output)
error_func(P['cmd'] + S)
cmd(S)
else:
print("Erro sintático na linha {}: comando esperado".format(cont_linha), file=output)
error_func(S)
def ident(S):
if(token == 'simb_atrib'):
get_token()
expressao(S)
elif(token == P['lista_arg']):
lista_arg(S)
else:
print("Erro sintático na linha {}: atribuição ou lista de argumentos esperada".format(cont_linha), file=output)
error_func(S)
def condicao(S):
expressao(P['relacao'] + S)
relacao(P['expressao'] + S)
expressao(S)
def relacao(S):
if(token == 'simb_igual'):
get_token()
elif(token == 'simb_dif'):
get_token()
elif(token == 'simb_maior_igual'):
get_token()
elif(token == 'simb_menor_igual'):
get_token()
elif(token == 'simb_maior'):
get_token()
elif(token == 'simb_menor'):
get_token()
else:
print("Erro sintático na linha {}: comparação esperada".format(cont_linha), file=output)
error_func(S)
def expressao(S):
termo(P['outros_termos'] + S)
outros_termos(S)
return
def op_un(S):
if(token == 'simb_mais'):
get_token()
elif(token == 'simb_menos'):
get_token()
else:
return
def outros_termos(S):
if(token in P['op_ad']):
op_ad(P['termo'] + S)
termo(P['outros_termos'] + S)
outros_termos(S)
else:
return
def op_ad(S):
if(token == 'simb_mais'):
get_token()
elif(token == 'simb_menos'):
get_token()
else:
print("Erro sintático na linha {}: operador '+' ou '-' esperado".format(cont_linha), file=output)
error_func(S)
def termo(S):
op_un(P['fator'] + S)
fator(P['mais_fatores'] + S)
mais_fatores(S)
def mais_fatores(S):
if(token in P['op_mul']):
op_mul(P['fator'] + S)
fator(P['mais_fatores'] + S)
mais_fatores(S)
else:
return
def op_mul(S):
if(token == 'simb_mult'):
get_token()
elif(token == 'simb_div'):
get_token()
else:
print("Erro sintático na linha {}: operador '*' ou '/' esperado".format(cont_linha), file=output)
error_func(S)
def fator(S):
if(token == 'id'):
get_token()
elif(token == 'simb_apar'):
get_token()
expressao(['simb_fpar'] + S)
if(token == 'simb_fpar'):
get_token()
else:
error_func(S)
elif(token in P['numero']):
numero(S)
else:
print("Erro sintático na linha {}: fator esperado".format(cont_linha), file=output)
error_func(S)
def numero(S):
if(token == 'num_int'):
get_token()
elif(token == 'num_real'):
get_token()
else:
print("Erro sintático na linha {}: valor numérico esperado".format(cont_linha), file=output)
error_func(S)
P = {
'programa': ['simb_program'],
'corpo': ['simb_const', 'simb_var', 'simb_procedure'],
'dc': ['simb_const', 'simb_var', 'simb_procedure'],
'dc_c': ['simb_const'],
'dc_v': ['simb_var'],
'tipo_var': ['simb_tipo'],
'variaveis': ['id'],
'mais_var': ['simb_virg'],
'dc_p': ['simb_procedure'],
'parametros': ['simb_apar'],
'lista_par': ['id'],
'mais_par': ['simb_pv'],
'corpo_p': ['simb_var'],
'dc_loc': ['simb_var'],
'lista_arg': ['simb_apar'],
'argumentos': ['id'],
'mais_ident': ['simb_pv'],
'pfalsa': ['simb_else'],
'comandos': ['simb_read', 'simb_write', 'simb_while', 'simb_if', 'id', 'simb_begin', 'simb_for'],
'cmd': ['simb_read', 'simb_write', 'simb_while', 'simb_if', 'id', 'simb_begin', 'simb_for'],
'ident': ['simb_atrib', 'simb_apar'],
'relacao': ['simb_igual', 'simb_dif', 'simb_maior_igual', 'simb_menor_igual', 'simb_maior', 'simb_menor'],
'expressao': ['simb_mais', 'simb_menos', 'id', 'simb_apar', 'num_int', 'num_real'],
'op_un': ['simb_mais', 'simb_menos'],
'outros_termos': ['simb_mais', 'simb_menos'],
'op_ad': ['simb_mais', 'simb_menos'],
'termo': ['simb_mais', 'simb_menos', 'simb_apar', 'id', 'num_int', 'num_real'],
'mais_fatores': ['simb_mult', 'simb_div'],
'op_mul': ['simb_mult', 'simb_div'],
'fator': ['id', 'num_int', 'num_real', 'simb_fpar'],
'numero': ['num_int', 'num_real']
}
get_token()
programa([])
f.close()
output.close()