【发布时间】:2019-12-23 17:58:11
【问题描述】:
我对可以管理多种类型的解析器有问题,例如算术表达式的解析器。目前我的解析器只输入整数:
aexpr :: Parser Int
aexpr = aterm `chainl` addOp
aterm :: Parser Int
aterm = afactor `chainl` mulOp
afactor :: Parser Int
afactor = parenP '(' aexpr ')'
<|>
do
s <- sign
a <- aexpr
return (s * a)
<|>
token int_const
这适用于两个整数,但我引入了浮点类型,因此算术表达式的解析器可以在输入中输入两个Int、两个Float 或Int 和Float 的两种混合类型。根据输入,解析器的结果类型应为Int 或Float(即,如果两个输入均为Int,则为Int,否则为Float)。
我的问题是:管理此问题的最佳方法是什么?一种简单的方法是将所有输入管理为Float,因此整数值将转换为浮点值。但我不喜欢这种解决方案:最终结果将始终是Float。
我是否应该创建两个不同的解析器,即一个用于Int,一个用于Float?但是这两个解析器几乎是一样的。
有更好的解决方案吗?
【问题讨论】:
-
你可以使用
Either Int Float作为返回类型,所以Parser (Either Int Float)。 -
如果您要返回一个整数或浮点值,您已经编写了一个求值器(它会解析以求值)。解析器将返回解析树或类似的东西。 (我知道这听起来像是一个狡辩,但这种区别很有用。)