def analyze(self): self.ERROR = False self.head = node() self.head.setData('head') stack = MyStack() self.lex = LexAn(self.string) endNode = node() endNode.setData('#') stack.push(endNode) startNode = node() startNode.setData(self.start) startNode.setParent(self.head) self.head.addChildren(startNode) stack.push(startNode) self.pointer = 0 self.lineCounter = 1 word, label, now = self.advance() outResult = '' while (True): '''遇注释号跳过''' if label == '注释号': word, label, now = self.advance() continue '''文件读完,未完成语法分析''' if word == -1: self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' no end token #\n') outResult += '\n' break '''遇非法字符''' if label == 'ERROR': self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' skip %s\n' % word) outResult += '\n' break out = ('line %d: ' % self.lineCounter + word + ',' + label) outResult = outResult + out.ljust(20, ' ') proResult = False topNode = stack.pop() X = topNode.data if X in self.Terminals: if X == now: if X == "标识符": topNode.parent.addAttributes('place', word) if topNode.parent.parent.data == '参数': symbol = {} symbol['type'] = topNode.parent.parent.children[ 0].data symbol['idName'] = word symbol['label'] = 'formal' symbol["domain"] = self.domain code = self.genCode(op='pop', result={'reg': self.newTmp()}) symbol['reg'] = code['result']['reg'] self.symbolList.append(symbol) self.funCode[self.domain].append(code) if topNode.parent.parent.data == '内部变量声明': symbol = {} symbol['type'] = topNode.parent.parent.children[ 0].data symbol['idName'] = word symbol['offset'] = self.offset self.offset += 4 symbol['label'] = 'data' symbol['domain'] = self.domain self.symbolList.append(symbol) if X == "num": topNode.parent.addAttributes('place', {'Imme': word}) if X == ';': if topNode.parent.data == '赋值语句': symbolIndex, tag = self.lookUpSymbol( topNode.parent.children[0].attributes['place'], self.domain) if symbolIndex < 0 or (tag != self.domain and tag != "global"): self.errorReason += ( "Line%d: undeclared identifier %s\n" % (self.lineCounter, topNode.parent. children[0].attributes['place'])) break if self.symbolList[symbolIndex][ 'label'] == 'formal': code = self.genCode( op=':=', arg1=topNode.parent.children[2]. attributes['place'], result={ 'reg': self.symbolList[symbolIndex]['reg'] }) elif self.symbolList[symbolIndex][ 'label'] == 'data': code = self.genCode( op=':=', arg1=topNode.parent.children[2]. attributes['place'], result={'symbolIndex': symbolIndex}) self.funCode[self.domain].append(code) elif topNode.parent.data == '返回值': self.haveReturn[self.domain] = True if topNode.parent.children[0].data == '表达式': symbolIndex, _ = self.lookUpSymbol( self.domain, self.domain) if self.symbolList[symbolIndex][ 'type'] == 'void': self.errorReason += 'Line%d: void %s can not have a return value.\n ' % ( self.lineCounter, self.domain) break self.funCode[self.domain].append( self.genCode( op='push', result=topNode.parent.children[0]. attributes['place'])) else: symbolIndex, _ = self.lookUpSymbol( self.domain, self.domain) if self.symbolList[symbolIndex][ 'type'] == 'int': self.errorReason += 'Line%d: int %s has no return value.\n ' % ( self.lineCounter, self.domain) break self.funCode[self.domain].append( self.genCode(op='jr', result='$ra')) self.domain = 'global' if X == ')': if topNode.parent.data == 'if语句': self.funCode[self.domain].append( self.genCode( op='j' + topNode.parent.children[2]. children[1].children[0].children[0].data, arg1=topNode.parent.children[2]. children[0].attributes['place'], arg2=topNode.parent.children[2].children[1] .children[1].attributes['place'], result=2)) self.funCode[self.domain].append( self.genCode(op='j', result=0)) topNode.parent.attributes['false'] = len( self.funCode[self.domain]) - 1 elif topNode.parent.data == 'while语句': self.funCode[self.domain].append( self.genCode( op='j' + topNode.parent.children[2]. children[1].children[0].children[0].data, arg1=topNode.parent.children[2]. children[0].attributes['place'], arg2=topNode.parent.children[2].children[1] .children[1].attributes['place'], result=2)) self.funCode[self.domain].append( self.genCode(op='j', result=0)) topNode.parent.attributes['end'] = len( self.funCode[self.domain]) - 1 elif topNode.parent.data == '因子': topNode.parent.attributes[ 'place'] = topNode.parent.children[ 1].attributes['place'] if X == '}': if topNode.parent.data == '语句块': if topNode.parent.parent.data == 'if语句': self.funCode[self.domain].append( self.genCode(op='j', result=0)) false = topNode.parent.parent.attributes[ 'false'] self.funCode[ self.domain][false]['result'] = len( self.funCode[self.domain]) - false topNode.parent.parent.attributes['end'] = len( self.funCode[self.domain]) - 1 elif topNode.parent.parent.data == 'else语句': end = topNode.parent.parent.parent.attributes[ 'end'] self.funCode[self.domain][end]['result'] = len( self.funCode[self.domain]) - end elif topNode.parent.parent.data == 'while语句': end = topNode.parent.parent.attributes['end'] self.funCode[self.domain].append( self.genCode( op='j', result=end - len(self.funCode[self.domain]) - 1)) self.funCode[self.domain][end]['result'] = len( self.funCode[self.domain]) - end topNode.addAttributes('lineNum', self.lineCounter) word, label, now = self.advance() else: self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' expect %s\n' % (X)) outResult += '\n' break elif X == '#': if X == now: break else: self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' please check near %s\n' % (word)) outResult += '\n' break elif X in self.Virables and self.Table.table[X][now] not in [ ' ', 'synch' ]: if self.Table.table[X][now].right == ['NULL']: newNode = node() newNode.setParent(topNode) newNode.setData('NULL') topNode.addChildren(newNode) else: k = len(self.Table.table[X][now].right) - 1 while (k >= 0): newNode = node() newNode.setParent(topNode) newNode.setData(self.Table.table[X][now].right[k]) topNode.addChildren(newNode) stack.push(newNode) k -= 1 topNode.reverseChildren() if X == '变量声明': symbol = {} symbol['type'] = topNode.parent.parent.children[0].data symbol['idName'] = topNode.parent.parent.children[ 1].attributes['place'] symbol['offset'] = self.offset self.offset += 4 symbol['label'] = 'data' symbol['domain'] = self.domain self.symbolList.append(symbol) elif X == '函数声明' and topNode.parent.data == '声明类型': symbol = {} symbol['type'] = topNode.parent.parent.children[0].data symbol['idName'] = topNode.parent.parent.children[ 1].attributes['place'] self.domain = symbol['idName'] self.funCode[self.domain] = [] symbol['label'] = 'func' symbol['domain'] = self.domain symbol['offset'] = self.offset self.offset += 4 self.haveReturn[self.domain] = False self.symbolList.append(symbol) elif X == '函数声明' and topNode.parent.data == '声明': symbol = {} symbol['type'] = topNode.parent.children[0].data symbol['idName'] = topNode.parent.children[1].attributes[ 'place'] self.domain = symbol['idName'] self.funCode[self.domain] = [] symbol['label'] = 'func' symbol['domain'] = self.domain self.haveReturn[self.domain] = True self.symbolList.append(symbol) if X == '加法表达式': self.tmpAddNodeList.push([]) elif X == '加法表达式1': top = self.tmpAddNodeList.top() top.append(topNode) elif X == '项': self.tmpMulNodeList.push([]) elif X == '项1': top = self.tmpMulNodeList.top() top.append(topNode) if X == '加法表达式1' and topNode.children[0].data == 'NULL': topAddNode = self.tmpAddNodeList.top() self.tmpAddNodeList.pop() if topNode.parent.data == '加法表达式': topNode.parent.attributes[ 'place'] = topNode.parent.children[0].attributes[ 'place'] del topAddNode[-1] for k in range(len(topAddNode)): addNode = topAddNode[len(topAddNode) - k - 1] if addNode.children[0].data == '-': addNode.children[0].data = '减' newTmp = self.newTmp() self.funCode[self.domain].append( self.genCode(op='+', arg1={'reg': 0}, arg2=addNode.children[1]. attributes['place'], result={'reg': newTmp})) self.funCode[self.domain].append( self.genCode(op='uminus', result={'reg': newTmp})) addNode.children[1].attributes['place'] = { 'reg': newTmp } if addNode.parent.children[0].data == '-': addNode.parent.children[0].data = '减' newTmp = self.newTmp() self.funCode[self.domain].append( self.genCode(op='+', arg1={'reg': 0}, arg2=addNode.parent.children[1]. attributes['place'], result={'reg': newTmp})) self.funCode[self.domain].append( self.genCode(op='uminus', result={'reg': newTmp})) addNode.parent.children[1].attributes['place'] = { 'reg': newTmp } newTmp = self.newTmp() if addNode.parent.data == '加法表达式': code = self.genCode( '+', addNode.parent.children[0].attributes['place'], addNode.children[1].attributes['place'], {'reg': newTmp}) addNode.parent.addAttributes( 'place', {'reg': newTmp}) else: code = self.genCode( '+', addNode.parent.children[1].attributes['place'], addNode.children[1].attributes['place'], {'reg': newTmp}) addNode.parent.children[1].addAttributes( 'place', {'reg': newTmp}) self.funCode[self.domain].append(code) elif X == '项1' and topNode.children[0].data == 'NULL': topMulNode = self.tmpMulNodeList.top() self.tmpMulNodeList.pop() if topNode.parent.data == '项': topNode.parent.attributes[ 'place'] = topNode.parent.children[0].attributes[ 'place'] del topMulNode[-1] for k in range(len(topMulNode)): mulNode = topMulNode[len(topMulNode) - k - 1] newTmp = self.newTmp() if mulNode.parent.data == '项': code = self.genCode( mulNode.children[0].data, mulNode.parent.children[0].attributes['place'], mulNode.children[1].attributes['place'], {'reg': newTmp}) mulNode.parent.addAttributes( 'place', {'reg': newTmp}) else: code = self.genCode( mulNode.children[0].data, mulNode.parent.children[1].attributes['place'], mulNode.children[1].attributes['place'], {'reg': newTmp}) mulNode.parent.children[1].addAttributes( 'place', {'reg': newTmp}) self.funCode[self.domain].append(code) elif X == '表达式1' and topNode.children[0].data == 'NULL': if topNode.parent.data != '表达式1': topNode.parent.addAttributes( 'place', topNode.parent.children[0].attributes['place']) if topNode.parent.parent.data == '因子': topNode.parent.parent.addAttributes( 'place', topNode.parent.children[0].attributes['place']) if topNode.parent.parent.data in ['实参列表', '实参列表1']: top = self.tmpParam.top() top.append(topNode.parent.attributes['place']) elif X == 'FTYPE' and topNode.children[0].data == 'NULL': symbolIndex, tag = self.lookUpSymbol( topNode.parent.children[0].attributes['place'], self.domain) if symbolIndex < 0 or (tag != self.domain and tag != "global"): self.errorReason += ( "Line%d: undeclared identifier %s\n" % (self.lineCounter, topNode.parent.children[0].attributes['place'])) break if self.symbolList[symbolIndex]['label'] == 'formal': topNode.parent.addAttributes( 'place', {'reg': self.symbolList[symbolIndex]['reg']}) elif self.symbolList[symbolIndex]['label'] == 'data': topNode.parent.addAttributes( 'place', {'symbolIndex': symbolIndex}) elif X == 'call': symbolIndex, tag = self.lookUpSymbol( topNode.parent.parent.children[0].attributes['place'], self.domain) if symbolIndex < 0: self.errorReason += ( "Line%d: undeclared function %s\n" % (self.lineCounter, topNode.parent.parent. children[0].attributes['place'])) break self.tmpSymbolIndex.push(symbolIndex) self.tmpParam.push([]) self.tmpCallNode.push(topNode.parent.parent) elif X in ['实参列表', '实参列表1' ] and topNode.children[0].data == 'NULL': paramCount = 0 for s in self.symbolList: if s['domain'] == self.symbolList[self.tmpSymbolIndex.top()]['idName'] \ and s['label'] == 'formal': paramCount += 1 topParam = self.tmpParam.top() topSymbolIndex = self.tmpSymbolIndex.top() self.tmpParam.pop() self.tmpSymbolIndex.pop() if paramCount != len(topParam): self.errorReason += ( "Line%d: %s function doesn't accept %d parameters\n" % (self.lineCounter, self.symbolList[topSymbolIndex]['idName'], len(topParam))) break for i in range(len(topParam)): self.funCode[self.domain].append( self.genCode( op='push', result=topParam[len(topParam) - i - 1], )) self.funCode[self.domain].append( self.genCode( op='jal', result='to_%s' % (self.symbolList[topSymbolIndex]['idName']), )) topCallNode = self.tmpCallNode.top() self.tmpCallNode.pop() newTmp = self.newTmp() self.funCode[self.domain].append( self.genCode(op='pop', result={'reg': newTmp})) topCallNode.addAttributes("place", {'reg': newTmp}) out = ('产生式: ' + self.Table.table[X][now].left + '-->' + ' '.join(self.Table.table[X][now].right)) outResult += out.ljust(40, ' ') proResult = True else: if len(stack.s) == 1 or self.Table.table[X][now] == ' ': newNode = node() newNode.setData(X) stack.push(newNode) self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' skip %s , check near %s\n' % (word, word)) word, label, now = self.advance() if word == -1: self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' meet the end token # before finishing analysis or no end token #\n' ) outResult += '\n' break break elif self.Table.table[X][now] == 'synch': self.errorReason += ( 'Syntax error, line %d:' % self.lineCounter + ' pop %s from the stack, check near %s\n' % (X, word)) break outResult += '\n' continue if not proResult: outResult += ' '.ljust(40) outResult += (('栈: ' + stack.show()).ljust(40) + '\n') if self.errorReason == '' and 'main' not in self.funCode.keys(): self.errorReason += 'No main function defined.\n ' if self.errorReason == '': for key in self.funCode.keys(): if key == 'global': continue self.funCode[key][0]['entry'] = key if self.haveReturn[key] == False: self.errorReason += 'int %s must have a return value.\n' % ( key) self.arrangeAddr() return self.errorReason, self.codeList, self.symbolList else: return self.errorReason, None, None
def analyze(self): self.ERROR = False self.head = node() self.head.setData('head') stack = MyStack() self.lex = LexAn(self.string) endNode = node() endNode.setData('#') stack.push(endNode) startNode = node() startNode.setData(self.start) startNode.setParent(self.head) self.head.addChildren(startNode) stack.push(startNode) self.pointer = 0 self.lineCounter = 1 word, label, now = self.advance() outResult = '' ErrorResult = '' while (True): '''遇注释号跳过''' if label == '注释号': word, label, now = self.advance() continue '''文件读完,未完成语法分析''' if word == -1: ErrorResult += ('line %d:' % self.lineCounter + ' 语法分析错误结束\n') outResult += '\n' break '''遇非法字符''' if label == 'ERROR': ErrorResult += ('line %d:' % self.lineCounter + ' 跳过非法词%s\n' % word) outResult += '\n' word, label, now = self.advance() continue out = ('line %d: ' % self.lineCounter + word + ',' + label) outResult = outResult + out.ljust(20, ' ') proResult = False topNode = stack.pop() X = topNode.data if X in self.Terminals: if X == now: if X == "标识符": topNode.addAttributes("idName", word) if X == "num": topNode.addAttributes("NumValue", word) topNode.addAttributes("lineNum", self.lineCounter) word, label, now = self.advance() else: ErrorResult += ('line %d:' % self.lineCounter + ' 期待%s\n' % (X)) outResult += '\n' continue elif X == '#': if X == now: break else: ErrorResult += ('line %d:' % self.lineCounter + ' 检查%s附近\n' % (word)) outResult += '\n' break elif X in self.Virables and self.Table.table[X][now] not in [ ' ', 'synch' ]: if self.Table.table[X][now].right == ['NULL']: newNode = node() newNode.setParent(topNode) newNode.setData('NULL') topNode.addChildren(newNode) pass else: k = len(self.Table.table[X][now].right) - 1 while (k >= 0): newNode = node() newNode.setParent(topNode) newNode.setData(self.Table.table[X][now].right[k]) topNode.addChildren(newNode) stack.push(newNode) k -= 1 topNode.reverseChildren() out = ('产生式: ' + self.Table.table[X][now].left + '-->' + ' '.join(self.Table.table[X][now].right)) outResult += out.ljust(40, ' ') proResult = True else: if len(stack.s) == 1 or self.Table.table[X][now] == ' ': newNode = node() newNode.setData(X) stack.push(newNode) ErrorResult += ('line %d:' % self.lineCounter + ' 跳过%s, 检查%s附近\n' % (word, word)) word, label, now = self.advance() if word == -1: ErrorResult += ('line %d:' % self.lineCounter + ' 语法分析错误结束\n') outResult += '\n' break elif self.Table.table[X][now] == 'synch': ErrorResult += ('line %d:' % self.lineCounter + ' %s出栈, 检查%s附近\n' % (X, word)) outResult += '\n' continue if not proResult: outResult += ' '.ljust(40) outResult += (('栈: ' + stack.show()).ljust(40) + '\n') if ErrorResult == '': return ErrorResult, outResult else: self.ERROR = True return ErrorResult, outResult