| letter | ::= | a | b | ... | z | A | B | ... | Z |
| digit | ::= | 0 | 1 | ... | 9 |
| id | ::= | letter { letter | digit | _ } |
| intcon | ::= | digit { digit } |
| charcon | ::= | 'ch'
| '\n'
| '\0',
where ch denotes any printable ASCII character
(as specified by isprint()) other than \
(backslash) and ' (single quote). |
| stringcon | ::= | "{ ch }", where ch denotes any printable ASCII character (as specified by isprint()) other than " (double quotes) and newline. |
| Comments | Comments are as in C, i.e. a sequence of characters preceded by /* and followed by */, and not containing any occurrence of */. | |
| prog | : | { dcl `;' | func } |
| dcl | : | type var_decl { `,' var_decl } |
| | | [ extern ] [ type | void ] id `(' parm_types `)' { `,' id `(' parm_types `)' } | |
| var_decl | : | id [ `[' intcon `]' ] |
| type | : | char |
| | | int | |
| parm_types | : | void |
| | | type id [ `[' `]' ] { `,' type id [ `[' `]' ] } | |
| func | : | [ type | void ] id `(' parm_types `)' `{' { type var_decl { `,' var_decl } `;' } { stmt } `}' |
| stmt | : | if `(' expr `)' stmt [ else stmt ] |
| | | while `(' expr `)' stmt | |
| | | for `(' [ assg ] `;' [ expr ] `;' [ assg ] `)' stmt | |
| | | return [ expr ] `;' | |
| | | assg `;' | |
| | | id `(' [expr { `,' expr } ] `)' `;' | |
| | | `{' { stmt } `}' | |
| | | `;' | |
| assg | : | id [ `[' expr `]' ] = expr |
| expr | : | '-' expr |
| | | '!' expr | |
| | | expr binop expr | |
| | | expr relop expr | |
| | | expr logical_op expr | |
| | | id [ `(' [expr { `,' expr } ] `)' | `[' expr `]' ] | |
| | | `(' expr `)' | |
| | | intcon | |
| | | charcon | |
| | | stringcon | |
| binop | : | + |
| | | - | |
| | | * | |
| | | / | |
| relop | : | == |
| | | != | |
| | | <= | |
| | | < | |
| | | >= | |
| | | > | |
| logical_op | : | && |
| | | || | |
| Operator | Associativity |
| !, - (unary) | right to left |
| *, / | left to right |
| +, - (binary) | left to right |
| <, <=, >, >= | left to right |
| ==, != | left to right |
| && | left to right |
| || | left to right |
Values of type char are considered to be signed quantities, and widening a char to an int requires sign extension.
NUL character '\0'.
The result of indexing into an array with an out-of-range index is left unspecified.
A value of type int is converted (truncated) to an 8-bit quantity, by discarding the top 24 bits, before it is assigned to an object of type char.
An object of type char is converted (sign extended) to a 32-bit quantity before it is passed as an actual parameter to a function.
Since a function that has a formal parameter of type char will, in any case, be passed a 32-bit quantity as an actual, it must convert (truncate) the actual to an 8-bit quantity before using it.