第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不定期跟新,不见不散!
>>
下期传送门