[用python自制编程语言]第1篇

    科技2022-08-14  97

    第1篇:常量折叠

    前言开始先看_cal函数参数先看前4行再往后看再继续看后面是最后为总结一下 继续看part1函数参数先看前2行再往后看总结一下作者

    前言

    我做过一个编程语言:mylang

    开始

    做编程语言最基础的就是常量折叠部分 那么先看一下mylang中的常量折叠部分

    def _cal(t,a,b,inter): A = copy.deepcopy(a) B = copy.deepcopy(b) _a = comp(a) _b = comp(b) if(_a[0] != 'error'): a = _a[0] else: return _a if(_b[0] != 'error'): b = _b[0] else: return _b if(isinstance(a,str) and a.startswith('{')): a = comp(a)[0] if(isinstance(a,str) and a.startswith('{')): b = comp(b)[0] t = t[1:] result = None try: if(t == '+'):result = a + b elif(t == '-'):result = a - b elif(t == '/'): if(b != 0): result = a / b else: return ['error','ZeroDivisionError:division by zero'] elif(t == '*'):result = int(a * b) elif(t == '<'):result = int(a < b) elif(t == '<='):result = int(a <= b) elif(t == '='):result = int(a == b) elif(t == '>='):result = int(a >= b) elif(t == '>'):result = int(a > b) elif(t == '&'):result = int(a and b) elif(t == '|'):result = int(a or b) elif(t == '!'):result = int(not a) elif(t == '^'):result = int(a ** b) elif(t == '%'):result = int(a % b) else:return ['error','OperatorError:undefined operator'] if(isinstance(result,list)): string = str(result) string = string.replace('[','{') string = string.replace(']','}') return [string] elif(inter and isinstance(result,mytype.stack)): return ['stack' + str(result._stack)] elif(inter and isinstance(result,mytype.queue)): return ['queue' + str(result._queue)] else: return [result] except: return ['error','TypeError: can\'t concatenate {0} to {1} with operater \'{2}\''.format(comp(A,inter=True)[0],comp(B,inter=True)[0],t)] def part1(string,inter): if(string.count('(') != string.count(')')): return ['error','EOLError:EOL while scanning'] string += ' ' ls = [] buf = '' flag = 0 qmflag = False if(len(string.split(' ')) != 3): for i in string: if(i == '('): flag += 1 if(i == ')'): flag -= 1 if(i == '"'): if(qmflag): qmflag = False flag -= 1 else: qmflag = True flag += 1 if((not flag) and i == ' '): ls.append(buf.strip()) buf = '' buf += i if(len(ls) != 3 and ls[0] != '@!'): return ['error','OperatingError:wrong length'] if(ls[0].strip() != '@!'): t,a,b = ls else: t,a = ls b = None else: t,a,b = string.split(' ') if('(' in a): a = comp(a[1:-1]) if(a[0] == 'error'): return [a] if('(' in b): b = comp(b[1:-1]) if(b[0] == 'error'): return b if(isinstance(a,list)): if(a[0] == 'error'): return a a = a[0] if(isinstance(b,list)): if(b[0] == 'error'): return b b = b[0] return _cal(t,a,b,inter)

    先看_cal函数

    def _cal(t,a,b,inter): A = copy.deepcopy(a) B = copy.deepcopy(b) _a = comp(a) _b = comp(b) if(_a[0] != 'error'): a = _a[0] else: return _a if(_b[0] != 'error'): b = _b[0] else: return _b if(isinstance(a,str) and a.startswith('{')): a = comp(a)[0] if(isinstance(a,str) and a.startswith('{')): b = comp(b)[0] t = t[1:] result = None try: if(t == '+'):result = a + b elif(t == '-'):result = a - b elif(t == '/'): if(b != 0): result = a / b else: return ['error','ZeroDivisionError:division by zero'] elif(t == '*'):result = int(a * b) elif(t == '<'):result = int(a < b) elif(t == '<='):result = int(a <= b) elif(t == '='):result = int(a == b) elif(t == '>='):result = int(a >= b) elif(t == '>'):result = int(a > b) elif(t == '&'):result = int(a and b) elif(t == '|'):result = int(a or b) elif(t == '!'):result = int(not a) elif(t == '^'):result = int(a ** b) elif(t == '%'):result = int(a % b) else:return ['error','OperatorError:undefined operator'] if(isinstance(result,list)): string = str(result) string = string.replace('[','{') string = string.replace(']','}') return [string] elif(inter and isinstance(result,mytype.stack)): return ['stack' + str(result._stack)] elif(inter and isinstance(result,mytype.queue)): return ['queue' + str(result._queue)] else: return [result] except: return ['error','TypeError: can\'t concatenate {0} to {1} with operater \'{2}\''.format(comp(A,inter=True)[0],comp(B,inter=True)[0],t)]
    参数

    其中参数t,a,b,inter,其中t是运算符,a是第一个参数,b是第二个参数,inter是表示是否为交互模式的布尔值

    先看前4行
    A = copy.deepcopy(a) B = copy.deepcopy(b) _a = comp(a) _b = comp(b)

    其中A和B是原值的备份,_a和_b是a和b所代表的值

    再往后看
    if(_a[0] != 'error'): a = _a[0] else: return _a if(_b[0] != 'error'): b = _b[0] else: return _b

    此处是为了防止a和b所代表的值有误

    再继续看
    if(isinstance(a,str) and a.startswith('{')): a = comp(a)[0] if(isinstance(a,str) and a.startswith('{')): b = comp(b)[0]

    此处特别处理列表

    后面是
    t = t[1:] result = None

    其中result是结果,t = t[1:]是为了如下原因:

    常量折叠语法: @[t] [a] [b] 传入的t是@[t]部分 所以t = t[1:]是为了将@去掉

    最后为
    try: if(t == '+'):result = a + b elif(t == '-'):result = a - b elif(t == '/'): if(b != 0): result = a / b else: return ['error','ZeroDivisionError:division by zero'] elif(t == '*'):result = int(a * b) elif(t == '<'):result = int(a < b) elif(t == '<='):result = int(a <= b) elif(t == '='):result = int(a == b) elif(t == '>='):result = int(a >= b) elif(t == '>'):result = int(a > b) elif(t == '&'):result = int(a and b) elif(t == '|'):result = int(a or b) elif(t == '!'):result = int(not a) elif(t == '^'):result = int(a ** b) elif(t == '%'):result = int(a % b) else:return ['error','OperatorError:undefined operator'] if(isinstance(result,list)): string = str(result) string = string.replace('[','{') string = string.replace(']','}') return [string] elif(inter and isinstance(result,mytype.stack)): return ['stack' + str(result._stack)] elif(inter and isinstance(result,mytype.queue)): return ['queue' + str(result._queue)] else: return [result] except: return ['error','TypeError: can\'t concatenate {0} to {1} with operater \'{2}\''.format(comp(A,inter=True)[0],comp(B,inter=True)[0],t)]

    此处就是在进行运算

    总结一下
    Created with Raphaël 2.2.0 开始 对两个参数进行转化 检查两个参数的正确性 对特殊值进行特判 进行运算 结束 报错 yes no

    继续看part1函数

    def part1(string,inter): if(string.count('(') != string.count(')')): return ['error','EOLError:EOL while scanning'] string += ' ' ls = [] buf = '' flag = 0 qmflag = False if(len(string.split(' ')) != 3): for i in string: if(i == '('): flag += 1 if(i == ')'): flag -= 1 if(i == '"'): if(qmflag): qmflag = False flag -= 1 else: qmflag = True flag += 1 if((not flag) and i == ' '): ls.append(buf.strip()) buf = '' buf += i if(len(ls) != 3 and ls[0] != '@!'): return ['error','OperatingError:wrong length'] if(ls[0].strip() != '@!'): t,a,b = ls else: t,a = ls b = None else: t,a,b = string.split(' ') if('(' in a): a = comp(a[1:-1]) if(a[0] == 'error'): return [a] if('(' in b): b = comp(b[1:-1]) if(b[0] == 'error'): return b if(isinstance(a,list)): if(a[0] == 'error'): return a a = a[0] if(isinstance(b,list)): if(b[0] == 'error'): return b b = b[0] return _cal(t,a,b,inter)
    参数

    参数中string为表达式,inter是表示是否为交互模式的布尔值

    先看前2行
    if(string.count('(') != string.count(')')): return ['error','EOLError:EOL while scanning']

    这是为了判断表达式嵌套是否正确

    再往后看
    string += ' ' ls = [] buf = '' flag = 0 qmflag = False if(len(string.split(' ')) != 3): for i in string: if(i == '('): flag += 1 if(i == ')'): flag -= 1 if(i == '"'): if(qmflag): qmflag = False flag -= 1 else: qmflag = True flag += 1 if((not flag) and i == ' '): ls.append(buf.strip()) buf = '' buf += i if(len(ls) != 3 and ls[0] != '@!'): return ['error','OperatingError:wrong length'] if(ls[0].strip() != '@!'): t,a,b = ls else: t,a = ls b = None else: t,a,b = string.split(' ')

    这里是为了分开操作符(operator,这里用t(token)表示)和两个参数(a和b) 先看4个变量

    ls:分解后的结果 buf:不完整的t/a/b(尚未完全分段的) flag:嵌套的"()数量 qmflag:记录是否为""内的部分

    继续看主体部分

    if(len(string.split(' ')) != 3): # ...... else: t,a,b = string.split(' ')

    此处处理是否有嵌套的表达式 接着看主体部分

    for i in string: if(i == '('): flag += 1 if(i == ')'): flag -= 1 if(i == '"'): if(qmflag): qmflag = False flag -= 1 else: qmflag = True flag += 1 if((not flag) and i == ' '): ls.append(buf.strip()) buf = '' buf += i

    此处为了分开t,a,b三个部分 接着是

    if(len(ls) != 3 and ls[0] != '@!'): return ['error','OperatingError:wrong length'] if(ls[0].strip() != '@!'): t,a,b = ls else: t,a = ls b = None

    此处是将ls分成t,a,b三部分

    if('(' in a): a = comp(a[1:-1]) if(a[0] == 'error'): return [a] if('(' in b): b = comp(b[1:-1]) if(b[0] == 'error'): return b if(isinstance(a,list)): if(a[0] == 'error'): return a a = a[0] if(isinstance(b,list)): if(b[0] == 'error'): return b b = b[0]

    转化a和b,避错

    return _cal(t,a,b,inter)

    这里进行计算

    总结一下
    Created with Raphaël 2.2.0 开始 检查代码的表达式嵌套 分成operator,a,b三部分 转化a和b a和b的正确性 运行 结束 报错 yes no
    作者

    hit-road

    拜拜,下课!

    hit-road不定期跟新,不见不散!

    >> 下期传送门
    Processed: 0.010, SQL: 8