2017-10-29 70 views
1

我在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

回答

0

當我需要做一些複雜的事情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