如何描述 EBNF 中的作用域?
How to describe scopes in EBNF?
我正在尝试使用 Grako 和 Python 为 Cisco IOS 和 ASA 配置编写解析器。我正在尝试弄清楚如何在 EBNF 中表示 'scoped' 关键字 - 例如,'description' 关键字必须出现在 interface
范围内,但是 [=12= 有多个选项] 它们都是可选的(我相信顺序可以在设备之间改变):
interface Vlan1435
nameif untrust
description the outside interface for customer X
bridge-group 1
security-level 0
我找到的最接近示例的是一个名为 Farly 的 Perl 应用程序,它使用 perl Parse::Recdescent 模块,它看起来类似于 Grako。
从那里我得到了这种类型的递归定义:
@@eol_comments :: /!([^\n]*?)\n/
@@whitespace :: /[\t ]+/
start
=
file_input $
;
file_input
=
{NEWLINE | asa_line}
;
asa_line
=
'names' NEWLINE
| interface NEWLINE
;
interface
=
'interface' string NEWLINE interface_options
;
interface_options
=
if_name | sec_level | if_addr | if_bridgegroup | NEWLINE
;
if_bridgegroup
=
'bridge-group' digit NEWLINE interface_options
;
if_name
=
'nameif' string NEWLINE interface_options
;
sec_level
=
'security-level' digit NEWLINE interface_options
;
但它会产生一个奇怪的嵌套 AST,并且它不会 "reset" 检测第二个接口或后续配置中的任何其他内容。
EBNF 中通常如何定义这些范围?
(是否也有针对此类内容的有用教程?我的 google-fu 通常没有为 Grako 或解析器提供任何内容)
我在这些情况下使用的一个技巧是使用重复,即使选项只能出现一次:
interface_options
=
{ @+:(if_name | sec_level | if_addr | if_bridgegroup) NEWLINE}*
;
如有必要,您可以使用语义操作来验证选项是否不重复。
我正在尝试使用 Grako 和 Python 为 Cisco IOS 和 ASA 配置编写解析器。我正在尝试弄清楚如何在 EBNF 中表示 'scoped' 关键字 - 例如,'description' 关键字必须出现在 interface
范围内,但是 [=12= 有多个选项] 它们都是可选的(我相信顺序可以在设备之间改变):
interface Vlan1435
nameif untrust
description the outside interface for customer X
bridge-group 1
security-level 0
我找到的最接近示例的是一个名为 Farly 的 Perl 应用程序,它使用 perl Parse::Recdescent 模块,它看起来类似于 Grako。
从那里我得到了这种类型的递归定义:
@@eol_comments :: /!([^\n]*?)\n/
@@whitespace :: /[\t ]+/
start
=
file_input $
;
file_input
=
{NEWLINE | asa_line}
;
asa_line
=
'names' NEWLINE
| interface NEWLINE
;
interface
=
'interface' string NEWLINE interface_options
;
interface_options
=
if_name | sec_level | if_addr | if_bridgegroup | NEWLINE
;
if_bridgegroup
=
'bridge-group' digit NEWLINE interface_options
;
if_name
=
'nameif' string NEWLINE interface_options
;
sec_level
=
'security-level' digit NEWLINE interface_options
;
但它会产生一个奇怪的嵌套 AST,并且它不会 "reset" 检测第二个接口或后续配置中的任何其他内容。
EBNF 中通常如何定义这些范围? (是否也有针对此类内容的有用教程?我的 google-fu 通常没有为 Grako 或解析器提供任何内容)
我在这些情况下使用的一个技巧是使用重复,即使选项只能出现一次:
interface_options
=
{ @+:(if_name | sec_level | if_addr | if_bridgegroup) NEWLINE}*
;
如有必要,您可以使用语义操作来验证选项是否不重复。