- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想我会尝试使用 FParsec 编写一个快速解析器并很快意识到 many
返回一个列表是一个严重的性能问题。然后我在文档中发现了一个使用 ResizeArray
的替代方法:
let manyA2 p1 p =
Inline.Many(firstElementParser = p1,
elementParser = p,
stateFromFirstElement = (fun x0 ->
let ra = ResizeArray<_>()
ra.Add(x0)
ra),
foldState = (fun ra x -> ra.Add(x); ra),
resultFromState = (fun ra -> ra.ToArray()),
resultForEmptySequence = (fun () -> [||]))
let manyA p = manyA2 p p
在我的代码中使用它会使它的运行速度提高数倍。那么为什么 FParsec 默认使用列表而不是 ResizeArray
?
最佳答案
使用内置的 F# 列表类型作为序列组合器的结果类型使组合器在 F# 中使用起来更方便,并且可以说会导致更惯用的客户端代码。由于大多数 F# 开发人员都重视简单性和优雅而不是性能(至少根据我的经验),因此在我设计 API 时使用列表作为默认值似乎是正确的选择。同时,我试图让用户可以轻松定义自己的专用序列组合器。
目前,返回列表的序列组合器也在内部使用列表来构建序列。这对于包含超过 2 个元素的序列来说是次优的,因为在返回列表之前必须反转列表。但是,我不确定更改实现是否值得付出努力,因为如果您的解析器对性能敏感并且您正在解析长序列,那么您最好根本不使用列表。
我可能应该在用户指南的性能章节中添加一个关于使用数组而不是列表的部分。
关于fparsec - 为什么 FParsec 使用列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29400763/
我想我会尝试使用 FParsec 编写一个快速解析器并很快意识到 many 返回一个列表是一个严重的性能问题。然后我在文档中发现了一个使用 ResizeArray 的替代方法: let manyA2
我正在使用 Bill Casarin关于如何使用 fparsec 解析分隔文件的帖子,我正在简化逻辑以了解代码的工作原理。我正在将多行分隔文档解析为 Cell 列表结构(目前),其中 Cell 是字符
我想使用 FParsec 解析字符串文字。 “字符串文字”是指介于开头和结尾引号之间的内容(在我的例子中是单引号): 'Please, switch off your mobile phone' 我目
对于带有关键字的语言,需要发生一些特殊的技巧以防止例如“if”被解释为标识符和“ifSomeVariableName”在 token 流中成为关键字“if”后跟标识符“SomeVariableName
在简单的查询语言中,我想识别日期和时间文字,最好不使用分隔符。例如, CreationDate = 2013-05-13 5:30 PM 我可以使用组合器来检测基本语法(例如, yyyy-MM-dd
我的 AST 模型需要携带位置信息(文件名、行、索引)。是否有任何内置方式来访问这些信息?从引用文档中,流似乎带有位置,但我更喜欢我不必为了保存位置而实现虚拟解析器,并在任何地方添加它。 提前致谢 最
我有这个测试程序: open FParsec let test p str = match run p str with | Success(result, _, _) -> pr
为了在后面的步骤中创建更好的错误消息,我想保存解析器成功的位置以及文本。获取位置似乎很容易(因为有 getPosition 解析器),但我不知道如何访问文本。 假设我有这种类型来保存位置 type S
以下顶级 XML 解析器定义返回错误 The value or constructor ‘TOP_LEVEL_RECORD’ is not defined. … let xTop_Level, xTo
我正在尝试使用 FParsec 实现一个对空格敏感的解析器,并且我从定义一个函数的第一步开始,该函数将解析以 n 开头的文本行。空格字符。 这是我到目前为止所拥有的: let test: Parser
我计划将 FParsec 用于我的一个更大项目的原型(prototype)。所以我决定通过下面列出的测试程序来获得我对这个库的第一次体验。但似乎通过使用 fparsec 'choice' 函数组合我的
例如,从给定解析器中提取行号和列号以便将它们添加到 AST 中的最佳方法是什么? 谢谢! 最佳答案 您可以使用 getPosition,这是一个不消耗任何输入并返回当前位置的解析器。例如: type
我决定查看 FParsec,并尝试为 λ 表达式编写解析器。事实证明,渴望使递归解析变得困难。我该如何解决这个问题? 代码: open FParsec type λExpr = | Varia
假设我有一些文字: a = "foobarbaz" b = "foobar" c = "foo" d = "rubbish" e = "foobazbar" 以及分别用于字符串 'foo'、'bar'
我遇到一个问题,在流的解析过程中,我通过多次(按顺序)应用特定的解析器来指出需要解析下 N 个字符的位置。 (剥离玩具)示例: 17 0 then let! v
我正在寻找一些用 FParsec 编写的示例语法,这些语法超出了项目存储库中的示例。 我发现这非常好grammar of GLSL ,但这是我找到的唯一样本。我需要的是类似于 C 或 JavaScri
假设我有一些文字: a = "foobarbaz" b = "foobar" c = "foo" d = "rubbish" e = "foobazbar" 以及分别用于字符串 'foo'、'bar'
我遇到一个问题,在流的解析过程中,我通过多次(按顺序)应用特定的解析器来指出需要解析下 N 个字符的位置。 (剥离玩具)示例: 17 0 then let! v
我有一个用户输入文本,如“abc,def,ghi”。我想解析它以获取字符串列表 ["abc", "def"]. 我试过了 let str : Parser = many1Chars (noneOf "
我遇到了具有两个递归分支的解析器的问题。为了更容易地演示问题,我使用了来自 the article written by Luca Bolognese 的 lambda 演算的简单语法。例如: ::
我是一名优秀的程序员,十分优秀!