我正在尝试使用Haskell编写Lisp解释器,灵感来自Norvig在Python中的实现(http://norvig.com/lispy.html)。如果需要,我可以提供一个成功的标记生成器。它可以正确地输出代码,就像Norvig的Python标记生成器一样。
program = "(begin (define r 10) (* pi (* r r)))"
astTokenized = tokenize program
astTokenized == ["(","begin","(","define","r","10",")","(","*","pi","(","*","r","r",")",")",")"]
在这里,我定义了我的抽象语法树数据类型,尽管我知道它已经存在一些隐含的错误,因为它没有被包装在列表中。
data Ast x = Val x | Node [Ast x] deriving (Show)
这是我的第一次尝试:
parse :: [[Char]] -> [Ast [Char]]
parse (x:xs)
| x == "(" = [Node (parse xs)]
| x == ")" = []
| otherwise = (Val x) : parse xs
希望,除了它在第一个 ')' 后就终止。
Prelude> parse astTokenized
[Node [Val "begin",Node [Val "define",Val "r",Val "10"]]]
我修改了[]的基本情况,并调整了')'的条件,以便它解析整个输入终止,但现在只是创建了更深层的树,因此无法正确分支。
parse [] = []
parse (x:xs)
| x == "(" = [Node (parse xs)]
| x == ")" = parse xs
| otherwise = (Val x) : parse xs
Prelude> parse astTokenized
[Node [Val "begin",Node [Val "define",Val "r",Val "10",Node [Val "*",Val "pi",Node [Val "*",Val "r",Val "r"]]]]]
在某种程度上,它需要允许“并行”树,而不仅仅是嵌套的。任何帮助将不胜感激。