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

  1. 使用rust 实现的一个简单的脚本语法解释器。
  2. 使用了 rust的nom库。
  3. 代码结构很简单
    - 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: "你好吗 兄弟们",
                            },
                        },
                    ],
                },
            },
        ),
    ],
}

目前支持

  1. 全局变量 global
  2. 加减乘除 + - * /
  3. 换行打印 println()
  4. 字符串定义 “ “
  5. 无参数 方法调用。(新支持)

TODO

  1. 带参数方法调用
  2. 类定义
  3. 错误提示
  4. 循环遍历
  5. if判断
  6. 内置函数功能实现
  7. 带入参数计算等。。
  8. ………..(待发掘)

源码地址
github.com/529124368/rust_create_s...

执行效果图

rust开发的自制脚本语言的解释器

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!