智能合约语言(eDSL)—— 使用rust实现eDSL的原理

        为理解rust变成eDSL的实现原理,我们需要简单了解元编程与宏的概念,元编程被描述成一种计算机程序可以将代码看待成数据的能力,使用元编程技术编写的程序能够像普通程序在运行时更新、替换变量那样操作更新、替换代码。宏在 Rust 语言中是一种功能,能够在编译实际代码之前按照自定义的规则展开原始代码,从而能够达到修改原始代码的目的。从元编程的角度理解,宏就是“生成代码的代码”,因而 Rust 语言中的元编程能力主要来自于宏系统。通过 Rust 语言的宏系统,不仅能够实现 C语言的宏系统所提供的模式替换功能,甚至还能够控制编译器的行为、设计自己的语法从而实现 eDSL,所以我们正是基于 Rust 语言的宏系统实现的 eDSL。

        Rust 源代码文件编译需要经过下列阶段:

  1. 编译器在获得源代码文件后,会先进行词法分析,即把源代码字符序列转换为标记(Token)序列。标记是单独的语法单元,在 Rust 语言中,关键字、标识符都能够构成标记。词法分析还会将标记与标记的关系也记录下来,从而的生成标记树(Token tree),以一条简单的程序语句为例:

    a + b + (c + d[0])  + e
    

    其标记树如下图所示:

    token_tree

    注意

    与C中宏处理(导入 #include 头文件、替换 #define 符号等)是发生在预编译阶段不同,Rust语言并没有预编译阶段,其宏展开是发生在的完成语法分析后。也正是因为如此,Rust宏能够获得更详细、更复杂的编译期信息,从而提供极为强大的元编程能力。

  2. 随即,编译器启动语法分析流程,将词法分析生成的标记树翻译为 AST(Abstract Syntax Tree,抽象语法树)。在计算机科学中,AST 是源代码语法结构的一种抽象表示,能够方便地被编译器处理。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。上述第 1 步中生成的样例标记树会被翻译为如下图所示的 AST:

ast

  1. 然后,编译器开始分析 AST 并执行宏展开过程。此阶段是是最为重要的阶段,因为我们的eDSL 主要工作在这个阶段。以我们xq合约为例,编译器构造出xq合约的 AST 后,当扫描至 AST 中表示#[call(contract = "xq", function = "abc")]语句的语法树节点时,编译器能够知道,此处正在调用属性宏(Rust 中一种特殊的宏),因此会开始寻找call属性宏的定义并尝试进行展开。call属性宏的定义如下:

    #[proc_macro_attribute]
    pub fn call(attr: TokenStream, item: TokenStream) -> TokenStream {let attrs = parse_macro_input!(attr as AttributeArgs);let contract = get_attribute(attrs.clone(), "contract").unwrap().unwrap();let function = get_attribute(attrs.clone(), "function").unwrap().unwrap();//let payable = contains_attribute2(attrs.clone(), "payable");
    

    属性宏以函数形式定义,其输入是两个标记序列(TokenStream),其输出也是一个标记序列。事实上,在 Rust 语言中,宏可以理解为将某一个 AST 变换到另外一个 AST 的函数。Rust 编译器并不会向属性宏直接传递 AST,而且会将其调用位置所在的语法树节点转换为标记序列传递给属性宏,由属性宏的编写者自行决定如何处理这段标记序列。无论如何处理,属性宏都需要返回一段标记序列,Rust 编译器接收到这段标记序列后,会将其重新编译为 AST 并插入到宏的调用位置,从而完成代码的编译期修改。具体到 Liquid 的call属性宏,当编译器进行展开时,call属性宏会获取到自身及其后跟随的代码块的标记序列,并将其解析为一棵 AST。

  2. 编译器将经过宏展开之后的 AST 编译为可执行文件:若是需要在本地运行单元测试,则会将 AST 编译为本地操作系统及 CPU 所能识别的可执行文件;若是需要能够在链上部署运行,则会将 AST 编译为 Wasm 格式字节码。至此,合约的基本构建流程结束。

        从上述实现原理中可以看出,我们的eDSL 可以理解为是一种以 Rust 语言目标语言的编程语言。在编译器的广义定义中,编译器是一种能够将以某种编程语言(原始语言)书写的源代码转换成另一种编程语言(目标语言)的计算机程序,因此我们的eDSL在一定程度上扮演了编译器的角色。通过屏蔽区块链的底层实现细节,智能合约的开发过程能够更加便利及自然

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/756814.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器人离散化阻抗控制

机器人离散化阻抗控制是一种控制策略,它结合了阻抗控制的思想与离散化方法,以实现对机器人运动与外力之间动态关系的精细调节。这种控制方法旨在使机器人在与环境交互时能够表现出期望的阻抗特性,从而实现对接触力和位置的精确控制。 在离散…

STM32—控制蜂鸣器(定时器)

目录 1 、 电路构成及原理图 2 、编写实现代码 main.c tim_irq.c 3、代码讲解 4、烧录到开发板调试、验证代码 5、检验效果 此笔记基于朗峰 STM32F103 系列全集成开发板的记录。 1 、 电路构成及原理图 定时器中断是利用定时器的计数功能(向上计数或向下计…

算法---二分查找练习-3(山脉数组的顶峰索引)

山脉数组的顶峰索引 1. 题目解析2. 讲解算法原理3. 编写代码 1. 题目解析 题目地址&#xff1a;点这里 2. 讲解算法原理 初始化两个指针 left 和 right&#xff0c;分别指向数组的起始位置和结束位置。 进入循环&#xff0c;循环条件为 left < right。 在每次循环中&…

Visual Studio - 添加快捷键图标

Visual Studio - 添加快捷键图标 1. Text Editor Toolbar Options -> Add or Remove Buttons -> Customize2. Toolbars3. Commands -> Debug4. Add Command...References 1. Text Editor Toolbar Options -> Add or Remove Buttons -> Customize 2. Toolbars B…

机器学习-05-特征工程

总结 本系列是机器学习课程的系列课程&#xff0c;主要介绍机器学习中特征工程部分。 参考 机器学习之特征工程详解 特征工程&#xff08;Feature Engineering&#xff09; 特征工程是指使用专业的背景知识和技巧处理数据&#xff0c;使得特征能在机器学习算法上发生更好的…

Lvs+keepalived+nginx搭建高可用负载均衡集群

环境配置 master主机192.168.199.149&#xff0c;虚拟IP192.168.199.148 back备机192.168.199.150 真实服务器1 192.168.199.155 真实服务器2 192.168.199.156 关闭防火墙和selinux master配置&#xff08;149&#xff09; 添加虚拟IP ip addr add 192.168.199.148/24 …

手机备忘录隐藏功能:生日纪念日重要日子倒计时天数和提醒

在日常使用手机时&#xff0c;我们经常会用到备忘录、便签或笔记等记事工具来记录生活的点点滴滴&#xff0c;无论是购物清单、工作任务还是学习笔记。然而&#xff0c;你可能不知道&#xff0c;手机备忘录中其实隐藏着一些非常实用的功能&#xff0c;比如记录生日、纪念日、重…

Java设计模式 | 简单工厂模式

概述 需求 设计一个咖啡店点餐系统设计一个咖啡类&#xff08;Coffee&#xff09;&#xff1b;并定义其两个子类&#xff08;美式咖啡AmericanCoffee和拿铁咖啡LatteCoffee&#xff09;&#xff1b;再设计一个咖啡店类&#xff08;CoffeeStore&#xff09;&#xff0c;其具备…

Node.js常用命令:了解Node.js的核心命令和用法

学习目标&#xff1a; 理解Node.js和npm的概念及其在开发中的作用&#xff1b;掌握Node.js的核心命令&#xff0c;包括node、npm、npx等&#xff1b;学会使用node命令来执行JavaScript文件和模块&#xff1b;熟悉npm命令&#xff0c;包括安装、更新、卸载依赖包等操作&#xf…

【Ubuntu】常用命令

一般操作 pwd&#xff08;present working directory&#xff09; 显示当前的工作目录/路径。 cd (change directory) 改变目录&#xff0c;用于输入需要前往的路径/目录。 有一些特殊命令也很常用 : 解释 前往同一级的另一个目录 cd ../directory name cd .. 表示进入上…

STP环路避免实验(华为)

思科设备参考&#xff1a;STP环路避免实验&#xff08;思科&#xff09; 一&#xff0c;技术简介 Spanning Tree Protocol&#xff08;STP&#xff09;&#xff0c;即生成树协议&#xff0c;是一种数据链路层协议。主要作用是防止二层环路&#xff0c;并自适应网络变化和故障…

unity学习(62)——emptyObject+昵称+血条

1.地图比较麻烦&#xff0c;先最后回头再做&#xff0c;地图是锦上添花的东西。 2.MapHandler中的使用技巧&#xff1a; 2.1.继承必须有&#xff0c;要不脚本绑不到相机上 2.2当场景被调用时触发函数OnLevelWasLoaded&#xff0c;这个和Start一样属于一个机制函数。 3.自己做…

长安链Docker Java智能合约引擎的架构、应用与规划

#功能发布 长安链3.0正式版发布了多个重点功能&#xff0c;包括共识算法切换、支持java智能合约引擎、支持后量子密码、web3生态兼容等。我们接下来为大家详细介绍新功能的设计、应用与规划。 在《2022年度长安链开源社区开发者调研报告》中&#xff0c;对Java合约语言支持是开…

51单片机—直流电机

1.元件介绍 2.驱动电路 3.电机调速 一般会保证一个周期的时间是一样的 应用&#xff1a; 1.LED呼吸灯 #include <REGX52.H>sbit LEDP2^0;void Delay(unsigned int t) {while(t--); } void main() {unsigned char Time,i;while(1){for(Time0;Time<100;Time){for(i0;…

【前端寻宝之路】学习和总结HTML的标签属性

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不…

Linux-Arm环境下配置编译qt-everywhere及交叉编译环境

前言 最近在搞交叉编译的事&#xff0c;手上拿了个同事的香橙派玩交叉编译&#xff0c;现在来到了第一步&#xff0c;就是先在arm上配置qt的开发环境。当然了Qt没有直接提供qt on arm&#xff0c;而是需要自行在arm环境下编译一个qt环境出来&#xff0c;所以这里需要使用到qt提…

【Linux】vim详细介绍(四)

文章目录 什么是 vimvim的主要功能&#xff1a;vim的三种模式.viminfo和.vimrc文件 什么是 vim 点击跳转至官网了解更多 Vim是一款功能强大的文本编辑器&#xff0c;适用于各种编程和文本处理任务&#xff0c;最初由Bram Moolenaar开发于1991年。它是Vi编辑器的增强版&#xf…

GitHub Copilot+ESP开发实战-串口

上篇文章讲了GitHub Copilot在应用中可能遇到的问题&#xff0c;接下来小启就简单介绍下GitHub Copilot在ESP32开发中C语言实现串口功能&#xff0c;感兴趣的可以看看。 一、向Copilot提问&#xff1a; 1. ESP32用C语言实现串口初始化&#xff1b; 2.配置uart为1&#xff0c…

【Thread 线程】线程的方法与状态

SueWakeup 个人中心&#xff1a;SueWakeup 系列专栏&#xff1a;学习Java 个性签名&#xff1a;保留赤子之心也许是种幸运吧 本文封面由 凯楠&#x1f4f7; 友情赞助播出&#xff01; 目录 一个线程的生命周期 线程终止的原因 线程的方法 Thread 类的静态方法 1. 设置线程…

59、服务攻防——中间件安全CVE复现IISApacheTomcatNginx

文章目录 中间件——IIS漏洞中间件——Nginx漏洞中间件——Apache中间件——Tomcat 中间件&#xff1a;IIS、Apache、Nginx、Tomcat、Docker、Weblogic、JBoss、WebSphere、Jenkinsphp框架&#xff1a;Laravel、Thinkphppythonl框架&#xff1a;Flaskjs框架&#xff1a;jQueryj…