BNF语言语法示例,其中缩进级别定义了一个块?

时间:2018-08-27 10:40:08

标签: python indentation bnf ebnf

我尝试记录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_entrysubsubmenu_entry的冗余性。
知道python也使用缩进来创建块的概念后,我想查找python语法的BNF /定义(如此处:https://docs.python.org/3/reference/grammar.html),但是却留下了INDENTDEDENT就是语法。

因此,我的问题是: 如何正确地使用EBNF来描述以缩进为分组块的语法/语法? 理想情况下,将不胜感激的一个小例子(或者可能是我尝试的更正)。

在最佳情况下,EBNF将定义nesting-levelblock的概念,即:submenu_entry为1,subsubmenu_entry ....

1 个答案:

答案 0 :(得分:1)

当您需要语言创建者的思想时,您可能会想到程序员。传统上,创建语言有两个部分:

  1. Lexeme规范:定义代表单个语法结构(即令牌或终端值)的字符组
  2. 语法规范:定义语法结构/标记/终端值的有效组合,这些组合构成表示语言使用方式的非终端值

某些语言能够结合语言创建的词汇和句法部分,但是在您的情况下这样做并不是一个好主意,因为语法本身无法单独表达特定缩进的思想。那是您留给词法分析器处理的东西。

下面是BNF语法,其中int day = 25; int month = 08; var currentYear = DateTime.Now.Year; var dateToCompare = new DateTime(currentYear, month, day); var scheduledDt = "25/08/2018"; var scheduledDate = DateTime.ParseExact(scheduledDt, "dd/MM/yyyy", System.Globalization.CultureInfo.InvariantCulture); if(dateToCompare.Date == scheduledDate.Date) { //Your logic } STRINGNEWLINEINDENT都是您的词法分析器生成的最终值:

DEDENT

很简单,对吧?我加入了start ::= list | list NEWLINE . list ::= entry | list entry . entry ::= STRING NEWLINE | STRING NEWLINE INDENT list DEDENT . 规则,以确保任何以startNEWLINE标记结尾的文件都是有效的。如果没有它,则以DEDENT标记结尾而不是NEWLINE标记的文件将无效。

我使用了BNF,但是如果您愿意的话,也可以轻松地使用EBNF。关键是,词法分析器可以理解使用了多少缩进空间来生成STRINGINDENT令牌(如果需要,还可以生成错误),并且语法应简单地指定如何使用令牌生成。