2012-03-24 106 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,你不會在有趣的情況下解析任何「=」。而且,在「和」之後,你甚至不解析任何標識符,只是函數體。