2个版本
0.1.11 | 2021年1月2日 |
---|---|
0.1.0 | 2021年1月1日 |
#991 在 进程宏
39KB
825 行
想法
Rust宏,用于生成PEG解析器。
功能
- 文字
- strs
"Hello"
- chars
'c'
- 字符范围
'0'..='9'
- 任何字符
any
- strs
- Span
$e
- 原子
@e
- 命名
name: e
- 前瞻
- 正向前瞻
&e
- 负向前瞻
!e
- 正向前瞻
- 序列
e e
- 选择
e | e
- 数字
- 多个0(零个或多个)
e*
- 多个1(一个或多个)
e+
- 可选(零个或一个)
e?
- 多个0(零个或多个)
预定义规则
any = // Matches any single character
digit = '0'..='9'
alpha = insensitive['a'..='z']
alnum = alpha | digit
comment = !any
space = (whitespace | comment)*
语法
rule = name '=' alt
alt = cat ('|' cat)* action?
cat = (named | unary)+
named = name ':' unary
unary = prefix | postfix | atom
prefix_op
= '$' // Span
| '@' // Atomic
| '!' // Negative lookahead
| '&' // Positive lookahead
postfix_op
= '*' // Many0
| '+' // Many1
| '?' // Optional
prefix = prefix_op atom
postfix = postfix_op atom
atom = name | literal | parenthesized
parenthesized = '(' alt ')'
左递归
检测
运行时
尝试规则,从1..开始递归,直到解析失败。现在最新的缓存结果是答案。
编译
- 解析语法
- 将所有规则名称替换为索引
- 检测内置规则的覆盖
- 标记左递归规则
- 报告可反驳的绑定
分隔符
对于分隔符,我们可能想要选择
- 0个或多个出现
[]
- 1个或多个出现
[1]
- 1个或多个出现,但只有当有尾随逗号时
[1,]
- 当
x
的返回类型为X
且y
的返回类型为Y
时,x ^ y
应该有返回类型(Vec<X>, Vec<Y>)
- 元组可以按以下方式创建
tuple = '(' item: item ',' items: item ^ ',' ')' {
let mut items = items.0;
items.insert(0, item);
items
}
或者(目前还不行)
tuple = '(' items: item ^ ',' ')' {?
// At least one comma
match items.1.len() {
0 => None
_ => Some(items.0)
}
}
待办事项
依赖项
~1.5MB
~35K SLoC