【问题标题】:Scala parsing mutually recursive functions for SMLScala解析SML的相互递归函数
【发布时间】:2017-02-01 03:21:22
【问题描述】:

我正在尝试在 Scala 中为带有令牌的 SML 编写解析器。它几乎按照我想要的方式工作,除了当前解析的事实

让 fun f x = r 和 fun g y in r 结束;

而不是

让 fun f x = r and g y in r end;

如何更改我的代码以使其识别出第二个函数不需要 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.");
  }
}

【问题讨论】:

    标签: parsing scala sml


    【解决方案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]
    

    顺便说一句,我认为您对 fun 的解析还有其他问题。 AFAICS,在有趣的情况下,您没有解析任何“=”。此外,在“and”之后,您甚至不解析任何标识符,只解析函数体。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-06-13
        • 1970-01-01
        • 2012-04-29
        • 1970-01-01
        • 2015-06-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多