写微分器和编译器?
请先看下
可以边干边学:
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,难道我们只用一两个寄存器,光在内存里倒腾吗?
如果用户写了:
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