haskell - 作为 Haskell 中的解释器将一个完整的字符串转换为整数和单词

标签 haskell

我正在尝试用 Haskell 编写一个 Forth 解释器。有许多子问题和类别可以实现这一目标,但是,我正在尝试完成最基本的步骤,并且我已经以不同的方法尝试了一段时间。我尝试访问的简单输入案例是 "25 12 +"-> [37]。我并不担心 Forth 中的列表与 Haskell 相反,但我确实想尝试适应输入字符串的可扩展性,所以我使用 Maybe,就好像有一个错误,我什么都不做。

我首先尝试使用 Prelude 的 words 函数将输入字符串分解为“单词”列表。从那里我使用 Prelude 的 reads 函数将其转换为元组列表 (Int,String)。所以这很有效,直到我到达命令“word”,例如示例问题中的 char +

那么如何将字符串的命令解析/解释为我可以使用的内容?
我是否创建一个包含所有 Forth 命令或特殊字符的新数据结构? (假设如此,如何将其从字符串格式转换为该数据类型?)

还有什么需要的尽管问。我很感谢您帮助我思考这个问题。

最佳答案

read 本质上是一个非常简单的字符串解析器。您可能需要考虑学习使用解析器组合器库,例如Parsec,而不是对其进行调整。 .

有很多关于解析器组合器的不同教程,因此您可能需要在它们“点击”之前进行一些阅读。然而,this tutorial中的第一个例子与您的问题密切相关。

import Text.Parsec
import Text.Parsec.String

play :: String -> Either ParseError Integer
play s = parse pmain "parameter" s

pmain :: Parser Integer
pmain = do
  x <- pnum `chainl1` pplus
  eof
  return x

pnum = read `fmap` many1 digit

pplus = char '+' >> return (+)

这是一个简单的解析器,可以计算任意长的列表:

*Main> play "1+2+3+4+5"
Right 15

它还会产生有用的解析错误:

*Main> play "1+2+3+4+5~"
Left "parameter" (line 1, column 10):
    unexpected '~'
    expecting digit, "+" or end of input

如果您可以理解这个简单的解析器,您应该能够弄清楚如何使其适应您的特定问题(请参阅 the documentation for Text.Parsec.Combinator 中的通用组合器列表)。一开始会比使用read花费更长的时间,但是使用合适的解析库会让解析Forth整个语法的最终目标变得更容易。

关于haskell - 作为 Haskell 中的解释器将一个完整的字符串转换为整数和单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26110235/

相关文章:

haskell - 列表的唯一元素和相应的索引

haskell - 为什么我无法安装 template-haskell-2.17.0.0?

haskell - 如何在 Haskell 中编写编译器?在 C# 中,我使用了很多状态

haskell - 是否可以以无点形式编写模式匹配函数?

haskell - 如何解决 cabal 存储库中不再存在的旧软件包?

haskell - 具有下游状态且无损失的惯用双向管道

多参数函数的 Haskell 类型声明

haskell - 在 Haskell 中并发读写 IOArray

list - 查找最大整数的索引

performance - 分析 Haskell 程序的缓慢性能