Моя проблема в том, что я хотел бы реализовать грамматику, которая (на бумаге) выглядит следующим образом:
functionCall = expression "(" [{expression ";"} expression ] ")"
Вот несколько примеров:
- Foo (вар)
- foo (var1; var2)
- Foo ()
- foo (var1; var2; var3)
С этой указанной грамматикой это также должно работать:
foo(var1)()
foo (var1) => выражение
"("
")"
С этой грамматикой происходит левая рекурсия, и я не знаю, как с ней справиться.
Я использую библиотеку синтаксического анализатора Scala для реализации этой грамматики.
Я заглянул в какой-то пост, особенно в этот Рекурсивные определения с 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
со списком.
Если мне что-то неясно, я прошу прощения и буду рад ответить вам.
Любая помощь очень ценится!