Appendix D
ICL Syntax

The following gives a formal definition of the syntax of ICL. Note that there are in effect two levels to the ICL Syntax. One level describes how statements (strictly simple_statements as defined below) are built up, while a second level describes how statements (normally one per line) are combined to form control structures and procedures. The definitions of if_block, loop_block and procedure below form the second level syntax, and in these cases items on different lines in the definition, must appear on separate lines. The notation is as follows.

Both spaces and layout are significant. Spaces may not appear within identifiers, or numbers. Spaces may be used as separators in parameter lists. layout is currently restricted to one statement per line. Thus the end of line character is effectively a statement separator.

  
  letter  =   any of the letters A to Z or a to z
  
  digit   =   0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
  
  binary_digit  =  0 | 1
  
  octal digit  =  0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
  
  hex_digit  =  digit | A | B | C | D | E | F | a | b | c | d | e | f
  
  comment  =  ; anything   |
              { anything
  
  unquoted_string  =  any sequence of characters not including a space,
                      comma or left parenthesis
  
  string_delimiter  =  ’ | "
  
  open_string  =   any sequence of characters not including a string delimiter
  
  string  =   string_delimiter  open_string  string_delimiter
              { string_delimiter  open_string  string_delimiter  }
  
  identifier  =  letter  {  letter | digit | _  }
  
       ( certain identifiers have a special meaning within the language
         and are not available for general use
  
         these are  AND, OR, NOT, LOOP, WHILE, FOR, IF, ELSE, END, PROC,
                    TRUE, FALSE, BREAK, ENDIF, ELSEIF, ENDPROC, ENDLOOP,
                    EXCEPTION, ENDEXCEPTION.
  
         In identifiers a letter in upper or lower case is considered
         to be the same  )
  
  integer  =  digit  {  digit  }
  
  binary_integer  =  %B binary_digit  {  binary_digit  }
  
  octal_integer  =  %O octal_digit  {  octal_digit  }
  
  hex_integer  =  %X  hex_digit  {  hex_digit  }
  
  scale_factor  =  E  integer  |
                   E  +  integer  |
                   E  -  integer
  
  real  =  integer  .  {  digit  }  |
           integer  scale_factor  |
    integer  .  {  digit  }  scale_factor
  
  number  =  real | integer | binary_integer | octal_integer | hex_integer
  
  multiplication_operator  =  * | /
  
  addition_operator  =  + | -
  
  relational_operator  =   = | < | > | >= | <= | <>
  
  logical_operator  =  AND | OR
  
  function_call =  identifier  (  [ expression { , expression } ] )
  
  primary  =  identifier  |  number  |  string  | function_call
              TRUE  |  FALSE  |  (  expression  )
  
  factor  =  primary  {  **  primary  }
  
  term    =  factor  {  multiplication_operator  factor  }
  
  simple_expression  =  [  addition operator ]  term
   {  addition_operator  term  }
  
  relation  =  simple_expression  |
               simple_expression  relational_operator  simple_expression  |
               simple_expression : simple_expression [ : simple_expression ]
  
  expression  =  relation  |
                 NOT  relation  |
                 relation  {  logical_operator  relation  }  |
                 relation  {  &  relation  }
  
  parameter  =  unquoted_string  |  string  |  (  expression  )
  
  simple_statement  =   =  expression  |
                        identifier  =  expression  |
                        comment  |
                        simple_statement  comment
  
  command   =   identifier  [  parameter  { [,]  parameter  }  ]
  
  
  statement  =  simple_statement  |  command  |  if_block  |
                loop_block  |  BREAK
  
  if_block  =   IF  expression
                  { statement }
                [ ELSE IF  expression
                  { statement } ]
                [ ELSE
                  { statement } ]
                END IF
  
  loop_clause =  WHILE expression  |
                 FOR identifier = expression TO expression [ STEP expression ]
  
  loop_block =  LOOP [loop_clause]
                { statement }
                END LOOP
  
  procedure  =  PROC identifier [  identifier  { [,]  identifier }  ]
                { statement }
                { EXCEPTION identifier
                  { statement }
                  END EXCEPTION }
                END PROC