使用 LALR 从单词列表中解析可选关键字的语法规则

Grammar rules for parsing optional keywords from list of words with LALR

我有这样的字符串:

我制定了一些规则来解析它,并且使用百灵鸟早期解析器它工作正常。现在我想用 Lalr-Parser 尝试一下,但是特殊的词无法识别。 我对大写字母组合和数字感兴趣。我有一个可能的字母组合列表。数字总是两位数。字符串的其余部分可以是任何内容。

我正在使用 lark。 这是我的解析器:

from lark import Lark

tryoutabc = Lark(r"""
    start: mat_all_and_restl
    ?mat_all_and_restl: mat_all restl | restl | restl mat_br
    restl: REST*
    ?mat_all: mat_br| mat_num| num
    mat_num: mat_br ("-")? NUM
    ?num: NUM  ("ZZ")?
    NUM: /\d{2}/
    ?mat_br:  "("? MAT ")"?
    MAT:  "ABC" 
        | "HFG" 
        | "ZT" 
        | "DFG" 
    REST: /([\-])?[A-Za-zÜ]+([\/.][A-Za-zÜ]+)?/
    %import common.WS
    %ignore WS
""", start='start', parser='lalr')   #remove "parser='lalr'" and the results are right

我该如何更改规则才能使 lalr-parser 能够解析它?

尝试一下:

textl = ["ABC SOME OTHER STUFF", "Some other stuff", "HFG 54 Some other stuff and even     more",
         "HFG 54 ZZ Some other stuff and even more", "HFG-54 Some other stuff and even more", "ZT Some other stuff",
         "(ZT) Some other stuff", "Some other stuff DFG", "Some other stuff (DFG)", "68 Some other stuff "]
for text in textl:
    print(tryoutabc.parse(text).pretty())

我明白了

start
  restl
    ABC
    SOME
    OTHER
    STUFF

但我想要

start
  ABC
  restl
    SOME
    OTHER
    STUFF

对于 "HFG 54 Some other stuff and even more" 我得到一个错误:

HFG 54 Some other stuff and even more
    ^

Expecting: {'REST'}`

但我想要:

start
  mat_num
    HFG
    54
  restl
    Some
    other
    stuff
    and
    even
    more

实际上,字符串更长,看起来像这样“有趣的东西,我已经解析了 ABC 一些其他的东西”,我已经解析了字符串开头的东西,而且效果很好。


从评论来看,这似乎是不可能的,因为我这里没有上下文无关语言,显然 larl 只能使用 cfg 语言。如果有人补充并回答这两个都很快解释的地方,我会很高兴。

问题出在 REST 终端。它可以通过设计解析几乎任何东西,这意味着


start
    mat_all_and_restl
      ABC
      restl
        SOME
        OTHER
        STUFF

start
    restl
      ABC
      SOME
      OTHER
      STUFF

都是第一个例句的有效解释 (ABC SOME OTHER STUFF)。如果您将 ambiguity='explicit' 传递给 earley 解析器,您可以查看此内容。

此示例适用于 lalr,因为如果 lalr 只是将所有内容解释为 REST 就没有问题,但它确实会给您错误的结果。

另一方面,有问题的示例 "HFG 54 Some other stuff and even more" 不起作用。它将 HFG 作为 REST,然后尝试解析它可以解析的 54,因为它不是 REST 并且它不期望 NUM 正确现在。


如果这是您语法的完整扩展,请使用 earley,或者为了比 lalr 提供的速度更快,一个(或多个)正则表达式也可以很好地完成这项工作。

(请注意,我说错了:这可能是一个 CFG,只是模棱两可。您可能会继续破解 grammar/the REST 正则表达式以使其工作,但它不会漂亮。)