提问人:Jerry 提问时间:6/1/2023 更新时间:6/2/2023 访问量:42
为什么我的 FParsec 解析器无法识别块注释?
Why is my FParsec parser failing to recognize a block comment?
问:
我正在尝试使用 FParsec 解析 C 样式注释。不知道为什么会失败:
我的解析器代码:
let openComment : Parser<_,unit> = pstring "/*"
let closeComment : Parser<_,unit> = pstring "*/"
let comment = pstring "//" >>. restOfLine true
<|> openComment >>. (charsTillString "*/" true System.Int32.MaxValue) |>> Comment
//<|> openComment >>. manyCharsTill anyChar closeComment |>> Comment
let spaceComments = many ((spaces1 |>> IgnoreU) <|> comment)
let str s = spaceComments >>. pstring s .>> spaceComments
测试线束:
let testStr = @"
// test comment
/* a block comment
*/
x // another comment
"
match run (str "x") testStr with
| Success(result, _, _) -> printfn "Success: %A" result
| Failure(errorMsg, _, _) -> assert false
()
错误消息器。charsTillString 和 manyCharsTill 都是一样的
Error in Ln: 6 Col: 4
^
Note: The error occurred at the end of the input stream.
Could not find the string '*/'.
Comment 和 IgnoreU 都是一种区分类型的字符串
答:
5赞
Brian Berns
6/2/2023
#1
问题在于解析器中的组合器没有所需的优先级/关联性。您可以通过使用 parens 分组来解决此问题:comment
let comment = (pstring "//" >>. restOfLine true)
<|> (openComment >>. (charsTillString "*/" true System.Int32.MaxValue)) |>> Comment
我发现这通常比复杂的解析器更容易阅读:choice
<|>
let comment =
choice [
pstring "//" >>. restOfLine true
openComment >>. (charsTillString "*/" true System.Int32.MaxValue)
] |>> Comment
评论