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

2024-09-24 00:21:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我有这样的字符串:

  • “ABC一些其他东西”(通常在开头有一个简短的字母组合)
  • “一些其他的东西”(有时没有什么有趣的东西)
  • “HFG 54其他一些东西,甚至更多”(有时有一个有趣的数字)
  • “HFG 54 ZZ一些其他东西,甚至更多”(有时数字后面有ZZ)
  • “HFG-54 ZZ一些其他东西,甚至更多”(soemtimes有一个破折号)
  • “ZT其他一些东西”(其余也可以资本化)
  • “(ZT)其他一些东西”(该部分可以放在括号中)
  • “68其他东西”(只能有一个数字)
  • “其他一些东西DFG”(可以在末尾)

我制定了一些规则来解析它,使用larks早期解析器,它可以很好地工作。现在我想用Lalr解析器进行测试,但是特殊的单词无法识别。 我对大写字母组合和数字感兴趣。我有一个可能的字母组合列表。数字总是两位数。字符串的其余部分可以是任何内容

我正在使用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解析器来解析它

要尝试:

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语言。如果有人补充并回答这两个问题,我会很高兴


Tags: andmore数字somestartnumevenother
1条回答
网友
1楼 · 发布于 2024-09-24 00:21:10

问题是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,只是模棱两可。您可能会继续攻击语法/theRESTregex使其工作,但它不会很好。)

相关问题 更多 >