简单模拟编译前端过程,简单模拟编译过程,学了几天python基础
简单模拟编译前端过程,简单模拟编译过程,学了几天python基础
学了几天python基础,感觉还挺好用,写个程序巩固下,以最简单的表达式计算来模拟编译前端。
#!/usr/bin/python#coding=utf-8import reimport sysreserveList=('for','while','do','int') #保留字表calList=('+','-','*','/','=','>','<') #运算符表boundList=('{','}','(',')','/*','*/',';',',') #界符表symbolTable=set() #符号表constTable=set() #常量表source='' #处理后的源程序words=list() #词法分析得到的输入串p=0 #搜索指示器V=set() #所有文法符号VN=set() #非终结符VT=set() #终结符expressions=[] #产生式SLRTable=[] #SLR分析表def lexInit(filename): '''简单模拟词法分析器''' global source,words #读取输入串 for line in file(filename): source=source+preProcess(line) while True: word=getWord() if word=='#': words.append(word) break if word[0]!='id': word=word[0] words.append(word) def preProcess(source): '''输入预处理''' #消除单行注释,换行符和行首空白 source=re.sub('/\\*.*\\*/|//.*|\\\\n|^[\\\\t| ]*','',source) #将多个空格改为一个空格 source=re.sub(' +|\\\\t',' ',source) return sourcedef getWord(): '''词法分析''' global p,source #输入末尾添加'#' if p==len(source): return '#' strToken='' ch=source[p] p=p+1 while ch.isspace(): ch=source[p] p=p+1 #字母开头 if ch.isalpha(): while ch.isalpha() or ch.isdigit(): strToken+=ch ch=source[p] p+=1 p=p-1 #保留字 if strToken in reserveList: return [strToken,'-'] #标识符 else: symbolTable.add(strToken) return ['id',strToken] #数字开头 elif ch.isdigit(): while ch.isdigit(): strToken+=ch ch=source[p] p=p+1 if ch.isalpha(): characterError(ch) p=p-1 #常数 constTable.add(int(strToken)) return ['id',int(strToken)] #运算符 elif ch in calList: return [ch,'-'] #界符 elif ch in boundList: return [ch,'-'] #出错处理 else: print'error:%s'%ch sys.exit()def grammarInit(filename): '''模拟SLR分析表的生成(为简便直接手写)''' global expressions,VT,VN,V,SLRTable expressions=readExpressions(filename) VT=V.difference(VN) SLRTable=[{'(':'s4', 'id':'s5', 'expr':1, 'term':2, 'factor':3},\\ {'+':'s6', '#':'acc'},\\ {'+':'r2', '*':'s7', '(':'r2', ')': 'r2', 'id':'r2', '#':'r2'},\\ {'+':'r4', '*':'r4', '(':'r4', ')': 'r4', 'id':'r4', '#':'r4'},\\ {'(':'s4', 'id':'s5', 'expr':8, 'term':2, 'factor':3},\\ {'+':'r6', '*':'r6', '(':'r6', ')': 'r6', 'id':'r6', '#':'r6'},\\ {'(':'s4', 'id':'s5', 'term':9,'factor':3},\\ {'(':'s4', 'id':'s5','factor':10},\\ {'+':'s6',')':'s11'},\\ {'+':'r1', '*':'s7', '(':'r1', ')': 'r1', 'id':'r1', '#':'r1'},\\ {'+':'r3', '*':'r3', '(':'r3', ')': 'r3', 'id':'r3', '#':'r3'},\\ {'+':'r5', '*':'r5', '(':'r5', ')': 'r5', 'id':'r5', '#':'r5'}] def readExpressions(filename): '''读取文法''' global VN,V num=0 expressions=[] for line in file(filename): dic={'id':'','left':'','right':''} dic['id']=num num=num+1 dic['left']=line[0:line.index('->')].rstrip()[1:-1] VN.add(dic['left']) V.add(dic['left']) dic['right']=line[line.index('->')+3:].rstrip().replace('<','').replace('>','').split(' ') for word in dic['right']: V.add(word) expressions.append(dic) return expressions#初始化lexInit('test.e')#只含有+,*,(),数字的算术表达式grammarInit('E文法.txt')'''E文法内容:<prog> -> <expr><expr> -> <expr> + <term><expr> -> <term><term> -> <term> * <factor><term> -> <factor><factor> -> ( <expr> )<factor> -> id'''stateStack=[0] #状态栈symbolStack=['#'] #符号栈valueStack=[''] #属性栈sp=0 #输入串的指示器#语法分析并翻译计算属性值while True: print stateStack print symbolStack print words[sp:] print '----------------------------------------------------------------------' #判断栈顶元素是列表还是字符串 if isinstance(symbolStack[-1],list): top=symbolStack[-1][0] else: top=symbolStack[-1] #若栈顶符号是非终结符 if top in VN: try: num=SLRTable[stateStack[-1]][top] stateStack.append(num) continue except KeyError: pass #栈顶符号为终结符或'#' try: action=SLRTable[stateStack[-1]][words[sp][0]] except KeyError: print 'GrammarError' break #当前动作为移进 if action[0]=='s': stateStack.append((int)(action[1:])) symbolStack.append(words[sp]) if words[sp][0]=='id': valueStack.append(words[sp][1]) else: valueStack.append(' ') sp=sp+1 #当前动作为规约 if action[0]=='r': n=(int)(action[1:]) #执行语义规则 if n==1:#产生式1的语义规则 result=valueStack[-3]+valueStack[-1] valueStack=valueStack[0:-3] valueStack.append(result) if n==3:#产生式3的语义规则 result=valueStack[-3]*valueStack[-1] valueStack=valueStack[0:-3] valueStack.append(result) if n==5:#产生式5的语义规则 result=valueStack[-2] valueStack=valueStack[0:-3] valueStack.append(result) right=expressions[(int)(action[1:])]['right'] stateStack=stateStack[:-len(right)] symbolStack=symbolStack[0:-len(right)] symbolStack.append(expressions[(int)(action[1:])]['left']) #当前动作为接受 if action[0]=='a' and words[sp]=='#': print 'success!' print valueStack[-1] break#该片段来自于http://byrx.net
评论关闭