缩进级别定义块的语言语法的BNF示例?

5
我试图记录我在menuentries.conf中使用的语法,这是一个用于菜单条目的配置文件,通过使用称为扩展Backus-Naur-Form EBNF(BNF)的符号说明法来描述语法/语法。此menuentries.conf使用缩进级别作为语法组件,如以下示例所示:
menu_entry_1
menu_entry_2
    menu_entry_2_submenu_entry_1
    menu_entry_2_submenu_entry_2
        menu_entry_2_submenu_entry_2_subsubmenu_1
        menu_entry_2_submenu_entry_2_subsubmenu_2
    menu_entry_2_submenu_entry_3
menu_entry_3
    menu_entry_3_submenu_entry_1

在上面的示例中,每个条目都由一个字符串表示,为了示例的方便,该字符串表示其位置。此外,示例应遵循以下规则:
  • 每个菜单项都由一行表示(因此菜单条目由NEWLINE分隔)
  • 没有任何缩进的菜单条目是“顶级”菜单条目
  • 具有缩进的菜单条目不是“顶级”,而是相应更高/上级菜单条目的子条目。

我提供BNF的尝试如下:

NEWLINE:= '\n'
INDENTING:= '    '
menu_entry_string:=('a'|'b'|....|'z'|'_'|'0'|'1'|...|'9')+
menu_entries:= menu_entry(NEWLINE menuentry)*
menu_entry:= menu_entry_string(NEWLINE INDENTING menu_entry)*
submenu_entry:= INDENTING menu_entry_string
subsubmenu_entry:= INDENTING INDENTING menu_entry_string
我的问题是关于我对递归声明的“menu_entry”概念及其与“submenu_entry”和“subsubmenu_entry”的冗余不满。
知道Python也使用缩进来创建块的概念,我想查找Python语法的BNF /定义(在此处找到:https://docs.python.org/3/reference/grammar.html),但它将INDENTDEDENT的相关概念留了下来。

因此,我的问题是: 如何正确地使用EBNF描述使用缩进作为分组块的语法/语法? 最好提供一个小例子(或者如果可能的话纠正我的尝试)。

在最理想的情况下,EBNF将定义“嵌套级别”的“块”概念,其中“submenu_entry”的级别为1,“subsubmenu_entry”的级别为2....

1个回答

4
你可能在需要语言创作者的思维时,以程序员的思维在思考。通常创建一种语言有两个部分:
  1. 词法规范:定义表示单个句法结构(即令牌或终端值)的字符组。
  2. 语法规范:定义可用于非终端值的句法结构/令牌/终端值的有效组合,表达语言的使用方式。
有些语言能够将语言创建的词法和句法部分结合起来,但在你的情况下这样做并不是个好主意,因为仅凭语法无法表达特定缩进的想法。这是留给词法分析器处理的事情。
以下是BNF语法,其中STRINGNEWLINEINDENTDEDENT都是由你的词法分析器生成的终端值:
start ::= list
        | list NEWLINE
        .

list  ::= entry
        | list entry
        .

entry ::= STRING NEWLINE
        | STRING NEWLINE INDENT list DEDENT
        .

足够简单,不是吗?我包含了“start”规则以确保任何以“NEWLINE”或“DEDENT”标记结尾的文件都是有效的。如果没有它,在没有前导“STRING”标记的情况下,以“NEWLINE”标记结尾的文件将无效。
我使用了BNF,但你也可以轻松使用EBNF。关键是词法分析器可以理解使用了多少空格缩进来生成“INDENT”或“DEDENT”标记(或必要时生成错误),并且您的语法应该仅指定如何使用生成的标记。

首先,非常感谢您的回答。其次,您能否提供一些见解,是否可能使INDENT和DEDENT不成为词法分析器的结果/输出/部分? - humanityANDpeace
使用可以处理这些事情的解析器,当然不需要词法分析器来处理它,但是语法本身无法描述您想要的 INDENTDEDENT,因为它们所表示的空格数量会有所变化。 - user539810

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接