Scala解析器使用List

时间:2019-06-11 08:22:22

标签: scala parsing recursion

我的问题是我想实现一个(在纸上)如下所示的语法:

functionCall = expression "(" [{expression ";"} expression ] ")"

以下是一些示例:

      
  • foo(var)
  •   
  • foo(var1; var2)
  •   
  • foo()
  •   
  • foo(var1; var2; var3)

使用此指定的语法,它也应该起作用:

foo(var1)()  

  • foo(var1)=>表达式
  •   
  • “(”
  •   
  • “)”
  • 有了这种语法,就会发生左递归,我不知道该如何处理。

    我正在使用Scala解析器库来实现此语法。

    我研究了一些帖子,尤其是这篇Recursive definitions with scala-parser-combinators,以找出解决方案。

    我找到了许多类似于以下问题的解决方案:

    expression ~ "." ~ expression

    我试图为我的问题复制解决方案,但是我没有成功。

    我的简化代码如下:

    sealed trait Baz
    case class Start(code: Baz) extends Baz
    case class FunctionCall(call: Baz, arg: List[Baz]) extends Baz
    case class foo(text: String) extends Baz
    case class bar(nr: Int) extends Baz
    
    class ExpParser extends JavaTokenParsers {
    
      def start: Parser[Start] = expression ^^ {s => Start(s)}
    
      def expression: Parser[Baz] = foo | bar | functionCall 
    
      private val foo: Parser[Foo] = "[a-z]*".r ^^ {f => Foo(f)}
      private val bar: Parser[Bar] = "[0-9]*".r ^^ {b => Bar(b)}
    
      private val functionCall: Parser[Baz] = expression ~ "(" ~  repsep(expression, ";") <~ ")" ^^ {case l~_~r => FunctionCall(l,r)}
    }
    
    object ParseProgram extends ExpParser {
      def parse(s: String): ParseResult[Start] = {
        parseAll(code, s)
      }
    }
    
    

    我尝试使用chainl1,但阅读该实现至少对我来说似乎不适用于我的问题。

    我想知道是否有任何方法可以更改我的代码,以便可以避免这种左递归并将functionCall的数据结构保留在列表中。

    如果我不清楚任何事情,我深表歉意,很高兴为您解答。

    非常感谢您的帮助!

    0 个答案:

    没有答案