- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试解析可能是项目列表或可能只是一个项目的内容。我想将结果放入 DU(下面的 Thing
)。
我处理这个问题的方式如下,但即使列表中只有一件事,它也会给我一个列表。
let test p str =
match run p str with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errorMsg, _, _) -> printfn "Failure: %s" errorMsg
type Thing =
| OneThing of int
| LotsOfThings of Thing list
let str s = pstringCI s .>> spaces
let one = str "one" |>> fun x -> OneThing 1
let two = str "two" |>> fun x -> OneThing 2
let three = str "three" |>> fun x -> OneThing 3
let oneThing = (one <|> two <|> three)
let lotsOfThings = sepBy1 oneThing (str "or") |>> LotsOfThings
let lotsFirst = (lotsOfThings <|> oneThing)
test lotsFirst "one or two" // Success: LotsOfThings [OneThing 1; OneThing 2]
test lotsFirst "one" // Success: LotsOfThings [OneThing 1]
OneThing
当列表中只有一项时?
let lotsOfThings = sepBy1 oneThing (str "or") |>> fun l -> if l.Length = 1 then l.[0] else l |> LotsOfThings
最佳答案
如果你不喜欢在解析后测试列表长度,那么你可以尝试切换你的 <|>
表达式先测试单项情况,然后使用 notFollowedBy
确保单项案例不会与列表匹配:
let oneThing = (one <|> two <|> three)
let separator = str "or"
let lotsOfThings = sepBy1 oneThing separator |>> LotsOfThings
let oneThingOnly = oneThing .>> (notFollowedBy separator)
let lotsSecond = (attempt oneThingOnly) <|> lotsOfThings
test lotsSecond "one or two" // Success: LotsOfThings [OneThing 1; OneThing 2]
test lotsSecond "one" // Success: OneThing 1
attempt
的使用解析器
oneThingOnly
.那是因为
documentation for the <|>
parser声明(强调原文):
The parser
p1 <|> p2
first applies the parserp1
. Ifp1
succeeds, the result ofp1
is returned. Ifp1
fails with a non‐fatal error and without changing the parser state, the parserp2
is applied.
attempt
在那里,“一两个”将首先尝试用
oneThingOnly
解析,这将消耗“一”,然后在“或”上失败,但解析器状态将已更改。
attempt
组合器基本上在尝试解析器之前制作解析器状态的“书签”,如果该解析器失败,它会返回到“书签”。所以
<|>
将在
attempt oneThingOnly
之后看到未更改的解析器状态,然后会尝试
lotsOfThings
.
关于f# - 使用 FParsec 解析分隔列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50455569/
我想我会尝试使用 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 演算的简单语法。例如: ::
我是一名优秀的程序员,十分优秀!