The Crate, Package, and Moudle in Rust
The Crate Package and Moudle in Rust
References
Defining Modules to Control Scope and Privacy
Defining Modules to Control Scope and Privacy
when we are implementing a compiler, there is always a difficult problem we will encounter.
How can we evaluate an infix operator?
An infix operator is an operator placed between two expressions, like minus, plus, asterisk, slash and so forth. Here are some common infix operator:
Evaluation is where interpreter implementations diverge the most.There are a lot of different strategies to choose from when evaluating source code.so looking at different options is worthwhile.
Before we start, though, it's also worthy noting again that the line between interpreter and compiler is a blurry one.
the most obvious and classical choice of what to do with the AST is
to just interpret it. Traverse the AST,visit each node and do what the
node signifies: print a string,add two number, execute a function's
body.Sometimes their evaluation is preceded by small optimization that
rewrite the AST(e.g. remove unused variable bindings) or convert it into
another intermediate representation(IR) that's more
suitable for recursive and repeated evaluation.
使用本文记录学习
Pratt Parser的过程,全部代码实现基于go version go1.20.14 darwin/arm64实现,代码地址位于:0x822a5b87/test-pratt-parsing
在语法解析器(Parser)的工作过程中,我们通常会将一个字符串转换为一个抽象语法树(Abstract Syntax Tree):
---
title: The workflow of Paser
---
flowchart LR
Input["0 + 1 + 2! * -3"] -->|Parser| AST
subgraph AST
Add --> Add2[Add]
Add2 --> 0
Add2 --> 1
Add --> Mul
Mul --> ! --> 2w
Mul --> - --> 3
end
在这个解析过程中,我们会碰到许多问题:
今天,有个朋友突然问了我一个问题,为什么在以下代码中会发生以下这种情况呢?
secretId == "" 可以正常的进行比较;printString(secretId) 会提示类型不匹配;1 | import "fmt" |
看到这个问题我的第一反应是由于 类型推导(Type
inference),"" 被直接推导为 Password
类型,所以可以直接和 secretId 对象进行比较。可惜的是,在 golang
反编译的代码中已经丢失了类型信息,所以只能慢慢探索了。
Generics
是一种基本所有现代高级强类型编程语言中都会提供的特性,各个语言的实现模式不一样,例如:
cpp 基于 Template
来实现泛型,模版在编译时进行实例化。golang 基于 类型参数 和
约束 来实现泛型。总的来说优缺点如下表所示:
| 特性/语言 | Java 泛型 | C++ 模板 | Go 泛型 |
|---|---|---|---|
| 实现方式 | 类型擦除(Type Erasure) | 编译时实例化 | 类型参数和约束 |
| 类型安全 | 有 | 有 | 有 |
| 编译时类型检查 | 有 | 有 | 有 |
| 灵活性 | 差 | 极高,支持模板化和模板元变成 | 一般 |
| 复杂性 | 简单 | 极复杂 | 简单 |
| 运行时开销 | 有 | 无 | 有 |
| 缺点 | - 运行时无法获取泛型类型信息 - 不能创建泛型数组 - 不能使用基本类型作为泛型参数 - 不能在静态上下文中使用泛型类型参数 - 不能直接实例化泛型类型参数 |
- 编译速度慢:模板实例化可能导致编译时间增加 - 代码膨胀:大量模板实例化可能导致生成的二进制代码体积增大 - 错误信息复杂:模板错误信息可能难以理解和调试 |
- 相对较新的特性,生态系统和社区支持可能还不够成熟 - 可能引入一些性能开销,具体需要根据实际使用场景评估 |
由于最近接手了公司的一些血缘解析,SQL优化相关的任务,同时也涉及到了一些DSL的开发,在开发的过程中涉及到大量的calcite规则(Rule)定制,用此文章记录一下calcite的学习心得。
flowchart LR
subgraph 模版
direction LR
模板Parser.jj
compoundIdentifier.ftl
parserImpls.ftl
config.fmpp
default_config.fmpp
end
模版 --> FMPP --> Parser.jj:::underline --> JavaCC --> SqlParserImpl:::underline
classDef underline fill:#f9f,stroke:#333,stroke-width:4px;
本文是对 SQL 查询优化原理与 Volcano Optimizer 介绍 这篇文章的阅读一些补充和记录。
基于规则的优化方法的要点在于结构匹配和替换。 应用规则的算法一般需要先在关系代数结构上匹配一部分局部的结构, 再根据结构的特点进行变换乃至替换操作。
pprof 是 golang 内置的一种用于调优和性能分析的工具,有三种最常用的方式使用:
"net/http/pprof"
包,在包中会初始化一个http服务,随后可以通过http服务对pprof进行访问;wget 的方式访问 /debug/pprof/profile
接口(也需要通过1监听http端口)下载文件,文件可以通过
go tool pprof 打开并进入可视化界面;go test 进入测试用例剖析;如果我们想要使用pprof服务,可以通过如下两种方式开启:
匿名函数
1 | func main() { |