Scala - 构建AST解析器 - 如何返回预定义类的列表?

时间:2014-11-01 06:50:31

标签: java scala abstract-syntax-tree

我正在完成我的作业,这需要我为“新”程序语言构建Abstract Syntax Tree Parser使用Scala 。这是我遇到麻烦的代码:

case class ParamDecl(val id: Id, val paramType: Type) extends Decl {
        override def toString = "param(" + id + "," + paramType + ")"
}
// myIdent: a valid identifier
def myIdent: Parser[Id] = ident ^^ {case i => Id(i)}

// myIdentList: a list of myIdent, seperated by comma(s)
def myIdentList: Parser[List[Id]] = rep1sep( myIdent, "," )

// paramList: a list of params, declared by case class ParamDecl above
def paramsList: Parser[List[ParamDecl]] = repsep((myIdentList <~ ":") ~ varType, ";") ^^ {
      case List() => List()
      // TODO my problem
      // how to return a list of ParamDecl ?
      // each ParamDecl should follow its nearby ParamDecl by using ":::"
}

我现在要做的是paramList Parser会识别参数的输入列表并返回ParamDecl的列表,以:::符号分隔。

以下代码是我刚试过的,我认为它在逻辑上解决了问题,但我收到了一个错误:

def paramsList: Parser[List[ParamDecl]] = repsep((myIdentList <~ ":") ~ varType, ";") ^^ {
      case List() => List()
      case paramDeclList => paramDeclList.tail.foldLeft(paramDeclList.head)((a,b) => a match { // this line throw an error says that: "type mismatch, found: [List[Id], Type]" required: List[ParamDecl]
        case x ~ y => List(x.map(ParamDecl(_, y)):::b)
      })
    }

我希望你们可以帮助我。我已经习惯了Scala所以也许我会犯很多错误。非常感谢先进!

1 个答案:

答案 0 :(得分:0)

累加器首先出现在传递给foldLeft的文件夹功能的参数中 - 它应该是(b, a)而不是(a, b)。一般来说,我建议使用更有意义的名字。

另外,为什么使用paramDeclList.head作为弃牌的基本情况?你也不需要单独的案件。只需从空List[ParamDecl]开始:

def paramsList: Parser[List[ParamDecl]] = repsep((myIdentList <~ ":") ~ varType, ";") ^^ {
  paramDeclList => paramDeclList.foldLeft(List[ParamDecl]())(
    (alreadyParsed,next) => next match {
    case x ~ y => List(x.map(ParamDecl(_, y)):::alreadyParsed)
  })
}