「回顾旧贴,以前不知道sympy,如今sympy用的还算可以,但没啥人对这个感兴趣。」
请先看下 https://www.cnblogs.com/funwithwords/p/15635065.html
可以边干边学:
1. PLY (Python Lex-Yacc)的文档和源码。PLY is a pure-Python implementation of the popular compiler construction tools lex and yacc.
2. PLY文档里提到的:"Compilers: Principles, Techniques, and Tools", by Aho, Sethi, and Ullman和"Lex and Yacc" by John Levine.
微分器:
1. 实现多项式加法
2. 支持(x + 1)^2, sin((x + 1)^2)这样的语法
3. 自底向上构造语法树。print可看到shift, reduce的过程
4. 自上至底套用微分规则(递归?),把多项式乘了加,加了乘,如何处理2*sin(x) + 2*cos(x)之类?
5. 祈祷机器学习不用exp(sin(cos(2 ^ sin(cos(x)) + 3 * exp(sin(cos(x): 我未能把左式的括号匹配对。
计算器:
def p_expression_plus(p):
'expression : expression PLUS term'
p[0] = p[1] + p[3] # 0 : 1 PLUS(2) 3
可以用变量: dict['d'] = dict['c'] = dict['a'] + dict['b']
编译器:
注意不是一边分析语法,一遍解释执行的解释器。可能也需要先构造语法树再处理。解释器像数值运算,编译器像符号运算。除了看书也可以仿python. search(dis - Disassembler for Python bytecode).
a = 1; b = 2; d = c = a + b的bytecode,或者说汇编/中间语言:
3 0 LOAD_CONST 1 (1)
2 STORE_FAST 0 (a)
4 4 LOAD_CONST 2 (2)
6 STORE_FAST 1 (b)
5 8 LOAD_FAST 0 (a)
10 LOAD_FAST 1 (b)
12 BINARY_ADD
14 DUP_TOP
16 STORE_FAST 2 (d)
18 STORE_FAST 3 (c)
6 20 LOAD_FAST 2 (d)
22 RETURN_VALUE
LOAD_CONST(consti) Pushes co_consts[consti] onto the stack.
STORE_FAST(var_num) Stores TOS (top of stack) into the local co_varnames[var_num].
LOAD_FAST(var_num) Pushes a reference to the local co_varnames[var_num] onto the stack.
BINARY_ADD Implements TOS = TOS1 + TOS.
DUP_TOP Duplicates the reference on top of the stack.
显然python不是解释执行LOAD_CONST这样的字符串的,而是它们都有对应的0010111这样的stuff. 但这只是一小步。我们生成的程序里有co_consts和co_varnames这样两块内存,还有个stack,难道我们只用一两个寄存器,光在内存里倒腾吗?llvm有无限个虚拟寄存器,即编译器假设寄存器的数量是无限的,优化器没有寄存器可用时用临时变量。编译器也可以自己管理寄存器的分配,好像用堆栈就可以。
如果用户写了:
def after_one_day():
global g
g += 1
sleep(24_HOURS)
return 42
def fn():
a = after_one_day()
b = after_one_day()
a = (b ^ b) + g
return a
咋办?
还要处理访问数组,调用函数, dict做成python库的形式还是翻译过来…… 还有闭包:
LOAD_CLOSURE(i) Pushes a reference to the cell contained in slot i of the cell and free variable storage. The name of the variable is co_cellvars[i] if i is less than the length of co_cellvars. Otherwise it is co_freevars[i - len(co_cellvars)].
真的是很麻烦。
LLVM is an an optimizer and code generator. Clang is an "LLVM native" C/C++/Objective-C compiler. The LLVM Core libraries provide a modern source- and target-independent optimizer, along with code generation support for many popular CPUs (as well as some less common ones!) These libraries are built around a well specified code representation known as the LLVM intermediate representation ("LLVM IR"). The LLVM Core libraries are well documented, and it is particularly easy to invent your own language (or port an existing compiler) to use LLVM as an optimizer and code generator.
最后看个简单的高兴下吧:
8 0 LOAD_FAST 0 (a)
2 LOAD_CONST 1 (0)
4 COMPARE_OP 4 (>)
6 POP_JUMP_IF_FALSE 12
8 LOAD_CONST 2 (1)
10 RETURN_VALUE
9 >> 12 LOAD_FAST 0 (a)
14 LOAD_CONST 1 (0)
16 COMPARE_OP 2 (==)
18 POP_JUMP_IF_FALSE 24
20 LOAD_CONST 1 (0)
22 RETURN_VALUE
10 >> 24 LOAD_CONST 3 (-1)
26 RETURN_VALUE
28 LOAD_CONST 0 (None)
30 RETURN_VALUE
if a > 0: return 1
elif a == 0: return 0
else: return -1
浙公网安备 33010602011771号