2014-11-01 59 views
0

我正在做我的功课,这需要我建立一个“新”程序语言的Abstract Syntax Tree Parser使用Scala。这就是我在有麻烦的代码:斯卡拉 - 建立AST解析器 - 如何返回一个preifined类的列表?

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分析器将识别的参数输入列表并返回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

累加器首先在您传递给文件夹功能的参数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) 
    }) 
}