注意:
AST-IR规范
相对于STVC-TAC规范
是一种“更古老”的编码规范,我们建议编译器和虚拟机采用更先进的STVC-TAC规范
。但AST-IR
仍然是一种稳定,方便的格式。
AST-IR(以下简称AstIr
)是一种将抽象语法树(以下简称Ast
)转为迭代表示方式的编码结构。
基于AstIr的编译器的基本运作原理是:在编译生成Ast后,将Ast转为AstIr的二进制编码文件,最后交给虚拟机运行,虚拟机将AstIr复原成Running-Ast
数据结构(这种数据结构与编译器生成的Ast略有差别),然后递归执行。
有关Running-Ast
的解释,我引用编译器开发文档
的解释:
Ast
和Running-Ast
的区别就在于:Running-Ast的叶子节点皆为AstLeaf
,而Ast非然。
不难见得,Running-Ast是为了适应AstIr而诞生的结构。
有关AstIr的结构示例,我已经在编译器开发文档
中提及,因此我将其解释放到了文末的“AST-IR格式附注”中。
一个AstIr文件结构由以下几种规则构成:
Ast.hpp
的_AstType
为准,特别的,结束单元的类型是-1);后四字节是单元的数据,如果该单元是逻辑单元或结束单元,则后四字节默认为0,如果该单元是数据单元,则后四字节为数据的二进制存储(采用大端存储,以Python的大端存储为标准),数据单元的种类以文末的“数据单元附表”为准。单元类型 | 对应的数据 |
---|---|
ast::AstAnonClass | isHaveFather |
ast::AstExpression | ass_type |
ast::AstBinary | getOperatorType() |
ast::AstUnary | getOperatorType() |
ast::AstPostfix | getPostfixType() |
AstIr的格式和HTML的格式类似:由逻辑单元、数据单元和结束单元组成。一棵Ast可以通过深度优先遍历转为AstIr。
这样的描述也许会较为拗口,我们来看一个示例:
考虑以下Ast:
Add |-a |-Sub |--b |--1
该Ast可以转为以下AstIr:
<Add> //此为逻辑单元,以此类推 <data val=a> //此为数据单元,以此类推 <Sub> <data val=b> <data val=1> <end> //此为结束单元,以此类推 <end>
这段AstIr和上面的Ast本质上是等价的。这样只需将Ast转为AstIr,就能获得一系列单元,方便存入文件。
逻辑单元本质上就是Ast节点的非叶子节点,数据单元本质上就是Ast节点的叶子节点。
摘自
编译器开发文档
,2025年4月26日
一个常量表由常量表长度(占4字节)和若干个常量组成,其中常量又由常量类型(占1字节)和常量值组成:
其中每种类型的编码格式如下:
一个常量表下标默认为4字节。
摘自
STVC-TAC二进制编码规范
,2025年4月26日