问题标签 [nom]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
286 浏览

rust - 在 nom 5.1.2 中使用位解析器时未能找到正确的类型参数

我在 nom 5 中找不到正确的语法来进行位解析。

我正在尝试这个:

并从编译器中获取:

我尝试过各种可怕的事情,比如:

...尝试遵循我在 nom 源中看到的内容,但这会产生不同的错误:

我究竟做错了什么?

0 投票
0 回答
107 浏览

sqlite - 用 nom 解析 SQLite B-Tree-Page

我正在尝试使用 nom 解析 SQLite BTree 页面(https://www.sqlite.org/fileformat2.html#btree)。

Nom 可以很好地解析两个标题(数据库文件标题和 btree 标题)以及单元格指针数组。我现在被困在如何解析单个单元格上。

据我了解, nom 只是线性遍历输入,但我更需要的是随机访问:从单元格指针数组中获取一个值,跳转到页面中的那个位置,然后解析它。

这是一种有效的方法吗?我是否应该将剩余的输入包装在光标中的标题之后并随机访问单元格指针位置?

我的另一个想法是按升序对单元格指针数组进行排序,并且只占用尽可能多的字节,直到下一个单元格开始。这里的问题是每个单元格的有效负载长度 varint 都包含溢出。我在如何识别该页面上单元有效负载的确切长度方面遇到问题,因为一个空闲块可以跟随一个单元。为此,我需要首先解析所有空闲块页面的链接列表,以便检索所有空闲块的位置和长度,然后才能开始解析单元块。但后来我又回到了随机访问。

0 投票
1 回答
157 浏览

rust - HashMap 持有 Vec 缓冲区和切片到缓冲区

我正在尝试将HashMap文本文件的解析操作的结果存储到一个文本文件中(使用nom解析)。结果由一个Vec缓冲区和该缓冲区上的一些切片组成。目标是将它们一起存储在一个元组或结构中,作为哈希映射中的一个值(带有String键)。但我无法解决终身问题。

语境

解析本身采用&[u8]并返回一些包含同一输入上的切片的数据结构,例如

现在,因为解析在没有存储的切片上运行,所以我需要首先将输入文本存储在 aVec中,以便输出切片保持有效,例如:

然后我会理想地将它存储Entry到一个HashMap. 这是出现了麻烦。我尝试了两种不同的方法:

尝试 A:存储然后解析

首先使用输入创建HashMap条目,直接解析引用HashMap条目,然后更新它。

这不起作用,因为借用检查器抱怨&entry.input_data[..]借用的生命周期与 相同,因此由于存在活动借用entry,因此无法移入。map

尝试 B:先解析然后存储

首先解析,然后尝试将Vec缓冲区和数据切片一起存储到HashMap.

这不起作用,因为借用检查器抱怨cmds具有相同的生命周期,&buffer[..]buffer将在函数结束时被删除。它忽略了cmdsandbuffer具有相同生命周期的事实,并且都(我希望)移入entry,它本身已移入map,因此这里应该没有生命周期问题。

最小(非)工作示例

编辑:尝试使用 2 张地图

正如凯文指出的那样,这就是我第一次(以上尝试)让我失望的原因,借用检查器不明白移动 aVec不会使切片无效,因为Vec没有触及 的堆缓冲区。很公平。

旁注:我忽略了凯文的回答中与使用索引相关的部分(Rust 文档明确指出 slices 是 index 的更好替代品,所以我觉得这对语言不利)和使用外部板条箱(这也是明确的反对语言)。我正在努力学习和理解如何做到这一点“Rust 方式”,而不是不惜一切代价。

所以我对此的直接反应是改变数据结构:首先将存储Vec插入到 firstHashMap中,一旦它在那里调用parse()函数来创建直接指向HashMap值的切片。然后将它们存储到 secondHashMap中,这自然会使两者分离。但是,一旦我将所有这些都放在一个循环中,这也不起作用,这是这段代码的更广泛目标:

这里的问题是,一旦输入缓冲区在第一个 mapinput_map中,引用它会将每个新解析结果的生命周期绑定到 that 的条目,HashMap因此是&'a mut引用('a添加的生命周期)。如果没有这个,编译器会抱怨数据从不相关的生命周期流入input_mapcmds_map这很公平。但是这样一来,对的&'a mut引用input_map在第一次循环迭代中被锁定并且永远不会被释放,并且借用检查器在第二次迭代中阻塞,这是理所当然的。

所以我又被困住了。我在 Rust 中尝试做的事情是完全不合理和不可能的吗?我如何解决问题(算法、数据结构)以使事情终生有效?我真的看不出这里有什么“Rust 方式”来存储缓冲区集合和这些缓冲区上的切片。是唯一的解决方案(我想避免)首先加载所有文件,然后解析它们吗?这在我的情况下是非常不切实际的,因为大多数文件都包含对其他文件的引用,我想加载最小的依赖链(可能 < 10 个文件),而不是整个集合(类似于 3000 多个文件),我可以仅通过解析每个文件来访问依赖项。

问题的核心似乎是,将输入缓冲区存储到任何类型的数据结构中都需要在插入操作期间对所述数据结构进行可变引用,这与对每个单个缓冲区的长期不可变引用不兼容(对于切片),因为这些引用需要具有与定义相同的生命周期HashMap。是否有任何其他数据结构(可能是不可变的)可以解决这个问题?还是我完全走错了路?

0 投票
1 回答
186 浏览

rust - 解析 nom 中一定大小的一个数

我可以解析这样的数字:

但是只有在一定范围内,我才能解析一个数字?

0 投票
0 回答
50 浏览

rust - 不知道如何使用 nom 的 dbg_dmp

我有一个解析器设置,我已尽dbg_dmp我所能注入:

这给了我:

不知道为什么或如何解决这个问题。

0 投票
1 回答
314 浏览

rust - 将 Box 与 nom 解析器一起使用时出现神秘错误“一种类型比另一种更通用”

在尝试解决今天的代码出现难题时,我正在尝试使用 nom 来构建一些取决于输入字符串的动态解析器​​。但是在这样做的过程中,我遇到了一个对我来说非常特殊的问题,我对 Rust 缺乏熟悉(我正在使用 Advent of Code 来尝试学习 Rust,从未使用过它,或者任何其他“低级“以前的语言)使我无法解决。

以下是一个超级简化的示例,如果它编译,显然不会做任何有用的事情 - 但它说明了编译器错误(遗憾的是我不能把它放在 Rust Playground 上,因为它没有可用的 nom,但它可以很容易地独立运行):

Box 是必需的,否则编译器会抱怨在编译时不知道类型的大小。

这失败了,出现了 2 个非常相似的错误Box::new(尽管请注意,在我的真实代码中只发生了其中的第二个),两者都抱怨实际上相同的不匹配类型:

注意:我在谷歌上搜索并遇到了许多关于类似错误的问题 - 其中似乎是最有希望的,但该答案或我发现的其他讨论中没有任何线索让我知道我的情况可能发生了什么。我已经尝试了很多更改,但到目前为止没有任何效果,而且我觉得我只是在挣扎,不了解导致此错误的原因。

任何见解将不胜感激,它可以解决上述问题而不会彻底改变它。

0 投票
0 回答
189 浏览

rust - 如何将成功组合器与 nom 中的映射组合器结合使用?

我正在编写一个 nom 解析器组合器,它消耗字节并返回一个Option<&[u8]>. 解析器组合器应遵循以下规则:

  1. 读取单个有符号大端 16 位整数 ( s)
  2. 如果s是-1,返回None
  3. 如果s不是 -1,则读取s位并返回Some

这是我的解析器组合器:

但是我看到以下错误:

我可以看到nom::combinator::success确实有一个返回类型impl Fn(I) -> ...,并且nom::combinator::map返回impl FnMut(I) -> ...。有没有一种更惯用的方式来使用 nom ,这些组合器可以以这种方式一起使用?

0 投票
1 回答
165 浏览

rust - 标称 & 借来的价值不存在足够长的错误

尝试使用nom并迭代我的结果,但我无法弄清楚为什么这个借来的值不能活得足够长。对 Rust 来说还是新手,并且已经折腾了好几个小时。非常感谢帮助!

和错误:

0 投票
2 回答
144 浏览

rust - Rust 函数语法问题,示例出现在 nom

我正在查看nomrust 的 crate,其中包含许多解析字节/字符的函数。

许多函数,例如tag()下面看到的,处理输入不是作为函数的参数提供的,而是出现在第二组括号中,跟在我称之为参数的后面。在示例中,如果在haystack中寻找针头,则该函数使用它自己的参数,这是指定needle的方式,但haystack是单独指定的,在参数括号之后,在它自己的括号内 (也许是因为它是一个单值元组?)。tag()

在上面的示例中,tag()的工作是测试输入是否以s开头Hello。您可以调用parser,并传入“Hello 大家!”,该tag()函数确实验证了开头sHello。但是如何(s)找到它的方式tag()

有人可以向我解释这种语法,或者显示在哪里阅读它。它有效,我可以使用它,但我不明白我在看什么!

谢谢

0 投票
1 回答
60 浏览

generics - 如何包装 nom tag_no_case 解析器?

我想tag_no_case用特定的字符串值包装解析器以便能够重用它们:

像这样使用

我试图复制tag_no_case打字和其他一些随机方法,但对我没有任何帮助。

类型声明应该如何才能使用所示的自定义解析器?