我在nom中编写了一个完全无状态的解析器,现在我需要将它包装在几个有状态的层中。
我有一个名为alt_fn
的顶级解析函数,它将为我提供下一部分解析输出作为枚举变体,其详细信息可能并不重要。
我需要做三件涉及国家的事情:
1)如果在我的alt_fn
结构中不可变的HashMap中存在匹配,我需要有条件地对State
的输出执行转换。这应该基本上像map!
,但作为我的结构上的方法调用。像这样:
named!(alt_fn<AllTags> ,alt!(// snipped for brevity));
fn applyMath(self, i:AllTags)->AllTags { // snipped for brevity }
method!(apply_math<State, &[u8], AllTags>, mut self, call_m!(self.applyMath, call!(alt_fn)));
目前这给了我error: unexpected end of macro invocation
alt_fn
加下划线。
2)我需要使用从输入中获得的数据更新state结构的其他字段(例如计算校验和和更新时间戳等),然后使用这些新知识再次转换输出。这可能如下所示:
fn updateState(mut self, i:AllTags) -> AllTags { // snipped for brevity }
method!(update_state<State, &[u8], AllTags>, mut self, call_m!(self.updateState, call_m!(self.applyMath)));
3)我需要重复调用第二部分中的方法,直到所有输入都用完为止:
method!(pub parse<State,&[u8],Vec<AllTags>>, mut self, many1!(update_state));
不幸的是,nom
文档非常有限,而且我的宏语法不是很好,所以我不知道我做错了什么。
答案 0 :(得分:1)
当我需要做一些复杂的nom
时,我通常会编写自己的函数。
例如
named!(my_func<T>, <my_macros>);
相当于
fn my_func(i: &[u8]) -> nom::IResult<T, &[u8]> {
<my_macros>
}
附带条件是您必须将i
传递给宏(请参阅我的评论)。
创建自己的函数意味着你可以在那里拥有你想要的任何控制流,只要它需要&amp; [u8]并返回nom :: IResult,它就会与nom
很好地匹配&amp; [u8]是剩余未解析的原始输入。
如果您需要更多信息评论,我会尽力改善我的答案!