Scala parsing mutually recursive functions for SML

I am trying to write a parser in Scala for SML with tokens. It almost works the way I want it to work, except for the fact that it is currently analyzing

let fun fx = r and fun gy at the end of r;

instead

let fun fx = r and gy at the end of r;

How can I change the code so that it finds out that the second function does not need a 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."); } } 
+4
source share
2 answers

Just follow the correct grammar. Instead

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

SML grammar is actually

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

By the way, I think there are other problems with your analysis of the fun. AFAICS, you do not parse any "=" in a funny case. Moreover, after "and" you do not even parse any identifiers, just the body of the function.

+1
source

You can insert FunToken back into your input stream using the "uneat" function. This is not the most elegant solution, but it requires the least modification of your current code.

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

Source: https://habr.com/ru/post/1403211/


All Articles