使用 FParsec 跳过空格和注释
Skip whitespace and comments with FParsec
我尝试在解析编程语言时跳过任何空格或注释。
我想跳过两种类型的评论:
- 行评论:
;; skip rest of line
- 屏蔽评论:
(; skip anything between ;)
使用注释和空格解析的示例代码:
(type (; block comment ;) (func))
(import "env" "g" (global $g (mut i32)))
(func (type 0) ;; line comment
i32.const 100
global.set $g)
(export "f" (func 0))
我尝试了多种方法,但解析器总是在某处中断。我的想法是这样的:
let comment : Parser<unit, Ctx> =
let lineComment = skipString ";;" >>. skipRestOfLine true
let blockComment = between (skipString "(;") (skipString ";)") (skipMany anyChar)
spaces >>. lineComment <|> blockComment
let wsOrComment = attempt comment <|> spaces
我希望像空格一样完全忽略评论。任何想法如何做到这一点? (这是我使用 FParsec 的第一个项目)
根据 Koenig Lear 的建议,我通过解析器在 运行 文本之前用正则表达式过滤了所有评论。这可能不是最好的选择,但它仅用两行代码就可以可靠地完成工作。
let removeComments s =
let regex = Regex(@"\(;.*;\)|;;.*")
regex.Replace(s, String.Empty)
let input = """
(type (; block comment ;) (func))
(import "env" "g" (global $g (mut i32)))
(func (type 0) ;; line comment
i32.const 100
global.set $g)
(export "f" (func 0))
"""
let filtered = removeComments input
// parse "filtered" with FParsec
我尝试在解析编程语言时跳过任何空格或注释。
我想跳过两种类型的评论:
- 行评论:
;; skip rest of line
- 屏蔽评论:
(; skip anything between ;)
使用注释和空格解析的示例代码:
(type (; block comment ;) (func))
(import "env" "g" (global $g (mut i32)))
(func (type 0) ;; line comment
i32.const 100
global.set $g)
(export "f" (func 0))
我尝试了多种方法,但解析器总是在某处中断。我的想法是这样的:
let comment : Parser<unit, Ctx> =
let lineComment = skipString ";;" >>. skipRestOfLine true
let blockComment = between (skipString "(;") (skipString ";)") (skipMany anyChar)
spaces >>. lineComment <|> blockComment
let wsOrComment = attempt comment <|> spaces
我希望像空格一样完全忽略评论。任何想法如何做到这一点? (这是我使用 FParsec 的第一个项目)
根据 Koenig Lear 的建议,我通过解析器在 运行 文本之前用正则表达式过滤了所有评论。这可能不是最好的选择,但它仅用两行代码就可以可靠地完成工作。
let removeComments s =
let regex = Regex(@"\(;.*;\)|;;.*")
regex.Replace(s, String.Empty)
let input = """
(type (; block comment ;) (func))
(import "env" "g" (global $g (mut i32)))
(func (type 0) ;; line comment
i32.const 100
global.set $g)
(export "f" (func 0))
"""
let filtered = removeComments input
// parse "filtered" with FParsec