CaltechCS122 笔记:Assignment 0: NanoDB Introduction
Assignment 0: NanoDB Introduction
NanoDB 是加州理工大学 Caltech CS122 课程使用的教学数据库系统
ANTLR
ANTLR (ANother Tool for Language Recognition) 是一个开源的语言识别器生成器,它可以用于生成词法分析器、语法分析器和解析树等组件。ANTLR 支持多种编程语言,包括 Java、C++、Python 和 C# 等。
ANTLR 的主要功能是将输入的文本流转换为解析树,解析树是一种抽象语法树(Abstract Syntax Tree,AST)的一种实现形式。ANTLR 提供了一种简单的方法来定义词法分析器和语法分析器,只需要编写一个以 .g4 结尾的 ANTLR 语法文件即可。ANTLR 将使用该文件来生成所需的代码。
ANTLR 规则
如下图所示为 NanoDB 的语法规则 NanoSQL.g4 的部分内容
下面分析一段规则的含义:
- Keyword 如 CREATE 等都是在词法分析中定义的关键字
- 字符 ‘,’, ‘(’ 与输入的 SQL 一一对应
- () 是用来分组语法规则的语法元素,使用括号可以让语法规则更加清晰和灵活,有助于明确规定子规则之间的关系和操作顺序。
- ()? 是一个语法规则的语法元素,表示前面的子规则是可选的(即出现零次或一次)。这种语法元素被称为“选项”,它允许匹配规则的片段可以存在,也可以不存在。
- ()* 是一个语法规则的语法元素,表示前面的子规则可以重复零次或多次。这种语法元素被称为“重复”,它允许匹配规则的片段可以出现任意次数,包括零次。
- (|) 表示一个选择操作符,也称为“或”操作符。它用于指定多个子规则之间的选择关系,表示其中任意一个子规则都可以进行匹配。
- 规则 如 createTableStmt, cmdProperties 等
- 规则? abc? 表示 abc 规则是可选的(即出现零次或一次)。这种语法元素被称为“选项”,它允许匹配规则的片段可以存在,也可以不存在。
IDEA 与 ANTLR
- 对于 .g4 文件,grammar 后的名字需要与文件名保持一致
- 在使用 idea 时,如果需要导入不同文件夹下的 .g4 文件,需要配置如下图所示路径。
idea 的 antlr 插件提供了可视化语法树功能,效果如下所示
Vistor
使用访问者模式遍历语法树
访问者模式
主要作用
- 将数据结构和数据操作分离
- 使操作集合可以独立于数据结构的变化
主要组件
- Element
- ConcreteElement
- Visitor
- ConcreteVisitor
package v32_visitor.java;
interface Shape {
void accept(Visitor visitor);
}
class Circle implements Shape {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
class Rectangle implements Shape {
public void accept(Visitor visitor) {
visitor.visit(this);
}
}
interface Visitor {
void visit(Circle circle);
void visit(Rectangle rectangle);
}
class DrawVisitor implements Visitor {
public void visit(Circle circle) {
System.out.println("Drawing a circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Drawing a rectangle");
}
}
class ResizeVisitor implements Visitor {
public void visit(Circle circle) {
System.out.println("Resizing a circle");
}
public void visit(Rectangle rectangle) {
System.out.println("Resizing a rectangle");
}
}
public class ShapeMain2 {
public static void main(String[] args) {
Shape circle = new Circle();
Shape rectangle = new Rectangle();
Visitor drawVisitor = new DrawVisitor();
Visitor resizeVisitor = new ResizeVisitor();
circle.accept(drawVisitor);
rectangle.accept(drawVisitor);
circle.accept(resizeVisitor);
rectangle.accept(resizeVisitor);
}
}