第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