我有这样的字串:
- “ABC Some other stuff”(通常开头有一个短字母组合)
- “一些其他的东西”(有时没有什么有趣的)
- “HFG 54 Some other stuff and even more”(有时有一个有趣的数字)
- “HFG 54 ZZ Some other stuff and even more”(有时在数字后面有 ZZ)
- “HFG-54 ZZ 一些其他的东西,甚至更多”(有时会有破折号)
- “ZT SOME OTHER STUFF”(其余部分也可以大写)
- "(ZT) Some other stuff" (部分可以在括号中)
- “68 Some other stuff”(只能是数字)
- “其他一些东西 DFG”(可以在最后)
我制定了一些规则来解析它,并且使用 larks Early-parser 可以正常工作。现在我想用 Lalr-Parser 试一试,但特殊词无法识别。我对大写字母组合和数字感兴趣。我有一个可能的字母组合列表。数字总是两位数。字符串的其余部分可以是任何东西。
我正在使用云雀。这是我的解析器:
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 语言。如果有人添加并回答快速解释这两者的地方,我会很高兴。