From 8c33d1a6e504cfc15a8c3c3aa6d0d9490cde8df5 Mon Sep 17 00:00:00 2001 From: wxy Date: Sat, 7 Apr 2018 10:31:29 +0800 Subject: [PATCH] PRF:20150703 Let-s Build A Simple Interpreter. Part 2..md @BriFuture --- ...t-s Build A Simple Interpreter. Part 2..md | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md b/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md index a22a94bae0..e9591cddd1 100644 --- a/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md +++ b/translated/tech/20150703 Let-s Build A Simple Interpreter. Part 2..md @@ -1,9 +1,9 @@ -让我们做个简单的解释器(2) +让我们做个简单的解释器(二) ====== -在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,一个举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单符号可以让人更好的掌握复杂的部分。这个例子很清晰 - 要成为真正的名家,必须要掌握简单基础的思想。 +在一本叫做 《高效思考的 5 要素》 的书中,作者 Burger 和 Starbird 讲述了一个关于他们如何研究 Tony Plog 的故事,他是一位举世闻名的交响曲名家,为一些有才华的演奏者开创了一个大师班。这些学生一开始演奏复杂的乐曲,他们演奏的非常好。然后他们被要求演奏非常基础简单的乐曲。当他们演奏这些乐曲时,与之前所演奏的相比,听起来非常幼稚。在他们结束演奏后,老师也演奏了同样的乐曲,但是听上去非常娴熟。差别令人震惊。Tony 解释道,精通简单音符可以让人更好的掌握复杂的部分。这个例子很清晰 —— 要成为真正的名家,必须要掌握简单基础的思想。 -故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解他们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: +故事中的例子明显不仅仅适用于音乐,而且适用于软件开发。这个故事告诉我们不要忽视繁琐工作中简单基础的概念的重要性,哪怕有时候这让人感觉是一种倒退。尽管熟练掌握一门工具或者框架非常重要,了解它们背后的原理也是极其重要的。正如 Palph Waldo Emerson 所说: > “如果你只学习方法,你就会被方法束缚。但如果你知道原理,就可以发明自己的方法。” @@ -15,11 +15,11 @@ 2. 识别输入字符串中的多位整数 3. 做两个整数之间的减法(目前它仅能加减整数) - 新版本计算器的源代码在这里,它可以做到上述的所有事情: + ``` # 标记类型 -# EOF (end-of-file 文件末尾) 标记是用来表示所有输入都解析完成 +# EOF (end-of-file 文件末尾)标记是用来表示所有输入都解析完成 INTEGER, PLUS, MINUS, EOF = 'INTEGER', 'PLUS', 'MINUS', 'EOF' @@ -168,9 +168,10 @@ if __name__ == '__main__': main() ``` -把上面的代码保存到 calc2.py 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 +把上面的代码保存到 `calc2.py` 文件中,或者直接从 [GitHub][2] 上下载。试着运行它。看看它是不是正常工作:它应该能够处理输入中任意位置的空白符;能够接受多位的整数,并且能够对两个整数做减法和加法。 这是我在自己的笔记本上运行的示例: + ``` $ python calc2.py calc> 27 + 3 @@ -182,21 +183,21 @@ calc> 与 [第一部分][1] 的版本相比,主要的代码改动有: - 1. get_next_token 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 - 2. 增加了一些方法:skip_whitespace 用于忽略空白字符,integer 用于处理输入字符的多位整数。 - 3. expr 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 + 1. `get_next_token` 方法重写了很多。增加指针位置的逻辑之前是放在一个单独的方法中。 + 2. 增加了一些方法:`skip_whitespace` 用于忽略空白字符,`integer` 用于处理输入字符的多位整数。 + 3. `expr` 方法修改成了可以识别 “整数 -> 减号 -> 整数” 词组和 “整数 -> 加号 -> 整数” 词组。在成功识别相应的词组后,这个方法现在可以解释加法和减法。 -[第一部分][1] 中你学到了两个重要的概念,叫做 **标记** 和 **词法分析**。现在我想谈一谈 **词法**, **解析**,和**解析器**。 +[第一部分][1] 中你学到了两个重要的概念,叫做 标记token词法分析lexical analyzer。现在我想谈一谈词法lexeme解析parsing解析器parser。 -你已经知道标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?**词法** 是一个标记中的字符序列。在下图中你可以看到一些关于标记的例子,还好这可以让它们之间的关系变得清晰: +你已经知道了标记。但是为了让我详细的讨论标记,我需要谈一谈词法。词法是什么?词法lexeme是一个标记token中的字符序列。在下图中你可以看到一些关于标记的例子,这可以让它们之间的关系变得清晰: ![][3] -现在还记得我们的朋友,expr 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。expr 方法最重要的工作是:它从 get_next_token 方法中得到流,并找出标记流的结构然后解释已经识别出的词组,产生数学表达式的结果。 +现在还记得我们的朋友,`expr` 方法吗?我之前说过,这是数学表达式实际被解释的地方。但是你要先识别这个表达式有哪些词组才能解释它,比如它是加法还是减法。`expr` 方法最重要的工作是:它从 `get_next_token` 方法中得到流,并找出该标记流的结构,然后解释已经识别出的词组,产生数学表达式的结果。 -在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫 **解析**。解释器或者编译器中执行这个任务的部分就叫做 **解析器**。 +在标记流中找出结构的过程,或者换种说法,识别标记流中的词组的过程就叫解析parsing。解释器或者编译器中执行这个任务的部分就叫做解析器parser。 -现在你知道 expr 方法就是你的解释器的部分,**解析** 和 **解释** 都在这里发生 - expr 方法首先尝试识别(**解析**)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (**解析**) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 +现在你知道 `expr` 方法就是你的解释器的部分,解析parsing解释interpreting都在这里发生 —— `expr` 方法首先尝试识别(解析)标记流里的 “整数 -> 加法 -> 整数” 或者 “整数 -> 减法 -> 整数” 词组,成功识别后 (解析了) 其中一个词组,这个方法就开始解释它,返回两个整数的和或差。 又到了练习的时间。 @@ -206,15 +207,12 @@ calc> 2. 扩展这个计算器,让它能够计算两个整数的除法 3. 修改代码,让它能够解释包含了任意数量的加法和减法的表达式,比如 “9 - 5 + 3 + 11” - - **检验你的理解:** 1. 词法是什么? 2. 找出标记流结构的过程叫什么,或者换种说法,识别标记流中一个词组的过程叫什么? 3. 解释器(编译器)执行解析的部分叫什么? - 希望你喜欢今天的内容。在该系列的下一篇文章里你就能扩展计算器从而处理更多复杂的算术表达式。敬请期待。 -------------------------------------------------------------------------------- @@ -223,12 +221,12 @@ via: https://ruslanspivak.com/lsbasi-part2/ 作者:[Ruslan Spivak][a] 译者:[BriFuture](https://github.com/BriFuture) -校对:[校对者ID](https://github.com/校对者ID) +校对:[wxy](https://github.com/wxy) 本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译,[Linux中国](https://linux.cn/) 荣誉推出 [a]:https://ruslanspivak.com -[1]:http://ruslanspivak.com/lsbasi-part1/ (Part 1) +[1]:https://linux.cn/article-9399-1.html [2]:https://github.com/rspivak/lsbasi/blob/master/part2/calc2.py [3]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_lexemes.png [4]:https://ruslanspivak.com/lsbasi-part2/lsbasi_part2_exercises.png