Parsing 使用(读取a,显示a)解析二进制树
我在如何开始这个问题上有点困难。我应该解析一个二叉树的字符串表示,并检查叶的内容是否有有效的字母,如果有,则创建树,否则返回“”用于解析失败,而不进行派生(Show,Read) 使用一个典型的解析器库,我可以使用Parsing 使用(读取a,显示a)解析二进制树,parsing,haskell,Parsing,Haskell,我在如何开始这个问题上有点困难。我应该解析一个二叉树的字符串表示,并检查叶的内容是否有有效的字母,如果有,则创建树,否则返回“”用于解析失败,而不进行派生(Show,Read) 使用一个典型的解析器库,我可以使用 parseTree = do{item; symb "Leaf"; x <- string; return Leaf (read x)} +++ {item; symb "Branch"; item;x <- parseTree; item; item; y <- p
parseTree = do{item; symb "Leaf"; x <- string; return Leaf (read x)} +++ {item; symb "Branch"; item;x <- parseTree; item; item; y <- parseTree; item; return (Branch x y)}
parseTree=do{item;symb“Leaf”;x正如Willem所说,您可以派生Read
免费获取此函数:
数据字母=A | B | C | D | E | F | G
派生(显示、相等、枚举、有界、读取)
数据二叉树a=叶a |分支(二叉树a)(二叉树a)
推导(等式、显示、读取)
二叉树字母
t=枝(叶A)(枝(枝(叶A)(叶C))(叶D))
试一试:
λ>t==读取(显示t)
真的
创建树else return“”,用于解析所有未进行派生(显示、读取)
的失败
parseTree=do{item;符号“Leaf”;…+++…}
我不确定从字符串中读取二叉树的上下文中“”是什么意思:根据您对二叉树的定义,树不能为空,因为即使Leaf
也至少包含一个字母。因此,您可能正在寻找一个函数string->maybe(二叉树字母)
由于您不愿意使用派生的Show
和Read
实例,因此这必须是编写解析器的练习。您可以用以下方式构造递归下降解析器:
parseLetter::String->Maybe(字母,字符串)
解析字母s=。。。
parseTree::String->Maybe(二进制树字母,字符串)
解析树
|“叶”`isPrefixOf`s=。。。
|“Branch”`isPrefixOf`s=。。。
|否则=没有
这里,(…,String)
是正在被解析的字符串的剩余部分,子解析器没有使用它。例如,在解析分支(叶a)(叶B)
时,当解析的字母
解析了a
,它可能会为其调用者返回(a),(叶B)
但是,请注意,要获得与派生Read
质量相当的内容,需要在空格和括号方面非常灵活:
λ> read "Branch ( Leaf A)( Branch ( Leaf B ) ((Leaf C) ) ) " :: BinaryTree Letter
Branch (Leaf A) (Branch (Leaf B) (Leaf C))
我不确定如何处理穿过树叶或树枝的情况
穿过一片叶子意味着解析一个字母
遍历分支意味着递归调用解析器
您可能希望使用更高效、更符合人体工程学的解析库,如(它甚至包含一个读取树类型的示例),或者您可能希望使用解析器组合器框架,如或。您可以使用派生(Show,Read)
在您的数据二叉树中
,它将自己生成一个解析器。函数代码有一些不完全正确的地方,例如,它应该是返回(分支xy)
。
λ> read "Branch ( Leaf A)( Branch ( Leaf B ) ((Leaf C) ) ) " :: BinaryTree Letter
Branch (Leaf A) (Branch (Leaf B) (Leaf C))