Nom指南中文版

原文https://tfpk.github.io/nominomicon/introduction.html,使用Google进行机翻 nominomicon 欢迎阅读这本关于Nom的书;使用 Nom 解析器发挥巨大作用的指南。本指南将向您介绍使用 Nom 的理论和实践。 本指南仅假设您: 想学习Nom, 已经熟悉 Rust。 Nom 是一个解析器组合器库。换句话说,它为您提供了定义以下内容的工具: “解析器”(接受输入并返回输出的函数),以及 “组合器”(采用解析器并将它们组合在一起的函数!)。 通过将解析器与组合器相结合,您可以从简单的解析器构建复杂的解析器。这些复杂的解析器足以理解 HTML、mkv 或 Python! 在我们出发之前,列出一些注意事项很重要: 本指南适用于 Nom7。 Nom 发生了重大变化,因此如果您正在搜索文档或 StackOverflow 答案,您可能会找到较旧的文档。一些常见的表明它是旧版本的指标是: 2021 年 8 月 21 日之前的文档 named! 宏的使用 使用 CompleteStr 或 CompleteByteArray 。 Nom 可以解析(几乎)任何东西;但本指南几乎完全专注于将完整的 &str 解析为事物。 第一章:Nom 方式 首先,我们需要了解 nom 思考解析的方式。正如简介中所讨论的,nom 让我们构建简单的解析器,然后组合它们(使用“组合器”)。 让我们讨论一下“解析器”实际上是做什么的。解析器接受输入并返回结果,其中: Ok 表示解析器成功找到了它要查找的内容;或者 Err 表示解析器找不到它要查找的内容。 如果解析器成功,它将返回一个元组。元组的第一个字段将包含解析器未处理的所有内容。第二个将包含解析器处理的所有内容。这个想法是解析器可以愉快地解析输入的第一部分,而无法解析整个内容。 如果解析器失败,则可能会返回多个错误。然而,为了简单起见,在接下来的章节中,我们将不对这些进行探讨。 ┌─► Ok( │ what the parser didn't touch, │ what matched the regex │ ) ┌─────────┐ │ my input───►│my parser├──►either──┤ └─────────┘ └─► Err(....

April 29, 2024 · 7 min · czyt

在你的Rust程序中使用Deref和DerefMut trait

Deref Deref 是一种 Rust 编译器宏,用于实现 Deref trait。Deref trait 允许将自定义类型转换为引用,从而使其能够用于任何需要引用的地方。 Deref 宏通常用于以下场景: 新类型模式: 当您定义一个新类型时,deref 宏可以使其能够像引用一样使用。例如,您可以创建一个 Box 类型,该类型将值存储在堆上,并实现 Deref trait 以便可以使用 * 运算符访问值。 链式访问: deref 宏可以用于创建链式访问语法。例如,您可以创建一个 Vec<Box<T>> 类型,其中 T 是任何可实现 Deref trait 的类型。这允许您使用 * 运算符在向量中迭代并访问每个值。 泛型代码: deref 宏可以用于编写泛型代码,该代码可以与任何可实现 Deref trait 的类型一起使用。例如,您可以创建一个函数,该函数接受任何可实现 Deref trait 的类型并返回其值。 deref宏在 Rust 中扮演着重要的角色,它允许你自定义类型在特定情况下表现得像引用一样。这带来了许多便利,例如: 简化访问底层数据: 无需手动解引用,直接访问结构体内部数据。 使用运算符重载: 使自定义类型支持 * 和 [] 等运算符。 自动解引用: 在需要引用的地方,自动解引用自定义类型。 实用例子 1. 自定义智能指针 use std::ops::Deref; struct MyBox<T>(T); impl<T> Deref for MyBox<T> { type Target = T; fn deref(&self) -> &Self::Target { &self....

April 25, 2024 · 3 min · czyt

一些Rust的机器学习资料

代码示例 ONNX web interface to YOLOv8 object detection neural network implemented on Rust. 仓库地址 Client/server face detection from your webcam with tokio, axum, tract-onnx and the lightweight ultraface network. 仓库地址 Segment anything inference using Rust llm https://github.com/jondot/awesome-rust-llm 其他 https://github.com/rustai-solutions 文章 图书

April 24, 2024 · 1 min · czyt

一些rust clap库的笔记

小试牛刀 clap是rust下面的一款命令行解析的库,下面是一些使用的笔记。 在Cargo.toml中添加下面的依赖 [dependencies] clap = {version = "4",features = ["derive"]} 对应feature的作用如下: 默认特性 std: Not Currently Used. Placeholder for supporting no_std environments in a backwards compatible manner. color: Turns on colored error messages. help: Auto-generate help output usage: Auto-generate usage error-context: Include contextual information for errors (which arg failed, etc) suggestions: Turns on the Did you mean '--myoption'? feature for when users make typos. 可选特性 deprecated: Guided experience to prepare for next breaking release (at different stages of development, this may become default) derive: Enables the custom derive (i....

April 19, 2024 · 5 min · czyt

使用 Pest 和 PEG 构建 Rust 解析器【译】

本文原为为 https://blog.logrocket.com/building-rust-parser-pest-peg/,使用Google翻译进行机翻,部分内容做了细微润色。 编写一个高效的词法分析器对来解析复杂的结构可能具有挑战性。如果格式或结构是固定的,并且您必须以易于理解、维护和扩展以适应未来更改的方式编写解析器,那么这会变得更加复杂。 在这些情况下,我们可以使用解析器生成器,而不是手写解析器或手动解析我们的项目。在本文中,我们将回顾什么是解析器生成器,并探索一个名为 Pest 的 Rust 解析工具。我们将涵盖: [TOC] 请注意,您应该能够轻松地阅读和编写基本的 Rust 代码,例如函数、结构和循环。 什么是解析器生成器? 解析器生成器是一些程序,它接受解析器需要考虑的规则,然后以编程方式为您生成一个解析器,该解析器将根据这些规则解析输入。 大多数时候,规则以简化语言(例如正则表达式)提供给解析器生成器。因此,当您想要通过更改规则或添加新规则来更新解析器时,您只需更新或添加规则的正则表达式即可。然后,当您运行解析器生成器时,它将重写解析器以适应这些规则。 可以想象使用这样的解析工具可以节省多少时间。许多解析器生成器还会生成词法分析器,因此您不必自己编写词法分析器。如果生成的词法分析器不适合您,您可以选择使用您自己的词法分析器运行解析器(如果需要)。 目前,Rust 生态系统中有多个解析器生成器可供您使用。其中最受欢迎的三个是 LalrPop、Nom 和 Pest。 LalrPop 与 Yacc 非常相似,它让您定义规则和相应的操作。我个人用它来为我的 8086 模拟器项目编写规则。 Nom 是一个解析器组合器库,您可以在其中将规则编写为函数组合。这更面向解析二进制输入,但也可用于解析字符串。 最后,Pest 使用 Parsing Expression Grammar 来定义解析规则。我们将在这篇文章中详细探讨 Rust 与 Pest 的解析。 Pest 中的解析表达式语法是什么? 解析表达式语法(PEG)是用 Pest 定义 Rust 解析“规则”的方法之一。 Pest 接受具有此类规则定义的文件的输入,并生成遵循它们的 Rust 解析器。 在编写规则时,您应该考虑 Pest 和 PEG 的三个定义特征。 第一个特点是贪婪匹配。 Pest 将始终尝试将输入的最大值与规则相匹配。例如,假设我们编写了如下规则: match one or more alphabets 在这种情况下,Pest 将消耗输入中的所有内容,直到达到数字、空格或符号。在此之前它不会停止。 要考虑的第二个特征是交替匹配是有序的。为了理解这意味着什么,假设我们给出了多个匹配来满足一条规则,如下所示: rule1 | rule2 | rule3 Pest 将首先尝试匹配 rule1 。当且仅当 rule1 失败时,Pest才会尝试匹配 rule2 ,依此类推。如果第一条规则匹配,Pest 将不会尝试匹配任何其他规则来找到最佳匹配。...

April 19, 2024 · 10 min · czyt

使用rust操作mongodb

准备工作 使用rust进行mongodb连接需要添加依赖,在Cargo.toml中添加下面的依赖 [dependencies] mongodb="2" serde = "1" 添加serde的原因是我们建模的时候需要用。 预备知识 连接数据库 下面是我们的本地数据库连接 const CONNECT_STR:&str = "mongodb://czyt:[email protected]:27017"; 然后使用连接字符串进行数据库连接 let mut client_options = ClientOptions::parse_async(CONNECT_STR).await?; // Set the server_api field of the client_options object to Stable API version 1 let server_api = ServerApi::builder() .version(ServerApiVersion::V1) .build(); client_options.server_api = Some(server_api); // Create a new client and connect to the server let client = Client::with_options(client_options)?; // Send a ping to confirm a successful connection client.database("admin").run_command(doc! { "ping": 1 }, None)....

April 15, 2024 · 9 min · czyt

enum_dispatch在rust中的简单使用

请先看下面这个例子: enum Creatures { Dog(Dog), Cat(Cat), } trait Animal { fn make_sound(&self); } struct Dog; struct Cat; impl Animal for Dog { fn make_sound(&self) { println!("Bark!"); } } impl Animal for Cat { fn make_sound(&self) { println!("Meow!"); } } fn main() { let animals: Vec<Creatures> = vec![ Creatures::Dog(Dog), Creatures::Cat(Cat), ]; for animal in animals { match animal { Creatures::Dog(dog) => dog.make_sound(), Creatures::Cat(cat) => cat.make_sound(), } } } 在 main 函数中,我们创建了一个名为 animals 的 Vec<Creatures> 向量,其中包含不同种类的生物。遍历 animals 向量时,使用 match 语句来确定每个生物的实际类型,然后调用相应实例的 make_sound 方法。...

April 8, 2024 · 2 min · czyt

一个RustFace demo程序

下面是一个基于RustFace这个库的demo程序。基于原项目 整理。image随便下载一张,model.bin从原项目进行下载即可。 Cargo.toml配置 [package] name = "faceDemo" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] rustface = "0" image= "0.23.14" src/main.rs use rustface::{Detector, FaceInfo, ImageData}; fn main() { let imageFile = "1.png"; let modelFile = "model.bin"; let mut detector = rustface::create_detector(modelFile).unwrap(); detector.set_min_face_size(20); detector.set_score_thresh(2.0); detector.set_pyramid_scale_factor(0.8); detector.set_slide_window_step(4, 4); let img = image::open(imageFile).unwrap(); let gray = img.to_luma8(); let (width, height) = gray.dimensions(); let mut image = ImageData::new(&*gray, width, height); for face in detector....

February 27, 2024 · 1 min · czyt

Rust完整备忘单【译】

原文 https://katib.moe/the-completesh-rust-cheat-sheet 本文大部分通过机器翻译进行翻译,小部分进行了微调。官方有个更全的 https://cheats.rs 这个“完整的 Rust 备忘单”提供了 Rust 编程语言的全面指南,涵盖了它的所有主要功能。涵盖的主题范围从非常基础的知识(例如语法和基本概念)到更复杂的方面(例如并发和错误处理)。该备忘单还深入研究了 Rust 的独特功能,例如所有权、借用和生命周期,以及其强大的类型系统和健壮的宏系统。对于每个主题,都提供了清晰的示例来阐明解释。对于刚刚开始使用 Rust 的初学者和想要快速回顾特定 Rust 概念的经验丰富的开发人员来说,这是一个理想的资源。 我编写了这份备忘单作为 Rust 编程语言的综合指南,旨在将其作为个人参考工具。然而,Rust 社区的美妙之处在于共享学习和协作。因此,如果您发现我遗漏的内容、错误,或者您有改进建议,请随时分享您的反馈。请记住,没有人是绝对正确的,本资源也不例外 - 通过您的见解,我们可以继续改进和完善它。快乐 Rustacean! 基本语法和概念 你好世界 这是标准的“你好,世界!” Rust 中的程序。 fn main() { println!("Hello, world!"); } 变量和可变性 Rust 中的变量默认是不可变的。要使变量可变,请使用 mut 关键字。 let x = 5; // immutable variable let mut y = 5; // mutable variable y = 6; // this is okay 数据类型 Rust 是一种静态类型语言,这意味着它必须在编译时知道所有变量的类型。 let x: i32 = 5; // integer type let y: f64 = 3....

February 23, 2024 · 12 min · czyt

Rust的一些难点解惑【译】

原文 https://katib.moe/the-hard-things-about-rust, 本文使用机器翻译而成,部分文字进行了调整。 Rust 是一种系统编程语言,运行速度极快,可防止段错误并保证线程安全。虽然这些功能使 Rust 成为系统编程的强大工具,但它们也引入了一些对于来自其他语言的人可能不熟悉的新概念。 在这份综合指南“Rust 的困难之处”中,我们的目标是阐明 Rust 的这些具有挑战性的方面,并使新手和经验丰富的程序员都可以使用它们。我们将阐明这些复杂的概念,并用具体示例和现实场景来说明每个概念,以便更好地理解。 以下是我们将要介绍的内容: 所有权:我们将从 Rust 中所有权的基本概念开始。我们将探讨一个值拥有所有者意味着什么,所有权如何转移,以及 Rust 的所有权模型如何帮助内存管理。 借用和生命周期:在所有权的基础上,我们将深入研究借用和生命周期,这两个相互关联的概念可让您安全地引用数据。 切片:我们将揭开切片的神秘面纱,切片是内存块的视图,它在 Rust 中广泛用于高效访问数据。 错误处理:Rust 处理错误的方法是独特且稳健的。我们将介绍 Result 和 Option 类型,以及如何使用它们进行优雅的错误处理。 并发:我们将深入研究 Rust 强大而复杂的并发模型。我们将讨论线程、消息传递和共享状态并发等。 高级类型和Trait:我们将探索 Rust 的一些高级类型,例如 Box 、 Rc 、 Arc 。我们还将介绍 Trait 和 Trait 对象。 Async/Await 和 Futures:当我们转向高级概念时,我们将解释 Rust 的 async/await 语法和用于处理异步编程的 Futures 模型。 本指南的目标不仅仅是提供这些主题的概述,而是帮助您了解这些概念背后的基本原理、它们在幕后如何工作以及如何在 Rust 程序中有效地使用它们。 无论您是希望深入了解该语言的 Rust 初学者,还是旨在巩固对这些复杂概念的理解的中级 Rustacean,本指南都适合您。让我们踏上这段征服 Rust 难点的旅程吧! 所有权 所有权是 Rust 的一个基本概念。它是 Rust 内存安全方法的一部分,使 Rust 在编程语言中独一无二。理解所有权对于编写 Rust 程序至关重要,因为许多其他 Rust 概念(例如借用和生命周期)都是建立在它之上的。...

February 21, 2024 · 9 min · czyt