.Dt CDECL99 \&1 "Cdecl99 User's Manual"
.Sh NAME
.Nm cdecl99
-.Nd Make sense of C declaratiosns
+.Nd Make sense of C declarations
.Sh SYNOPSIS
.Nm
.Op Fl q
Translates a given C declaration or type name into something resembling
English.
.It simplify Ar declaration
-Simplifies a given C decalaration or type name by eliminating redundant
+Simplifies a given C declaration or type name by eliminating redundant
components.
.It declare Ar identifier No as Ar english-decl
Translates an English declaration into C code.
and is described by the following context-free grammar. This grammar is for
illustrative purposes only: it is ambiguous and doesn't capture all the nuances
of the C language. In this grammar, nonterminals are represented
-.Va thusly ,
+.Va [ thusly ] ,
\[*e] represents the empty string, and both
.Li |
and successive \[->] under the same nonterminal indicate alternation. All
other symbols are terminals. The nonterminals
-.Va identifier , type-specifier , type-qualifier , storage-class-specifier
+.Va [ identifier ] , [ type-specifier ] ,
+.Va [ type-qualifier ] , [ storage-class-specifier ]
and
-.Va function-specifier
+.Va [ function-specifier ]
are defined as in C.
.Bl -column -offset indent ".Va english-decl" ""
-.It Va english Ta \[->] Ta Li declare Va identifier Li as Va english-decl
-.It Ta \[->] Ta Li type Va english-decl
-.It Va english-decl Ta \[->] Ta Va sf-specs declarator
-.It Va declarator Ta \[->] Ta Va qualifiers Li pointer to Va declarator
-.It Ta \[->] Ta Li array Va size Li of Va declarator
-.It Ta \[->] Ta Li function Va parameters Li returning Va declarator
-.It Ta \[->] Ta Va tq-specs
-.It Va qualifiers Ta \[->] Ta Va type-qualifier qualifiers | No \[*e]
-.It Va tq-specs Ta \[->] Ta Va type-qualifier tq-specs
-.It Ta \[->] Ta Va type-specifier tq-specs
+.It Va english Ta \[->] Ta Li declare Va [ identifier ] Li as Va [ english-decl ]
+.It Ta \[->] Ta Li type Va [ english-decl ]
+.It Va english-decl Ta \[->] Ta Va [ sf-specs ] [ declarator ]
+.It Va declarator Ta \[->] Ta Va [ qualifiers ] Li pointer to Va [ declarator ]
+.It Ta \[->] Ta Li array Va [ size ] Li of Va [ declarator ]
+.It Ta \[->] Ta Li function Va [ parameters ] Li returning Va [ declarator ]
+.It Ta \[->] Ta Va [ tq-specs ]
+.It Va qualifiers Ta \[->] Ta Va [ type-qualifier ] [ qualifiers ] | No \[*e]
+.It Va tq-specs Ta \[->] Ta Va [ type-qualifier ] [ tq-specs ]
+.It Ta \[->] Ta Va [ type-specifier ] [ tq-specs ]
.It Ta \[->] Ta \[*e]
-.It Va sf-specs Ta \[->] Ta Va storage-class-specifier sf-specs
-.It Ta \[->] Ta Va function-specifier sf-specs
+.It Va sf-specs Ta \[->] Ta Va [ storage-class-specifier ] [ sf-specs ]
+.It Ta \[->] Ta Va [ function-specifier ] [ sf-specs ]
.It Ta \[->] Ta \[*e]
-.It Va size Ta \[->] Ta Va integer | Va identifier | Li * | No \[*e]
-.It Va parameters Ta \[->] Ta Po Va param-list Pc
-.It Ta \[->] Ta Po Va param-list Li , ... Pc
+.It Va size Ta \[->] Ta Va [ integer ] | Va [ identifier ] | Li * | No \[*e]
+.It Va parameters Ta \[->] Ta Po Va [ param-list ] Pc
+.It Ta \[->] Ta Po Va [ param-list ] Li , ... Pc
.It Ta \[->] Ta \[*e]
-.It Va param-list Ta \[->] Ta Va parameter | Va parameter Li , Va param-list
-.It Va parameter Ta \[->] Ta Va identifier Li as Va english-decl
-.It Ta \[->] Ta Va english-decl
+.It Va param-list Ta \[->] Ta Va [ parameter ] | Va [ parameter ] Li , Va [ param-list ]
+.It Va parameter Ta \[->] Ta Va [ identifier ] Li as Va [ english-decl ]
+.It Ta \[->] Ta Va [ english-decl ]
.El
.Sh RESOLVING AMBIGUITIES
The C context-free grammar has many ambiguities regarding declarations.
.Nm
will choose the alternative with the simplest explanation. Thus, f is
interpreted as a function which takes an int and returns an int.
+.Sh EXAMPLES
+.Bl -tag -width Output:
+.It Input:
+.Li explain int x;
+.It Output:
+.Li declare x as int
+.It Input:
+.Li explain static int* x, y;
+.It Output:
+.Li declare x as static pointer to int
+.sp 0
+.Li declare y as static int
+.It Input:
+.Li explain extern int printf(const char *fmt, ...);
+.It Output:
+.Li declare printf as extern function (fmt as pointer to const char, ...) returning int
+.It Input:
+.Li explain size_t volatile * const (* restrict)[1][2][3]
+.It Output:
+.Li type restrict pointer to array 1 of array 2 of array 3 of const pointer to volatile int
+.It Input:
+.Li declare x as int
+.It Output:
+.Li int x
+.It Input:
+.Li type function (pointer to const char) returning size_t
+.It Output:
+.Li size_t (const char *)
+.It Input:
+.Li declare f as inline function (g as pointer to array 6 of pointer to const char) returning pointer to function (int, ...) returning int
+.It Output:
+.Li inline int (*f(const char *(*g)[6]))(int, ...)
+.It Input:
+.Li simplify const int const ((*restrict x))
+.It Output:
+.Li const int * restrict x
+.El
.Sh AUTHORS
Nick Bowler <nbowler@draconx.ca>
.Sh COPYRIGHT