初识抽象语法树(AST)

  • 基本概念
  1. 基本字:阿拉伯数字、大小写拉丁字母、其他字符(~、!、%、&、_、-、+、=、{}、[]、:、;、<、>、,、.、?、/、|、\)、空格符、换行符、制表符等。
  2. 关键字(keyword):提前被定义,并赋予有特殊的含义的单词
  3. 保留字: 提前被定义,但还未被赋值(保留字与关键字有时等价)
  4. 标识符(identifier): 由数字、字母、下划线组成,且不能以数字开头,用于给变量、常量、函数、语句块等命名。
  • c语言中标识符包括:关键字(如int、while)、预定义标识符(如printf)和用户自定义标识符。

当下的编译器都做了纯文本转AST的事情。

一款编译器的编译流程是很复杂的,但我们只需要关注词法分析语法分析,这两步是从代码生成AST的关键所在。

  • 词法分析器(scanner)
词法分析器结构

在扫描器的驱动下,预处理子程序将到输入缓冲区中源代码的字符处理后由
扫描缓冲区读入。扫描器在扫描缓冲区中识别单词符号,然后输出。

其中预处理子程序的作用是:

  1. 剔除源代码中的空格、回车符、换行符等编辑性字符
  2. 区分标号区、捻接续行,给出句末符等等

现代程序设计语言在最初设计时就遵循了一些规则:

  1. 所有基本字都是保留字,不可再作为标识符
  2. 基本字作为特殊的标识符处理
  3. 基本字、标识符和常数间若没有确定的运算符或界符作间隔,必须使用一个空白符作间隔,一方面避免了超前搜索、方便编译程序进行词法分析,另一方面增加代码的可读性

  • 词法分析器设计:
  1. 确定语言单词规范——单词表
  2. 有单词表得到该语言所有字的状态转换图
  3. 根据状态转换图实现词法分析器

词法分析器会读取代码,它会一个一个字母地读取代码,所以很形象地称之为扫描(scanner)。然后把它们按照预定的规则合并成一个个的标识(tokens),当它遇到空格、操作符,或者特殊符号的时候,它会认为一个话已经完成了。同时,它会移除空白符、注释等。最后,整个代码将被分割进一个 tokens 列表(或者说一维数组)

//词法分析器典型输入输出
const a = 5;
// 转换成
[{value: 'const', type: 'keyword'}, {value: 'a', type: 'identifier'}, ...]

  • 语法分析器(parser)

语法分析会将词法分析出来的列表转换成树形的形式,同时验证语法。语法如果有错的话,抛出语法错误。

[{value: 'const', type: 'keyword'}, {value: 'a', type: 'identifier'}, ...]
// 语法分析后的树形形式
{
   type: "VariableDeclarator", //变量声明
   id: {
       type: "Identifier",//标识符
       name: "a"
   },
   ...

当生成树的时候,解析器会删除一些没必要的标识 tokens(比如:不完整的括号),因此 AST 不是 100% 与源码匹配的。


  • 语法分析相关概念
  1. 巴克斯范式(EBNF)【巴克斯范式(Backus Form)简单例子-from知乎
EBNF元符号 含义
::= 可解释为,可推导为
|
() 一项,一次重复
[] 0次和1次重复
{} 0次或任意多次重复
. 一条生成规则的结束
<> 非终结符
“” 终结符
  1. 翻译单元: 什么是翻译单元?

酷文章: ==C实现词法分析及语法分析==


现在,我们拆解一个简单的add函数

function add(a, b) {
    return a + b
}

首先,我们拿到的这个语法块,是一个FunctionDeclaration(函数定义)对象。

用力拆开,它成了三块:

  • 一个id,就是它的名字,即add
  • 两个params,就是它的参数,即[a, b]
  • 一块body,也就是大括号内的一堆东西
{
    name: 'add'
    type: 'identifier'
    ...
}

params继续拆下去,其实是两个Identifier组成的数组。之后也没办法拆下去了。

[
    {
        name: 'a'
        type: 'identifier'
        ...
    },
    {
        name: 'b'
        type: 'identifier'
        ...
    }
]
  • 接下来,我们继续拆开body,我们发现,body其实是一个BlockStatement(块状域)对象,用来表示是\color{blue}{\{return\ a + b\}}

  • 打开Blockstatement,里面藏着一个ReturnStatement(Return域)对象,用来表示\color{blue}{return\ a + b}

  • 继续打开ReturnStatement,里面是一个BinaryExpression(二项式)对象,用来表示\color{blue}{a + b}

  • 继续打开BinaryExpression,它成了三部分,\color{blue}{left}\color{blue}{operator}\color{blue}{right}

  • \color{blue}{operator }\color{blue}{+}

  • \color{blue}{left} 里面装的,是Identifier对象 \color{blue}{a}

  • \color{blue}{right }里面装的,是Identifer对象 \color{blue}{b}

就这样,我们把一个简单的add函数拆解完毕,用图表示就是

"add" `s AST

酷文章:

词法分析器中的预处理程序部分

词法分析器中的词法分析程序部分

词法分析器
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容