Island Grammar 使用 Python textx 解析无序网络配置时出现问题

问题描述 投票:0回答:1

使用 Python 的 textx 库,我无法从网络配置文件中准确捕获我想要的内容。我可以捕获接口及其属性信息,但我希望 textx 在将模型传递回我的代码之前完成大部分解析和过滤工作。我遇到的问题是 textx 解析所有数据而不进行过滤或捕获,我认为是所有目标数据,留下一些内容未解析或忽略。

对于语言的复杂性,我深表歉意。这是我当前要解析的文本,假设所呈现的数据块周围还有其他数据,解析器将根据后面显示的语法忽略这些数据:

网络配置文件

     interface TenGigabitEthernet1/1/4
        description Some interface
        switchport trunk native vlan 232
        switchport trunk allowed vlan 395,398
        switchport mode trunk
        switchport nonegotiate
        no cdp enable
        flowcontrol receive off
        channel-group 1 mode active
        lacp rate fast
    !
    interface Vlan1
        no ip addr

语法.tx

Config:
    (
            Junk
            | interface=INTERFACE
    )*
;

Junk[noskipws]:
   !(INTERFACE)/[^\n]*\n/
;

INTERFACE[noskipws]:
 'interface' intf=/.+[0-9]+[^\n]*//\n/-
    (mode+=MODE
     attributes+=ATTRIBUTES)#
;


ATTRIBUTES[noskipws]:
  !MODE/\s+[^\n]*//\n/-
;

MODE[noskipws]:
  /\s+/'switchport mode trunk'/[^\n]*//\n/-
;

这里的目标是能够捕获

mode trunk
的接口及其所有定义 - 换句话说,Config.interface[...] 应该仅由 组成,而它应该忽略其他接口(
Interface Vlan1
):

     interface TenGigabitEthernet1/1/4
        description Some interface
        switchport trunk native vlan 232
        switchport trunk allowed vlan 395,398
        switchport mode trunk
        switchport nonegotiate
        no cdp enable
        flowcontrol receive off
        channel-group 1 mode active
        lacp rate fast

但我发现代码捕获了:

     interface TenGigabitEthernet1/1/4
        description Some interface
        switchport trunk native vlan 232
        switchport trunk allowed vlan 395,398
        switchport mode trunk

我推断这是因为语法的以下部分

ATTRIBUTES[noskipws]:
  !MODE/\s+[^\n]*//\n/-

指示捕获之前没有的所有文本

switchport mode trunk
。所以我尝试使用以下表达式包含这两种模式:

ATTRIBUTES[noskipws]:
  (!MODE/\s+[^\n]*//\n/-
   |/\s+[^\n]*//\n/-!MODE)

虽然这导致了

len(Config.interface) == 0

我将继续阅读文档,但我会在这里发帖,以防有人可以看到我的错误所在。


一种可能的解决方案...但并不理想

Config:
    (
            Junk
            | interface=INTERFACE
    )*
;

Junk[noskipws]:
   !(INTERFACE)/[^\n]*\n/
;

INTERFACE[noskipws]:
 'interface' intf=/.+[0-9]+[^\n]*//\n/-
    (mode+=MODE
     attributes+=PREATTRIBUTES
     attributes+=POSTATTRIBUTES
     )#
;


PREATTRIBUTES:
  !MODE
   /\s+[^\n]*//\n/-
;

POSTATTRIBUTES:
   /\s+[^\n]*//\n/-
   !MODE
;

MODE:
  /\s+/'switchport mode trunk'/[^\n]*//\n/-
;

通过此配置,只有具有“模式中继”的卡才会放入

interface
列表中,并且该接口对应的所有属性都会放入该接口的
attributes
列表中。

虽然我认为

must
可以制作一个
single ATTRIBUTES definition

python parsing configuration grammar textx
1个回答
0
投票

我花了一些时间,但是以下语法可以解析 Cisco 配置文件,这些文件具有缩进依赖性,因此解析器需要考虑空格 - 我在解析时遇到了一些惊喜(主要是

'\n'
字符) -但通过这种方法,我能够遍历整个配置,并且只选择带有
  switch mode trunk
配置条目的条目。

Config[noskipws]:
    (
        junk=JUNK
        | interface=INTERFACE
    )*
;

JUNK[noskipws]:
    !INTERFACE/[^\n]*\n+/
;

INTERFACE[noskipws]:
    'interface' /\s+/ name=/[^\n]*//\n+/-
    (
      ( attributes=ATTRS)*
      | mode+=MODE
      | (attributes=ATTRS)*
    )#
;

MODE[noskipws]:
    INDENT TRUNK /[^\n]*//\n+/-
;

ATTRS[noskipws]:
    INDENT !TRUNK /[^\n]*//\n+/-
;

INDENT[noskipws]:
    /\s+/
;

TRUNK[noskipws]:
    'switchport' /\s+/ 'mode' /\s+/ 'trunk'
;
© www.soinside.com 2019 - 2024. All rights reserved.