【问题标题】:Skip whitespace and comments with FParsec使用 FParsec 跳过空格和注释
【发布时间】:2020-06-16 11:21:55
【问题描述】:

我在解析编程语言时尝试跳过任何空格或注释。

我想跳过两种类型的评论:

  1. 行注释:;; skip rest of line
  2. 屏蔽评论:(; skip anything between ;)

用 cmets 和空格解析的示例代码:

(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

我希望像空格一样完全忽略 cmets。任何想法如何做到这一点? (这是我第一个使用 FParsec 的项目)

【问题讨论】:

  • 你真的要解析程序吗?或者只是删除cmets?如果您只是删除 cmets,那么使用正则表达式可能会更好。如果不是,你需要声明你的语言的整个语法,而不仅仅是开始的 cmets。
  • @KoenigLear 程序本身的解析已经可以正常工作了。只是我无法可靠地“跳过”两种不同的 cmets 类型来工作。
  • 也许您可以提供一个简化的解析示例并结合空格,以便我们进行测试?单独的注释解析器不起作用

标签: f# fparsec


【解决方案1】:

根据 Koenig Lear 的建议,在通过解析器运行文本之前,我使用正则表达式过滤了所有 cmets。这可能不是最好的选择,但它只需要两行代码就可以可靠地完成工作。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多