2012-03-24 46 views
4

我正在尝试在Scala中为带标记的SML编写解析器。它几乎按照我希望它工作的方式工作,除了目前解析的这一事实:Scala为SML解析相互递归函数

let fun f x = r and fun g y in r end;的

代替

让r中端乐趣˚FX = R和Gÿ;

如何更改我的代码,以便它可以识别它不需要第二个函数的FunToken?

def parseDef:Def = { 
    currentToken match { 
    case ValToken => { 
    eat(ValToken); 

    val nme:String = currentToken match { 
     case IdToken(x) => {advance; x} 
     case _ => error("Expected a name after VAL.") 
    } 

    eat(EqualToken);  
    VAL(nme,parseExp) 
    } 

    case FunToken => { 

    eat(FunToken); 

    val fnme:String = currentToken match { 
     case IdToken(x) => {advance; x} 
     case _ => error("Expected a name after VAL.") 
    } 

    val xnme:String = currentToken match { 
     case IdToken(x) => {advance; x} 
     case _ => error("Expected a name after VAL.") 
    } 

    def parseAnd:Def = currentToken match { 
     case AndToken => {eat(AndToken); FUN(fnme,xnme,parseExp,parseAnd)} 
     case _ => NOFUN 
    } 


    FUN(fnme,xnme,parseExp,parseAnd) 
    } 
    case _ => error("Expected VAL or FUN."); 
    } 
} 

回答

0

您可以使用“uneat”函数将FunToken注入到输入流中。这不是最优雅的解决方案,但它是需要最少修改当前代码的解决方案。

def parseAnd:Def = currentToken match { 
    case AndToken => { eat(AndToken); 
         uneat(FunToken); 
         FUN(fnme,xnme,parseExp,parseAnd) } 
    case _ => NOFUN 
} 
1

只要执行正确的语法。取而代之的

def ::= "val" id "=" exp | fun 
fun ::= "fun" id id "=" exp ["and" fun] 

SML的语法实际上

def ::= "val" id "=" exp | "fun" fun 
fun ::= id id "=" exp ["and" fun] 

顺便说一句,我认为还有其他问题,您的乐趣解析。 AFAICS,你不会在有趣的情况下解析任何“=”。而且,在“和”之后,你甚至不解析任何标识符,只是函数体。