此问题与省略了一些小括号的表达式中匹配括号的问题完全类似。这里的“如果”(或中代表语法)是一个开放的括号和“其他”(b)是一个右括号。(从a和b的序列中,您可以通过在每个b的前面放置一个c,然后在末端的一个末端机械地插入c s 。)因为它更适合我的括号大脑,所以我写的好像是手头的问题。一个b一个bCb
传统的“最接近匹配”悬挂-其他分辨率将每个关闭与最近尚未匹配的打开相匹配。这意味着匹配的开盘价与其匹配的开盘价之间绝不会存在不匹配的开盘价。
一种可能的选择是使每个关闭与最早可行的不匹配打开相匹配。“可行”在这里的意思是,开能不违反插句嵌套匹配(例如,第一个在()()不能切实匹配最后))。(()())
必须从外到外进行此匹配,以便在所有包围对都匹配后才尝试进行闭合匹配。这个事实使得无法使用有界超前算法生成解析,因为解析必须在将字符串拆分为完全匹配的段之后从两端向内进行(因为这些段有效地限制了潜在匹配的范围)。
但是,不存在在线从左到右的解析器这一事实并不意味着没有明确的CFG。(显然:回文语言必须从两端到中间进行解析,但是编写明确的语法很容易)。
为了产生“最匹配”括号问题的语法,我依靠这样一个事实,即不匹配的开放不能跟随匹配的开放。如果是,那么最远匹配属性将不适用,因为不匹配的开盘可能已经匹配了匹配的开盘的收盘,因此不匹配的事实违反了最匹配的属性。
所以这是有点笨拙的语法:
小号ü中号Ť→ U|中号→ T|一个Ub Ť|一个Ub ç|一个Mb ü→ 一个Mb 中号|C→ 一个Ť|一个ç
是开始符号;M是完全匹配的语句;U绝对是不匹配的语句(这意味着它们至少包含一个不匹配的 a,因此它们不能为空), T是仅由不匹配的 s组成的“尾巴”。关于无与伦比的开放的上述事实可以直接从语法阅读:所有无与伦比打开衍生自牛逼,一个牛逼只能出现在年底 ü,和 ü只能跟着一个牛逼。小号中号ü一个Ť一个ŤŤüüŤ
üü小号中号∗ü小号中号ü中号ü
可能有比我选择的方法更好的解决方法。但这似乎有效,并且可以与我用来测试的Bison的GLR解析器配合使用。除非您编写额外的代码来处理歧义,否则该解析器会抱怨模棱两可的解析,而我实在太懒了。我用最多20个open + closes的字符串进行了测试,它似乎为每个正确嵌套的序列生成了明确的解析,而没有为错误嵌套的序列生成解析。