【问题标题】:Haskell parse expressionHaskell 解析表达式
【发布时间】:2017-10-02 22:49:24
【问题描述】:

您好,我收到了这样的代码:

data Digit = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | 
             Nine 
             deriving (Eq, Show)

data Number = Single Digit | Many Digit Number deriving (Eq, Show)

data Expr = Lit Number
          | Sub Expr   
          | Sum Expr Expr 
          | Mul Expr Expr
          deriving (Eq, Show)

所以这段代码的想法是有一个字符串,比如* + 2 3 * 2 + 6 - 2,它将表示为((2 + 3) * (2 * (6 - 2))),然后使用它来将部分字符串放入其中。当然最后找到结果,在这种情况下是 40。问题是我对解析不太了解,所以我真的不知道如何解析这样的表达式。我见过一些简单的解析,其中字符串被解析为类型,比如人或其他东西。但我认为这有点复杂。如果有人有任何建议,我会很感兴趣。

【问题讨论】:

  • 你确定你的输入不应该是* + 2 3 * 2 - 6 2吗?这看起来像前缀波兰表示法。
  • stackoverflow.com/q/46516500/625403比较——我认为某处一定有一些课程将其作为练习。在这种情况下,- 应该是一元负数,而不是二元减法。
  • @Alec Sum Expr Expr 对我来说是正确的。有问题的构造函数是Sub,而不是Sum
  • 另外,如果你写的是 (6 + (-2)) 而不是 (6 - 2),那么你的例子会更清楚,这就是输入的实际代表。

标签: parsing haskell expression


【解决方案1】:

虽然 Haskell 存在复杂的解析库,并且非常适合这项任务,但您的输入格式非常简单,手动解析不会太麻烦,递归函数会消耗输入并返回解析后的表达式和字符串的剩余部分继续解析。

这是它的外观骨架:

parse :: String -> (String, Expr)
parse (' ':more) = parse more
parse ('-':more) = let (remainder, e) = parse more
                   in (remainder, Sub e)
parse ('+':more) = undefined -- TODO
parse ('*':more) = undefined -- TODO
parse s@(num:more) | isDigit num = parseNumber s
parse s = error ("unexpected input: " ++ s)

parseNumber :: String -> (String, Expr)
parseNumber s = undefined

【讨论】:

  • 对一元解析概念的一个很好的介绍是Functional Pearls Paper
  • 谢谢老兄,很有帮助!如果您有兴趣,我已将我几乎完成的代码放在页面顶部。也许你也不能对我如何改进代码提出一些建议:P
  • @iIllumination:请不要那样做;仅保留问题的问题帖子;如果您有解决方案(甚至是部分解决方案),请为此使用答案帖子。我已回滚您的编辑。
  • 哦,好吧,对不起,我的错。
猜你喜欢
  • 2010-12-06
  • 1970-01-01
  • 1970-01-01
  • 2022-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-29
  • 2010-10-05
相关资源
最近更新 更多