对于一个任务,我们必须实现像一个非常基本的SEXP解析器,这样对于输入,如:很简单SEXP解析器
"((a b) ((c d) e) f)"
这将返回:
[["a", "b"], [["c", "d"], "e"], "f"]
由于这是作为较大赋值的一部分,解析器仅被赋予有效输入(匹配parens & c)。我想出了Ruby中的以下解决方案:
def parse s, start, stop
tokens = s.scan(/#{Regexp.escape(start)}|#{Regexp.escape(stop)}|\w+/)
stack = [[]]
tokens.each do |tok|
case tok
when start
stack << []
when stop
stack[-2] << stack.pop
else
stack[-1] << tok
end
end
return stack[-1][-1]
end
这可能不是最好的解决方案,但它可以完成这项工作。
现在,我对核心功能的惯用Haskell解决方案感兴趣(即,我不在乎分隔符的选择或松散,如果可能的话只使用“核心” haskell,没有扩展名或像parsec这样的库。
请注意,这不是任务的一部分,我只是对Haskell做事感兴趣。
惯用的解决方案是使用解析器库(combinator或其他)。既然你明确排除了这个选项,一个惯用的解决方案是不可能的。编程是关于重用,而不是重新创建。 – jrockway 2010-06-29 04:41:37
当然,如果这是一个现实世界的问题,那么你是绝对正确的。但是考虑到所有教授haskell的书籍,为了学习的目的,Prelude功能正在被重新实现。你会不同意有一些解决方案比其他地方更习惯?是的,编程是关于重用,但学习有时可能会重塑。 – danlei 2010-06-29 10:18:07