Lark:如何让字面值出现在树中
Lark: How to make literals appear in the tree
使用Python。
在我的语法中,我有这样一行:
ipv6_comp: [ipv6_hex (":" ipv6_hex)~0..5] "::" [ipv6_hex (":" ipv6_hex)~0..5]
我的变压器有合适的功能
def ipv6_comp(self, args):
但是,args
看起来像这样:
<class 'list'>: ['2001', 'db8', '85a3', '8a2e', '370', '7334']
因为不包括文字。但是,从这个结构来看,我显然不可能知道原来的ip是不是这样的:
2001:db8:85a3::8a2e:370:7334
2001:db8:85a3:8a2e::370:7334
我想我可以用他们自己的规则来掩盖文字,比如
colon: ":"
doublecolon: "::"
ipv6_comp: [ipv6_hex (colon ipv6_hex)~0..5] doublecolon [ipv6_hex (colon ipv6_hex)~0..5]
这甚至可能更干净。但是,我使用的语法是半自动生成的,这将需要更多的人工劳动。
我的转换器函数 ipv6_comp
是否有办法在 args
参数中也包含文字?
有两种方法可以解决您的问题。
- 把
ipv6_comp
变成一个终端。然后 Lark 会在一个正则表达式中匹配它,并且 return 所有匹配的字符:
IPV6_COMP: [HEX (":" HEX)~0..5] "::" [HEX (":" HEX)~0..5]
为您的标点符号提供一个名称(您建议的,但作为终端)
冒号:“:”
使用!
运算符在规则中包含标点符号(即:未命名符号)
!ipv6_comp: [ipv6_hex (":" ipv6_hex)~0..5] "::" [ipv6_hex (":" ipv6_hex)~0..5]
我推荐第一种解决方案,因为它解析速度更快,解析完成后可以使用专用库将IPv6地址解析成组件。
使用Python。 在我的语法中,我有这样一行:
ipv6_comp: [ipv6_hex (":" ipv6_hex)~0..5] "::" [ipv6_hex (":" ipv6_hex)~0..5]
我的变压器有合适的功能
def ipv6_comp(self, args):
但是,args
看起来像这样:
<class 'list'>: ['2001', 'db8', '85a3', '8a2e', '370', '7334']
因为不包括文字。但是,从这个结构来看,我显然不可能知道原来的ip是不是这样的:
2001:db8:85a3::8a2e:370:7334
2001:db8:85a3:8a2e::370:7334
我想我可以用他们自己的规则来掩盖文字,比如
colon: ":"
doublecolon: "::"
ipv6_comp: [ipv6_hex (colon ipv6_hex)~0..5] doublecolon [ipv6_hex (colon ipv6_hex)~0..5]
这甚至可能更干净。但是,我使用的语法是半自动生成的,这将需要更多的人工劳动。
我的转换器函数 ipv6_comp
是否有办法在 args
参数中也包含文字?
有两种方法可以解决您的问题。
- 把
ipv6_comp
变成一个终端。然后 Lark 会在一个正则表达式中匹配它,并且 return 所有匹配的字符:
IPV6_COMP: [HEX (":" HEX)~0..5] "::" [HEX (":" HEX)~0..5]
为您的标点符号提供一个名称(您建议的,但作为终端)
冒号:“:”
使用
!
运算符在规则中包含标点符号(即:未命名符号)
!ipv6_comp: [ipv6_hex (":" ipv6_hex)~0..5] "::" [ipv6_hex (":" ipv6_hex)~0..5]
我推荐第一种解决方案,因为它解析速度更快,解析完成后可以使用专用库将IPv6地址解析成组件。