将状态添加到nom分析器

问题描述:

我在nom中编写了一个完全无状态的分析器,现在我需要将它包装在几个有状态的层中。将状态添加到nom分析器

我有一个名为alt_fn的*解析函数,它将为我提供解析输出的下一位,作为枚举变体,其细节可能不重要。

我有三件事情,我需要做的是涉及国家:

1)我需要的,如果存在一个不可变的HashMap比赛是一部分有条件地执行对alt_fn输出转换我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 invocationalt_fn下划线。我需要使用从输入中获得的数据(例如计算校验和和更新时间戳等)更新状态结构的其他字段,然后使用这些新知识再次转换输出。这可能看起来像下面这样:

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

我不知道我知道答案 - >我不确定问题是什么,但我可以解释一下宏在'nom'中的工作方式。在函数式语言中,您可以使用[部分应用程序](https://en.wikipedia.org/wiki/Partial_application),其中将某些参数传递给函数会创建一个新函数,请求其余参数。 Nom将combinators视为这些函数,其中最后一个参数是输入,因此在部分应用程序中传递其他参数会创建具体的解析器。所以'tag(“a”)'是一个期待'i'的函数,而'tag(i,“a”)'是应用解析器的实际命令。希望我帮助 – derekdreery

当我需要做一些复杂的事情nom,我通常写我自己的功能。

例如

named!(my_func<T>, <my_macros>); 

相当于

fn my_func(i: &[u8]) -> nom::IResult<T, &[u8]> { 
    <my_macros> 
} 

与您必须通过i于宏(见我的意见)的条件。

创建自己的功能意味着你可以有你有想要的任何控制流,只要它需要一个& [U8],返回NOM :: IResult其中输出& [U8]会起到很好的与nom是剩余未分类的原始输入。

如果您需要更多的信息评论,我会尽量改进我的答案!

+0

我会继续并移动您的评论进入你的答案 - 评论是短暂的,答案不那么重要。 – Shepmaster