我工作的一个模板引擎,其中的一些语法可能是这样的:匹配模板过滤器表达式与NOM
{{ somevar|filter }}
在地方的somevar
可以是任意“表达”,这是说,要么是变量名称,如somevar
,要么是嵌套的过滤器表达式(如{{ somevar|filter|anotherfilter }}
)。我试图用Rust的nom分析器组合库来解析这个问题,但是到目前为止还没有得到它的工作。
这里的解析器,我拿出这么远:
#[macro_use]
extern crate nom;
use std::str;
#[derive(Debug)]
pub enum Expr<'a> {
Var(&'a [u8]),
Filter(&'a str, Box<Expr<'a>>),
}
#[derive(Debug)]
pub enum Node<'a> {
Lit(&'a [u8]),
Expr(Expr<'a>),
}
named!(expr_var<Expr>, dbg_dmp!(map!(nom::alphanumeric, Expr::Var)));
named!(expr_filter<Expr>,
dbg_dmp!(do_parse!(
val: any_expr >>
tag_s!("|") >>
name: map_res!(nom::alphanumeric, str::from_utf8) >>
(Expr::Filter(name, Box::new(val)))
))
);
named!(any_expr<Expr>, dbg_dmp!(ws!(
alt_complete!(
expr_filter |
expr_var
))));
named!(expr_node<Node>, dbg_dmp!(map!(
delimited!(tag_s!("{{"), any_expr, tag_s!("}}")),
Node::Expr)));
named!(parse_template< Vec<Node> >, many1!(expr_node));
随着playground。当前版本通过堆栈溢出发生混乱。我可以通过逆转any_expr
中的expr_var | expr_filter
订单来解决此问题,但后来我恢复了与之前基本相同的错误。
我强烈建议在尝试编写代码之前写出实际的语法。解析工具的一个重点是它们帮助将语法映射到代码。 – Shepmaster
我也会推荐1)做一个正确的http://stackoverflow.com/help/mcve(也许用http://play.rust-lang.org/)。另见http://www.sscce.org/。 2)提供一种单元测试,作为解析语法的例子。 – ArtemGr