解析器的实现是须要根据语言特性来实现的,是一个较为复杂的任务。事实上,咱们须要将一段代码或者字母转换为抽象语法树 (abstract syntax tree, AST)。抽象语法树是程序在内存中展示的一种形式,抽象表示它不关心是由什么源码构成的,可是他很确信是符合语义学的。javascript
例如:java
sum = lambda(a, b) {
a + b;
}
print(sum(1, 2));
复制代码
解析器会将上面的代码转换为一个javascript对象
:正则表达式
{
type: "prog",
prog: [
// 第一行
{
type: "assign",
operator: "=",
left: { type: "var", value: "sum" },
right: {
type: "lambda",
vars: [ "a", "b" ],
body: {
// body 部分也应该是 prog 类型,由于它包含一个表达式
type: "binary",
operator: "+",
left: { type: "var", value: "a" },
right: { type: "var", value: "b" }
}
}
},
// 第二行
{
type: "call",
func: { type: "var", value: "print" },
args: [{
type: "call",
func: { type: "var", value: "sum" },
args: [ { type: "num", value: 1 },
{ type: "num", value: 2 } ]
}]
}
]
}
复制代码
写一个解析器最大的困难在于如何合理的组织代码。解析器应该站在比读取字符更高的层面。这里有一些建来控制程序的适度的复杂性:编程
为了保持胆码的简洁性,我将代码分割成了三部分,未来会被分割成更小的函数:bash
原文连接: lisperator.net/pltut/parse…编程语言