我正在使用 lark,一个优秀的python 解析库。
它提供了 Earley 和 LALR(1) 解析器,并通过自定义EBNF
格式定义。(EBNF 代表扩展巴科斯-瑙尔形式)。
小写定义是规则,大写定义是终端。Lark 还为大写定义提供了权重,以优先匹配。
我正在尝试定义语法,但我陷入了一种我似乎无法平衡的行为。
我对未命名的文字(双引号之间的字符串或字符)有一些规则:
directives: directive+
directive: "@" NAME arguments ?
directive_definition: description? "directive" "@" NAME arguments? "on" directive_locations
directive_locations: "SCALAR" | "OBJECT" | "ENUM"
arguments: "(" argument+ ")"
argument: NAME ":" value
union_type_definition: description? "union" NAME directives? union_member_types?
union_member_types: "=" NAME ("|" NAME)*
description: STRING | LONG_STRING
STRING: /("(?!"").*?(?<!\\)(\\\\)*?"|'(?!'').*?(?<!\\)(\\\\)*?')/i
LONG_STRING: /(""".*?(?<!\\)(\\\\)*?"""|'''.*?(?<!\\)(\\\\)*?''')/is
NAME.2: /[_A-Za-z][_0-9A-Za-z]*/
它适用于 99% 的用例。但是,如果在我解析的语言中,我使用了一个directive
叫做的 directive
,那么一切都会中断:
union Foo @something(test: 42) = Bar | Baz # This works
union Foo @directive(test: 42) = Bar | Baz # This fails
在这里,当字符串应该匹配终端时,它会匹配规则directive
中未命名的文字。directive_definition
NAME.2
我怎样才能平衡/调整它,以便 LALR(1) 解析器没有歧义?