简单模拟编译前端过程,简单模拟编译过程,学了几天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

评论关闭