我正在完成我的作业,这需要我为“新”程序语言构建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所以也许我会犯很多错误。非常感谢先进!
答案 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)
})
}