4个版本 (破坏性更新)
0.4.0 | 2024年5月15日 |
---|---|
0.3.0 | 2024年5月15日 |
0.2.1 | 2021年2月8日 |
0.2.0 |
|
0.1.0 | 2021年1月10日 |
#72 in 编程语言
每月下载量:272
170KB
4.5K SLoC
Analisar
Rust的Lua解析器
使用方法
解析器
此crate提供了3种不同的API用于解析Lua。第一种是一个相当标准的AST解析器,它不提供任何关于空白、标点符号或关键字位置的上下文信息。提供的AST旨在表示程序的意图,而不是其他任何东西。
这种解析器可以用于构建一个树遍历解释器。以下是一个输出示例
use analisar::Parser;
fn main() {
let lua = "print('hello world')";
let mut p = Parser::new(lua.as_bytes());
println!("{:#?}", p.next());
}
cargo run
Some(
Ok(
Expression(
FuncCall(
FunctionCall {
prefix: Name(
Name {
name: "print",
attr: None,
},
),
args: ExpList(
[
LiteralString(
LiteralString(
"\'hello world\'",
),
),
],
),
method: false,
},
),
),
),
)
TokenBufferParser
这是这两种解析器中的一种混合体。它提供了语句/表达式的树,以及给定语句表示的原始标记。
以下是一个此类解析器输出的示例
use analisar::TokenBufferParser;
fn main() {
let lua = "
-- print out hello world to stdout
print(--[[ why!!! ]]'hello world' --[[seriously???]])";
let mut p = TokenBufferParser::new(lua.as_bytes());
println!("{:#?}", p.next());
}
cargo run
Some(
Ok(
(
[
Item {
token: Comment(
"-- print out hello world to stdout",
),
span: Span {
start: 5,
end: 39,
},
},
Item {
token: Name(
"print",
),
span: Span {
start: 44,
end: 49,
},
},
Item {
token: Punct(
OpenParen,
),
span: Span {
start: 49,
end: 50,
},
},
Item {
token: Comment(
"--[[ why!!! ]]",
),
span: Span {
start: 50,
end: 64,
},
},
Item {
token: LiteralString(
"\'hello world\'",
),
span: Span {
start: 64,
end: 77,
},
},
Item {
token: Comment(
"--[[seriously???]]",
),
span: Span {
start: 78,
end: 96,
},
},
Item {
token: Punct(
CloseParen,
),
span: Span {
start: 96,
end: 97,
},
},
],
Expression(
FuncCall(
FunctionCall {
prefix: Name(
Name {
name: "print",
attr: None,
},
),
args: ExpList(
[
LiteralString(
LiteralString(
"\'hello world\'",
),
),
],
),
method: false,
},
),
),
),
),
)
如您所见,Statement::Expression
的输出与之前完全相同,但还有一个提供标记的Vec
。
aware::Parser
此crate提供的最后一个解析器是一个完全上下文感知的解析器。让我们看看这种解析器的输出是什么样的。
use analisar::aware::Parser;
fn main() {
let lua = "print(('hello world')) -- print the string 'hello world' to stdout";
let mut p = Parser::new(lua.as_bytes());
println!("{:#?}", p.next());
}
cargo run
Some(
Ok(
StatementWithComments {
statement: Expression(
FuncCall(
FunctionCall {
prefix: Name(
Name {
name_span: Span {
start: 0,
end: 5,
},
name: "print",
attr: None,
},
),
args: ExpList {
open_paren: Span {
start: 5,
end: 6,
},
exprs: [
Expr(
Parened {
open_span: Span {
start: 6,
end: 7,
},
expr: LiteralString(
LiteralString {
span: Span {
start: 7,
end: 20,
},
value: "\'hello world\'",
},
),
close_span: Span {
start: 20,
end: 21,
},
},
),
],
close_paren: Span {
start: 21,
end: 22,
},
},
},
),
),
comments: [
Item {
token: Comment(
"-- print the string \'hello world\' to stdout",
),
span: Span {
start: 23,
end: 66,
},
},
],
},
),
)
请注意,这与前两种解析器有很大的不同。首先,函数调用的名称有一个相关的Span
,它表示原始字符串中标记的字节偏移量,您会注意到每个条目中都有类似的跨度。它还提供了一种Parened
表达式,用于表示表达式被放入括号中的情况。最后,我们看到还提供了适用于此语句的注释。通过这三个添加项,可以完全重建标记的原始顺序,这对于构建代码格式化器或文档生成器非常有用。
依赖关系
~540–740KB
~11K SLoC