我正在用OCaml实现一种符号语言,并且一直在努力将我的s表达式树转换成抽象语法树。
S-表达式树是
(* sexpr.mli *)
type atom =
| Atom_unit
| Atom_int of int
| Atom_sym of string
type expr =
| Expr_atom of atom
| Expr_list of expr list抽象语法树是
(* ast.ml *)
open Sexpr
type sym = string
(* abstract syntax tree nodes *)
type expr =
| Expr_unit
| Expr_int of int
| Expr_sym of sym
(* Sexp.atom -> Ast.expr *)
let ast_of_atom a =
match a with
| Atom_unit -> Expr_unit
| Atom_int n -> Expr_int n
| Atom_sym s -> Expr_sym s
(* Sexp.expr -> Ast.expr *)
let rec ast_of_sexpr sx = match sx with
| Expr_atom a -> ast_of_atom a
| Expr_list l ->
match l with
| [] -> ast_of_atom Atom_unit
| [x] -> ast_of_sexpr x
| h::t -> ignore ( ast_of_sexpr h ); ast_of_sexpr ( Expr_list t )函数ast_of_sexpr需要符合类型签名。
val ast_of_sexpr : Sexpr.expr -> expr。
这是我的挑战;我想不出一种符合类型签名的方法,即将s表达式树(即嵌套列表)转换为抽象语法树节点。
在一个理想的世界里,我可以在一个表达式中计算列表头和对尾部进行递归。我试着用测序来模仿这个理想。但是,这当然会忽略左边的值,只会在打印解析的令牌流时输出最后一个值。
有人能建议一种在不忽略值的情况下计算列表头的方法,并将其递归到s-表达式树中吗?我甚至愿意阅读更好的解决方案,在这两棵树之间进行翻译。
发布于 2014-03-30 17:26:29
Ast.expr类型定义看上去是错误的:它并不表示抽象语法树,而仅仅表示原子表达式的语法。这是因为这个类型根本不是递归的,所以它很难被称为树。相比之下,Sexp.expr是一种递归类型。
我的猜测是,您忘记了类型定义中的一个案例,例如:
type expr =
| Expr_unit
| Expr_int of int
| Expr_sym of sym
| Expr_call of expr list一旦完成,这两种类型实际上是相同的,因此转换变得很简单。
发布于 2014-03-30 16:55:48
通常,以下是如何“在不忽略它们的情况下”计算某些值:
let v = <calculate> in
let w = <calculate> in
<expression using v and w>我不确定这就是你要问的问题,但这对于从OCaml开始的人来说是一个概念上的困难。
https://stackoverflow.com/questions/22746361
复制相似问题