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
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
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
+ < # = ; .. : - > { } | := <: * <= ( ) ^ , => / >= [ ] . &
A comment is an arbitrary character sequence opened by (* and closed by *). Comments can be nested and can extend over more than one line.
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.
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 = [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.
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 = 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 .
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} ["," ".."].
IdList = Id {"," Id}. QualId = Id ["." Id]. TypeName = QualId | ROOT | UNTRACED ROOT.
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].