Lark解析器无法解析字符,即使它们是在规则的正则表达式中定义的

2024-09-27 07:25:34 发布

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

我正在尝试编写一个SMTP解析器,并从rfc中获取了一些引用字符串的信息。因此,我有以下语法(去掉所有有效的部分,重点放在不起作用的部分):

quoted_string  : /[\x22]/ qcontentsmtp* /[\x22]/
qcontentsmtp   : qtextsmtp | quoted_pairsmtp
quoted_pairsmtp  : /[\x5C\x5C]/ /[\x20-\x7E]/
qtextsmtp      : /[\x20-\x21|\x23-\x5B|\x5D-\x7E]/

command : [ quoted_string ]

解析器的唯一startcommand-规则

当我输入"quoted_string"时,我希望它被解析为:

command -> quoted_string -> qcontentsmtp -> qtextsmtp

如您所见,qtextsmtp包含字母数字字符,编码为正则表达式,如rfc中所示。但是,当我尝试解析它时,我得到以下消息:

input = '"quoted_string"'
....
####### Parsing Failed
No terminal defined for 'q' at line 1 col 2

"quoted_string"
 ^

当我只输入""时,它会按预期工作

当我更改规则qtextsmtp并将正则表达式交换为"a"并使输入为'"a"'时,它也可以工作

我在transformer中将所有规则定义为函数,非常基本,如下所示:

class StringsTransformer(Transformer):
# externals
def quoted_string(self, args):
    return "".join(args)

# internals
def qcontentsmtp(self, args):
    return "".join(args)

def quoted_pairsmtp(self, args):
    return "".join(args)

def qtextsmtp(self, args):
    return "".join(args)

但我甚至不了解这些规则,因为正如我所说,它甚至不会解析

我不太清楚为什么正则表达式不起作用。我在其他部分使用这些类型的规则,它们工作得很好,但在这个部分就不行了


Tags: self解析器stringreturn规则rfcdefargs
2条回答

如果可以,我建议在终端中使用字符串文字;尽管它们不能完全匹配RFC,但它们肯定可以在现有的lark解析器实现中工作。(你的例子对我来说也是失败的,但使用下面的方法是有效的。我不确定我是否理解为什么

DOUBLE_QUOTED_STRING  : /"[^"]*"/

来自the lark src的引用

你如何定义你的语法?如果要在代码中内联定义\反斜杠(而不是从文件中读取),则可能需要对其进行转义

似乎Lark的regexp解析器与[]分别引用为\x5b\x5d相混淆,并且q字母与regexp根本不匹配。将\x5b替换为\[并将\x5d替换为\]后,语法将解析提供的输入,如下程序所示:

import lark

grammar = r"""
quoted_string  : /[\x22]/ qcontentsmtp* /[\x22]/
qcontentsmtp   : qtextsmtp | quoted_pairsmtp
quoted_pairsmtp  : /[\x5C\x5C]/ /[\x20-\x7E]/
qtextsmtp      : /[\x20-\x21\x23-\[\]-\x7E]/

command : [ quoted_string ]
"""

parser = lark.Lark(grammar, start='command')

print(parser.parse('"quoted_string"'))

(请注意|在字符集中是多余的,它被解释为只是另一个要匹配的字符。)

这不是Python正则表达式的一般限制,它完全能够接受以十六进制转义的[]

>>> re.compile(r'[\x23-\x5b\x5d-\x7e]').match('q')
<re.Match object; span=(0, 1), match='q'>

我现在向百灵鸟的维护者致意

相关问题 更多 >

    热门问题