【问题标题】:how can i show a derivation tree in haskell?如何在haskell中显示派生树?
【发布时间】:2016-02-17 22:31:27
【问题描述】:

我正在做一个构建 while 语言派生树的练习。我对 while 语言的实现由代数数据类型组成,例如“Aexp”(算术表达式)“Bexp”(布尔表达式)和“Stm”(语句):

type  Var   =  String
data  Aexp  =  N Integer
        |  V Var
        |  Add Aexp Aexp
        |  Mult Aexp Aexp
        |  Sub Aexp Aexp
        deriving (Show, Eq)

data  Bexp  =  TRUE
        |  FALSE
        |  Eq Aexp Aexp
        |  Le Aexp Aexp
        |  Neg Bexp
        |  And Bexp Bexp
        deriving (Show, Eq)

data  Stm   =  Ass Var Aexp
        |  Skip
        |  Comp Stm Stm
        |  If Bexp Stm Stm
        |  While Bexp Stm
        |  Repeat Stm Bexp
        deriving Show

在这些代数数据类型之后,我创建了更多的代数数据类型来表示while语言程序的派生树

type  State  =  Var -> Z

data Config = Inter Stm State  -- <S, s>
        | Final State      -- s

data Transition = Config :-->:  State

data DerivTree = AssNS     Transition
           | SkipNS    Transition
           | CompNS    Transition DerivTree DerivTree
           | IfTTNS    Transition DerivTree
           | IfFFNS    Transition DerivTree
           | WhileTTNS Transition DerivTree DerivTree
           | WhileFFNS Transition
           | RepeatTTNS Transition 
           | RepeatFFNS Transition DerivTree DerivTree

我怎样才能显示这种派生树??

<z:=x, s> -> s'    <x:=,s1> -> s''
----------------------------------
    <z:=x; x:=y,s> -> s''             <y:=z,s''> -> s'''
    ------------------------------------------------------
            <z:=x; x:=y; y:=z, s> -> s'''

每个构造函数的期望值如下所示:

【问题讨论】:

  • 只是递归地做。您想如何渲染树、文本、乳胶或其他内容?
  • ConfigState 是什么?
  • 您尝试了哪些方法,遇到了哪些问题? AexprBexprStm 真的与您显示 DerivTrees 的问题有关吗?
  • 如果您要使用乳胶,应该很容易,因为乳胶也只是一个语法树。只需将每个节点转换为适当的乳胶命令。为子节点递归调用该函数。不,您不必从最深的节点开始打印,这只是简单的结构递归。
  • @EduGR:无论如何,如果您不能告诉我们输出应该是什么样子,那么这不是一个适合 SO 的问题。请向我们展示您想要生成的乳胶标记或多行字符串,我们可以帮助您实现 haskell。

标签: haskell tree functional-programming semantics algebraic-data-types


【解决方案1】:

这是一个使用boxes 包生成类似派生树的东西的简单示例。您应该能够轻松地根据您的需要调整它——通过生成Tree String,或者使用pp 中的想法直接从您的派生树生成Box。 (我在这里选择使用Tree String 而不是您的类型,主要是为了避免必须弄清楚具有大量构造函数的数据类型的所有漂亮打印细节。)

import Data.Tree
import Text.PrettyPrint.Boxes

pp :: Tree String -> Box
pp (Node here []      ) = text here
pp (Node here children) = vcat center1 [premises, separator, conclusion]
    where
    premises   = hsep 4 bottom (map pp children)
    conclusion = text here
    width      = max (cols premises) (cols conclusion)
    separator  = text (replicate width '-')

sampleTree :: Tree String
sampleTree = Node "<z:=x; x:=y; y:=z, s> -> s'''"
    [Node "<z:=x; x:=y,s> -> s''"
        [Node "<z:=x, s> -> s'" []
        ,Node "<x:=,s1> -> s''" []
        ]
    ,Node "<y:=z, s''> -> s'''" []
    ]

这是在 ghci 中运行的示例:

*Main> printBox (pp sampleTree)
<z:=x, s> -> s'    <x:=,s1> -> s''                       
----------------------------------                       
      <z:=x; x:=y,s> -> s''           <y:=z, s''> -> s'''
---------------------------------------------------------
              <z:=x; x:=y; y:=z, s> -> s'''              

【讨论】:

  • 谢谢!!太好了!
猜你喜欢
  • 1970-01-01
  • 2013-09-03
  • 2013-07-19
  • 1970-01-01
  • 2018-08-30
  • 2012-09-16
  • 2012-01-14
  • 1970-01-01
相关资源
最近更新 更多