10 个版本
0.6.6 | 2024年6月19日 |
---|---|
0.6.5 | 2023年12月19日 |
0.6.4 | 2023年7月20日 |
0.6.1 | 2023年3月5日 |
0.3.0 | 2021年7月7日 |
#20 在 编程语言
55 每月下载量
在 2 个 crate 中使用 (通过 tokay-macros)
1.5MB
18K SLoC
Tokay
Tokay 是一种为即席解析而设计的编程语言。
Tokay 正在开发中,目前尚未考虑用于生产;成为 Tokay 持续开发的一部分,并 贡献!
关于
Tokay 旨在成为一种可以用于快速实现文本处理问题的编程语言。这可以涉及简单的数据提取,也可以是解析句法结构或其部分,并将信息转换为结构化解析树或抽象语法树以进行进一步处理。
因此,Tokay 不仅是一个适用于简单单行代码(如匹配器或识别器)的实用工具,而且还可以用于实现代码分析器、重构工具、解释器、编译器或转换器。实际上,Tokay 的自身语言解析器也是用 Tokay 实现的。
Tokay 受 awk 启发,具有 Python 和 Rust 的句法和语义风味,但同时也遵循其自身的哲学、思想和设计原则。因此,它不能与其他语言或项目直接比较,而是一个独特的存在。
Tokay 仍然是一个非常年轻的项目,具有巨大的潜力。 志愿者欢迎加入!
亮点
- 解释型、过程型和命令型脚本语言
- 简洁易学的语法和对象系统
- 基于流的输入处理
- 自动解析树构建和合成
- 支持左递归解析结构("解析器")
- 内部实现记忆化 packrat 解析算法
- 由于完全用安全的 Rust 编写,因此稳健且快速
- 结合其他工具启用awk风格的单行脚本
- 通用解析器和函数
- 导入系统以创建模块化程序(即将推出)
- 与其他程序的嵌入式互操作性(即将推出)
安装
通过使用Rust的依赖管理器和构建工具cargo
,简单安装Tokay:
$ cargo install tokay
对于基于Arch Linux的发行版,Arch Linux AUR(Arch Linux用户仓库)中也有一个tokay
和一个tokay-git
软件包。
示例
Tokay的“Hello World”版本相当明显。
print("Hello World")
$ tokay 'print("Hello World")' Hello World
Tokay还可以问候任何输入给它的wor(l)ds。下一个程序打印“Hello Venus”,“Hello Earth”或“Hello”后跟之前由内置的Word
令牌解析的任何其他名称。任何非单词输入都会自动省略。
print("Hello", Word)
$ tokay 'print("Hello", Word)' -- "World 1337 Venus Mars 42 Max" Hello World Hello Venus Hello Mars Hello Max
一个简单的程序,用于计算单词和数字,并在之后打印总数,可以像这样实现:
Word words += 1
Number numbers += 1
end print(words || 0, "words,", numbers || 0, "numbers")
$ tokay 'Word words += 1; Number numbers += 1; end print(words || 0, "words,", numbers || 0, "numbers")' -- "this is just the 1st stage of 42.5 or .1 others" 9 words, 3 numbers
设计上,Tokay会自动从消耗的信息中构建语法树。
下一个程序实现了一个简单数学表达式的解析器和解释器,例如1 + 2 + 3
或7 * (8 + 2) / 5
。每个表达式的结果随后打印出来。
处理直接和间接左递归而不会导致无限循环是Tokay的核心特性之一。
_ : Char< \t>+ # redefine whitespace to just tab and space
Factor : @{
Int _ # built-in 64-bit signed integer token
'(' _ Expr ')' _
}
Term : @{
Term '*' _ Factor $1 * $4
Term '/' _ Factor $1 / $4
Factor
}
Expr : @{
Expr '+' _ Term $1 + $4
Expr '-' _ Term $1 - $4
Term
}
Expr _ print("= " + $1) # gives some neat result output
$ tokay examples/expr_from_readme.tok 1 + 2 + 3 = 6 7 * (8 + 2) / 5 = 14 7*(3-9) = -42 ...
从解析的整数计算斐波那契数列
fibonacci : @n {
if n <= 1 n else fibonacci(n - 1) + fibonacci(n - 2)
}
Int print($1, "=>", fibonacci($1))
$ tokay examples/fibonacci2.tok 0 0 => 0 1 1 => 1 2 2 => 1 3 3 => 2 4 4 => 3 5 5 => 5 6 6 => 8 7 7 => 13 8 8 => 21 9 9 => 34 10 10 => 55
文档
Tokay的主页tokay.dev提供了快速入门和文档的链接。文档源代码维护在一个单独的仓库中。
调试
调试有两种方法可以使用。
使用log
-crate进行跟踪
对于Rust标准跟踪,使用env_logger
功能。完整的跟踪只编译到调试可执行文件中,发布版本只提供警告级别及以上。
$ RUST_LOG=tokay=debug tokay
或者,可以通过设置TOKAY_LOG
来为__main__
程序激活跟踪。这用于在内部解析器已编译和执行,并解析了实际程序之后开始跟踪。TOKAY_LOG
可以设置为任何RUST_LOG
兼容的格式,因为它立即变成了RUST_LOG
。
$ TOKAY_LOG=tokay=debug tokay
使用TOKAY_DEBUG
和TOKAY_PARSER_DEBUG
的内置AST和VM调试器
将TOKAY_DEBUG
设置在1到6的调试级别之间。这也可以通过使用tokay -dddd
来实现,其中每个d
都会增加调试级别。此外,还可以将TOKAY_INSPECT
设置为要逐步跟踪的解析器名称(-前缀)的列表(TOKAY_DEBUG=6
)。
级别 | 模式 |
---|---|
0 | 无调试 |
1 | 打印构建的AST |
2 | 打印最终的中间程序 |
3 | 打印编译的VM程序 |
4 | 打印VM执行跟踪 |
5 | 打印VM堆栈内容 |
6 | VM指令调试器 |
在调试级别1中查看程序的解析AST
$ cargo run -q -- -d 'x = 42 print("Hello World " + x)' main [start 1:1, end 1:33] sequence [start 1:1, end 1:33] assign_drop [start 1:1, end 1:8] lvalue [start 1:1, end 1:3] identifier [start 1:1, end 1:2] => "x" value_integer [start 1:5, end 1:7] => 42 call [start 1:8, end 1:33] identifier [start 1:8, end 1:13] => "print" callarg [start 1:14, end 1:32] op_binary_add [start 1:14, end 1:32] value_string [start 1:14, end 1:28] => "Hello World " identifier [start 1:31, end 1:32] => "x"
TOKAY_PARSER_DEBUG
设置解析器的特定调试级别,该解析器在Tokay本身中实现,并作为编译器的一部分。这里只能识别 > 2 的级别,因为解析器的AST已内置于代码中。
以下是运行简单“Hello World”程序的VM调试器操作过程。
`$ TOKAY_INSPECT="__main__" cargo run -q -- 'print("Hello World")'` __main__ --- Code --- __main__ 000 Offset(Offset { offset: 6, row: 1, col: 7 }) __main__ >001 LoadStatic(1) __main__ 002 Offset(Offset { offset: 0, row: 1, col: 1 }) __main__ 003 CallStaticArg((2, 1)) __main__ --- Reader --- __main__ offset=Offset { offset: 0, row: 1, col: 1 } __main__ eof=false __main__ --- Globals --- __main__ --- Stack --- __main__ --- Frames --- __main__ 000 capture: 0, reader: 0, fuse: None __main__ ip = 1 state = Ok(Push([59d29e639f88] "Hello World" (10))) __main__ --- Code --- __main__ 000 Offset(Offset { offset: 6, row: 1, col: 7 }) __main__ 001 LoadStatic(1) __main__ 002 Offset(Offset { offset: 0, row: 1, col: 1 }) __main__ >003 CallStaticArg((2, 1)) __main__ --- Reader --- __main__ offset=Offset { offset: 0, row: 1, col: 1 } __main__ eof=false __main__ --- Globals --- __main__ --- Stack --- __main__ 000 [59d29e639f88] "Hello World" (10) __main__ --- Frames --- __main__ 000 capture: 0, reader: 0, fuse: None Hello World __main__ ip = 3 state = Ok(Push([59d29e498fd8] void (10))) __main__ exit state = Ok(Push([59d29e498fd8] void (10)))
标志
托凯编程语言以亚洲的托凯壁虎(Gekko gecko)命名,它在夜晚高喊“token”。
托凯标志和图标由Timmytiefkuehl设计。
还可以查看tokay-artwork存储库中的不同版本的标志。
许可证
版权所有 © 2024 由Jan Max Meyer,Phorward软件技术公司。
托凯是MIT许可证下的免费软件。
请参阅LICENSE文件以获取详细信息。
依赖项
~8–16MB
~198K SLoC