Victor's Code Journey
Victor's Code Journey

JavaCC:Token Manager

JavaCC的词法解析被转化为一组词法状态,每个状态都有一个唯一的标识符用于命名。Token Manager(生成的代码)在运行时总是处于状态之一,默认的一个词法状态是DEFAULT。当Token Manager初始化时,默认情况下是以DEFAULT状态开始。也可以在Token Manager 构造时,指定起始词法状态1

JavaCC 简介

JavaCC 是 java 生态中常用的Parser Generator。特征如下:

  • JavaCC 生成的解析器是基于LL 的,默认是LL(1),通过配置可以支持 LL(K)。
  • 由于是LL 方式,需要用户自己书写递归下降的语法规则来避免出现左递归问题。
  • JavaCC 支持 EBNF 语法范式。

JavaCC的工作流程如下:

  • 令牌管理器读入一个字符序列并生成一个称为令牌的对象序列。用于将字符序列分解为标记序列的规则取决于语言-它们由用户作为正则表达式的集合提供。
  • 解析器使用一个令牌序列,分析它的结构,并产生一个由用户定义的输出。

Rust Future 实现原理

Rust 既支持了基于系统线程的多线程编程模型,也支持了基于async/await的异步编程模型。Rust 的async编程有有以下特性:

  • Future 在 Rust 中是惰性的
  • Async 在 Rust 中使用开销是零
  • Rust 没有内置异步调用所必需的运行时,但是社区生态中已经提供了非常优异的运行时实现,例如 tokio和async-std
  • 运行时同时支持单线程和多线程

发明服务特征

Tower是一个模块化和可重用组件库,用于构建健壮的网络客户端和服务器。其核心是Service特征。Service是一个异步函数,它接受请求并产生响应。然而,其设计的某些方面可能并不明显。与其解释目前Tower中存在的Service特征,让我们通过想象如果你从头开始,你会如何发明它来看看Service背后的动机。

Rust Struct 字段自引用问题

先来看一段 Java 代码,Application中有version和 logger。logger 依赖了 Version。

public class Application
{
    public Version version;
    public Logger logger;
    public Application() {
        version = new Version(1);
        logger =  new Logger(version);
    }

    public static void main(String[] args)
    {
        Application application = new Application();
        application.logger.log("Hello World!");
        // console output:
        // [version 1] Hello World!
    }
    class Version {
        public int ver;
        public Version (int ver){
            this.ver = ver;
        }
        public String toString() {
            return String.format("version %d",ver);
        }
    }
    class Logger {
        public Version version;
        public Logger (Version version){
            this.version = version;
        }
        void log(String msg) {
            System.out.println(String.format("[%s] %s",version,msg));
        }
    }
}

那么问题来了,如何在 Rust 中实现相同的代码?