Home
  Contact
  Short Vita
  Research
  Teaching
  LSDIS Lab
  Links

µ-C: Micro-C Language Definition

Lexical conventions

Micro-C is case sensitive, i.e. corresponding upper- and lower-case letters are treated as different characters.

Comments and ignored characters

A comment is a sequence of characters enclosed within a pair of matching /* ... */. Comments can extend over several lines, but nested comments are not recognized, i.e. the first pair */ within a comment closes it. Comments are ignored.

Other ignored characters include the newline, horizontal tab, CR, and white space.

Tokens

Sequences of characters enclosed within two single quotes (') are terminals. Any other sequence of characters denotes the name of a lexical class, e.g. letter (see below).

In later sections we will use the following lexical definitions:

  • letter = '_' | 'a' | 'b' | ... | 'z' | 'A' | 'B' | ... | 'Z'
  • digit = '0' | '1' | ... | '9'

Note that the undesrscore character (_) is treated as a letter.

Identifiers

An identifier is a finite sequence of letters and digits which begins with a letter. Identifiers may be of any length, however, identifiers with no difference in their corresponding first 31 characters are considered the same.

  • identifier = ( letter ) ( letter | digit )* .

Numeric constants

An integer constant is a sequence of digits (must not begin with a 0, unless it is the number 0).

  • integer_constant = digit+

A floating constant is defined as follows:

  • floating_point = integer_constant '.' integer_constant

An integer_constant following the period (when used as part of a floating point constant) may begin with a 0.

A numeric constant must be separated from an identifier or keyword.

String constants

A string constant is a sequence of characters enclosed within two double quotes ("). A string constant may include the sequence \" which represents a double quote character in the string in which it occurs and does not terminate the string. The sequence \n represents the NEWLINE character, while the sequence \\ represents the backslash character and may be included in a string as well. A sequecne composed of the backslash followed by any char other than 'n', '\', or '"' is illegal. As a consequence, a string constant may not extend beyond the end of the line. A pair of matching pairs /* ... */ within a string constant is not treated as a comment.

Operators

  • add_op = '+' | '-'
  • mul_op = '*' | '/'
  • eq_op = '==' | '!='
  • rel_op = '<' | '<=' | '>=' | '>'

Additionally, the '&' (address-of) operator is used with arguments to scanf (see below).

Other tokens

Other tokens appearing in the grammar below are enclosed within double quotes. Reserved words are additionally boldfaced. Tokens which were defined above are printed in boldface only. .

Micro-C Grammar

translation_unit->external-declaration |
translation_unit external-declaration
external-declaration ->function-definition |
declaration
function_definition-> function_def_header function_body
function_def_header-> return_type identifier "(" parameters _def ")"
return_type ->type | "void"
parameters_def-> parameter_def_list | "void"
parameter_def_list->type identifier |
parameter_def_list "," type identifier
function_body ->"{" declarations statement_list "}"
declarations ->declarations declaration | Ø
declaration-> variable_declaration |
function_declaration
variable_declaration->type identifier_list ";"
function_declaration-> return_type identifier "(" parameters _decl ")" ";"
parameters_decl->parameter_decl_list | parameter_decl_list "," "..." | "void"
parameter_decl_list->parameter_decl_spec |
parameter_decl_list "," parameter_decl_spec
parameter_decl_spec ->type identifier | "char" "*" identifier
statement_list->statement_list statement | statement
statement->expression ";" |
"return" ";" |
"return" expression ";" |
"while" "(" expression ")" statement |
"if" "(" expression ")" statement |
"if" "(" expression ")" statement "else"statement |
"{" statement_list "}"
expression->equality_expression "=" equality_expression |
equality_expression
equality_expression ->relational_expression eq_op relational_expression |
relational_expression
relational_expression->simple_expression rel_op simple_expression |
simple_expression
simple_expression ->simple_expression add_op term |
term
term->term mul_op factor | factor
factor->constant | identifier | "(" expression ")" |
add_op factor | identifier "(" expression_list ")" | identifier "(" ")"
constant->string_constant | numeric_constant
numeric_constant ->integer_constant | floating_constant
expression_list->expression | expression_list "," expression
identifier_list ->identifier | identifier_list "," identifier
type ->"int" | "float"

Comments

µ-C is a small subset of the programming language C. Any correct program written in µ-C should compile correctly using an ANSI C compiler.

Data types

µ-C features two standard (predefined) data types: int and float

Blocks

µ-C follows usual scoping rules. Functions may be recursive.

Each variable or function identifier must be declared prior to its use.

Expressions

There are four binary arithmetic operators: +, -, *, /. + and - have lower precedence than *, and /. In addition, + and -may be used as unary operators.

Given int arguments, each operation returns int result. If either argument is of type float, the result is always float. In case of mixed type arguments, the int argument is converted to float before the operation is performed.

There are six binary relational operators: <, <=, ==, !=, >=, >. Types are handled as above. The equality operators (== and !=) have lower precedence than the other relational operators.

Assignment expressions involve the assignment operator (=) which is of lower precedence than the relational operators. .

Statements

µ-C has five different statements: the expression statement, return statement, while statement, if statement, and the compound statement. The semantics of each statement is the same as in C. All parameters are passed by value. The second paramater to scanf must ba a numeric variable preceded by the & operator (note that this operator is not explicitly defined in the grammer).

Standard I/O library

µ-C provides simple versions of two I/O functions from the standard C library: printf and scanf.

scanf requires two actual parameters. The first parameter is a format string (a string constant) which may be either "%d" or "%f" only. scanf's second parameter is used to read-in a single number of type int or float. The supplied parameter must be a variable (or function parameter preceded by the & operator).

printf requires one or two actual parameters. This function is used to write the value of a numeric expression (int or float) or just a string constant. The first parameter is a format string (a string constant) which may contain a single conversion directive %d or %f (to output % use %%). The second parameter (if supplied) is converted accoring to the conversion directive.

Examples

A simple expression calculation

/*
 * a sample program #1
 */
 
int scanf( char *fmt, ... );
int printf( char *fmt, ... );
 
int
main( void )
{
  int i, j;
 
  scanf( "%d", &i );                /* get i */
  j = 9 + i * 8;                    /* evaluate j */
  printf( "Result is %d\n", j );    /* print j */
}

A simple function call

/*
 * a sample program #2
 */
 
int scanf( char *fmt, ... );
int printf( char *fmt, ... );
 
int count( int n );
 
int
main( void )
{
  int i, sum;
 
  scanf( "%d", &i);              /* get i */
  sum = count(i);                /* call count */
  printf( "%d\n", sum );         /* write result */
}
 
int
count( int n )
{
  int i, sum;
 
  i = 1;
  sum = 0;
  while ( i <= n ) {
    sum = sum + i;
    i = i + 1;
  }
  return sum;
}

A simple recursive function

/*
 * recursive factorial calculation
 */
 
int scanf( char *fmt, ... );
int printf( char *fmt, ... );
 
int factorial( int n );
 
int
main( void )
{
  int n, fact;
 
  printf( "Enter an integer: " );
  scanf( "%d", &n );       /* get i */
  fact = factorial( n );   /* call factorial */
  printf( "Factorial of %d ", n );
  printf( "is %d\n", fact );
}
 
int
factorial( int n )
{
  if ( n <= 1 )
    return 1;
  else
    return n * factorial( n - 1 );
}