展开 AST
Unwrapping an AST
我正在设计一种保存文件格式,为了简单起见,它是 YAML 的一个子集,具有 3 种基本类型和 2 种数据结构。
我的 AST,用 Scala 写的:
sealed trait SaveElement
/**
* Trait for save data primitives
*/
sealed trait SaveKey extends SaveElement
case class Integer(i: Long) extends SaveKey
case class FloatingPoint(f: Double) extends SaveKey
case class Str(s: String) extends SaveKey
case class SaveList(elems: SaveElement*) extends SaveElement
case class SaveHash(keyValuePairs: Map[SaveKey, SaveElement]) extends SaveElement
它非常基础,除了包装基本的 Scala 类型之外没有太多其他内容。鉴于我拥有的 AST,我应该如何以希望简单的方式在程序中使用的具体类型与 AST 中的类型之间进行转换?
当然,我可能完全以错误的方式解决这个问题,在这种情况下,我也会感谢任何正确方向的指示。
编辑 在仔细思考我的问题之后,我得出的结论是我想要做的是将 AST 解包为 Scala 类型。我想以一种不涉及将 SaveElement
类型转换为它们必须是的案例类的方式来执行此操作(因为首先知道 AST 是如何构建的)。
一种可能的方法如下。
model = <result of parsing input>
extractElements(model)
其中:
def extractElements(mdl: Model): // or whatever your parser returns
// Assuming the model contains a top-level collection of SaveElements
// in a SaveList called 'elements'
for (element <- mdl.elements.elems) {
element match {
case SaveMap(pairs) => // do something with the map
case SaveList(elems) => // do something with the list
...
}
}
您可以修改此方法以满足您的需要。这就是你想要的吗?
我正在设计一种保存文件格式,为了简单起见,它是 YAML 的一个子集,具有 3 种基本类型和 2 种数据结构。
我的 AST,用 Scala 写的:
sealed trait SaveElement
/**
* Trait for save data primitives
*/
sealed trait SaveKey extends SaveElement
case class Integer(i: Long) extends SaveKey
case class FloatingPoint(f: Double) extends SaveKey
case class Str(s: String) extends SaveKey
case class SaveList(elems: SaveElement*) extends SaveElement
case class SaveHash(keyValuePairs: Map[SaveKey, SaveElement]) extends SaveElement
它非常基础,除了包装基本的 Scala 类型之外没有太多其他内容。鉴于我拥有的 AST,我应该如何以希望简单的方式在程序中使用的具体类型与 AST 中的类型之间进行转换?
当然,我可能完全以错误的方式解决这个问题,在这种情况下,我也会感谢任何正确方向的指示。
编辑 在仔细思考我的问题之后,我得出的结论是我想要做的是将 AST 解包为 Scala 类型。我想以一种不涉及将 SaveElement
类型转换为它们必须是的案例类的方式来执行此操作(因为首先知道 AST 是如何构建的)。
一种可能的方法如下。
model = <result of parsing input>
extractElements(model)
其中:
def extractElements(mdl: Model): // or whatever your parser returns
// Assuming the model contains a top-level collection of SaveElements
// in a SaveList called 'elements'
for (element <- mdl.elements.elems) {
element match {
case SaveMap(pairs) => // do something with the map
case SaveList(elems) => // do something with the list
...
}
}
您可以修改此方法以满足您的需要。这就是你想要的吗?