rust开发的自制脚本语言解释器
最近学习rust的Nom库,一款很强大的字符串解析库。顺便在学习中去开发一款小应用->自制脚本语言的解释器,进而提高对nom的使用的熟悉。
罗列一部分nom库的函数功能
方法名 | 说明 |
---|---|
alpha0, alpha1 | 字母序列:[a-zA-Z]*、[a-zA-Z]+ |
digit0, digit1 | 数字序列:[0-9]*, [0-9]+ |
hex_digit0, hex_digit1 | 十六进制数字序列:[0-9a-fA-F]*, [0-9a-fA-F]+ |
oct_digit0, oct_digit1 | 八进制数字序列:[0-7]*, [0-7]+ |
alphanumeric0, alphanumeric1 | 字母和数字的顺序:[a-zA-Z0-9]*, [a-zA-Z0-9]+ |
space0, space1 | 连续的空格或制表符:[ \t]*, [ \t]+ |
multispace0, multispace1 | 一系列空格、制表符和换行符:[ \t\r\f]*, [ \t\r\f]+ |
tab, newline, crlf, line_ending, not_line_ending | 各种控制字符:\t、\n、\r\n、\n |
anychar | 任何单个字符: . |
char | 指定单个字符:$1 |
one_of | 任意单个字符:[$1$2$3…] |
none_of | 一个不匹配的字符:[^$1$2$3…] |
tag, tag_no_case | 指定字节序列:$1, (?i)$1 |
is_a | 任何字符序列:[$1]+ |
is_not | 一个不匹配的字符序列:[^$1]+ |
take | 固定长度的任意字符串:.{$1} |
take_till, take_till1, | 继续到匹配条件的字符或直到结尾 |
take_until | 匹配条件的字符串 |
等等….
github地址 github.com/Geal/nom
正题 实现一个初级的脚本解释器
rust_create_script_language
- 使用rust 实现的一个简单的脚本语法解释器。
- 使用了 rust的nom库。
- 代码结构很简单
- ast.rs token定义 - exec.rs AST(抽象语法树)执行 - main.rs 入口函数 - parse.rs 利用nom实现字符串解析成token
例子:
global wh = 122.3;
fn test() {
println("你说什么 sfsfs");
}
fn main()
{
s = 1 +2-3;
println(s);
println("hello world !!!");
s=7+(2-3)+(3+4);
println(s);
s=5-3+(3+4);
test();
println(s);
s=5*3 / (3+4);
println(s);
v=122.33;
println(123.2421);
println(wh);
println(v);
println("你好吗 兄弟们");
}
AST 抽象语法树 格式
Tree {
root: [
GlobalParmDef {
name: "wh",
token: Zval {
type_name: Number,
float: 122.3,
string: "",
},
},
FunctionDef(
Function {
name: "test",
args: [],
content: Block {
elements: [
PrintLn {
token: Zval {
type_name: String,
float: 0.0,
string: "你说什么 sfsfs",
},
},
],
},
},
),
FunctionDef(
Function {
name: "main",
args: [],
content: Block {
elements: [
Assignment {
name: "s",
token: Express {
opcode: Subtract,
left: Express {
opcode: Add,
left: Zval {
type_name: Number,
float: 1.0,
string: "",
},
right: Zval {
type_name: Number,
float: 2.0,
string: "",
},
},
right: Zval {
type_name: Number,
float: 3.0,
string: "",
},
},
},
PrintLn {
token: Flg {
name: "s",
},
},
PrintLn {
token: Zval {
type_name: String,
float: 0.0,
string: "hello world !!!",
},
},
Assignment {
name: "s",
token: Express {
opcode: Add,
left: Express {
opcode: Add,
left: Zval {
type_name: Number,
float: 7.0,
string: "",
},
right: Express {
opcode: Subtract,
left: Zval {
type_name: Number,
float: 2.0,
string: "",
},
right: Zval {
type_name: Number,
float: 3.0,
string: "",
},
},
},
right: Express {
opcode: Add,
left: Zval {
type_name: Number,
float: 3.0,
string: "",
},
right: Zval {
type_name: Number,
float: 4.0,
string: "",
},
},
},
},
PrintLn {
token: Flg {
name: "s",
},
},
Assignment {
name: "s",
token: Express {
opcode: Add,
left: Express {
opcode: Subtract,
left: Zval {
type_name: Number,
float: 5.0,
string: "",
},
right: Zval {
type_name: Number,
float: 3.0,
string: "",
},
},
right: Express {
opcode: Add,
left: Zval {
type_name: Number,
float: 3.0,
string: "",
},
right: Zval {
type_name: Number,
float: 4.0,
string: "",
},
},
},
},
CallFunction {
name: "test",
args: [],
},
PrintLn {
token: Flg {
name: "s",
},
},
Assignment {
name: "s",
token: Express {
opcode: Divide,
left: Express {
opcode: Multiply,
left: Zval {
type_name: Number,
float: 5.0,
string: "",
},
right: Zval {
type_name: Number,
float: 3.0,
string: "",
},
},
right: Express {
opcode: Add,
left: Zval {
type_name: Number,
float: 3.0,
string: "",
},
right: Zval {
type_name: Number,
float: 4.0,
string: "",
},
},
},
},
PrintLn {
token: Flg {
name: "s",
},
},
Assignment {
name: "v",
token: Zval {
type_name: Number,
float: 122.33,
string: "",
},
},
PrintLn {
token: Zval {
type_name: Number,
float: 123.2421,
string: "",
},
},
PrintLn {
token: Flg {
name: "wh",
},
},
PrintLn {
token: Flg {
name: "v",
},
},
PrintLn {
token: Zval {
type_name: String,
float: 0.0,
string: "你好吗 兄弟们",
},
},
],
},
},
),
],
}
目前支持
- 全局变量 global
- 加减乘除 + - * /
- 换行打印 println()
- 字符串定义 “ “
- 无参数 方法调用。(新支持)
TODO
- 带参数方法调用
- 类定义
- 错误提示
- 循环遍历
- if判断
- 内置函数功能实现
- 带入参数计算等。。
- ………..(待发掘)
源码地址
github.com/529124368/rust_create_s...
执行效果图
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: