def declaration(self): # int i =0, k; # int s = f() #variables = [] code = [] if self.symbol.value in self.lexer.types: type = self.symbol.value self.next() while self.symbol != Lexeme(';', 'punctuation'): if self.symbol.type == 'id' and self.symbol not in self.environment: symbol = self.symbol symbol.type = type self.environment.dict[symbol.value] = (type, None) self.next() if self.symbol == Lexeme(',', 'punctuation'): self.next() #variables.append(symbol) continue if self.symbol.value == '=': self.next() expr = self.expression() etype = expr.type #Check type expression and symbol. t = Operator('=') t.add_branch(Variable(symbol.value, symbol.type, True)) self.varnum+=1 if expr.type == 'funcall': function = self.get_env_value(Lexeme(expr.name, expr.type)) etype = function.returnType if etype == symbol.type: self.environment.dict[symbol.value] = expr t.add_branch(expr) code.append(t) else: self.error() # self.next() if self.symbol == Lexeme(',', 'punctuation'): self.next() continue else: self.error(self.symbol.value + ' already declared or not id') return code
def factor(self): """ factor = (expression) | number """ t = Operator('') if self.symbol.value == '(': self.next('(') branch = self.expression() t.add_branch(branch) self.next(')') else: symbol = self.symbol c = self.symbol.value if symbol.type in self.lexer.types: try: t = Constant(symbol.value, symbol.type) self.next() except ValueError as e: raise ParserError(self.symbol, self.lineNum, self.symbolNum) return t if symbol.type == 'id': (local, exist) = self.exists_in_env(symbol) if symbol.value in [x.name for x in builtin]: type = 'function' symbol.type = 'function' else: if exist: type = self.get_type_in_env(symbol) symbol.type = type else: self.error('unknown symbol') # Att! If funcname == id name, it will bad else: self.error('unknown symbol type') if symbol.type == 'function': t = self.function_call() else: symbol.type = type t = Variable(symbol.value, symbol.type, local) self.next() return t
def atom(self): """atom ::= factor^factor """ t = Operator('') lbranch = self.factor() t.add_branch(lbranch) flag = True onetime = False while self.symbol.value == '^': flag = False tt = t if (onetime): tt = Node() tt.add_branch(t) self.next() rbranch = self.factor() tt.add_branch(rbranch) t = tt onetime = True if flag: t = lbranch return t
def atom(self): """atom ::= factor^factor """ t = Operator('') lbranch = self.factor() t.add_branch(lbranch) flag = True onetime = False while self.symbol.value == '^': flag = False tt = t if(onetime): tt = Node() tt.add_branch(t) self.next() rbranch = self.factor() tt.add_branch(rbranch) t = tt onetime = True if flag: t = lbranch return t
def declaration(self): # int i =0, k; # int s = f() #variables = [] code = [] if self.symbol.value in self.lexer.types: type = self.symbol.value self.next() while self.symbol != Lexeme(';', 'punctuation'): if self.symbol.type == 'id' and self.symbol not in self.environment: symbol = self.symbol symbol.type = type self.environment.dict[symbol.value] = (type, None) self.next() if self.symbol == Lexeme(',', 'punctuation'): self.next() #variables.append(symbol) continue if self.symbol.value == '=': self.next() expr = self.expression() etype = expr.type #Check type expression and symbol. t = Operator('=') t.add_branch(Variable(symbol.value, symbol.type, True)) self.varnum += 1 if expr.type == 'funcall': function = self.get_env_value( Lexeme(expr.name, expr.type)) etype = function.returnType if etype == symbol.type: self.environment.dict[symbol.value] = expr t.add_branch(expr) code.append(t) else: self.error() # self.next() if self.symbol == Lexeme(',', 'punctuation'): self.next() continue else: self.error(self.symbol.value + ' already declared or not id') return code
def expression(self): """ expression ::= [term+-term] """ t = Operator('') sign = 1 # I have no good idea for unary [+/-] if self.symbol.value == '+': # ignore this operator #t.add_branch(Tree(self.symbol)) self.next() if self.symbol.value == '-': t.add_branch(Node(self.symbol.value, self.symbol.type)) self.next() sign = -1 lbranch = self.term() t.add_branch(lbranch) flag = True onetime = False while self.symbol.value in ['+', '-']: flag = False if (onetime): tt = Operator('') tt.add_branch(t) else: tt = Operator('') tt.add_branch(lbranch) symbol = self.symbol if self.symbol.value == '+': rbranch = self.add() tt.name = '+' if self.symbol.value == '-': rbranch = self.sub() tt.name = '-' tt.mark = symbol.value tt.add_branch(rbranch) t = tt onetime = True if flag: t = lbranch return t
def term(self): """ term ::= [atom/*factor] """ lbranch = self.atom() t = Operator('') t.add_branch(lbranch) # flag == True ==> We don't wrap tree as term. Keep it atom. flag = True # onetime == True ==> Every iteration in while() we build new tree, where old tree = left branch of it. onetime = False while self.symbol.value in ['/', '*']: flag = False tt = t if onetime: tt = Operator('') tt.add_branch(t) tt.mark = self.symbol.value if self.symbol.value == '/': rbranch = self.div() tt.name = '/' if self.symbol.value == '*': rbranch = self.mul() tt.name = '*' tt.add_branch(rbranch) onetime = True t = tt if (flag): t = lbranch return t
def instruction(self, nl=True): #funcall or assignment if self.symbol.value == 'return': if (self.environment.top == None): raise ParserError('return in global scope') t = Return() self.next() expr = self.expression() type = self.currentFunction.returnType etype = expr.type if (type == etype): t.add_branch(expr) self.next(';') else: self.error('incompatible types when returning type "' + etype + '" but "' + type + '" was expected') return t else: if self.symbol.value in [x.name for x in builtin]: ex = True local = True else: (local, ex) = self.exists_in_env(self.symbol) if ex: type = self.get_type_in_env(self.symbol) symbol = self.symbol symbol.type = type if symbol.type == 'func': t = self.factor() self.next(';') return t #t = Operator('=') self.next() if self.symbol.value in self.lexer.operations: t = Operator(self.symbol.value) self.next() expr = self.expression() etype = expr.type #Check type expression and symbol. if expr.type == 'funcall': if expr.name in [x.name for x in builtin]: for x in builtin: if x.name == expr.name: function = x break else: function = self.get_env_value( Lexeme(expr.name, expr.type)) etype = function.returnType if symbol.type == etype: t.add_branch(Variable(symbol.value, symbol.type, local)) t.add_branch(expr) if (nl): self.next(';') self.next() return t else: self.error('unexpected assignment ' + expr.type + ' to ' + symbol.type) else: self.error('undefined or rvalue')
def expression(self): """ expression ::= [term+-term] """ t = Operator( '') sign = 1 # I have no good idea for unary [+/-] if self.symbol.value == '+' : # ignore this operator #t.add_branch(Tree(self.symbol)) self.next() if self.symbol.value == '-': t.add_branch(Node(self.symbol.value, self.symbol.type)) self.next() sign = -1 lbranch = self.term() t.add_branch(lbranch) flag = True onetime = False while self.symbol.value in ['+', '-']: flag = False if(onetime): tt = Operator('') tt.add_branch(t) else: tt = Operator('') tt.add_branch(lbranch) symbol = self.symbol if self.symbol.value =='+': rbranch = self.add() tt.name = '+' if self.symbol.value =='-': rbranch = self.sub() tt.name = '-' tt.mark = symbol.value tt.add_branch(rbranch) t = tt onetime = True if flag: t = lbranch return t
def term(self): """ term ::= [atom/*factor] """ lbranch = self.atom() t = Operator('') t.add_branch(lbranch) # flag == True ==> We don't wrap tree as term. Keep it atom. flag = True # onetime == True ==> Every iteration in while() we build new tree, where old tree = left branch of it. onetime = False while self.symbol.value in ['/', '*']: flag = False tt = t if onetime: tt = Operator('') tt.add_branch(t) tt.mark = self.symbol.value if self.symbol.value == '/': rbranch = self.div() tt.name = '/' if self.symbol.value == '*': rbranch = self.mul() tt.name = '*' tt.add_branch(rbranch) onetime = True t = tt if(flag): t = lbranch return t