The document has five subsections, each dealing with one aspect of the language: basic symbols, programs, declarations, statements, and expressions. Basic symbols are the indivisible atoms of the language, and their meanings are defined by relating them to our shared experience with programming languages. All other constructs are composite---each is formed by combining parts. Their meanings can thus be defined in terms of the meanings of their components and fundamental concepts such as ``sequence of execution.''
Identifier: [a-zA-Z][a-zA-Z0-9]* Integer: [0-9]+Upper- and lower-case versions of the same letter are distinct. The delimiters and other denotations of the language are the following special characters and keywords:
( ) : ; + - * = , := ~ # < > . [ ] .. | AND ARRAY BEGIN BOOLEAN CONST DO ELSE ELSIF END EXIT FALSE FOR IF INTEGER LOOP MOD OF OR PROGRAM RETURN THEN TO TRUE VAR WHILEAn identifier is a freely chosen representation for an object. It is given meaning by a construct of the program. The appearances at which an identifier is given a meaning are called defining occurrences of that identifier. All other appearances of the identifier are called applied occurrences.
Denotations have the usual meanings.
Keywords can be used only as indicated by the context-free grammar productions.
Comments are arbitrary sequences of characters beginning with ``(*'' and ending with ``*)''. Comments cannot be nested. Comments, spaces, and newlines may not appear within basic symbols. Two adjacent basic symbols must be separated by one or more comments, spaces, or newlines, unless one of the basic symbols is a special character. Otherwise comments, spaces, and newlines are meaningless.
Program : "PROGRAM" Identifier "(" ParameterDecl (";" ParameterDecl)* ")" ":" "INTEGER" ";" Declarations "BEGIN" StatementSeq "END" Identifier ".". StatementSeq : Statement*.A program specifies a computation by describing a sequence of actions. A computation specified in Obr may be realized by any sequence of actions having the same effect as the one described here for the given computation. The meaning of constructs that do not satisfy the rules given here is undefined. Whether, and in what manner, a particular implementation of Obr gives meaning to undefined constructs is outside the scope of this definition.
A program is executed by reading parameter values from the standard input and executing the component StatementSeq. A Return statement must be executed to terminate the program.
The component statements of a statement sequence are executed in the sequence in which they were written.
All of the occurrences of Identifier in the productions for Program, ParameterDecl, ConstantDecl and VariableDecl are defining occurrences, except the last occurrence in Program. All instances of Identifier in other productions are applied occurrences.
The last occurrence of Identifier in the Program production must identify the defining occurrence immediately after the "PROGRAM" keyword.
ParameterDecl : Identifier ":" "INTEGER". Declarations : ("CONST" (ConstantDecl ";")+)? ("VAR" (VariableDecl ";")+)?. ConstantDecl : Identifier "=" Integer. VariableDecl : Identifier ":" TypeSpec. TypeSpec : "INTEGER" | "BOOLEAN" | "ARRAY" Integer "OF" "INTEGER".
Every object and variable has a specified extent during which it can be operated upon. The extents of denotations are unbounded; the extents of constants and variables are determined by their declarations.
Values of type "INTEGER" have the usual meanings. The range of integer values is determined by the particular implementation of Obr.
Values of type "BOOLEAN" represent truth values. Only two Boolean values exist: true and false, denoted by the keywords "TRUE" and "FALSE", respectively.
Values of array type represent collections of a given number of integer elements.
If the parameter declaration has the form:
Identifier : tthen the created variable can refer to objects of type t.
If the constant declaration has the form:
Identifier = integerthen the created constant refers to an object whose value is that of the specified integer denotation.
If the variable declaration has the form:
Identifier : tthen the created variable can refer to objects of type t. Initially, it refers to an arbitrary object.
Statement : Identifier ":=" Expression ";" | Identifier "[" Expression "]" ":=" Expression ";" | Conditional | Iteration | "EXIT" ";" | "RETURN" Expression ";". Conditional : "IF" Expression "THEN" StatementSeq ("ELSE" StatementSeq)? "END". Iteration : "LOOP" StatementSeq "END" | "WHILE" Expression "DO" StatementSeq "END" | "FOR" Identifier ":=" Expression "TO" Expression "DO" StatementSeq "END".
An iteration of the form
WHILE e DO s ENDis identical in meaning to the iteration
LOOP IF ~ e THEN EXIT END; s ENDAn iteration of the form
FOR id := e1 TO e2 DO s ENDrequires that id be an integer variable, e1 and e2 be expressions yielding integer values, and the iteration is identical in meaning to the sequence of statements
id := e1; limit := e2; LOOP IF id > limit THEN EXIT END; s; id := id + 1; END;where limit is a compiler-generated temporary integer variable.
Expression : SimpleExp | Expression RelOp SimpleExp. RelOp : "=" | "#" | "<" | ">". SimpleExp : Term | SimpleExp AddOp Term. AddOp : "+" | "-" | "OR". Term : Factor | Term MulOp Factor. MulOp : "*" | "/" | "MOD" | "AND". Factor : Identifier | Integer | | Identifier "[" Expression "]" | "TRUE" | "FALSE" | "(" Expression ")" | "~" Factor | "-" Factor.Each subexpression (SimpleExp, Term and Factor) may be evaluated to yield an object of a certain type. The operands of an expression may be evaluated in an arbitrary order unless the operator is "OR" or "AND" (see below).
The following table shows all Obr operators with their the operand type(s) and result type.
Op1 Op2 Result Operation = integer integer Boolean integer equality Boolean Boolean Boolean Boolean equality # integer integer Boolean integer inequality Boolean Boolean Boolean Boolean inequality < integer integer Boolean integer less than > integer integer Boolean integer greater than + integer integer integer integer addition - integer integer integer integer subtraction * integer integer integer integer multiplication / integer integer integer integer division MOD integer integer integer integer remainder OR Boolean Boolean Boolean disjunction AND Boolean Boolean Boolean conjunction - integer integer integer negation ~ Boolean Boolean Boolean complementEquality yields the value true if its operands have the same value. Otherwise, it yields the value false.
The arithmetic operators addition, subtraction, multiplication, division, and remainder have the usual meaning as long as the values of all operands and results lie in the range permitted by the mapping from Obr objects to target machine objects. Division and remainder are defined only when the value of the right operand is nonzero.
The result of an integer division operation with dividend m and divisor n # 0 is determined as follows:
The Boolean operators "OR" and "AND" are evaluated in a ``short circuit'' fashion. That is, when evaluating "OR" if the left operand evaluates to true then evaluation of the "OR" returns true and the right operand is not evaluated. Similarly, when evaluating "AND" if the left operand evaluates to false then evaluation of the "AND" returns false and the right operand is not evaluated.
PROGRAM GCD (x : INTEGER; y : INTEGER) : INTEGER; BEGIN WHILE x # y DO IF x > y THEN x := x - y ELSE y := y - x END END; RETURN x END GCD.The factorial program below uses a constant declaration to define the limit imposed by machine arithmetic. If the initial value of v is invalid, the program returns -1 as the answer.
PROGRAM Factorial (v : INTEGER) : INTEGER; CONST limit = 7; VAR c : INTEGER; fact : INTEGER; BEGIN IF (v < 0) OR (v > limit) THEN RETURN -1 ELSE c := 0; fact := 1; WHILE c < v DO c := c + 1; fact := fact * c END; RETURN fact END END Factorial.