parsec:有没有一种简单的方法可以让 comments/whitespace 在语法中随处可见?
parsec: is there an easy way to allow comments/whitespace everywhere in the grammar?
你如何处理空格和注释?通常在句法分析阶段删除的片段?我想在我正在解析的文档中的任何地方启用注释。在我定义的每个基本解析器中添加这些是唯一的选择吗?
你应该使用 parsec 的能力来定义一个“令牌解析器”。这个想法是你在 LanguageDef
中定义你的语言的特征,然后在结果 TokenParser
中使用派生的解析器,例如identifier
、integer
等。您可以从 TokenParser
中获取 lexeme
函数,将您可能拥有的任何解析器变成一个吞没所有尾随空格的解析器。
有关详细信息,请参阅 makeTokenParser。
一个例子是我写的this code。它是真实世界的代码,因此可能不如一个好的教程那样具有教育意义,但您可以看到我如何定义 lang = makeTokenParser...
,然后在下面的解析器中使用 whiteSpace lang
、parens lang
等解析器。 parseTime
是我在“普通”解析器周围使用 lexeme
的示例。
在 Text.Parsec.Token
中完成的方法是让每个标记都消耗白色space 和后面的评论。
这是通过 lexeme
组合器的帮助完成的:
lexeme p = do { x <- p; whitespace; return x }
运行解析器 p
,消耗它后面的白色 space 和 returns p
返回的任何内容。
当您查看 makeTokenParser
(link) 的源代码时,您会发现许多标记解析器都使用 lexeme
组合器包装,例如:
symbol name
= lexeme (string name)
使用这种方法,lexeme
(link) 的注释指出您的解析器唯一需要显式使用白色 space 的时间是在输入的开头以跳过第一个标记前的任何白色 space。
你如何处理空格和注释?通常在句法分析阶段删除的片段?我想在我正在解析的文档中的任何地方启用注释。在我定义的每个基本解析器中添加这些是唯一的选择吗?
你应该使用 parsec 的能力来定义一个“令牌解析器”。这个想法是你在 LanguageDef
中定义你的语言的特征,然后在结果 TokenParser
中使用派生的解析器,例如identifier
、integer
等。您可以从 TokenParser
中获取 lexeme
函数,将您可能拥有的任何解析器变成一个吞没所有尾随空格的解析器。
有关详细信息,请参阅 makeTokenParser。
一个例子是我写的this code。它是真实世界的代码,因此可能不如一个好的教程那样具有教育意义,但您可以看到我如何定义 lang = makeTokenParser...
,然后在下面的解析器中使用 whiteSpace lang
、parens lang
等解析器。 parseTime
是我在“普通”解析器周围使用 lexeme
的示例。
在 Text.Parsec.Token
中完成的方法是让每个标记都消耗白色space 和后面的评论。
这是通过 lexeme
组合器的帮助完成的:
lexeme p = do { x <- p; whitespace; return x }
运行解析器 p
,消耗它后面的白色 space 和 returns p
返回的任何内容。
当您查看 makeTokenParser
(link) 的源代码时,您会发现许多标记解析器都使用 lexeme
组合器包装,例如:
symbol name
= lexeme (string name)
使用这种方法,lexeme
(link) 的注释指出您的解析器唯一需要显式使用白色 space 的时间是在输入的开头以跳过第一个标记前的任何白色 space。