75个版本 (4个稳定版)
使用旧Rust 2015
2.0.1 | 2021年4月12日 |
---|---|
1.0.1 | 2021年2月25日 |
1.0.0 | 2019年5月15日 |
0.30.0 | 2018年12月5日 |
0.10.6 | 2015年7月19日 |
#985 在 解析器实现 中
每月162次下载
用于 15 个crates (14直接)
205KB
5K SLoC
Piston-Meta
用于人类可读文本文档的领域特定语言(DSL)解析库
简介
Piston-Meta使编写人类可读文本文档的解析器变得容易。它可以用于语言设计、自定义格式和数据驱动开发。
元解析是一种可以追溯到第一台现代计算机的开发技术。其思想是将计算机程序的部分转换为可编程的管道,从而加速开发。在项目之间,一个重要且令人惊讶的可重用部分是从文本生成结构化数据的概念,因为文本易于修改和推理。
大多数处理文本的程序使用以下管道
f : text -> data
这种方法的缺点是 f
从项目到项目都会变化,将文本转换为数据结构的任务可能会变得非常复杂。例如,要创建编程语言语法的解析器,可能需要数千行代码。这会减慢开发速度并增加出错的机会。
元解析是一种将 f
分为两步的技术
f <=> f2 . f1
f1 : text -> meta data
f2 : meta data -> data
第一步 f1
将文本转换为元数据。使用领域特定语言(DSL)来描述这种转换是如何发生的。第二步 f2
将元数据转换为数据,这通常写成代码。
规则
元语言用于描述如何读取其他文档。首先定义一些可重复使用的字符串,然后是一些节点规则。最后一个节点用于读取整个文档。
20document= [.l(string:"string") .l(node:"node") .w?]
字符串以下划线开头,可以在规则之间重复使用
_opt: "可选"
节点以数字开头,该数字乘以1000后用作调试ID。如果您收到错误 #4003
,则它是由以4开头的节点中的规则引起的。
规则 | 描述 |
---|---|
.l(rule) | 使用行分隔子规则。 |
.l+(rule) | 使用行和缩进(空白敏感)分隔子规则。 |
.r?(rule) | 重复子规则直到失败,允许零次重复。 |
.r!(规则) | 重复子规则直到失败,至少需要一次重复。 |
...任意字符?:名称 | 读取字符串直到任意字符,允许零个字符。名称是可选的。 |
...任意字符!:名称 | 读取字符串直到任意字符,至少需要一个字符。名称是可选的。 |
..任意字符?:名称 | 读取字符串直到任意字符或空白字符,允许零个字符。名称是可选的。 |
..任意字符!:名称 | 读取字符串直到任意字符或空白字符,至少需要一个字符。名称是可选的。 |
.w? | 读取空白字符。空白字符是可选的。 |
.w! | 读取空白字符。空白字符是必需的。 |
?规则 | 使规则可选。 |
"标记":名称 | 期望一个标记,将名称设置为 true 。名称是可选的。 |
"标记":!名称 | 期望一个标记,将名称设置为 false 。名称是必需的。 |
!"标记":名称 | 如果读取标记则失败,如果未读取则将名称设置为 true 。名称是可选的。 |
!"标记":!名称 | 如果读取标记则失败,如果未读取则将名称设置为 false 。名称是必需的。 |
!规则 | 如果读取规则则失败。 |
.s?(通过规则规则) | 通过另一个规则分隔规则,允许零次重复。 |
.s!(通过规则规则) | 通过另一个规则分隔规则,至少需要一次重复。 |
.s?.(通过规则规则) | 通过另一个规则分隔规则,允许尾部。 |
{规则} | 选择一个规则。尝试第一个规则,然后第二个,等等。规则由空白字符分隔。 |
[规则] | 一系列规则。规则由空白字符分隔。 |
node | 使用没有名称的节点。读取的数据放在当前节点中。 |
节点:名称 | 使用具有名称的节点。读取的数据放在具有该名称的新节点中。 |
.t?:名称 | 读取具有名称的 JSON 字符串。字符串可以为空。名称是可选的。 |
.t!:名称 | 读取具有名称的 JSON 字符串。字符串不能为空。名称是可选的。 |
.$:名称 | 读取具有名称的数字。名称是可选的。 |
.$_:名称 | 读取具有下划线作为可见分隔符的数字,例如 10_000 。名称是可选的。 |
"Hello world" 在 Piston-Meta 中
extern crate piston_meta;
use piston_meta::*;
fn main() {
let text = r#"hi James!"#;
let rules = r#"
1 say_hi = ["hi" .w? {"James":"james" "Peter":"peter"} "!"]
2 document = say_hi
"#;
// Parse rules with meta language and convert to rules for parsing text.
let rules = match syntax_errstr(rules) {
Err(err) => {
println!("{}", err);
return;
}
Ok(rules) => rules
};
let mut data = vec![];
match parse_errstr(&rules, text, &mut data) {
Err(err) => {
println!("{}", err);
return;
}
Ok(()) => {}
};
json::print(&data);
}
引导
当元语言发生变化时,使用引导将旧元语法提升到新元语法。以下是工作原理
- Piston-Meta 包含可组合的规则,可以解析许多可读文本格式。
- Piston-Meta 知道如何解析和转换为自身的规则,称为 "引导"。
- 因此,您可以使用元语言告诉 Piston-Meta 如何解析其他文本格式!
- 包括描述如何解析自身语法的文本格式,它生成与 Rust 中硬编码的规则等效的规则。
- 元语言的新版本可以通过略微更改自语法来描述旧版本,以保持向后兼容性,因此它可以读取旧版本的自身。
依赖项
~45KB