如何使用Scala Parser Combinators更改代码以考虑运算符优先级?

soc*_*soc 8 parsing scala operators operator-precedence parser-combinators

考虑这部分语法:

  def expression = SimpleExpression ~ opt(relation ~ SimpleExpression)
  def relation = "=" | "#" | "<=" | "<" | ">=" | ">" | "IN" | "IS"
  def SimpleExpression = opt("+" | "-") ~ rep1sep (term, AddOperator)
  def AddOperator = "+" | "-" | "OR"
  def term = factor ~ rep(MulOperator ~ factor)
  def MulOperator = "*" | "/" | "DIV" | "MOD" | "&"
  def factor: Parser[Any] = number | "(" ~ expression ~ ")" | "~" ~ factor
Run Code Online (Sandbox Code Playgroud)

是否有必要重写它的部分来创建新的规则,或者是有只是一个方法(如||||为第一与最长的规则匹配)我目前缺少这做必要的事情吗?

Dan*_*ral 5

运算符优先级是编写规则的自然结果.例如,在这个语法中,a SimpleExpression由加法,减法和逻辑 - 或者由terma term组成,并且由乘法,除法,模数和逻辑 - 和a组成factor.

所以,如果你有这个:

1 + 2 * 3
Run Code Online (Sandbox Code Playgroud)

你会得到以下回报(粗略地说,为了清晰起见):

List(1, (2 ~ List(* ~ 3)))
Run Code Online (Sandbox Code Playgroud)

如果你有这个:

1 * 2 + 3
Run Code Online (Sandbox Code Playgroud)

你会得到这个(粗略地说):

List((1 ~ List(* ~ 2)), 3)
Run Code Online (Sandbox Code Playgroud)

由于rep1sep- 分隔符被丢弃,您将丢失加法运算符.