我正在使用Rust中的解析器。目标是解析AST,然后使用serde将AST序列化为JSON。
我要解析的DSL与JavaScript类似,但更简单。
pub struct Parser<'a> {
source: Peekable<str::Chars<'a>>,
}
impl<'a> Parser<'a> {
pub fn new(source: &str) -> Parser {
Parser {
source: source.chars().peekable(),
}
}
pub fn parse(&mut self) -> Resource {
let mut entities = Map::new();
self.skip_ws();
loop {
let entity = self.get_entity();
entities.insert(entity.id, entity);
self.skip_ws();
}
Resource(entities)
}
fn get_entity(&mut self) {
let id = self.get_identifier();
self.skip_line_ws();
if !self.next_char('=') {
panic!();
}
self.bump();
self.skip_line_ws();
let value = self.get_pattern();
if self.next_char('[') && self.next_char('[', 1) {
// get attributes
// return entity with attributes
} else {
// return entity without attributes
}
}
}
在两种情况下,只偷看一个字符不足以识别我收集的令牌。例如,如果偷看的角色是&#39; [&#39;,则下一个是#&#39; [&#39;,那么它不是实体的一部分,但如果它&#39; 39; sa&#39; [&#39;然后不&#39; [&#39;,它是一个属性。
我知道理论上我可以使用next()
来收集一个角色,然后使用peek()
来查看下一个角色,但是当你发现结果不属于实体,因为在这种情况下,我想将指针移回一个字符,然后返回。
在我需要提前查看3个字符的情况下,这也无法解决问题。
在我看来,我要么需要能够向前看两个字符,要么我需要一个能够推进迭代器然后将其移回的能力。
我在Itertools中发现multipeek
声称允许在前面偷看多个角色,但我不知道如何将它放入我的解析器中。
有人可以指导我或指出不同的方法吗?