Definitions of a small C language for educational or hobbyist implementation
By Egdares Futch H. ยท Originally published June 8, 2017 on Medium after being moved from the original site at UNITEC.
The Small-C language definition presented here is a subset of the K&R second edition version of the C language, specifically designed for use in an undergraduate compiler design course.
Since this language definition is to be used as a teaching tool, it contains omissions, bugs and errors that are to be discovered by the implementer (the student), in order to develop the skills to implement a high-level language compiler.
As an example, some of the changes that could (or should) be made to the grammar are:
A sequence of digits denoting an integer number in the range -32768..32767. This should be stored in a twos-complement representation, or as appropiate for the underlying architecture. Could be expanded to support 32- or 64-bit integers.
A sequence of letters, digits and underscores that may only be initiated with underscores or letters, no longer than 16 characters.
break continue else if int return while readint writeint
+ - * / % ! ? : = , < > ( ) { } || && ==
Comments should start with /* and end with */, and can contain any legal character including newline. Comments should not be nested, nor go past the end of a source file.
Two adjacent terminal symbols should be separated by one or more comments, spaces or newlines, unless one of the other symbols is a special character. Comments, spaces and newlines have no syntactic value.
To avoid the need to implement a runtime library for I/O, I have included two reserved keywords for creating integer read and write functions, that can be generated directly from the object code module.
This is the Small-C syntax, described in EBNF:
smallc_program ::= type_specifier id '(' param_decl_list ')' compound_stmt
type_specifier ::= int | char
param_decl_list ::= param_decl ( ',' param_decl )*
param_decl ::= type_specifier id
compound_stmt ::= '{' ( var_decl* stmt* )? '}'
var_decl ::= type_specifier var_decl_list ';'
var_decl_list ::= variable_id ( ',' variable_id )*
variable_id ::= id ( '=' expr )?
stmt ::= compound_stmt | cond_stmt | while_stmt
| break ';' | continue ';' | return expr ';'
| readint '(' id ')' ';'
| writeint '(' expr ')' ';'
cond_stmt ::= if '(' expr ')' stmt ( else stmt )?
while_stmt ::= while '(' expr ')' stmt
expr ::= id '=' expr | condition
condition ::= disjunction | disjunction '?' expr ':' condition
disjunction ::= conjunction | disjunction '||' conjunction
conjunction ::= comparison | conjunction '&&' comparison
comparison ::= relation | relation '==' relation
relation ::= sum | sum ( '<' | '>' ) sum
sum ::= sum '+' term | sum '-' term | term
term ::= term '*' factor | term '/' factor | term '%' factor | factor
factor ::= '!' factor | '-' factor | primary
primary ::= num | charconst | id | '(' expr ')'
Note: A previous version of this work was published in http://maestros.unitec.edu/~efutch/small-c__english_version_.html but updated here for better editing and publishing capabilities.