import scala.util.parsing.combinator._
object ExprParser extends JavaTokenParsers {
lazy val name: Parser[_] = "a" ~ rep("a" | "1") | function_call
lazy val function_call = name ~ "(" ~> name <~ ")"
}
无限期地重复function_call.parseAll("aaa(1)")
。很明显,是因为 1 不能插入名字,而名字进入了function_call
,它尝试了名字,进入了函数调用。您如何解决此类情况?
有一种解决方案可以将名称简化为简单标识符
def name = rep1("a" | "1")
def function_call = name ~ "(" ~ (function_call | name) ~ ")"
但我不喜欢这样做,因为name ::= identifier | function_call
在 VHDL 规范中是 BNF-ed,并且function_call
可能在其他地方共享。出于同样的原因,此处发现的左递归消除是不可取的
def name: Parser[_] = "a" ~ rep("a" | "1") ~ pared_name
def pared_name: Parser[_] = "(" ~> name <~ ")" | ""
顺便说一句,我还想知道,如果我修复了错误,name.parseAll 会仅使用“aaa”作为名称规则中的第一个替代方案,还是使用整个“aaa(1)”?如何在仅消费 aaa 之前命名以消费整个 aaa(1)?我想我应该将 function_call 作为名称中的第一个替代项,但在这种情况下它会更加急切地堆栈溢出?