Page 134 - 《软件学报》2025年第8期
P. 134
于涛 等: 基于下推自动机的同步数据流语言可信编译 3557
算符为流指定不同的周期, 例如 A when ck 表示创建一个新的流, 其值为 A, 时钟周期为 ck, A when ck 只有在 ck
为真时才有值. 可以认为 A when ck 是对 A 的一个采样. current 是一个单目运算符, 作用是将一个非基础时钟周期
的流填补为一个基础时钟周期的值. merge 运算符是 current 的一个扩展, 作用是将多个时钟周期互补的流组合为
一个基础时钟周期的流.
(3) if 运算符: Lustre 中的 if 和其他语言中 if 条件语句相近的语法, 但其实是作为一个运算符出现在表达式当
中的, 类似于 C 语言中的三目条件运算符 (?: ). 例如, if A then B else C 表示若在该周期流 A 为 true, 则取 B 的值,
否则取 C 的值.
(4) 静态参数节点: 带有静态参数的节点 (或函数) 是一类未完成的函数, 需要给出静态参数的值从而实例化才
能使用, 支持的静态参数类型包括类型、常量和节点. 使用类型作为静态参数类似于 C++中的函数模板, 使用节点
或函数作为静态参数类似于 C++中的函数指针作为参数. 需要注意的是, 所有的静态参数需要在编译阶段就完全
已知, 而不能在运行时确定.
(5) 数组迭代器: 数组迭代器是 Lustre V6 版本的新特性, 可以用迭代器来操作数组, 提供了一种 (受限制的) 高
阶编程概念. 数组迭代器也可以认为是 Lustre 内置的静态参数节点, Lustre V6 中内置有 fill、red、fillred、map、
boolred 这 5 种数组迭代器. 以 red 为例, red<<op, size>>(init, array) 接受两个静态参数和两个实参, 静态参数 op 表
示要对数组进行的操作, 静态参数 size 表示数组的大小, 输入 init 表示初始值, 输入 array 表示需要操作的数组. 抽
象地说, red 迭代器将数组映射为标量; fill 迭代器将标量映射为数组; fillred 是 fill 和 red 结合, 将数组和标量映射
为数组和标量; map 将数组映射为数组; boolred 是针对 bool 类型的 red, 将 bool 数组映射为 bool 标量.
2 编译器总体框架
图 3 是可信编译系统的编译系统架构图, 以代码生成模块为核心, 主要有 3 个数据输入和 1 个数据输出.
文法 Lustre
Lustre 文法
标准化 源代码
标准化
Lustre 文法 拓扑排序 人工构建
下推自动机 词法分析 目标码
生成 转换模式
Lustre 下推自动机
下推自动机 识别 检查模块 转换模块
代码生成
C
目标码
图 3 编译系统架构图
本文将 Lustre V6 的文法人工进行标准化, 得到标准化 Lustre 文法, 将其输入下推自动机生成模块, 下推自动
机生成模块将上下文无关文法转换为下推自动机, 得到 Lustre 文法的下推自动机文件. 该文件在构建后即持久化,
不会在每次编译过程都重复这一过程.
目标码转换模式由人工分析 Lustre V6 和 C 语言语义手工构建, 目标码模式是消除掉语境对目标码序列的影
响而获得的目标码序列的一般化表示形式, 将下推自动机识别过程和转换动作结合起来.
Lustre 源代码首先经过拓扑排序正确处理赋值语句之间的顺序, 随后经过词法分析得到词法单元流, 最终转
换生成 C 目标码. 在生成代码时, 先生成当前层级代码, 然后递归生成子文法单元代码.

