scala - Scala解析器与List左递归
问题描述
我的问题是我想实现一个(在纸上)看起来像这样的语法:
functionCall = expression "(" [{expression ";"} expression ] ")"
这里有些例子:
- 富(变种)
- 富(var1; var2)
- 富()
- 富(变量 1;变量 2;变量 3)
使用这个指定的语法,这也应该起作用:
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
List 的数据结构。
如果我有什么不清楚的地方,我很抱歉,很乐意回答你。
非常感谢任何帮助!
解决方案
推荐阅读
- python-3.x - Docker,Ubuntu 18.04 python3.7.2:standard_init_linux.go:207:exec用户进程导致“exec格式错误”
- ruby-on-rails - 范围资源的 Rails 路由设计问题
- docker - 在 amd64 linux 机器上为 arm32v7 容器运行 docker build 时出错:standard_init_linux.go:207
- angular - Semantic UI - Accordion not expanding in Angular
- flutter - Flutter Error: Type 'File' not found. What's going on here?
- sorting - 如何在 Ansible 中对复杂的版本号进行排序
- jquery - 如何使用 jquery 删除类属性中的一些文本?
- python - 将 CSV 数据动态插入到动态创建的表中
- opengl - GLFW 在 Debian 上失败(使用 Python)
- gmail - Gmail 在双引号之间显示发件人