F# 简单的FParsec列表示例

F# 简单的FParsec列表示例,f#,fparsec,F#,Fparsec,我刚刚开始使用FParsec,无法理解一个简单的列表解析器。 给定输入 ”{ a、 b;c D }“ 我想得到结果['a';'b';'c';'d'] 如果我这样做 let baseChars = ['0'..'9'] @ ['A'..'Z'] @ ['a'..'z'] @ ['_'; '-'] let chars : Parser<_> = anyOf baseChars let nameChars : Parser<_> = anyOf (baseChars @ ['.

我刚刚开始使用FParsec,无法理解一个简单的列表解析器。 给定输入

”{
a、 b;c
D
}“

我想得到结果
['a';'b';'c';'d']

如果我这样做

let baseChars = ['0'..'9'] @ ['A'..'Z'] @ ['a'..'z'] @ ['_'; '-']
let chars : Parser<_> = anyOf baseChars
let nameChars : Parser<_> = anyOf (baseChars @ ['.'])                

let semiColonList p : Parser<_> = sepBy p (pstring ";")
let pList p : Parser<_> = between (pstring "{") (pstring "}") (semiColonList p)

do  """{
    a;b;c;
    d;
}"""
    |> run (parse {
        let! data = pList (spaces >>. many1Chars nameChars)
        return data
    })
    |> printfn "%A"
让baseChars=['0'..'9']@['A'..'Z']@['A'..'Z']@[''u';'-']
让chars:Parser=baseChars中的任意一个
让nameChars:Parser=anyOf(baseChars@['.]]
让分号列表p:Parser=sepBy p(pstring“”)
设pList p:Parser=between(pstring“{”)(pstring“}”)(分号列表p)
做{
a、 b ; c ;;
D
}"""
|>运行(解析){
let!data=pList(空格>>。许多字符名称字符)
返回数据
})
|>printfn“%A”
我在最后一个}上遇到了一个失败,因为它试图在关闭between解析器之前在nameChars解析器上匹配它。 这感觉像是有一个简单的解决方案,我错过了,特别是因为如果我删除了d之后的最后一个分号,所有的工作都如预期的那样。 谢谢你的帮助

[编辑] 感谢Fyodor Soikin完成以下工作:

    let semiColonList p = many (p .>> (pstring ";" >>. spaces))
    let pList p : Parser<_> = between (pstring "{") (pstring "}") (semiColonList p)
    """{
    a;b;c;
    d;
}"""
    |> run (parse {
        let! data = pList (spaces >>. many1Chars nameChars)
        return data
    })
    |> printfn "%A" 
让分号列表p=many(p.>>(pstring“>>.spaces))
设pList p:Parser=between(pstring“{”)(pstring“}”)(分号列表p)
"""{
a、 b ; c ;;
D
}"""
|>运行(解析){
let!data=pList(空格>>。许多字符名称字符)
返回数据
})
|>printfn“%A”

sebby
不允许尾随分隔符。类似于
sebby A b
的解析器用于解析类似于
A b A b A
的输入,但您的输入类似于
A b A b b b
——末尾有一个额外的分隔符
b

相反,您要做的是解析多个类似于
ab
的表达式,这将为您提供所需的输入形状

要解析一个这样的表达式,请使用排序运算符
>
,要解析多个这样的对,请使用
many

semiColonList p = many (p .>> pstring ";")

sebby
不允许使用尾随分隔符。请尝试使用
many
。@FyodorSoikin不确定您的意思。我不能做
many not semicolon
,因为第一次匹配后会回溯,然后期望结束。}我的意思是制作一个同时解析值和分号的解析器,然后运行该解析器的
many
semiColonList p=many(p.>>pstring“)
Fyodor Soikin认为
sebby
不允许使用尾部分隔符是正确的。但是也有
sepEndBy
,它允许一个可选的尾随分隔符。这可能更符合你的需要。有关详细信息,请参阅。