如何将高级 EBNF 构造(使用大括号)转换为 BNF(与 Bison 一起使用)

How to convert advanced EBNF construction (using braces) to BNF (to be used with Bison)

我正在自学Flex/Bison,我正在用VHDL93做一些实验。我对一些使用大括号的语法 "productions"(如标准中所称)有问题。

我理解标准中给出的这个例子的含义和转换方法:

term ::= factor { multiplying_operator factor }
term ::= factor | term multiplying_operator factor

但是:

choices ::= choice { | choice }

我不知道如何转换这个

block_configuration ::=
     for block_specification
          { use_clause }
          { configuration_item }
     end for ;

我在 Whosebug 中阅读了很多问题并搜索了一些 EBNF 教程,但我没有看到任何关于这种构造的信息。

终于明白了这种构造:

configuration_declarative_part ::=
     { configuration_declarative_item }

译为:

configuration_declarative_part ::= |
     configuration_declarative_part configuration_declarative_item

可以吗?

在此先感谢您的帮助。

一般情况是每个 {...} 将创建两个新规则(称为 n1n2)并由第二个替换一:

n1:  ...whatever was in the braces...
n2: /* empty */ | n2 n1 ;

所以对于 choices ::= choice { | choice },变成:

n1 ::= /*empty*/ | choice
n2 ::= /*empty*/ | n2 n1
choices ::= choice n2

然后重构它以消除歧义并根据需要对其进行简化。上面减少到等效:

choices ::= choice | choices choice

让我看看我是否理解:

choices ::= choice { | choice }

n1 ::= %empty | choice
n2 ::= %empty | n2 n1

choices ::= choice n2
        ::= choice ( %empty | n2 n1 )
        ::= choice | choice n2 n1
        ::= choice | choices n1
        ::= choice | choices ( %empty | choice )
        ::= choice | choices | choices choice

但是 choices ::= choices 是微不足道的,所以:

choices ::= choice | choices choice

configuration_declarative_part ::= { configuration_declarative_item }

n1 ::= configuration_declarative_item
n2 ::= %empty | n2 n1

configuration_declarative_part ::= n2
                               ::= %empty | n2 n1
                               ::= %empty | configuration_declarative_part n1
                               ::= %empty | configuration_declarative_part configuration_declarative_item

block_configuration ::= for block_specification { use_clause } { configuration_item } end for ;

n1 ::= use_clause
n2 ::= %empty | n2 n1

n3 ::= configuration_item
n4 ::= %empty | n4 n3

block_configuration ::= for block_specification n2 n4 end for ;
                    ::= for block_specification (%empty | n2 n1) (%empty | n4 n3) end for ;
                    ::= for block_specification end for ; |
                        for block_specification n2 n1 end for ; |
                        for block_specification n4 n3 end for ; |
                        for block_specification n2 n1 n4 n3 end for ;

现在怎么办?或者更好:

block_configuration ::= for block_specification n2 n4 end for ;

有:

n2 ::= %empty | n2 use_clause
n4 ::= %empty | n4 configuration_item

这似乎是个好规则:-D 谢谢


更新:我得出的结论是添加新规则(基于 http://lampwww.epfl.ch/teaching/archive/compilation-ssc/2000/part4/parsing/node3.html)比替换规则更好(更清晰)并且具有更复杂的规则。