mpe*_*pen 6 compiler-construction parsing terminology
当我想到"编译"时,我想把C++代码变成二进制代码.或者也许将C#转换成CLR字节码.但是"解析"可能类似于解析Python或Web模板语言,它不需要生成任何二进制文件,但可以立即执行代码,逐个语句或直接输出HTML.
在任何一种情况下,你基本上都会做同样的任务吗?忽略语言语法,编译C++与解析网站模板文件(Django,Smarty,无论如何)或Python一样困难吗?
我想提到的是,如果我学习"编译"或阅读一本关于"编译"的书,我是否必须掌握解析非编译语言的技能?
Jul*_*iet 26
简短回答:解析不是编译的子集.
答案很长:一般来说,将源代码转换为另一种格式有3个步骤:
(对于非常简单的语言,您甚至可能不需要解析器,您可能可以直接编译令牌流,或者您的解析器可以直接输出本机代码.)
所以从这样的原始字符串开始:
let x = 0
while x < 10
print x
x := x + 1
Run Code Online (Sandbox Code Playgroud)
词法分析器会将其转换为令牌流,可能是这样的:
[LET; String("x"); EQ; Int(0); NEWLINE; WHILE; String("x");
LT; VAL(10); ... ]
Run Code Online (Sandbox Code Playgroud)
解析器将流转换为更有意义的数据结构,即抽象语法树:
// AST definition
type expr =
| Block of expr list
| Assign of string * expr
| While of expr * expr
| Call of string * expr list
| Add of expr * expr
| Var of string
| Int of int
// AST instance created from token stream
Block
[
Assign("x", Int(10));
While
(
LessThan(Var("x"), Int(10)),
Block
[
Call("print", [Var("x")]);
Assign("x", Add(Var("x"), Int(1)));
]
);
]
Run Code Online (Sandbox Code Playgroud)
一旦你有了AST,你就可以用它做任何事情:
Var("x")并使用Var("y")类似于代码重构工具替换它们.因此,虽然您通常在编译之前解析输入,但这与说解析是编译的子集不同.
不,解析和编译可以完全独立.
大多数编译器都包含一个解析步骤,但我认为它不一定是编译的"子集",解析当然不必与编译有任何关系.
| 归档时间: |
|
| 查看次数: |
1876 次 |
| 最近记录: |