语句序列的 BNF 语法
如果我正在为具有一系列语句的类 C 语言创建语法,那么定义语法的最标准方法是什么?
我的想法是做这样的事情:
<program> ::= <statement>
<statement> ::= <statement-head><statement-tail>
<statement-head> ::= <if-statement> | <var-declaration> | <assignment> | <whatever>
<statement-tail> ::= ; | ;<statement>
但这对我来说有点笨拙。我也考虑过制作
<program> ::= <statement>*
或
<statement> ::= <statement-head> ; | <sequence>
<sequence> ::= <statement> <statement>
打字制作。
是否有标准或可接受的方法来做到这一点。我希望我的 AST 尽可能干净。
If I am making a grammar for a c-like language that has a sequence of statements, what is the most standard way for defining the grammar?
My thought is to do something like this:
<program> ::= <statement>
<statement> ::= <statement-head><statement-tail>
<statement-head> ::= <if-statement> | <var-declaration> | <assignment> | <whatever>
<statement-tail> ::= ; | ;<statement>
but that feels a little clunky to me. I've also considered making
<program> ::= <statement>*
or
<statement> ::= <statement-head> ; | <sequence>
<sequence> ::= <statement> <statement>
type productions.
Is there a standard or accepted way to do this. I want my AST to be as clean as possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一种非常常见的方法是:
<块语句> ::= '{' <语句列表>; '}';
<语句列表> ::= /* 空 */ | <语句列表> <声明> ;
<声明> ::= <随便>; ';' ;
然后定义实际的语句,而不是键入
。将尾随分号作为单个语句的一部分包含在内,而不是将它们放在非终结符列表的定义中,似乎更干净。A very common way would be:
<block-statement> ::= '{' <statement-list> '}' ;
<statement-list> ::= /* empty */ | <statement-list> <statement> ;
<statement> ::= <whatever> ';' ;
And then you define actual statements instead of typing
<whatever>
. It seems much cleaner to include trailing semicolons as part of individual statements rather than putting them in the definition for the list non-terminal.您可以在此处找到 C 的 BNF,我认为它取自 K&R,你可以查看一下。您还可以查看SQL BNF here,它可能会提供更多信息制定良好的序列。
这将提供一些约定信息。
就 AST 生成而言,只要您的定义能够正确解析所有排列的源代码,那么您的定义有多“笨重”并不重要。然后只需添加操作即可构建 AST。
只需确保您正在为正确的解析器生成器(例如 LL 或 LR 解析器)构建语法,因为您可能会遇到缩减问题,这意味着某些规则需要以新的方式重写。请参阅消除左递归。
您可能还想查看 Bison/Yacc 示例,例如 这些 或 这些。另请查看 Dragon Book 和一本名为“C 中的现代编译器实现”的书
You can find the BNF for C here and I think it was taken from K&R, which you could check out. You could also check out the SQL BNF here which may provide more information on formulating good sequences.
This will provide some convention information.
In terms of AST generation, it really doesn't matter how 'clunky' your definition is providing it parses the source correctly for all permutations. Then just add the actions to build your AST.
Just make sure you are constructing your grammer for the right parser generator such as an LL or LR parser as you may run into problems with reduction, which will mean some rules need rewriting in a new way. See this on eliminating left recursion.
You may also want to check out Bison/Yacc examples such as these or these. Also check out the Dragon Book and a book called "Modern Compiler Implementation in C"