如何在 FParsec 中添加解析数必须满足的条件?

2023-12-06

我正在尝试使用 FParsec 解析 int32,但有一个额外的限制,即该数字必须小于某个最大值。他们是否有一种无需编写我自己的自定义解析器(如下)即可执行此操作的方法和/或我的自定义解析器(如下)是实现要求的适当方法。

我问这个问题是因为大多数内置库函数似乎都围绕一个char满足某些谓词而不是任何其他类型。

let pRow: Parser<int> = 
   let error = messageError ("int parsed larger than maxRows")
   let mutable res = Reply(Error, error)
   fun stream ->
      let reply = pint32 stream
      if reply.Status = Ok && reply.Result <= 1000000 then
         res <- reply
      res

UPDATE

下面是根据下面评论中给出的方向尝试更合适的 FParsec 解决方案:

let pRow2: Parser<int> = 
   pint32 >>= (fun x -> if x <= 1048576 then (preturn x) else fail "int parsed larger than maxRows")

这是正确的方法吗?


您做了出色的研究,几乎回答了您自己的问题。

一般来说,有两种方法:

  1. 无条件地解析出一个int并让进一步的代码检查其有效性;
  2. Use a 警卫规则绑定到解析器。在这种情况下(>>=)是正确的工具;

为了做出好的选择,问问自己是否有一个整数failed要通过守卫规则必须通过触发“再给一次机会”另一个解析器?

这就是我的意思。通常,在现实项目中,解析器会组合在一些链中。如果一个解析器失败,则会尝试下一个解析器。例如,在这个问题,某些编程语言被解析,所以它需要类似:

let pContent =
    pLineComment <|> pOperator <|> pNumeral <|> pKeyword <|> pIdentifier

理论上,您的 DSL 可能需要将“小 int 值”与其他类型区分开来:

/// The resulting type, or DSL
type Output =
    | SmallValue of int
    | LargeValueAndString of int * string
    | Comment of string

let pSmallValue =
    pint32 >>= (fun x -> if x <= 1048576 then (preturn x) else fail "int parsed larger than maxRows")
    |>> SmallValue
let pLargeValueAndString =
    pint32 .>> ws .>>. (manyTill ws)
    |>> LargeValueAndString
let pComment =
    manyTill ws
    |>> Comment

let pCombined =
    [ pSmallValue; pLargeValueAndString; pComment]
    |> List.map attempt // each parser is optional
    |> choice // on each iteration, one of the parsers must succeed
    |> many // a loop

如此建造,pCombined将返回:

  • "42 ABC"被解析为[ SmallValue 42 ; Comment "ABC" ]
  • "1234567 ABC"被解析为[ LargeValueAndString(1234567, "ABC") ]

正如我们所看到的,保护规则会影响解析器的应用方式,因此保护规则必须位于解析过程中。

但是,如果您不需要这样的复杂功能(例如,int被解析无条件地),你的第一个片段就很好。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 FParsec 中添加解析数必须满足的条件? 的相关文章

  • 如何检查函数的类型参数是否静态解析?

    非常简单的例子 let myfun x x在智能感知中 它显示 x a gt a 在 FSI 中 它显示 x a gt a let inline myfun x x在智能感知中 它显示 x a gt a 在 FSI 中 它显示 x a gt
  • F# 中的部分匿名记录

    我如何输入一个函数 该函数接受具有字段的记录a and 任何其他领域 与此等效吗标准机器学习F 中可以使用函数吗 fun f a string Hello a 尝试了以下内容 但这些似乎在语法上无效 let f r a string imp
  • 作为参数的函数的类型推断

    我想编写一个函数 它接受几个元组作为参数 并用元素选择它们并传递给另一个函数 其中 i 作为另一个参数给出 我已经尝试过这样的事情 let function tup1 A A tup2 B B i otherFunction i tup1
  • 将 OCaml 转换为 F#:将 OCaml open_box 和 close_box 转换为 F#

    我正在将几个基于 OCaml 的模块转换为 F 并遇到了 OCaml 打印格式化函数open box 和 close box http caml inria fr pub docs manual ocaml libref Format ht
  • 从 F# 调用 C# 异步方法会导致死锁

    我有一组 F 脚本 它们调用我们创建的各种库 其中许多库公开了最初用 C 编写的异步方法 最近我发现脚本停止工作了 我想距离我上次使用它们已经有半年了 当时它们还可以工作 我试图隔离问题并提出了以下代码来重现它 首先 我们考虑一个包含以下
  • F# 图表示例

    我想使用内置功能或免费库在 F 中做一些基本的图表 我会对一个非常基本的例子感到非常非常满意 如果可能的话 饼图 示例数据 John 34 Sara 30 Will 20 Maria 16 其中整数是饼图中要表示的百分比 我最近安装了 VS
  • 从 F# 中存储为概率序列的离散分布函数中抽取随机数

    存在给定的有限长度 N 的浮点序列 介于 0 和 1 之间 表示整数 0 N 1 上的分布函数 我们试图从这个分布中抽取一个随机数 一种方法是在 0 1 浮点数 中绘制一个均匀随机变量 然后计算该数字的逆累积分布函数 如果分布在数组中 则代
  • 对 F# 联合类型列表进行操作

    这是我的问题的延续F 联合类型列表 https stackoverflow com questions 13770911 f list of union types 感谢有用的反馈 我能够创建一个列表Reports with Report要
  • 使用 F# 的爱因斯坦之谜解决方案 [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我在找爱因斯坦之谜 http en
  • 不可变数据结构性能

    我不明白作为一个集合的东西怎么可能是不可变的并且仍然具有可接受的性能 根据我在 F Sets 中读到的内容 内部使用红黑树作为其实现 如果每次我们想要向红黑树添加新内容时 我们基本上都必须重新创建它 那么它如何才能具有良好的性能呢 我在这里
  • 在 F# 中组合谓词

    F 中是否有逻辑组合谓词的标准方法 例如 假设我有isCar x and isBlue x然后我想要一些能给我的东西 let isBlueCar x isCar x isBlue x 但是使用某种组合而不是调用 可能像 let isBlue
  • 如何在 x 轴上显示每个元素的标签?

    我有包含文件名和编号的元组序列 我想绘制柱形图 其中 X 轴上有文件名 我的问题是现在 X 轴下仅显示 3 个标签 文件名 这可能是因为屏幕无法容纳更多内容 还是X轴间隔错误 如何让图表显示所有文件名 也许有办法将这些标签逆时针旋转 90
  • 双前向/后向管道操作符是否有记录?

    我记得读过有关双管道运算符的内容 gt 和 Example let print a b sprintf O O a b 1 2 gt print val it string 1 2 双 向前 向后 管道运算符记录在以下列表中MSDN 上的
  • F#、FParsec 和递归调用流解析器(第二次)

    感谢您的回复我的第一篇文章 https stackoverflow com questions 26853718 f fparsec and calling a stream parser recursively and 我的第二篇文章 h
  • 如何在 suave webpart 中设置 Json 响应

    我从 Suave 和 F 开始 我正在尝试在我的 web 部件中传递一个 json 序列化对象以在我的响应中获取它 在 php 中我有这个 player1Key hdegftzj25 gameKey aegfhzkfszl
  • FParsec:如何组合解析器以便它们以任意顺序匹配

    任务是找到特定的键值对并解析它们 这些对可以按任何顺序出现 我的部分工作尝试 open FParsec type Parser lt a gt Parser lt a unit gt type Status Running Done typ
  • 如何在 FsCheck 中注册任意实例并让 xUnit 使用它?

    我有一个类型Average有一个字段count这是积极的int64 and a double字段称为sum 我做了一个任意的生成有效实例的操作 let AverageGen Gen map2 fun s c gt Average float
  • 如何在插件场景中实现程序集绑定重定向?

    我有一个plugin P延伸和application A NET40 我无法控制 P 程序集 NET40 有一个shared dependency D NET35 P和D都依赖于FSharp Core 但版本不同 P是针对FSharp Co
  • 何时在 F# 中使用区分联合与记录类型

    在继续讨论复杂的示例之前 我试图先弄清楚 F 的基础知识 我正在学习的材料介绍了区分联合和记录类型 我已经审阅了两者的材料 但我仍然不清楚为什么我们要使用其中之一而不是另一个 我创建的大多数玩具示例似乎都可以在两者中实现 记录似乎非常接近我
  • 如何在 F# 中捕获任何异常(System.Exception)而不发出警告?

    我试图捕获异常 但编译器给出警告 此类型测试或向下转型将始终保持 let testFail try printfn Ready for failing failwith Fails with System ArgumentException

随机推荐

  • 使用 bash 我需要删除文件名中文件扩展名之前的尾随空格

    我有数百个文件 它们看起来类似于 QDN34 Unit5 mark up Judy pdf QDN34 Unit7 mark up Judy pdf file with two character ext ai file with dot
  • 如何扩展 float3 或任何其他内置类型以符合 Codable 协议?

    在尝试使用基本 JSONEncoder 序列化 float3 对象数组时 发现 float3 不符合 Codable 协议 因此无法完成此操作 我尝试按照中的建议编写基本扩展编码和解码自定义类型如下所示 但是错误 self used bef
  • JComboBox 作为自定义 TableCellEditor

    我有一张桌子 该表上的更改会更新数据库 该表中的一列由 JComboBox 编辑 单击该列中的任何单元格都会触发 tableChanged 事件 但是 在选择 JComboBox 的项目后需要触发它 如何让 tableChanged 在选择
  • UWP(通用Windows平台)上的套接字通信

    我想要实现的是基于UWP的程序和其他C 程序正在尝试与一台PC Windows 10 Pro 上的Socket进行通信 我尝试使用 DatagramSocket 类制作 UDP 通信模块 使用 StreamSocket 类制作 TCP 通信
  • 如何嵌入字体以在 Visual Basic 项目中使用?

    我正在尝试使用从该网站找到的以下代码嵌入字体 但是当我尝试构建时 我不断遇到错误 DIGITALDREAMNARROW is not a member of Resources 任何人都可以帮助我解决这个问题 即使我已将字体添加到资源文件夹
  • 具有有序编码的 LabelEncoder

    我正在使用标签编码器 data 1 A 1 A 1 B 2 C le LabelEncoder df pd DataFrame data data columns id element df element le fit transform
  • 如何从firestore数据库获取文档id

    我正在尝试通过调用检索文档 IDdoc getId 但我无法从这段代码中调用它 db collection Pegawai addSnapshotListener new EventListener
  • Excel Power Query - 用于等待 API 速率限制的睡眠或等待命令

    在Excel Power Query PQ 2016中 是否有这样的函数可以在继续之前插入 SLEEP 15秒 不是暂停 而是睡眠功能 问题 我在PQ中写了一个函数来查询 https westus api cognitive microso
  • 将 S3 数据加载到 AWS SageMaker Notebook 中

    我刚刚开始尝试使用 AWS SageMaker 并希望将 S3 存储桶中的数据加载到我的 SageMaker python jupyter 笔记本中的 pandas 数据框中进行分析 我可以使用 boto 从 S3 获取数据 但我想知道是否
  • 获取使用 HttpWebRequest/HttpWebResponse 发出的 HTTP 请求和响应以在 Fiddler 中显示

    有什么方法可以连接 Fiddler 来捕获使用 NET HttpWebRequest 和 HttpWebResponse 发出的请求和响应吗 Fiddler FAQ 给出了这个问题的答案 您本质上是通过 Fiddler 路由 HTTP 流量
  • 如何在调用 CheckBox.Focus() 时使 CheckBox 焦点边框出现?

    当用户按 Tab 键进入复选框以赋予其焦点时 复选框周围会出现虚线边框以指示它具有焦点 当复选框通过代码调用获得焦点时myCheckBox Focus 不会出现此类指示符 即使按空格键会切换状态 当我以编程方式聚焦复选框时 如何使复选框焦点
  • 无法调用类型“sqlite3_destructor_type”的初始值设定项

    到目前为止来自Martin R的回答效果很好 但从 Swift2 开始它现在会引发错误 无法使用类型为 COpaquePointer 的参数列表调用类型 sqlite3 destructor type 的初始值设定项 在这些行中 priva
  • C# DLL 无法影响从 VB6 应用程序通过引用传递的数字值

    我有一个调用 VB6 DLL 的旧 VB6 应用程序 并且我正在尝试将 VB6 DLL 移植到 C 但尚未接触主 VB6 应用程序代码 旧的 VB6 DLL 有一个接口 该接口通过引用接收 VB6 long 32 位整数 并更新该值 在我编
  • Access SQL语句创建表总是创建一个完整长度的字段

    我使用 oledbconnection 或立即在 access 中使用以下 SQL 创建一个表 安装版本 Office 365 MSO 32 位和 ACE 2016 32 位 CREATE TABLE Ticket ID COUNTER K
  • 在 ruby​​ 中从网络摄像头抓取快照

    如何在 ruby 中从网络摄像头拍摄快照 我知道网络摄像头设备位于 dev video0 但如何从中获取图片 我是开发者黄蜂眼 您可以使用HornetsEye的V4L2接口捕获图像 如下所示 require rubygems require
  • Laravel 4 邮件不传递数据

    电子邮件可以很好地处理虚拟数据 Mail send emails contact messageData function message use messageData message gt from email protected Jo
  • C++ 编译时程序范围唯一编号

    我已经提出了一个问题的解决方案 但我不确定它是否总是有效或仅在我的编译器上有效 首先 问题是 我注意到在很多情况下 希望有一个模板类 即使在给定相同类型的情况下 每次使用它时也会重新实例化 假设您的模板类具有初始化为函数调用的静态成员 有一
  • 检查每个字符是否有数字

    我试图循环遍历一个字符串并检查每个字符是否其中一个字符是数字 如果它是一个数字 我想将其返回为 true 我有一个字符串 crash 尽管它返回 true 它有一个数字 这是我到目前为止所拥有的 public boolean isNumbe
  • PhpMyAdmin 数据导入性能问题

    最初 我的问题与 PhpMyAdmin 的 SQL 部分无法正常工作有关 正如评论中所建议的 我意识到输入量是无法处理的 但是 这并没有为我提供如何处理具有 CSV 格式的文件 在我的情况下为 35 000 条记录行 的有效解决方案 201
  • 如何在 FParsec 中添加解析数必须满足的条件?

    我正在尝试使用 FParsec 解析 int32 但有一个额外的限制 即该数字必须小于某个最大值 他们是否有一种无需编写我自己的自定义解析器 如下 即可执行此操作的方法和 或我的自定义解析器 如下 是实现要求的适当方法 我问这个问题是因为大