沙滩车厂家
免费服务热线

Free service

hotline

010-00000000
沙滩车厂家
热门搜索:
行业资讯
当前位置:首页 > 行业资讯

自己手动编写一个简单的解释器Part3

发布时间:2020-07-20 16:18:09 阅读: 来源:沙滩车厂家

早上起来的时候我自顾自地想着:“为什么我们会发现学一门新的技能很困难呢?”

我认为这并不仅仅是因为辛苦的工作。我认为其中的一个原因可能是我们花了很多时间和辛苦的工作用在通过阅读文献和观看技术视频来获得知识,以致于没有足够的时间将这些知识通过实践来转化成技能。就拿游泳来说,你可以花大量的时间阅读成百上千本有关游泳的书籍,和有经验的游泳人员或者教练讨论数小时,观看可获取到的所有的教学视频,然而当你第一次跳下泳池的时候你还是会像块石头一样下沉。

底线在于:不管你认为你对这个目标知道的有多透彻——你一定要将这些知识用于实践并转化为技能。为了能够以实践方式来帮助你,我在这一系列中设置了 Part 1 和 Part 2 两个部分的练习。对了,我保证你还可以在今天的和以后的文章中看到更多的练习。

好了,让我们开始学习今天的资料,好吗?

到目前为止,你已经学过如何解释算数表达式,两个整数相加减如“7+3”或者“12-9”。今天我们将要讨论如何解析(识别)和解释任何加减号操作的数字算数表达式,比如"7-3+2-1"。

用图形表示,这篇文章中的算数表达式可以以下面的语法流程图表示:

什么是语法流程图?语流程图是程编程语言的语法规则的图形变现。基本上,语法流程图形象地为你展示在你的编程语言中哪些声明是被允许和哪些不被允许。

语法流程图非常容易理解:只需要沿着箭头指示的路径。一些路径指明选择。还有一些路径指明循环。

你可以这样来理解上面的语法流程图:一个term可以选择一个加号或者减号紧跟其后,再跟着其他的一次选择一个加号或者减号后面跟着另一个term的term等等。你可以按照字面上的意思理解上面的图片。你可能想知道term是什么。依照本文的目的,term只是一个整数。

语法图主要为两个目的服务:

它们使用图的形式来表达一门编程语言

他们可以帮助你编写你的解析器(parser),你可以使用几种简单的规则来把图转换为代码。

我们已经知道了,在一串标识符(token)中识别出短语(phrase)的过程叫做解析。而且解释器或者编译器的一部分就是解析器。解析也叫做『语法分析』,解析器也叫做——你猜对了——语法分析器。

参照上面的语法图,下面的数学表达式都是有效的。

3

3 + 4

7 - 3 + 2 - 1

因为算数表达式在不同的编程语言中都差不多一样, 我们可以用 Python 来『测试』一下我们的语法图。把你的 Python Shell 搞起来,然后输入:

1

2

3

4

5

6

白癜风药物治疗

>>>3

3

>>>3+4

7

>>>7-3+2-1

5

没啥特别的。

『3 + 』作为一个算数表达式是不合法的。 因为根据语法图,一个减号后面必须跟着一个 term(也就是整数),否则解释器就会报错。不信你试试:

1

2

3

4

>>>3+

File"<stdin>",line13+

^

SyntaxError:invalidsyntax

用 Python Shell 来做测试很爽,不过我们还是想自己用代码实现我们自己的解释器,对吧?

在前文(Part 1和 Part 2)中 ,你已经知道了expr方法就是我们的解释器和解析器工作的地方。也就是说,解析器仅识别出语法结构,确保语句符合规定,解释器在解析器工作完毕之后(也就是解析完了之后),将表达式计算出来。

下面是根据语法图写出来的解析器(parser)代码。语法图中的矩形在代码中变成了可以解析整数的 term 方法,expr 方法只负责跟随语法图:

1

2

de山东哪家医院治疗银屑病好fterm(self):

t(INTEGER)

1

2

3

4

5

6

7

8

9

10

11

12

13

defexpr(self):

#setcurrenttokentothefirsttokentakenfromtheinput

rrent_token=t_next_token()

rm()

rrent_pein(PLUS,MINUS):

token=rrent_token

pe==PLUS:

t(PLUS)

rm()

pe==MINUS:

t(MINUS)

rm()

你可以看到 expr 方法最先调用了 term 方法。然后 expr 方法进入到了一个可以执行任意多次的循环。在循环中,parser 通过 token(加号还是减号)来决定作出什么样的判断。 花点时间来证明上图的代码实现了可以解析算术表达式并遵照了上面的语法图。

解析器自己本身并不会解释任何东西:如果它识别出来一个合法的表达式它就不吱声了,如果表达式不合法,它就会抛出一个语法错误。 接下来我们修改一下 expr 方法,然后再加上解释器的代码。

1

2

3

4

5

defterm(self):

"""ReturnanINTEGERtokenvalue"""

token=rrent_token

t(INTEGER)

lue

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

defexpr(self):

"""Parser/Interpreter"""

#setcurrenttokentothefirsttokentakenfromtheinput

rrent_token=t_next_token()

result=rm()

rrent_pein(PLUS,MINUS):

token=rrent_token

pe==PLUS:

t(PLUS)

result=result+rm()

pe==MINUS:

t(MINUS)

result=rm()

returnresult

因为解释器需要去计算表达式的值。我们修改了 term 方法,它现在返回了一个整数值。修改 expr 方法,现在它在恰当的位置执行加减法操作,并且整个解释的结果。尽管代码已经很直观了,我还是建议花时间好好研究一下。

Node.js+Koa2+MySQL

thinkphp教程视频

java教程视频

相关阅读