24.8.1.2 运算符优先文法

SMIE 的优先文法为每个标记分配一对优先级:左优先级与右优先级。 若标记 T1 的右优先级小于 T2 的左优先级,我们记为 T1 < T2。 可以把这个 < 理解为一种括号关系:若出现 ... T1 something T2 ..., 则应解析为 ... T1 (something T2 ...,而非 ... T1 something) T2 ...。 若为 T1 > T2,则对应后一种解释。若为 T1 = T2, 表示 T2 与 T1 属于同一语法结构,典型如 "begin" = "end"。 这样的优先级对足以表达中缀运算符的左结合、右结合, 以及括号式嵌套等多种常见情况。

Function: smie-prec2->grammar table

接收一个 prec2 文法表 table,返回可用于 smie-setup 的关联表。 prec2 表本身由下面的函数构建。

Function: smie-merge-prec2s &rest tables

接收多个 prec2 表,合并为一个新的 prec2 表。

Function: smie-precs->prec2 precs

从优先级表 precs 构建 prec2 表。 precs 应是按优先级排序的列表(例如 "+" 排在 "*" 前面), 元素形如 (assoc op ...), 其中每个 op 是作为运算符的标记; assoc 为结合性,可为 leftrightassocnonassoc。 同一元素中的所有运算符共享同一优先级与结合性。

Function: smie-bnf->prec2 bnf &rest resolvers

允许使用 BNF 表示法定义文法。 它接收文法的 bnf 描述以及冲突消解规则 resolvers,返回一个 prec2 表。

bnf 是非终结符定义列表,形如 (nonterm rhs1 rhs2 ...), 每个 rhs 是由终结符(标记)或非终结符组成的非空列表。

并非所有文法都被接受:

  • rhs 不能为空列表(空列表并无必要,因为 SMIE 允许所有非终结符匹配空串)。
  • rhs 不能有两个连续的非终结符:任意一对非终结符之间必须用终结符(标记)分隔。 这是运算符优先文法的根本限制。

此外可能出现冲突:

  • 生成的 prec2 表保存标记对之间的约束关系,任意一对标记只能有一种约束: T1 < T2、T1 = T2 或 T1 > T2。
  • 一个标记可以是开标记(类似左括号)、闭标记(类似右括号),或两者都不是(如中缀运算符、"else" 这类内部标记)。

优先级冲突可以通过 resolvers 来解决,它是一个 优先级(precs) 表的列表(参见 smie-precs->prec2):对每一个优先级冲突,如果这些 precs 表中指定了某个特定约束,就使用该约束来解决冲突;否则会报告冲突,并任意选择其中一个冲突约束生效,其余约束则直接忽略。


emacs

Emacs

org-mode

Orgmode

Donations

打赏

Copyright

© Jasper Hsu

Creative Commons

Creative Commons

Attribute

Attribute

Noncommercial

Noncommercial

Share Alike

Share Alike