对于我要创建的解析器,我使用此正则表达式作为ID的定义:
ID: /[a-z_][a-z0-9]*/i
(对于不熟悉我正在使用的特定解析器的语法的人,“ i”标志仅表示不区分大小写。)
我也有很多关键字,例如:
CALL_KW: "call"
PRINT_KW: "print"
问题在于,由于语法上的某些歧义,有时关键字被视为ID,而我真的不希望它们成为ID。因此,我在考虑是否可以以完全不匹配关键字的方式重写ID的正则表达式。这样的事情有可能吗?
要提供更多背景信息,我使用了Lark Python解析器库。 Lark提供的Earley解析器(与动态词法分析器一起使用)在处理模棱两可的语法时非常灵活且功能强大,但是有时它们会做这种奇怪的事情(并且不确定地是这样!)。因此,我试图通过使关键字从不匹配ID规则来为解析器提供一些帮助。
答案 0 :(得分:2)
我相信Lark使用普通的Python正则表达式,因此您可以使用否定的超前断言来排除关键字。但是您必须注意不要拒绝以关键字开头的名称:
ID: /(?!(else|call)\b)[a-z_][a-z0-9]*/i
此正则表达式当然可以在Python3中使用:
>>> # Test with just the word
>>> for test_string in ["x", "xelse", "elsex", "else"]:
... m = re.match(r"(?!(else|call)\b)[a-z_][a-z0-9]*", test_string)
... if m: print("%s: Matched %s" % (test_string, m.group(0)))
... else: print("%s: No match" % test_string)
...
x: Matched x
xelse: Matched xelse
elsex: Matched elsex
else: No match
>>> # Test with the word as the first word in a string
... for test_string in [word + " and more stuff" for word in ["x", "xelse", "elsex", "else"]]:
... m = re.match(r"(?!(else|call)\b)[a-z_][a-z0-9]*", test_string)
... if m: print("%s: Matched %s" % (test_string, m.group(0)))
... else: print("%s: No match" % test_string)
...
x and more stuff: Matched x
xelse and more stuff: Matched xelse
elsex and more stuff: Matched elsex
else and more stuff: No match
答案 1 :(得分:0)