如何将高级 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
可以吗?
在此先感谢您的帮助。
一般情况是每个 {
...}
将创建两个新规则(称为 n1
和 n2
)并由第二个替换一:
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)比替换规则更好(更清晰)并且具有更复杂的规则。
我正在自学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
可以吗?
在此先感谢您的帮助。
一般情况是每个 {
...}
将创建两个新规则(称为 n1
和 n2
)并由第二个替换一:
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)比替换规则更好(更清晰)并且具有更复杂的规则。