BNF/Wiki 編集

Wiki記法のリンク機能を使ってC11の文法を記述してみた。

token
keyword
identifier
constant
string-literal
punctuator
preprocessing-token
header-name
identifier
pp-number
character-constant
string-literal
punctuator
{ each non-white-space character that cannot be one of the above }
keyword
auto
break
case
char
const
continue
default
do
double
else
enum
extern
float
for
goto
if
inlineN843
int
long
register
restrictN843
return
short
signed
sizeof
static
struct
switch
typedef
union
unsigned
void
volatile
while
_BoolN843
_ComplexN843
_ImaginaryN843
identifier
identifier-nondigit
identifier identifier-nondigit
identifier digit
identifier-nondigit
nondigit
universal-character-name
{ other implementation-defined characters }
nondigit
_
a | b | c | d | e | f | g | h | i | j | k | l | m
n | o | p | q | r | s | t | u | v | w | x | y | z
A | B | C | D | E | F | G | H | I | J | K | L | M
N | O | P | Q | R | S | T | U | V | W | X | Y | Z
digit
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
universal-character-name
\u hex-quadN843
\U hex-quad hex-quadN843
hex-quad
hexadecimal-digit hexadecimal-digit hexadecimal-digit hexadecimal-digit
constant
integer-constant
floating-constant
enumeration-constant
character-constant
integer-constant
decimal-constant integer-suffixopt
octal-constant integer-suffixopt
hexadecimal-constant integer-suffixopt
decimal-constant
nonzero-digit
decimal-constant digit
octal-constant
0
octal-constant octal-digit
hexadecimal-constant
hexadecimal-prefix hexadecimal-digit
hexadecimal-constant hexadecimal-digit
hexadecimal-prefix
0x | 0X
nonzero-digit
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
octal-digit
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
hexadecimal-digit
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
a | b | c | d | e | f
A | B | C | D | E | F
integer-suffix
unsigned-suffix long-suffixopt
unsigned-suffix long-long-suffix
long-suffix unsigned-suffixopt
long-long-suffix unsigned-suffixopt
unsigned-suffix
u | U
long-suffix
l | L
long-long-suffix
ll | LL
floating-constant
decimal-floating-constant
hexadecimal-floating-constant
decimal-floating-constant
fractional-constant exponent-partopt floating-suffixopt
digit-sequence exponent-part floating-suffixopt
hexadecimal-floating-constant
hexadecimal-prefix hexadecimal-fractional-constant binary-exponent-part floating-suffixopt
hexadecimal-prefix hexadecimal-digit-sequence binary-exponent-part floating-suffixopt
fractional-constant
digit-sequenceopt . digit-sequence
digit-sequence .
exponent-part
e signopt digit-sequence
E signopt digit-sequence
sign
+ | -
digit-sequence
digit
digit-sequence digit
hexadecimal-fractional-constant
hexadecimal-digit-sequenceopt . hexadecimal-digit-sequence
hexadecimal-digit-sequence .
binary-exponent-part
p signopt digit-sequence
P signopt digit-sequence
hexadecimal-digit-sequence
hexadecimal-digit
hexadecimal-digit-sequence hexadecimal-digit
floating-suffix
f | l | F | L
enumeration-constant
identifier
character-constant
' c-char-sequence '
L' c-char-sequence '
c-char-sequence
c-char
c-char-sequence c-char
c-char
{ any member of the source character set except the single-quote ', backslash \, or new-line character }
escape-sequence
escape-sequence
simple-escape-sequence
octal-escape-sequence
hexadecimal-escape-sequence
universal-character-name
simple-escape-sequence
\' | \" | \? | \\ | \a | \b | \f | \n | \r | \t | \v
octal-escape-sequence
\ octal-digit
\ octal-digit octal-digit
\ octal-digit octal-digit octal-digit
hexadecimal-escape-sequence
\x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit
string-literal
" s-char-sequenceopt "
L" s-char-sequenceopt "
s-char-sequence
s-char
s-char-sequence s-char
s-char
{ any member of the source character set except the double-quote ", backslash \, or new-line character }
escape-sequence
punctuator
[
]
(
)
{
}
.
->
++
--
&
*
+
-
~
!
/
%
<<
>>
<
>
<=
>=
==
!=
^
|
&&
||
?
;
...
=
*=
/=
%=
+=
-=
<<=
>>=
&=
^=
|=
,
#
##
<
:>
<%
%>
%
%:%
header-name
< h-char-sequence >
" q-char-sequence "
h-char-sequence
h-char
h-char-sequence h-char
h-char
{ any member of the source character set except the new-line character and > }
q-char-sequence
q-char
q-char-sequence q-char
q-char
{ any member of the source character set except the new-line character and " }
pp-number
digit
. digit
pp-number digit
pp-number identifier-nondigit
pp-number e sign
pp-number E sign
pp-number p sign
pp-number P sign
pp-number .
primary-expression
identifier
constant
string-literal
( expression )
postfix-expression
primary-expression
postfix-expression [ expression ]
postfix-expression ( argument-expression-listopt )
postfix-expression . identifier
postfix-expression -> identifier
postfix-expression ++
postfix-expression --
( type-name ) { initializer-list }
( type-name ) { initializer-list , }
argument-expression-list
assignment-expression
argument-expression-list , assignment-expression
unary-expression
postfix-expression
++ unary-expression
-- unary-expression
unary-operator cast-expression
sizeof unary-expression
sizeof ( type-name )
unary-operator
& | * | + | - | ~ | !
cast-expression
unary-expression
( type-name ) cast-expression
multiplicative-expression
cast-expression
multiplicative-expression * cast-expression
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression
additive-expression
multiplicative-expression
additive-expression + multiplicative-expression
additive-expression - multiplicative-expression
shift-expression
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression
relational-expression
shift-expression
relational-expression < shift-expression
relational-expression > shift-expression
relational-expression <= shift-expression
relational-expression >= shift-expression
equality-expression
relational-expression
equality-expression == relational-expression
equality-expression != relational-expression
AND-expression
equality-expression
AND-expression & equality-expression
exclusive-OR-expression
AND-expression
exclusive-OR-expression ^ AND-expression
inclusive-OR-expression
exclusive-OR-expression
inclusive-OR-expression '|' exclusive-OR-expression
logical-AND-expression
inclusive-OR-expression
logical-AND-expression && inclusive-OR-expression
logical-OR-expression
logical-AND-expression
logical-OR-expression || logical-AND-expression
conditional-expression
logical-OR-expression
logical-OR-expression ? expression : conditional-expression
assignment-expression
conditional-expression
unary-expression assignment-operator assignment-expression
assignment-operator
= | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
expression
assignment-expression
expression , assignment-expression
constant-expression
conditional-expression
declaration
declaration-specifiers init-declarator-listopt ;
declaration-specifiers
storage-class-specifier declaration-specifiersopt
type-specifier declaration-specifiersopt
type-qualifier declaration-specifiersopt
function-specifier declaration-specifiersopt
init-declarator-list
init-declarator
init-declarator-list , init-declarator
init-declarator
declarator
declarator = initializer
storage-class-specifier
typedef
extern
static
auto
register
type-specifier
void
char
short
int
long
float
double
signed
unsigned
_BoolN1124
_ComplexN1124
struct-or-union-specifier
enum-specifier
typedef-name
struct-or-union-specifier

struct-or-union identifieropt { struct-declaration-list } struct-or-union identifier

struct-or-union
struct
union
struct-declaration-list
struct-declaration
struct-declaration-list struct-declaration
struct-declaration
specifier-qualifier-list struct-declarator-list ;
specifier-qualifier-list
type-specifier specifier-qualifier-listopt
type-qualifier specifier-qualifier-listopt
struct-declarator-list
struct-declarator
struct-declarator-list , struct-declarator
struct-declarator
declarator
declaratoropt : constant-expression
enum-specifier
enum identifieropt { enumerator-list }
enum identifieropt { enumerator-list , }
enum identifier
enumerator-list
enumerator
enumerator-list , enumerator
enumerator
enumeration-constant
enumeration-constant = constant-expression
type-qualifier
const
restrictN843
volatile
function-specifier
inlineN843
declarator

pointeropt direct-declarator

direct-declarator
identifier
( declarator )
direct-declarator [ type-qualifier-listopt assignment-expressionopt ]
direct-declarator [ static type-qualifier-listopt assignment-expression ]
direct-declarator [ type-qualifier-list static assignment-expression ]
direct-declarator [ type-qualifier-listopt * ]
direct-declarator ( parameter-type-list )
direct-declarator ( identifier-listopt )
pointer
* type-qualifier-listopt
* type-qualifier-listopt pointer
type-qualifier-list
type-qualifier
type-qualifier-list type-qualifier
parameter-type-list
parameter-list
parameter-list , ...
parameter-list
parameter-declaration
parameter-list , parameter-declaration
parameter-declaration
declaration-specifiers declarator
declaration-specifiers abstract-declaratoropt
identifier-list
identifier
identifier-list , identifier
type-name
specifier-qualifier-list abstract-declaratoropt
abstract-declarator
pointer
pointeropt direct-abstract-declarator
direct-abstract-declarator
( abstract-declarator )
direct-abstract-declaratoropt [ assignment-expressionopt ]
direct-abstract-declaratoropt [ * ]
direct-abstract-declaratoropt ( parameter-type-listopt )

direct-abstract-declarator:N1124

( abstract-declarator )
direct-abstract-declaratoropt [ type-qualifier-listopt assignment-expressionopt ]
direct-abstract-declaratoropt [ static type-qualifier-listopt assignment-expression ]
direct-abstract-declaratoropt [ type-qualifier-list static assignment-expression ]
direct-abstract-declaratoropt [ * ]
direct-abstract-declaratoropt ( parameter-type-listopt )
typedef-name
identifier
initializer
assignment-expression
{ initializer-list }
{ initializer-list , }
initializer-list
designationopt initializer
initializer-list , designationopt initializer
designation
designator-list =
designator-list
designator
designator-list designator
designator
[ constant-expression ]
. identifier
statement
labeled-statement
compound-statement
expression-statement
selection-statement
iteration-statement
jump-statement
labeled-statement
identifier : statement
case constant-expression : statement
default : statement
compound-statement
{ block-item-listopt }
block-item-list
block-item
block-item-list block-item
block-item
declaration
statement
expression-statement
expressionopt ;
selection-statement
if ( expression ) statement
if ( expression ) statement else statement
switch ( expression ) statement
iteration-statement
while ( expression ) statement
do statement while ( expression ) ;
for ( expressionopt ; expressionopt ; expressionopt ) statement
for ( declaration expressionopt ; expressionopt ) statement
jump-statement
goto identifier ;
continue ;
break ;
return expressionopt ;
translation-unit
external-declaration
translation-unit external-declaration
external-declaration
function-definition
declaration
function-definition

declaration-specifiers declarator declaration-listopt compound-statement

declaration-list
declaration
declaration-list declaration
preprocessing-file
groupopt
group
group-part
group group-part
group-part
if-section
control-line
text-line
# { non-directive }
if-section
if-group elif-groupsopt else-groupopt endif-line
if-group
# if constant-expression new-line groupopt
# ifdef identifier new-line groupopt
# ifndef identifier new-line groupopt
elif-groups
elif-group
elif-groups elif-group
elif-group
# elif constant-expression new-line groupopt
else-group
# else new-line groupopt
endif-line
# endif new-line
control-line
# include pp-tokens new-line
# define identifier replacement-list new-line
# define identifier lparen identifier-listopt ) replacement-list new-line
# define identifier lparen ... ) replacement-list new-line
# define identifier lparen identifier-list , ... ) replacement-list new-line
# undef identifier new-line
# line pp-tokens new-line
# error pp-tokensopt new-line
# pragma pp-tokensopt new-line
# new-line
text-line
pp-tokensopt new-line
non-directive
pp-tokens new-line
lparen
{ a ( character not immediately preceded by white-space }
replacement-list
pp-tokensopt
pp-tokens
preprocessing-token
pp-tokens preprocessing-token
new-line
{ the new-line character }

BNF 編集

<token> ::= <keyword>
          | <identifier>
          | <constant>
          | <string-literal>
          | <punctuator>
<preprocessing-token> ::= <header-name>
                        | <identifier>
                        | <pp-number>
                        | <character-constant>
                        | <string-literal>
                        | <punctuator>
                        | {  each non-white-space character that cannot be one of the above  }
<keyword> ::= auto
            | break
            | case
            | char
            | const
            | continue
            | default
            | do
            | double
            | else
            | enum
            | extern
            | float
            | for
            | goto
            | if
            | inline
            | int
            | long
            | register
            | restrict
            | return
            | short
            | signed
            | sizeof
            | static
            | struct
            | switch
            | typedef
            | union
            | unsigned
            | void
            | volatile
            | while
            | _Bool
            | _Complex
            | _Imaginary
<identifier> ::= <identifier-nondigit>
               | <identifier> <identifier-nondigit>
               | <identifier> <digit>
<identifier-nondigit> ::= <nondigit>
                        | <universal-character-name>
                        | { other implementation-defined characters }
<nondigit> ::= _
             | a | b | c | d | e | f | g | h | i | j | k | l | m
             | n | o | p | q | r | s | t | u | v | w | x | y | z
             | A | B | C | D | E | F | G | H | I | J | K | L | M
             | N | O | P | Q | R | S | T | U | V | W | X | Y | Z
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<universal-character-name> ::= \u <hex-quad>
                             | \U <hex-quad> <hex-quad>
<hex-quad> ::= <hexadecimal-digit> <hexadecimal-digit> <hexadecimal-digit> <hexadecimal-digit>
<constant> ::= <integer-constant>
             | <floating-constant>
             | <enumeration-constant>
             | <character-constant>
<integer-constant> ::= <decimal-constant> <integer-suffix>opt
                     | <octal-constant> <integer-suffix>opt
                     | <hexadecimal-constant> <integer-suffix>opt
<decimal-constant> ::= <nonzero-digit>
                     | <decimal-constant> <digit>
<octal-constant> ::= 0
                   | <octal-constant> <octal-digit>
<hexadecimal-constant> ::= <hexadecimal-prefix> <hexadecimal-digit>
                         | <hexadecimal-constant> <hexadecimal-digit>
<hexadecimal-prefix> ::= 0x | 0X
<nonzero-digit> ::= 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
<octal-digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
<hexadecimal-digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
                      | a | b | c | d | e | f
                      | A | B | C | D | E | F
<integer-suffix> ::= <unsigned-suffix> <long-suffix>opt
                   | <unsigned-suffix> <long-long-suffix>
                   | <long-suffix> <unsigned-suffix>opt
                   | <long-long-suffix> <unsigned-suffix>opt
<unsigned-suffix> ::= u | U
<long-suffix> ::= l | L
<long-long-suffix> ::= ll | LL
<floating-constant> ::= <decimal-floating-constant>
                      | <hexadecimal-floating-constant>
<decimal-floating-constant> ::= <fractional-constant> <exponent-part>opt <floating-suffix>opt
                              | <digit-sequence> <exponent-part> <floating-suffix>opt
<hexadecimal-floating-constant> ::= <hexadecimal-prefix> <hexadecimal-fractional-constant> <binary-exponent-part> <floating-suffix>opt
                                  | <hexadecimal-prefix> <hexadecimal-digit-sequence> <binary-exponent-part> <floating-suffix>opt
<fractional-constant> ::= <digit-sequence>opt . <digit-sequence>
                        | <digit-sequence> .
<exponent-part> ::= e <sign>opt <digit-sequence>
                  | E <sign>opt <digit-sequence>
<sign> ::= + | -
<digit-sequence> ::= <digit>
                   | <digit-sequence> <digit>
<hexadecimal-fractional-constant> ::= <hexadecimal-digit-sequence>opt . <hexadecimal-digit-sequence>
                                    | <hexadecimal-digit-sequence> .
<binary-exponent-part> ::= p <sign>opt <digit-sequence>
                         | P <sign>opt <digit-sequence>
<hexadecimal-digit-sequence> ::= <hexadecimal-digit>
                               | <hexadecimal-digit-sequence> <hexadecimal-digit>
<floating-suffix> ::= f | l | F | L
<enumeration-constant> ::= <identifier>
<character-constant> ::= ' <c-char-sequence> '
                       | L' <c-char-sequence> '
<c-char-sequence> ::= <c-char>
                    | <c-char-sequence> <c-char>
<c-char> ::= { any member of the source character set except the single-quote ', backslash \, or new-line character }
           | <escape-sequence>
<escape-sequence> ::= 
<simple-escape-sequence>
<octal-escape-sequence>
<hexadecimal-escape-sequence>
<universal-character-name>
<simple-escape-sequence> ::= \' | \" | \? | \\ | \a | \b | \f | \n | \r | \t |  \v
<octal-escape-sequence> ::= \ <octal-digit>
                          | \ <octal-digit> <octal-digit>
                          | \ <octal-digit> <octal-digit> <octal-digit>
<hexadecimal-escape-sequence> ::= \x <hexadecimal-digit>
                                | <hexadecimal-escape-sequence> <hexadecimal-digit>
<string-literal> ::= " s-char-sequenceopt "
                   | L" s-char-sequenceopt "
<s-char-sequence> ::= <s-char>
                    | s-char-sequence <s-char>
<s-char> ::= { any member of the source character set except the double-quote ", backslash \, or new-line character }
           | <escape-sequence>
<punctuator> ::= [ | ] | ( | ) | { | } | . | ->
               | ++ | -- | & | * | + | - | ~ | !
               | / | % | << | >> | < | > | <= | >= | == | != | ^ | `|` | && | ||
               | ? | : | ; | ...
               | = | *= | /= | %= | += | -= | <<= | >>= | &= | ^= | |=
               | , | # | ##
               | <: | :> | <% | %> | %: | %:%> | ::= 
<header-name> ::= < <h-char-sequence> >
                | " <q-char-sequence> "
<h-char-sequence> ::= <h-char>
                    | <h-char-sequence> <h-char>
<h-char> ::= { any member of the source character set except the new-line character and > }
<q-char-sequence> ::= <q-char>
                    | <q-char-sequence> <q-char>
<q-char> ::= { any member of the source character set except the new-line character and " }
<pp-number> ::= <digit>
              | . <digit>
              | <pp-number> <digit>
              | <pp-number> <identifier-nondigit>
              | <pp-number> e <sign>
              | <pp-number> E <sign>
              | <pp-number> p <sign>
              | <pp-number> P <sign>
              | <pp-number> .
<primary-expression> ::= <identifier>
                       | <constant>
                       | <string-literal>
                       | ( <expression> )
<postfix-expression> ::= <primary-expression>
                       | <postfix-expression> [ <expression> ]
                       | <postfix-expression> ( <argument-expression-list>opt )
                       | <postfix-expression> . <identifier>
                       | <postfix-expression> -> <identifier>
                       | <postfix-expression> ++
                       | <postfix-expression> --
                       | ( <type-name> ) { <initializer-list> }
                       | ( <type-name> ) { <initializer-list> , }
<argument-expression-list> ::= <assignment-expression>
                             | <argument-expression-list> , <assignment-expression>
<unary-expression> ::= <postfix-expression>
                     | ++ <unary-expression>
                     | -- <unary-expression>
                     | <unary-operator> <cast-expression>
                     | sizeof <unary-expression>
                     | sizeof ( <type-name> )
<unary-operator> ::= & | * | + | - | ~ | !
<cast-expression> ::= <unary-expression>
                    | ( <type-name> ) <cast-expression>
<multiplicative-expression> ::= <cast-expression>
                              | <multiplicative-expression> * <cast-expression>
                              | <multiplicative-expression> / <cast-expression>
                              | <multiplicative-expression> % <cast-expression>
<additive-expression> ::= <multiplicative-expression>
                        | <additive-expression> + <multiplicative-expression>
                        | <additive-expression> - <multiplicative-expression>
<shift-expression> ::= <additive-expression>
                     | <shift-expression> << <additive-expression>
                     | <shift-expression> >> <additive-expression>
<relational-expression> ::= <shift-expression>
                          | <relational-expression> < <shift-expression>
                          | <relational-expression> > <shift-expression>
                          | <relational-expression> <= <shift-expression>
                          | <relational-expression> >= <shift-expression>
<equality-expression> ::= <relational-expression>
                        | <equality-expression> == <relational-expression>
                        | <equality-expression> != <relational-expression>
<AND-expression> ::= <equality-expression>
                   | <AND-expression> & <equality-expression>
<exclusive-OR-expression> ::= <AND-expression>
                            | <exclusive-OR-expression> ^ <AND-expression>
<inclusive-OR-expression> ::= <exclusive-OR-expression>
                            | <inclusive-OR-expression> '|' <exclusive-OR-expression>
<logical-AND-expression> ::= <inclusive-OR-expression>
                           | <logical-AND-expression> && <inclusive-OR-expression>
<logical-OR-expression> ::= <logical-AND-expression>
                          | <logical-OR-expression> || <logical-AND-expression>
<conditional-expression> ::= <logical-OR-expression>
                           | <logical-OR-expression> ? <expression> : <conditional-expression> 
<assignment-expression> ::= <conditional-expression> 
                          | <unary-expression> <assignment-operator>  <assignment-expression>
<assignment-operator> ::= = | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
<expression> ::= <assignment-expression>
               | <expression> , <assignment-expression>
<constant-expression> ::= <conditional-expression> 
<declaration> ::= <declaration-specifiers> <init-declarator-list>opt ;
<declaration-specifiers> ::= <storage-class-specifier> <declaration-specifiers>opt
                           | <type-specifier> <declaration-specifiers>opt
                           | <type-qualifier> <declaration-specifiers>opt
                           | <function-specifier> <declaration-specifiers>opt
<init-declarator-list> ::= <init-declarator>
                         | <init-declarator-list> , <init-declarator>
<init-declarator> ::= <declarator>
                    | <declarator> = <initializer>
<storage-class-specifier> ::= typedef
                            | extern
                            | static
                            | auto
                            | register
<type-specifier> ::= void
                   | char
                   | short
                   | int
                   | long
                   | float
                   | double
                   | signed
                   | unsigned
                   | _Bool
                   | _Complex
                   | <struct-or-union-specifier> *
                   | <enum-specifier>
                   | <typedef-name>
<struct-or-union-specifier> ::= 
<struct-or-union> <identifier>opt { <struct-declaration-list> }
<struct-or-union> <identifier>
<struct-or-union> ::= struct
                    | union
<struct-declaration-list> ::= <struct-declaration>
                            | <struct-declaration-list> <struct-declaration>
<struct-declaration> ::= <specifier-qualifier-list> <struct-declarator-list> ;
<specifier-qualifier-list> ::= <type-specifier> <specifier-qualifier-list>opt
                             | <type-qualifier> <specifier-qualifier-list>opt
<struct-declarator-list> ::= <struct-declarator>
                           | <struct-declarator-list> , <struct-declarator>
<struct-declarator> ::= <declarator>
                      | <declarator>opt : <constant-expression>
<enum-specifier> ::= enum <identifier>opt { <enumerator-list> }
                   | enum <identifier>opt { <enumerator-list> , }
                   | enum <identifier>
<enumerator-list> ::= <enumerator>
                    | <enumerator-list> , <enumerator>
<enumerator> ::= <enumeration-constant>
               | <enumeration-constant> = <constant-expression>
<type-qualifier> ::= const
                   | restrict
                   | volatile
<function-specifier> ::= inline
<declarator> ::= 
<pointer>opt <direct-declarator>
<direct-declarator> ::= <identifier>
                      | ( <declarator> )
                      | <direct-declarator> [ <type-qualifier-list>opt <assignment-expression>opt ]
                      | <direct-declarator> [ static <type-qualifier-list>opt <assignment-expression> ]
                      | <direct-declarator> [ <type-qualifier-list> static <assignment-expression> ]
                      | <direct-declarator> [ <type-qualifier-list>opt * ]
                      | <direct-declarator> ( <parameter-type-list> )
                      | <direct-declarator> ( <identifier-list>opt )
<pointer> ::= * <type-qualifier-list>opt
            | * <type-qualifier-list>opt <pointer>
<type-qualifier-list> ::= <type-qualifier>
                        | <type-qualifier-list> <type-qualifier>
<parameter-type-list> ::= <parameter-list>
                        | <parameter-list> , ...
<parameter-list> ::= <parameter-declaration>
                   | <parameter-list> , <parameter-declaration>
<parameter-declaration> ::= <declaration-specifiers> <declarator>
                          | <declaration-specifiers> <abstract-declarator>opt
<identifier-list> ::= <identifier>
                    | <identifier-list> , <identifier>
<type-name> ::= <specifier-qualifier-list> <abstract-declarator>opt
<abstract-declarator> ::= <pointer>
                        | <pointer>opt <direct-abstract-declarator>
<direct-abstract-declarator> ::= ( <abstract-declarator> )
                               | <direct-abstract-declarator>opt [ <assignment-expression>opt ]
                               | <direct-abstract-declarator>opt [ * ]
                               | <direct-abstract-declarator>opt ( <parameter-type-list>opt )
<typedef-name> ::= <identifier>
<initializer> ::= <assignment-expression>
                | { <initializer-list> }
                | { <initializer-list> , }
<initializer-list> ::= <designation>opt <initializer>
                     | <initializer-list> , <designation>opt <initializer>
<designation> ::= <designator-list> =
<designator-list> ::= <designator>
                    | <designator-list> <designator>
<designator> ::= [ <constant-expression> ]
               | . <identifier>
<statement> ::= <labeled-statement>
              | <compound-statement>
              | <expression-statement>
              | <selection-statement>
              | <iteration-statement>
              | <jump-statement>
<labeled-statement> ::= <identifier> : <statement>
                      | case <constant-expression> : <statement>
                      | default : <statement>
<compound-statement> ::= { <block-item-list>opt }
<block-item-list> ::= <block-item>
                    | <block-item-list> <block-item>
<block-item> ::= <declaration>
               | <statement>
<expression-statement> ::= <expression>opt ;
<selection-statement> ::= if ( <expression> ) <statement>
                        | if ( <expression> ) <statement> else <statement>
                        | switch ( <expression> ) <statement>
<iteration-statement> ::= 
                        | while ( <expression> ) <statement>
                        | do <statement> while ( <expression> ) ;
                        | for ( <expression>opt ; <expression>opt ; <expression>opt ) <statement>
                        | for ( <declaration> <expression>opt ; <expression>opt ) <statement>
<jump-statement> ::= goto <identifier> ;
                   | continue ;
                   | break ;
                   | return <expression>opt ;
<translation-unit> ::= <external-declaration>
                     | <translation-unit> <external-declaration>
<external-declaration> ::= <function-definition>
                         | <declaration>
<function-definition> ::= 
<declaration-specifiers> <declarator> <declaration-list>opt <compound-statement>
<declaration-list> ::= <declaration>
                     | <declaration-list> <declaration>
<preprocessing-file> ::= <group>opt
<group> ::= <group-part>
          | <group> <group-part>
<group-part> ::= <if-section>
               | <control-line>
               | <text-line>
               | # { non-directive }
<if-section> ::= <if-group> <elif-groups>opt <else-group>opt <endif-line>
<if-group> ::= # if <constant-expression> <new-line> <group>opt
             | # ifdef <identifier> <new-line> <group>opt
             | # ifndef <identifier> <new-line> <group>opt
<elif-groups> ::= <elif-group>
                | <elif-groups> <elif-group>
<elif-group> ::= # elif <constant-expression> <new-line> <group>opt
<else-group> ::= # else <new-line> <group>opt
<endif-line> ::= # endif <new-line>
<control-line> ::= # include <pp-tokens> <new-line>
                 | # define <identifier> <replacement-list> <new-line>
                 | # define <identifier> <lparen> <identifier-list>opt ) <replacement-list> <new-line>
                 | # define <identifier> <lparen> ... ) <replacement-list> <new-line>
                 | # define <identifier> <lparen> <identifier-list> , ... ) <replacement-list> <new-line>
                 | # undef <identifier> <new-line>
                 | # line <pp-tokens> <new-line>
                 | # error <pp-tokens>opt <new-line>
                 | # pragma <pp-tokens>opt <new-line>
                 | # <new-line>
<text-line> ::= <pp-tokens>opt <new-line>
<non-directive> ::= <pp-tokens> <new-line>
<lparen> ::= { a ( character not immediately preceded by white-space }
<replacement-list> ::= <pp-tokens>opt
<pp-tokens> ::= <preprocessing-token>
<pp-tokens> <preprocessing-token>
<new-line> ::= { the new-line character }