[top] [prev] [next]

Syntax

Care should be taken, when using colons and semicolons in the same sentence, that the reader understands how far the force of each sign carries. ---Robert Graves and Alan Hodge

Keywords

AND       DO          FROM        NOT         REPEAT     UNTIL   
ANY       ELSE        GENERIC     OBJECT      RETURN     UNTRACED
ARRAY     ELSIF       IF          OF          REVEAL     VALUE   
AS        END         IMPORT      OR          ROOT       VAR     
BEGIN     EVAL        IN          OVERRIDES   SET        WHILE   
BITS      EXCEPT      INTERFACE   PROCEDURE   THEN       WITH    
BRANDED   EXCEPTION   LOCK        RAISE       TO                 
BY        EXIT        LOOP        RAISES      TRY                
CASE      EXPORTS     METHODS     READONLY    TYPE               
CONST     FINALLY     MOD         RECORD      TYPECASE           
DIV       FOR         MODULE      REF         UNSAFE             

Reserved identifiers

ABS       BYTESIZE   EXTENDED  INTEGER    MAX     NULL      SUBARRAY
ADDRESS   CARDINAL   FALSE     ISTYPE     MIN     NUMBER    TEXT
ADR       CEILING    FIRST     LAST       MUTEX   ORD       TRUE
ADRSIZE   CHAR       FLOAT     LONGINT    NARROW  REAL      TRUNC
BITSIZE   DEC        FLOOR     LONGREAL   NEW     REFANY    TYPECODE
BOOLEAN   DISPOSE    INC       LOOPHOLE   NIL     ROUND     VAL

Operators

+        <         #        =        ;        ..       :
-        >         {        }        |        :=       <:
*        <=        (        )        ^        ,        =>
/        >=        [        ]        .        &

Comments

A comment is an arbitrary character sequence opened by (* and closed by *). Comments can be nested and can extend over more than one line.

Pragmas

A pragma is an arbitrary character sequence opened by <* and closed by *>. Pragmas can be nested and can extend over more than one line. Pragmas are hints to the implementation; they do not affect the language semantics.

We recommend supporting the two pragmas <*INLINE*> and <*EXTERNAL*>. The pragma <*INLINE*> precedes a procedure declaration to indicate that the procedure should be expanded at the point of call. The pragma <* EXTERNAL N:L *> precedes an interface or a declaration in an interface to indicate that the entity it precedes is implemented by the language L, where it has the name N. If ":L" is omitted, then the implementation's default external language is assumed. If "N" is omitted, then the external name is determined from the Modula-3 name in some implementation-dependent way.

Conventions for syntax

We use the following notation for defining syntax:

    X Y      X followed by Y
    X|Y      X or Y.  
    [X]      X or empty
    {X}      A possibly empty sequence of X's 
    X&Y      X or Y or X Y
"Followed by" has greater binding power than | or &; parentheses are used to override this precedence rule. Non-terminals begin with an upper-case letter. Terminals are either keywords or quoted operators. The symbols Id, Number, TextLiteral, and CharLiteral are defined in the token grammar. Each production is terminated by a period. The syntax does not reflect the restrictions that revelations and exceptions can be declared only at the top level; nor does it include explicit productions for NEW, INC, and DEC, which parse like procedure calls.

Compilation unit productions

Compilation = [UNSAFE] (Interface | Module) | GenInf | GenMod.

Interface   = INTERFACE Id ";" {Import} {Decl} END Id "."
            | INTERFACE Id "=" Id GenActls END Id ".".
Module      = MODULE Id [EXPORTS IdList] ";" {Import} Block Id "."
            | MODULE Id [EXPORTS IdList] "=" Id GenActls END Id ".".

GenInf = GENERIC INTERFACE Id GenFmls ";" {Import} {Decl} END Id ".".
GenMod = GENERIC MODULE Id GenFmls ";" {Import} Block Id ".".

Import      = AsImport | FromImport.
AsImport    = IMPORT ImportItem {"," ImportItem} ";".
FromImport  = FROM Id IMPORT IdList ";".
Block       = {Decl} BEGIN S END.
Decl = CONST {ConstDecl ";"}
     | TYPE {TypeDecl ";"}
     | EXCEPTION {ExceptionDecl ";"}
     | VAR {VariableDecl ";"}
     | ProcedureHead ["=" Block Id] ";" 
     | REVEAL {QualId ("=" | "<:") Type ";"}.

GenFmls        = "(" [IdList] ")".
GenActls       = "(" [IdList] ")".
ImportItem     = Id | Id AS Id.
ConstDecl      = Id [":" Type] "=" ConstExpr.
TypeDecl       = Id ("=" | "<:") Type.
ExceptionDecl  = Id ["(" Type ")"].
VariableDecl   = IdList (":" Type & ":=" Expr).
ProcedureHead  = PROCEDURE Id Signature.

Signature      = "(" Formals ")" [":" Type] [RAISES Raises].
Formals        = [ Formal {";" Formal} [";"] ].
Formal         = [Mode] IdList (":" Type & ":=" ConstExpr).
Mode           = VALUE | VAR | READONLY.
Raises         = "{" [ QualId {"," QualId} ] "}" | ANY.

Statement productions

Stmt = AssignSt | Block | CallSt | CaseSt | ExitSt | EvalSt | ForSt 
     | IfSt | LockSt | LoopSt | RaiseSt | RepeatSt | ReturnSt 
     | TCaseSt | TryXptSt | TryFinSt | WhileSt | WithSt.

S =  [ Stmt {";" Stmt} [";"] ].

AssignSt = Expr ":=" Expr.
CallSt   = Expr "(" [Actual {"," Actual}] ")".
CaseSt   = CASE Expr OF [Case] {"|" Case} [ELSE S] END.
ExitSt   = EXIT.
EvalSt   = EVAL Expr.
ForSt    = FOR Id ":=" Expr TO Expr [BY Expr] DO S END.
IfSt     = IF Expr THEN S {ELSIF Expr THEN S} [ELSE S] END.
LockSt   = LOCK Expr DO S END.
LoopSt   = LOOP S END.
RaiseSt  = RAISE QualId ["(" Expr ")"].
RepeatSt = REPEAT S UNTIL Expr.
ReturnSt = RETURN [Expr].
TCaseSt  = TYPECASE Expr OF [TCase] {"|" TCase} [ELSE S] END.
TryXptSt = TRY S EXCEPT [Handler] {"|" Handler} [ELSE S] END.
TryFinSt = TRY S FINALLY S END.
WhileSt  = WHILE Expr DO S END.
WithSt   = WITH Binding {"," Binding} DO S END.

Case    = Labels {"," Labels} "=>" S.
Labels  = ConstExpr [".." ConstExpr].
Handler = QualId {"," QualId} ["(" Id ")"] "=>" S.
TCase   = Type {"," Type} ["(" Id ")"] "=>" S.
Binding = Id "=" Expr.
Actual  = Type | [Id ":="] Expr .

Type productions

Type = TypeName | ArrayType | PackedType | EnumType | ObjectType
     | ProcedureType | RecordType | RefType | SetType | SubrangeType
     | "(" Type ")".

ArrayType     = ARRAY [Type {"," Type}] OF Type.
PackedType    = BITS ConstExpr FOR Type.
EnumType      = "{" [IdList] "}".
ObjectType    = [TypeName | ObjectType] [Brand] OBJECT Fields 
                 [METHODS Methods] [OVERRIDES Overrides] END.
ProcedureType = PROCEDURE Signature.
RecordType    = RECORD Fields END.
RefType       = [UNTRACED] [Brand] REF Type.
SetType       = SET OF Type.
SubrangeType  = "[" ConstExpr ".." ConstExpr "]".

Brand     = BRANDED [ConstExpr].
Fields    = [ Field {";" Field} [";"] ].
Field     = IdList (":" Type & ":=" ConstExpr).
Methods   = [ Method {";" Method} [";"] ].
Method    = Id Signature [":=" ConstExpr].
Overrides = [ Override {";" Override} [";"] ].
Override  = Id ":=" ConstExpr .

Expression productions

ConstExpr = Expr.

Expr = E1 {OR E1}.
  E1 = E2 {AND E2}.
  E2 = {NOT} E3.
  E3 = E4 {Relop E4}.
  E4 = E5 {Addop E5}.
  E5 = E6 {Mulop E6}.
  E6 = {"+" | "-"} E7.
  E7 = E8 {Selector}.
  E8 = Id | Number | CharLiteral | TextLiteral 
     | Constructor | "(" Expr ")".

Relop =  "=" | "#" | "<"  | "<=" | ">" | ">=" | IN.
Addop =  "+" | "-" | "&".
Mulop =  "*" | "/" | DIV | MOD.

Selector = "^"  |  "." Id  |  "[" Expr {"," Expr} "]"
         | "(" [ Actual {"," Actual} ] ")".

Constructor = Type "{" [ SetCons | RecordCons | ArrayCons ] "}".

SetCons = SetElt {"," SetElt}.
SetElt = Expr [".." Expr].
RecordCons = RecordElt {"," RecordElt}.
RecordElt = [Id ":="] Expr.
ArrayCons =  Expr {"," Expr} ["," ".."].

Miscellaneous productions

IdList      =  Id {"," Id}.
QualId      =  Id ["." Id].
TypeName    =  QualId | ROOT | UNTRACED ROOT.

Token productions

To read a token, first skip all blanks, tabs, newlines, carriage returns, vertical tabs, form feeds, comments, and pragmas. Then read the longest sequence of characters that forms an operator or an Id or Literal.

An Id is a case-significant sequence of letters, digits, and underscores that begins with a letter. An Id is a keyword if it appears in the list of keywords, a reserved identifier if it appears in the list of reserved identifiers, and an ordinary identifier otherwise.

In the following grammar, terminals are characters surrounded by double-quotes and the special terminal DQUOTE represents double-quote itself.

Id = Letter {Letter | Digit | "_"}.

Literal = Number | CharLiteral | TextLiteral.

CharLiteral = "'"  (PrintingChar | Escape | DQUOTE) "'".

TextLiteral = DQUOTE {PrintingChar | Escape | "'"} DQUOTE.

Escape = "\" "n"   | "\" "t"     | "\" "r"     | "\" "f"
       | "\" "\"   | "\" "'"     | "\" DQUOTE
       | "\" OctalDigit OctalDigit OctalDigit.

Number = Digit {Digit}
       | Digit {Digit} "_" HexDigit {HexDigit}
       | Digit {Digit} "." Digit {Digit} [Exp].

Exp = ("E" | "e" | "D" | "d" | "X" | "x") ["+" | "-"] Digit {Digit}.

PrintingChar = Letter | Digit | OtherChar.

HexDigit = Digit | "A" | "B" | "C" | "D" | "E" | "F"
                 | "a" | "b" | "c" | "d" | "e" | "f".

Digit = "0" | "1" | ... | "9".

OctalDigit = "0" | "1" | ... | "7".

Letter = "A"  | "B"  | ... | "Z"  | "a"  | "b"  | ... | "z".

OtherChar = " " | "!" | "#" | "$" | "%" | "&" | "(" | ")"
          | "*" | "+" | "," | "-" | "." | "/" | ":" | ";"
          | "<" | "=" | ">" | "?" | "@" | "[" | "]" | "^"
          | "_" | "`" | "{" | "|" | "}" | "~"
          | ExtendedChar

ExtendedChar = any char with ISO-Latin-1 code in [8_240..8_377].

[top] [prev] [next]