如何从Scheme程序中提取列表?

如何从Scheme程序中提取列表?,scheme,racket,Scheme,Racket,我一直在计划中提供一种语言 (define-datatype statement statement? (add1 (V symbol?)) (sub1 (V symbol?)) (skip (V symbol?)) (if-goto (V symbol?) (l symbol?))) (define-datatype instruction instruction? (labeled (l symbol?) (i stateme

我一直在计划中提供一种语言

(define-datatype statement statement?
  (add1 (V symbol?))
  (sub1 (V symbol?))
  (skip (V symbol?))
  (if-goto (V symbol?)
           (l symbol?)))

(define-datatype instruction instruction?
  (labeled (l symbol?)
           (i statement?))
  (unlabeled (i statement?)))

(define-datatype program program?
  (a-program (l (list-of instruction?))))
我正在尝试创建一个新函数,它将能够将程序转换为指令列表。我该怎么做呢

以下是我到目前为止的情况:

(define pgm->list
   (lambda (pgm)
     ;what goes here

抱歉,如果这是错误的,如果是,您可以共享代码的工作实现吗? 我真的很困惑

(define-datatype program program?
  (a-program (l (list-of instruction?))))
什么是工作清单?我可以想象,在这里,您想要声明程序的一些变体。 a-程序将被定义为指令列表。。。好啊如果list of返回的lambda是正确的谓词(仅当对指令列表执行操作时才返回true),则 这行吗

(define pgm->list
  (lambda (pgm)
    (cases program pgm
      (a-program (l) l))))
编辑:由于除OP外,大多数人都不知道定义数据类型,因此我添加了一些文档:

[语法](定义数据类型TYPENAME[谓词]变量…

定义名为TYPENAME的记录类型,其中变量。。。定义一个或多个 此类型实例的构造函数。变体应为以下形式:

变量=(构造函数(FIELDNAME FIELDPRED)…)

CONSTRUCTOR是将用as定义的构造函数过程的名称 指定了许多参数作为字段。(FIELDNAME FIELDPRED)。。。指定名称 对于每个字段和一个参数的过程,该参数应为 法律字段值

可选谓词应该是将要定义和执行的过程的名称 当应用于此变量记录的实例时,返回#t

[语法](cases TYPENAME EXP子句…

用于匹配和解构变量记录的实例EXP的工具 用TYPENAME这个名字。每个子句指定一个具有字段名和 构造函数与记录实例匹配时要执行的主体:

子句=(构造函数(字段名…)正文…) |(其他机构…)


干杯

定义数据类型
不是方案的一部分。您可以描述它还是删除
方案
标签?在
docs.racket-lang.org
上搜索,似乎
定义数据类型
lang/htdp advanced
eopl
模块的一部分。OP应该提到他们使用的是哪本书。如果我们假设
pgm
是一个
程序
,并且
程序
包含一个指令列表,那么问题仅仅是如何访问程序数据结构的字段?或者你对如何编写编译器感兴趣吗?还有一个叫做数据类型(datatype):一种创建和使用变体记录的工具,如弗里德曼、旺德和海恩斯的《编程语言要领》一书中所述。@ramrunner是的,这是我正在写的书。很抱歉没有提及,我不知道这是专门为我做的。谢谢!现在,如果我想将结果列表发送给另一个函数,我将如何进行呢?当我试图将最后一行修改为:(other func(a-program(l)l‘‘‘)’))时,我得到一个错误,说第一个l现在是一个未绑定的标识符,可能我不理解这里的问题。如果其他func需要从“程序”生成的(指令)列表,那么这不是(其他func(pgm->list program))?这看起来很琐碎,所以请您给我们一个运行它并解决它的工作示例好吗?:)谢谢你,杜德!。嗯,我看到了关于“最后一行”的事情。如果您想更改pgm->list代码的最后一行,那就行不通了。您可以看到“cases”lambda根据下面提供的类型解压程序结构。如果它是一个闭包,则必须使用整个闭包。也许您可以创建另一个lambda,它使用整个“pgm->list”来获取列表,然后将其发送到其他函数,如前面的注释所示?另一个快速问题。假设我试图从指令中去掉符号,我该怎么做呢?我试图遵循您之前给我的相同格式,我有:(定义指令->sym(lambda(ins)(cases指令ins(labeled(sym)sym)))这当然不起作用,因为labeled有两个参数。我似乎不能让编译器接受任何有两个参数的东西。我应该如何编写我的语法呢?杜德,我不知道这个模块,如果你不发布一些我可以运行的具体示例,我的理解已经到了极限:)。所以这里只是一个猜测:有两个参数。所以,如果你写你的案例,比如(案例指令ins(标记为(sym stat)sym),会发生什么?这里我猜你说标记等待2个域被定义。