Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 在Parsec中,有没有一种方法可以防止lexeme使用换行符?_Haskell_Parsec - Fatal编程技术网

Haskell 在Parsec中,有没有一种方法可以防止lexeme使用换行符?

Haskell 在Parsec中,有没有一种方法可以防止lexeme使用换行符?,haskell,parsec,Haskell,Parsec,Text.Parsec.Token中的所有解析器都礼貌地使用lexeme来吃令牌后面的空格。不幸的是,空格中包含新行,我想将其用作表达式终止符。有没有办法说服lexeme留下新行?如果新行是您的表达式终止符,那么在每个新行拆分输入并单独解析每行可能是有意义的。没有。这是相关代码 发件人: 词素p =do{x”“) |noMulti=skipMany(simpleSpace oneLineComment“”) |否则=skipMany(simpleSpace oneLineComment Mult

Text.Parsec.Token
中的所有解析器都礼貌地使用
lexeme
来吃令牌后面的空格。不幸的是,空格中包含新行,我想将其用作表达式终止符。有没有办法说服lexeme留下新行?

如果新行是您的表达式终止符,那么在每个新行拆分输入并单独解析每行可能是有意义的。

没有。这是相关代码

发件人:

词素p =do{x”“) |noMulti=skipMany(simpleSpace oneLineComment“”) |否则=skipMany(simpleSpace oneLineComment Multilecomment“”) 哪里 noLine=null(注释行语言定义) noMulti=null(commentStart语言定义) 在
whitespace
的where子句中,我们会注意到,所查看的唯一选项是处理注释的。
lexeme
函数使用
whitespace
,它在
parsec.token
的其余部分中大量使用


更新日期:2015年9月28日
对我来说,最终的解决办法是使用合适的词汇分析器().Parsec作为一个解析库做得很好,它可以用来进行词法分析,这是设计的功劳,但对于所有小型和简单的项目来说,它很快就会变得笨拙。我现在使用alex创建一组线性标记,然后Parsec将它们转换为AST。

尽管关于它的其他答案不是这样如果您的回答是正确的,我想指出,字符分析器没有使用词素分析器。
我使用parsec分析一些html小胡子模板。空格在分析中很重要。我所做的只是用
Text.parsec.Char.string


因为我对标记之间的空格感兴趣,而不是标记内部的空格,所以我仍然可以使用保留运算符来解析“嗯,
Text.Parsec.Token
中的并非所有解析器都使用
lexeme
,尽管 他们应该这样做。最糟糕的是,没有记录他们中的哪一个食用白色 空格,哪些没有空格。
Text.Parsec.Token
一定要在词素后加上空格,有些不加,有些不加 同时使用前导空格。您应该阅读上的现有问题 GitHub问题跟踪器,如果您想完全控制局势

特别是:

  • 十进制
    十六进制
    八进制
    解析器不使用尾随符 空白,请参见 , 及

  • integer
    也使用前导空格,请参见 )

  • 其余部分可能使用尾随空格,因此使用换行符, 然而,这很难确定,因为Parsec的代码是 特别多毛(IMHO),项目没有测试套件(3个测试套件除外) 但是,检查已经修复的bug不会再次出现的测试 仅仅防止倒退是不够的,每一个来源的改变都可能会导致衰退 )

有各种各样的建议如何使其可配置(应该是什么 被视为空白),但由于某种原因,它们都不会被合并或评论

但真正的问题在于
Text.Parsec.Token
的设计,它会锁定 由
makeTokenParser
构建的解决方案中的用户。此设计特别适用于 不灵活。在许多情况下,只有一种解决方案是复制 整个模块,并根据需要进行编辑

但是,如果您想要现代且一致的Parsec,可以选择切换到 这(以及 许多其他的)问题是不存在的



披露:我是Megaparsec的作者之一。

你看过uu parsinglib吗?它有词素和非词素版本的解析器,还有内置的错误更正。我以前通过复制和重命名Parsec.Token模块,然后更改
simpleSpace
的定义(靠近文件底部)来解决这个问题。这不是一个非常模块化的解决方案,但确实有效。与换行符相关的是潜在的终止符,但不一定如此。与Haskell本身的语义相同。@John--您是否试图处理类似于布局/越位规则的事情?有一整套专门的技术。@sclv不,只是作为表达式的新行。@类似Ruby或JavaScript+1中的minators,因为它是一些语言的可用解决方案,即使它在asker的情况下不起作用。我尝试用Parsec解析相当多的格式,包括识别新行。解决方案一直是逐行解析。这是不正确的,
simpleSpace
使用新行在宣传(甚至讨论)你自己的项目/包时,你应该公开你的联系。
lexeme p
    = do{ x <- p; whiteSpace; return x  }


--whiteSpace
whiteSpace
    | noLine && noMulti  = skipMany (simpleSpace <?> "")
    | noLine             = skipMany (simpleSpace <|> multiLineComment <?> "")
    | noMulti            = skipMany (simpleSpace <|> oneLineComment <?> "")
    | otherwise          = skipMany (simpleSpace <|> oneLineComment <|> multiLineComment <?> "")
    where
      noLine  = null (commentLine languageDef)
      noMulti = null (commentStart languageDef)