Text.Parsec.Token
中的所有解析器礼貌地使用lexeme
在令牌后吃空格。对我来说不幸的是,空格包括新行,我想将它用作表达式终止符。有没有办法说服lexeme
留下新的一行?
答案 0 :(得分:6)
不,不是。这是相关的代码。
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)
人们会注意到whitespace
的where子句中唯一的选项是处理注释。 lexeme
函数使用whitespace
,并在parsec.token
的其余部分中自由使用。
对我来说,最终的解决方案是使用合适的词法分析器(alex)。 Parsec作为一个解析库做得很好,设计可以归结为它可以被修改为词法分析,但是除了小而简单的项目之外,它很快就会变得难以处理。我现在使用alex来创建一组线性标记,然后Parsec将它们变成AST。
答案 1 :(得分:3)
如果换行符是你的表达式终结符,也许在每个换行符处拆分输入并自行解析每一行是有意义的。
答案 2 :(得分:2)
嗯,并非Text.Parsec.Token
中的所有解析器都使用lexeme
,尽管所有解析器都使用Text.Parsec.Token
他们应该。最糟糕的是,没有记录哪些消耗白色
空间,其中哪些不。 decimal
中的一些解析器
在lexeme之后消耗空白,其中一些没有。他们中有一些
消耗领先的空白。您应该阅读现有的问题
如果您想完全控制情况,请使用GitHub问题跟踪器。
特别是:
hexadecimal
,octal
和integer
解析器不会消耗尾随
白色空间,见
the source,
和this issue;
Text.Parsec.Token
也消耗领先的空白,请参阅
this issue;
其余的可能消耗尾随空格,因此换行, 然而,这很难确定,因为Parsec的代码是 特别毛茸茸(恕我直言),该项目没有测试套件(3除外) 但是,检查已经修复的错误的测试不再出现 它不足以阻止回归和源的每一个变化 break your code in next release of Parsec)。
如何使其可配置(应该是什么,有各种各样的命题 被认为是空白区域),由于某些原因,它们都没有被合并或评论。
但真正的问题在于makeTokenParser
的设计,它会锁定
用户转换为 else
{
Response.Redirect("AdministratorPage.aspx", true);
}
构建的解决方案。这种设计尤其如此
不灵活。在许多情况下,只有一个解决方案是复制
整个模块并根据需要进行编辑。
但是如果你想要现代和一致的Parsec,可以选择切换到 Megaparsec这里(和 许多其他问题)问题不存在。
披露:我是Megaparsec的作者之一。
答案 3 :(得分:1)
虽然关于它不可能的其他答案是正确的,但我想指出char解析器没有使用lexeme解析器。
我使用parsec来分析一些html胡子模板。在该分析中,空格很重要。我所做的只是解析“&gt;”和{}}“Text.Parsec.Char.string
的字符串
由于我对标签之间的空格感兴趣而不是在它们内部,我仍然可以使用保留的运算符来解析“&lt;”和“{{”等,因为lexeme解析器只消耗尾随空格。