我的问题是我想实现一个(在纸上)如下所示的语法:
functionCall = expression "(" [{expression ";"} expression ] ")"
以下是一些示例:
使用此指定的语法,它也应该起作用:
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
的数据结构保留在列表中。
如果我不清楚任何事情,我深表歉意,很高兴为您解答。
非常感谢您的帮助!