python - lark : How to make literals appear in the tree

标签 python parsing literals lark-parser

使用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_compargs 参数中也包含文字?

最佳答案

有两种方法可以解决您的问题。

  1. ipv6_comp 变成终端。然后 Lark 会在单个正则表达式中匹配所有内容,并返回所有匹配的字符:
    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 - lark : How to make literals appear in the tree,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58247933/

    相关文章:

    c# - 解析缩进文本文件

    c++ - token 的类层次结构并在解析器中检查它们的类型

    regex - 用于测试字符串是否由以 10 为底的有效实数组成的正则表达式

    java - Java 中文字的数据类型/文字算术运算的结果

    python - 如何向 Python 2.x ConfigParser 指定 unicode 和其他转义文字

    python - 在 Python 中比较 "similar"数字

    python - python中一致的读写文件

    python - 在多单词字符串的空格之间添加字符

    python - Python 的 PHP 样式内联标签?

    python - 创建一个包含 >255 个元素的列表