标签:
前两天发了那篇关于C语言复杂声明的解析之后。在评论中就有人提醒,如果把C语言声明的BNF写出来会更加清晰。
好吧。我承认,在看到这条评论之前,我并不知道什么是BNF。。百度之后,再此也分享给大家,确实非常好用。
BNF_百度百科
简单的来说BNF是一种能用递归来描述一种编程语言的方式,BNF的描述要比任何自然语言的描述更精确和简单,让我难以置信的是,一般描述一个语言BNF甚至只需要1 200行就可以了。。。
既然要描述C语言的声明,自然要知道C语言的准确定义了,为了简单,我选择的是C89标准的资料ISO_IEC_9899_1990,这个网上资料不多,完整的也就只有一个影印版本的pdf文档了.文档中对于C语言的描述大概是下面这样:
可以看出资料中对于C语言的描述也是按照BNF的方式来描述的。再根据网上的资料整理出以下C语言声明的BNF描述。顺带说一句,以前从未仔细想过C语言(初开预编译部分)居然只包含两个部分:函数定义和声明。。。
终结符为:
int_const (整型常量)
char_const (字符常量)
float_const (浮点数常量)
id (标识符)
string (字符串常量)
enumeration_const(枚举常量)
“”中的字符
decl ::= <decl_specs> <init_declarator_list> “;”
| <decl_specs> “;”
decl_list ::= <decl>
| <decl_list> <decl>
decl_specs ::= <storage_class_spec> <decl_specs>
| <storage_class_spec>
| <type_spec> <decl_specs>
| <type_spec>
| <type_qualifier> <decl_specs>
| <type_qualifier>
storage_class_spec ::= “auto” | “register” | “static” | “extern”
| “typedef”
type_spec ::= “void” | “char” | “short” | “int” | “long”
| “float”
| “double” | “signed” | “unsigned”
| <struct_or_union_spec>
| <enum_spec>
| <typedef_name>
type_qualifier ::= ’const’ | ’volatile’
struct_or_union_spec ::= <struct_or_union> <id> “{““}”
| <struct_or_union> “{““}”
| <struct_or_union> id
struct_or_union ::= “struct” | “union”
struct_decl_list ::= <struct_decl>
| <struct_decl_list> <struct_decl>
init_declarator_list ::= <init_declarator>
| <init_declarator_list> “,” <init_declarator>
init_declarator : <declarator>
| <declarator> “=” <initializer>
struct_decl : spec_qualifier_list struct_declarator_list’;’
spec_qualifier_list ::= <type_spec> <spec_qualifier_list>
| <type_spec>
| <type_qualifier> <spec_qualifier_list>
| <type_qualifier>
struct_declarator_list ::= <struct_declarator>
| <struct_declarator_list> “,” <struct_declarator>
struct_declarator ::= <declarator>
| <declarator> “:” <const_exp>
| “:” <const_exp>
enum_spec ::= “enum” id “{““}”
| “enum” “{““}”
| “enum” id
enumerator_list ::= <enumerator>
| <enumerator_list> “,” <enumerator>
enumerator ::= id
| id “=” <const_exp>
declarator ::= <pointer> <direct_declarator>
| <direct_declarator>
direct_declarator ::= id
| “(“ <declarator> “)”
| <direct_declarator> “[“ <const_exp> “]”
| <direct_declarator> “[“”]”
| <direct_declarator> “(“ <param_type_list> “)”
| <direct_declarator> “(“ <id_list> “)”
| <direct_declarator> “(“”)”
pointer ::= “*” <type_qualifier_list>
| “*”
| “*” <type_qualifier_list> <pointer>
| “*” <pointer>
type_qualifier_list ::= <type_qualifier>
| <type_qualifier_list> <type_qualifier>
param_type_list ::= <param_list>
| <param_list> “,” “...”
param_list ::= <param_decl>
| <param_list> “,” <param_decl>
param_decl ::= <decl_specs> <declarator>
| <decl_specs> <abstract_declarator>
| <decl_specs>
id_list ::= id
| <id_list> “,” id
initializer ::= <assignment_exp>
| “{““}”
| “{““,” “}”
initializer_list ::= <initializer>
| <initializer_list> “,” <initializer>
type_name ::= <spec_qualifier_list> <abstract_declarator>
| <spec_qualifier_list>
abstract_declarator ::= <pointer>
| <pointer> <direct_abstract_declarator>
| <direct_abstract_declarator>
direct_abstract_declarator::=
“(“ <abstract_declarator> “)”
| <direct_abstract_declarator> “[“ <const_exp> “]”
| “[“ <const_exp> “]”
| <direct_abstract_declarator> “[“”]”
| “[““]”
| <direct_abstract_declarator> “(“
<param_type_list> “)”
| “(“ <param_type_list> “)”
| <direct_abstract_declarator> “(“”)”
| “(“”)”
typedef_name ::= id
exp ::= <assignment_exp>
| <exp> “,” <assignment_exp>
assignment_exp ::= <conditional_exp>
| <unary_exp> <assignment_operator> <assignment_exp>
assignment_operator ::= “=” | “*=” | “/=” | “%=” | “+=” | “-=” | “<<=”
| “>>=” | “&=” | “^=” | “|=”
conditional_exp ::= <logical_or_exp>
| <logical_or_exp> “?” <exp> “:” <conditional_exp>
const_exp ::= <conditional_exp>
logical_or_exp ::= <logical_and_exp>
| <logical_or_exp> “||” <logical_and_exp>
logical_and_exp ::= <inclusive_or_exp>
| <logical_and_exp> “&&” <inclusive_or_exp>
inclusive_or_exp ::= <exclusive_or_exp>
| <inclusive_or_exp> “|” <exclusive_or_exp>
exclusive_or_exp ::= <and_exp>
| <exclusive_or_exp> “^” <and_exp>
and_exp ::= <equality_exp>
| <and_exp> “&” <equality_exp>
equality_exp ::= <relational_exp>
| <equality_exp> ’==’ <relational_exp>
| <equality_exp> ’!=’ <relational_exp>
relational_exp ::= <shift_expression>
| <relational_exp> “<”
| <relational_exp> “>” <shift_expression>
| <relational_exp> “<=”
| <relational_exp> “>=” <shift_expression>
shift_expression ::= <additive_exp>
| <shift_expression> “<<”
| <shift_expression> “>>” <additive_exp>
additive_exp ::= <mult_exp>
| <additive_exp> “+” <mult_exp>
| <additive_exp> “-“ <mult_exp>
mult_exp ::= <cast_exp>
| <mult_exp> “*” <cast_exp>
| <mult_exp> “/” <cast_exp>
| <mult_exp> “%” <cast_exp>
cast_exp ::= <unary_exp>
| “(“ <type_name> “)” <cast_exp>
unary_exp ::= <postfix_exp>
| “++” <unary_exp>
| “--" <unary_exp>
| <unary_operator> <cast_exp>
| “sizeof” <unary_exp>
| “sizeof” “(“ <type_name> “)”
unary_operator ::= “&” | “*” | “+” | “-“ | “~” | “!”
postfix_exp ::= <primary_exp>
| <postfix_exp> “[“ <exp> “]”
| <postfix_exp> “(“ <argument_exp_list> “)”
| <postfix_exp> “(“ “)”
| <postfix_exp> “.” id
| <postfix_exp> “->” id
| <postfix_exp> “++”
| <postfix_exp> “—-"
primary_exp ::= id
| const
| string
| “(“ <exp> “)”
argument_exp_list ::= <assignment_exp>
| <argument_exp_list> “,” <assignment_exp>
const ::= int_const
| char_const
| float_const
| enumeration_const
来源:闲扯创客
标签: