How to say(在BNF,EBNF等中)任何两个或更多个字母都放置在相同的垂直对齐方式中

例如,在python 2.x中,我们称为indentation

def hello():
    print "hello,"
    print "world"

hello()

注意字母p(第二行)放置在与字母p(第三行)相同的垂直对齐方式中

进一步的示例( Markdown ):
MyHeader
========
topic
-----

注意 M和第一个=放置在相同的垂直对齐方式(还有r和last =,t和first -c和last -)

我的问题是。如何使用BNF,EBNF等表示字母的这些垂直对齐方式?

进一步说明:
这个问题的重点是寻找一种表示方法,以表示代码的垂直对齐方式,而不仅仅是想知道如何编写PythonMarkdown的BNF或EBNF。

最佳答案

您可以通过使用一点技巧来解析对缩进敏感的语言(例如Python或Haskell),这在Python语言引用的lexical analysis章节中有很好的描述。如前所述,词法分析器将前导空格转换为INDENTDEDENT标记[注1],然后将它们以直接的方式用于Python语法中。这是一个小摘录:

suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]
while_stmt    ::=  "while" expression ":" suite ["else" ":" suite]
因此,如果您准备描述(或引用)词法分析算法,则BNF很简单。
但是,您实际上不能将该算法编写为上下文无关文法,因为它不是上下文无关的。 (我将省略证明,但这类似于abc不是上下文无关的证明,您可以在大多数基本的正式语言教科书中以及整个Internet上找到该证明。)
ISO standard EBNF(提供免费的PDF)提供了一种包括“用户可能需要的扩展名”的方式:Special-sequence,它是不包含?的任何文本。两侧都用?包围。因此,您可以通过包含[注2]来滥用该表示法:
DEDENT = ? See section 2.1.8 of https://docs.python.org/3.3/reference/ ? ;
或者,您可以插入算法的完整描述。当然,这些技术都不会允许解析器生成器生成准确的词法分析器,但这将是一种向人类读者传达意图的合理方法。
值得注意的是,EBNF本身使用特殊的序列来定义其产品之一:
(* see 4.7 *) syntactic exception
   = ? a syntactic-factor that could be replaced
       by a syntactic-factor containing no
       meta-identifiers
     ? ;

笔记
  • 词法分析器还将一些物理换行符转换为NEWLINE token ,同时使其他换行符消失。
  • EBNF通常在生产中使用语法=而不是::=,并坚持要求它们以;终止。注释包含在(**)之间。
  • 10-06 11:20