AST学习记录(不需要内部细节)

首先一个问题困扰了我很久。AST到底是一种标准还是一个概念?

先讲一下我对标准和概念的区分。

标准

标准就是一种定式。大家都按这种定式去做,大家所做出来的东西只要按照这种标准去理解都可以看的懂,可以互用。就像js,你写的和我写的尽管再不相同,但大家都是遵循JS语法规范去做的。所以不影响我阅读和使用你写的东西。

概念

概念就是一种想法,有利于处理这个问题的思路。大家都按照这种好的思路去做,做出来的东西可以互相看不懂,但是核心思想都是基于这个概念。就像面向对象,java(我也不懂,就这么一说)和js。大家实现的都是基于封装,继承,多态的思想。但是我直接使用你的甚至阅读是不互通的,因为我们都有自己定义好的实现细节。

先讲我截至(2021年01月28日17:13:53) 的理解结论:是一种概念(但因为做的人多了,就诞生出了小范围的标准,但你可以不遵守标准也丝毫不影响你实现这个概念)。

以上两张截图来自于https://blog.flqin.com/367.html

先感谢这位大佬的文章解决了我查阅很多资料和文档都没有解决的困惑。拜谢!

主要集中到这句话:每一个JS引擎都会有自己的抽象语法树格式。

然后我去粗略看了babel和jsx实现。果然如此!

那么就可以断定AST是一种处理语言的思想概念,基于这种转化可以更好,更简单有效的对语法做出分析。然后进行具体实现。也就是说即使我们没有按照AST对象文档的标准来做解析,只要我们是按照这种抽象语法提取思想去对目标语言去进行分析从而所生出的对象结构你都可以叫他AST,而不是非得有loc,source等什么的这种对象结构。你可以任意的命名,任意的分析,从而诞生出对你所解析的这段文本模板的抽象描述。只要他符合你接下来的编译需求。

理解了什么是AST之后我们来模拟回答两个问题。

  1. 为什么vue要生成AST?
  2. 为什么不直接使用AST转化VNode,而要经过render?

我的回答:

  1. 要理解为什么生成AST,首先要知道AST的作用在哪。

那么AST的作用在于通过对语言文本模板的静态解析形成抽象语法树,以至于更好的表现编程语言的语法结构。从而将解析,验证逻辑以及具体实现所分离(就像语法解析,验证检测,和实际执行分开)。

这样做如果有语法层面的错误将会及时暴露,而不会出现在具体实现该语法的逻辑时出现错误。而以上这些东西实际都是对某种语言所进行的编译处理时做的。

而vue也加入了自己定义的模板,所以我把它称之为建立在前端部分语言(html,js)之上建立的一种新的,就算不称之为语言但可以称之为新语法的语法模板。所以使用AST概念去作为编译具体指令,词法等等之前的抽象准备是很有必要的。当然你也可以不实现这个概念,直接通过字符串解析去实现具体指令也是可以的。但是请记住,虽然我们不能说谁是最好的方式,但是方式不同,到目的地的路程可能差的很多。

2.这里就要理解好AST的作用对象。它解析的对象实质上只是这些文件的静态字符串(模板,随你怎么称呼,他都只是一段文本,一段由人敲键盘所产生的字符串)。而这段文本在具体执行时是不会变的(至少你写的const a = 1;不会在执行这段代码的时候变成const b #¥%等等)。所以即便你看到的AST对象和VNode再像也不是属于一个时空的东西。VNode是会变化的,会随着代码的执行,逻辑的变化而变化的东西。

那为什么需要经过render?这里我们不谈具体的细节,我们只需要知道render对AST做了什么。render拿到AST然后才确定了对每一段编译过的代码,比如v-if,{{xxx}}等等该做了什么样的逻辑处理,记住这段逻辑处理行为在编译完生成render之后就固定了(借此我们也可以理解到各编程语言在你写完代码,编译完之后。你的代码的执行逻辑就固定了,就像a + b他就是会处理两个变量的相加)。而转化VNode也是在render之后就固定好的其中一段逻辑处理而已。所以核心就是他们所处的时空是不一样的。

Comments
登录后评论
Sign In