<p>Examples:</p>
- <pre>Table = ARRAY N OF Real
+ <pre>Table = array N of Real
</pre>
- <pre>Tree = POINTER TO Node
+ <pre>Tree = pointer to Node
</pre>
- <pre>Node = RECORD key: Int;
+ <pre>Node = record
+ key: Int;
left, right: Tree
-END
+end
</pre>
- <pre>CenterNode = RECORD (Node)
- name: ARRAY 32 OF Char;
+ <pre>CenterNode = record (Node)
+ name: array 32 of Char;
subnode: Tree
-END
+end
</pre>
- <pre>Function = PROCEDURE (x: Int): Int
+ <pre>Function = procedure (x: Int): Int
</pre>
<h3><a name="sec6.1">6.1. Basic types</a></h3>
<p>An array is a structure consisting of a fixed number of elements which are all of the same type, called the <dfn>element type</dfn>. The number of elements of an array is called its <dfn>length</dfn>. The elements of the array are designated by indices, which are integers between 0 and the length minus 1.</p>
- <pre>ArrayType = ARRAY length {"," length} OF type.
+ <pre>ArrayType = "array" length {"," length} "of" type.
length = ConstExpression.
</pre>
<p>A declaration of the form</p>
- <pre>ARRAY N0, N1, ... , Nk OF T
+ <pre>array N0, N1, ... , Nk of T
</pre>
<p>is understood as an abbreviation of the declaration</p>
- <pre>ARRAY N0 OF
- ARRAY N1 OF
+ <pre>array N0 of
+ array N1 of
...
- ARRAY Nk OF T
+ array Nk of T
</pre>
<p>Examples of array types:</p>
- <pre>ARRAY N OF Int
+ <pre>array N of Int
</pre>
- <pre>ARRAY 10, 20 OF Real
+ <pre>array 10, 20 of Real
</pre>
<h3><a name="sec6.3">6.3. Record types</a></h3>
<p>A record type is a structure consisting of a fixed number of elements of possibly different types. The record type declaration specifies for each element, called <dfn>field</dfn>, its type and an identifier which denotes the field. The scope of these field identifiers is the record definition itself, but they are also visible within field designators (see <a href="#sec8.1">8.1</a>) referring to elements of record variables.</p>
- <pre>RecordType = RECORD ["(" BaseType ")"] [FieldListSequence] END.
+ <pre>RecordType = "record" ["(" BaseType ")"] [FieldListSequence] "end".
BaseType = qualident.
FieldListSequence = FieldList {";" FieldList}.
FieldList = IdentList ":" type.
<p>Examples of record types:</p>
- <pre>RECORD day, month, year: Int
-END
+ <pre>record day, month, year: Int
+end
</pre>
- <pre>RECORD
- name, firstname: ARRAY 32 OF Char;
+ <pre>record
+ name, firstname: array 32 of Char;
age: Int;
salary: Real
-END
+end
</pre>
<h3><a name="sec6.4">6.4. Pointer types</a></h3>
<p>Variables of a pointer type <var>P</var> assume as values pointers to variables of some type <var>T</var>. It must be a record type. The pointer type <var>P</var> is said to be <dfn>bound to</dfn> <var>T</var>, and <var>T</var> is the pointer base type of <var>P</var>. Pointer types inherit the extension relation of their base types, if there is any. If a type T is an extension of <var>T0</var> and <var>P</var> is a pointer type bound to <var>T</var>, then <var>P</var> is also an extension of <var>P0</var>, <dfn>the pointer type bound to</dfn> <var>T0</var>.</p>
- <pre>PointerType = POINTER TO type.
+ <pre>PointerType = "pointer" "to" type.
</pre>
- <p>If a type <var>P</var> is defined as POINTER TO <var>T</var>, the identifier <var>T</var> can be declared textually following the declaration of <var>P</var>, but [if so] it must lie within the same scope.</p>
+ <p>If a type <var>P</var> is defined as pointer to <var>T</var>, the identifier <var>T</var> can be declared textually following the declaration of <var>P</var>, but [if so] it must lie within the same scope.</p>
- <p>If <var>p</var> is a variable of type <var>P</var> = POINTER TO <var>T</var>, then a call of the predefined procedure NEW(<var>p</var>) has the following effect (see <a href="#sec10.2">10.2</a>): A variable of type <var>T</var> is allocated in free storage, and a pointer to it is assigned to <var>p</var>. This pointer <var>p</var> is of type <var>P</var> and the referenced variable <var>p</var>^ is of type <var>T</var>. Failure of allocation results in <var>p</var> obtaining the value NIL. Any pointer variable may be assigned the value NIL, which points to no variable at all.</p>
+ <p>If <var>p</var> is a variable of type <var>P</var> = pointer to <var>T</var>, then a call of the predefined procedure New(<var>p</var>) has the following effect (see <a href="#sec10.2">10.2</a>): A variable of type <var>T</var> is allocated in free storage, and a pointer to it is assigned to <var>p</var>. This pointer <var>p</var> is of type <var>P</var> and the referenced variable <var>p</var>^ is of type <var>T</var>. Failure of allocation results in <var>p</var> obtaining the value nil. Any pointer variable may be assigned the value nil, which points to no variable at all.</p>
<h3><a name="sec6.5">6.5. Procedure types</a></h3>
- <p>Variables of a procedure type <var>T</var> have a procedure (or NIL) as value. If a procedure <var>P</var> is assigned to a procedure variable of type <var>T</var>, the (types of the) formal parameters of <var>P</var> must be the same as those indicated in the formal parameters of <var>T</var>. The same holds for the result type in the case of a function procedure (see <a href="#sec10.1">10.1</a>). <var>P</var> must not be declared local to another procedure, and neither can it be a standard procedure.</p>
+ <p>Variables of a procedure type <var>T</var> have a procedure (or nil) as value. If a procedure <var>P</var> is assigned to a procedure variable of type <var>T</var>, the (types of the) formal parameters of <var>P</var> must be the same as those indicated in the formal parameters of <var>T</var>. The same holds for the result type in the case of a function procedure (see <a href="#sec10.1">10.1</a>). <var>P</var> must not be declared local to another procedure, and neither can it be a standard procedure.</p>
- <pre>ProcedureType = PROCEDURE [FormalParameters].
+ <pre>ProcedureType = "procedure" [FormalParameters].
</pre>
<h2><a name="sec7">7. Variable declarations</a></h2>
<pre>f: Function
</pre>
- <pre>a: ARRAY 100 OF Real
+ <pre>a: array 100 of Real
</pre>
- <pre>w: ARRAY 16 OF
- RECORD ch: Char;
+ <pre>w: array 16 of
+ record ch: Char;
count: Int
- END
+ end
</pre>
<pre>t: Tree
<p>The syntax of expressions distinguishes between four classes of operators with different precedences (binding strengths). The operator ~ has the highest precedence, followed by multiplication operators, addition operators, and relations. Operators of the same precedence associate from left to right. For example, <var>x</var> − <var>y</var> − <var>z</var> stands for (<var>x</var> − <var>y</var>) − <var>z</var>.</p>
<pre>expression = SimpleExpression [relation SimpleExpression].
-relation = "=" | "!=" | "<" | "<=" | ">" | ">=" | IS.
+relation = "=" | "!=" | "<" | "<=" | ">" | ">=" | "is".
SimpleExpression = ["+"|"-"] term {AddOperator term}.
-AddOperator = "+" | "-" | OR.
+AddOperator = "+" | "-" | "or".
term = factor {MulOperator factor}.
-MulOperator = "*" | "/" | DIV | MOD | "&" .
-factor = number | string | NIL | TRUE | FALSE |
- designator [ActualParameters] | "(" expression ")" | "~" factor.
+MulOperator = "*" | "/" | "div" | "mod" | "and" .
+factor = number | string | "nil" | "true" | "false" |
+ designator [ActualParameters] | "(" expression ")" | "not" factor.
ActualParameters = "(" [ExpList] ")" .
</pre>
<p>The type of the expression must be the same as that of the designator. The following exceptions hold:</p>
<ol>
- <li>The constant NIL can be assigned to variables of any pointer or procedure type.</li>
+ <li>The constant nil can be assigned to variables of any pointer or procedure type.</li>
<li>Strings can be assigned to any array of characters, provided the number of characters in the string is less than that of the array. (A null character is appended). Single-character strings can also be assigned to variables of type Char.</li>
<li>In the case of records, the type of the source must be an extension of the type of the destination.</li>
<li>An open array may be assigned to an array of equal base type.</li>
<pre>x := AsFloat(i + 1)
</pre>
- <pre>k := (i + j) DIV 2
+ <pre>k := (i + j) div 2
</pre>
<pre>f := log2
<h3><a name="sec9.4">9.4. If statements</a></h3>
- <pre>IfStatement = IF expression THEN StatementSequence
- {ELSIF expression THEN StatementSequence}
- [ELSE StatementSequence]
- END.
+ <pre>IfStatement = "if" expression "then" StatementSequence
+ {"elsif" expression "then" StatementSequence}
+ ["elsif" StatementSequence]
+ "end".
</pre>
- <p>If statements specify the conditional execution of guarded statements. The Boolean expression preceding a statement is called its <dfn>guard</dfn>. The guards are evaluated in sequence of occurrence, until one evaluates to TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol ELSE is executed, if there is one.</p>
+ <p>If statements specify the conditional execution of guarded statements. The Boolean expression preceding a statement is called its <dfn>guard</dfn>. The guards are evaluated in sequence of occurrence, until one evaluates to TRUE, whereafter its associated statement sequence is executed. If no guard is satisfied, the statement sequence following the symbol "else" is executed, if there is one.</p>
<p>Example:</p>
- <pre>IF (ch >= "A") & (ch <= "Z") THEN ReadIdentifier
-ELSIF (ch >= "0") & (ch <= "9") THEN ReadNumber
-ELSIF ch = 22X THEN ReadString
-END
+ <pre>if (ch >= "A") and (ch <= "Z") then ReadIdentifier
+elsif (ch >= "0") and (ch <= "9") then ReadNumber
+elsif ch = 22X then ReadString
+end
</pre>
<h3><a name="sec9.5">9.5. Case statements</a></h3>
<p>Case statements specify the selection and execution of a statement sequence according to the value of an expression. First the case expression is evaluated, then the statement sequence is executed whose case label list contains the obtained value. If the case expression is of type Int or Char, all labels must be integers or single-character strings, respectively.</p>
- <pre>CaseStatement = CASE expression OF case {"|" case} END.
+ <pre>CaseStatement = "case" expression "of" case {"|" case} "end".
case = [CaseLabelList ":" StatementSequence].
CaseLabelList = LabelRange {"," LabelRange}.
LabelRange = label [".." label].
<p>Example:</p>
- <pre>CASE k OF
+ <pre>case k of
0: x := x + y
| 1: x := x − y
| 2: x := x * y
| 3: x := x / y
-END
+end
</pre>
<p>The type <var>T</var> of the case expression (case variable) may also be a record or pointer type. Then the
<p>Example:</p>
- <pre>TYPE R = RECORD a: Int END;
- R0 = RECORD (R) b: Int END;
- R1 = RECORD (R) b: Real END;
- R2 = RECORD (R) b: SET END;
- P = POINTER TO R;
- P0 = POINTER TO R0;
- P1 = POINTER TO R1;
- P2 = POINTER TO R2;
-VAR p: P;
+ <pre>type
+ R = record a: Int end;
+ R0 = record (R) b: Int end;
+ R1 = record (R) b: Real end;
+ P = pointer to R;
+ P0 = pointer to R0;
+ P1 = pointer to R1;
+var p: P;
</pre>
- <pre>CASE p OF
+ <pre>case p of
P0: p.b := 10 |
P1: p.b := 2.5 |
P2: p.b := {0, 2}
-END
+end
</pre>
<h3><a name="sec9.6">9.6. While statements</a></h3>
<p>While statements specify repetition. If any of the Boolean expressions (guards) yields TRUE, the corresponding statement sequence is executed. The expression evaluation and the statement execution are repeated until none of the Boolean expressions yields TRUE.</p>
- <pre>WhileStatement = WHILE expression DO StatementSequence
- {ELSIF expression DO StatementSequence} END.
+ <pre>WhileStatement = "while" expression "do" StatementSequence
+ {"elsif" expression "do" StatementSequence} "end".
</pre>
<p>Examples:</p>
- <pre>WHILE j > 0 DO
- j := j DIV 2; i := i+1
-END
+ <pre>while j > 0 do
+ j := j div 2;
+ i := i+1
+end
</pre>
- <pre>WHILE (t # NIL) & (t.key # i) DO
+ <pre>while (t != nil) and (t.key != i) do
t := t.left
-END
+end
</pre>
- <pre>WHILE m > n DO m := m - n
-ELSIF n > m DO n := n - m
-END
+ <pre>while m > n do
+ m := m - n
+elsif n > m do
+ n := n - m
+end
</pre>
<h3><a name="sec9.7">9.7. Repeat Statements</a></h3>
<p>A repeat statement specifies the repeated execution of a statement sequence until a condition is satisfied. The statement sequence is executed at least once.</p>
- <pre>RepeatStatement = REPEAT StatementSequence UNTIL expression.
+ <pre>RepeatStatement = "repeat" StatementSequence "until" expression.
</pre>
<h3><a name="sec9.8">9.8. For statements</a></h3>
<p>A for statement specifies the repeated execution of a statement sequence for a given number of times, while a progression of values is assigned to an integer variable called the <dfn>control variable</dfn> of the for statement.</p>
<pre>ForStatement =
- FOR ident ":=" expression TO expression [BY ConstExpression] DO
- StatementSequence END.
+ "for" ident ":=" expression "to" expression ["by" ConstExpression] "do"
+ StatementSequence "end".
</pre>
<p>The for statement</p>
- <pre>FOR v := beg TO end BY inc DO S END
+ <pre>for v := start to stop by inc do S end
</pre>
<p>is, if <var>inc</var> > 0, equivalent to</p>
- <pre>v := beg;
-WHILE v <= end DO S; v := v + inc END
+ <pre>v := start;
+while v <= stop do S; v := v + inc end
</pre>
<p>and if <var>inc</var> < 0 it is equivalent to</p>
- <pre>v := beg;
-WHILE v >= end DO S; v := v + inc END
+ <pre>v := start;
+while v >= stop do S; v := v + inc end
</pre>
<p>The types of <var>v</var>, <var>beg</var> and <var>end</var> must be Int, and <var>inc</var> must be an integer (constant expression). If the step is not specified, it is assumed to be 1.</p>
<p>Procedure declarations consist of a procedure heading and a procedure body. The heading specifies the procedure identifier, the formal parameters, and the result type (if any). The body contains declarations and statements. The procedure identifier is repeated at the end of the procedure declaration.</p>
<p>There are two kinds of procedures, namely proper procedures and function procedures. The latter are activated by a function designator as a constituent of an expression, and yield a result that is an operand in the expression. Proper procedures
-are activated by a procedure call. A function procedure is distinguished in the declaration by indication of the type of its result following the parameter list. Its body must end with a RETURN clause which defines the result of the function procedure.</p>
+are activated by a procedure call. A function procedure is distinguished in the declaration by indication of the type of its result following the parameter list. Its body must end with a return clause which defines the result of the function procedure.</p>
<p>All constants, variables, types, and procedures declared within a procedure body are local to the procedure. The values of local variables are undefined upon entry to the procedure. Since procedures may be declared as local objects too, procedure declarations may be nested.</p>
<p>The use of the procedure identifier in a call within its declaration implies recursive activation of the procedure.</p>
<pre>ProcedureDeclaration = ProcedureHeading ";" ProcedureBody ident.
-ProcedureHeading = PROCEDURE identdef [FormalParameters].
-ProcedureBody = DeclarationSequence [BEGIN StatementSequence]
- [RETURN expression] END.
-DeclarationSequence = [CONST {ConstDeclaration ";"}]
- [TYPE {TypeDeclaration ";"}] [VAR {VariableDeclaration ";"}]
+ProcedureHeading = "procedure" identdef [FormalParameters].
+ProcedureBody = DeclarationSequence ["begin" StatementSequence]
+ ["return" expression] "end".
+DeclarationSequence = ["const" {ConstDeclaration ";"}]
+ ["type" {TypeDeclaration ";"}] ["var" {VariableDeclaration ";"}]
{ProcedureDeclaration ";"}.
</pre>
<p>Formal parameters are local to the procedure, i.e. their scope is the program text which constitutes the procedure declaration.</p>
<pre>FormalParameters = "(" [FPSection {";" FPSection}] ")" [":" qualident].
-FPSection = [VAR] ident {"," ident} ":" FormalType.
-FormalType = {ARRAY OF} qualident.
+FPSection = ["var"] ident {"," ident} ":" FormalType.
+FormalType = {"array" "of"} qualident.
</pre>
<p>The type of each formal parameter is specified in the parameter list. For variable parameters, it must be identical to the corresponding actual parameter's type, except in the case of a record, where it must be a base type of the corresponding actual parameter's type.</p>
<p>If the formal parameter's type is specified as</p>
- <pre>ARRAY OF T
+ <pre>array of T
</pre>
<p>the parameter is said to be an <dfn>open array</dfn>, and the corresponding actual parameter may be of arbitrary length.</p>
<p>Examples of procedure declarations:</p>
- <pre>PROCEDURE ReadInt(VAR x: Int);
- VAR i: Int; ch: Char;
-BEGIN i := 0; Read(ch);
- WHILE ("0" <= ch) & (ch <= "9") DO
- i := 10*i + (ORD(ch) - ORD("0")); Read(ch)
- END;
+ <pre>procedure ReadInt(var x: Int);
+ var i: Int; ch: Char;
+begin
+ i := 0;
+ Read(ch);
+ while ("0" <= ch) and (ch <= "9") do
+ i := 10*i + (AsInt(ch) - AsInt("0"));
+ Read(ch)
+ end;
x := i
-END ReadInt
-</pre>
-
- <pre>PROCEDURE WriteInt(x: Int); (* 0 <= x < 10^5 *)
- VAR i: Int;
- buf: ARRAY 5 OF Int;
-BEGIN i := 0;
- REPEAT buf[i] := x MOD 10; x := x DIV 10; INC(i) UNTIL x = 0;
- REPEAT DEC(i); Write(CHR(buf[i] + ORD("0"))) UNTIL i = 0
-END WriteInt
-</pre>
-
- <pre>PROCEDURE log2(x: Int): Int;
- VAR y: Int; (*assume x>0*)
-BEGIN y := 0;
- WHILE x > 1 DO x := x DIV 2; INC(y) END;
- RETURN y
-END log2
+end ReadInt
+</pre>
+
+ <pre>procedure WriteInt(x: Int); (* 0 <= x < 10^5 *)
+ var i: Int;
+ buf: array 5 of Int;
+begin i := 0;
+ repeat buf[i] := x mod 10;
+ x := x div 10;
+ Increment(i)
+ until x = 0;
+ repeat
+ Decrement(i);
+ Write(AsChar(buf[i] + AsInt("0")))
+ until i = 0
+end WriteInt
+</pre>
+
+ <pre>procedure log2(x: Int): Int;
+ var y: Int; (*assume x>0*)
+begin
+ y := 0;
+ while x > 1 do
+ x := x div 2;
+ Increment(y)
+ end;
+ return y
+end log2
</pre>
<h3><a name="sec10.2">10.2. Predefined procedures</a></h3>
<p>A module is a collection of declarations of constants, types, variables, and procedures, and a sequence of statements for the purpose of assigning initial values to the variables. A module typically constitutes a text that is compilable as a unit.</p>
- <pre>module = MODULE ident ";" [ImportList] DeclarationSequence
- [BEGIN StatementSequence] END ident "." .
-ImportList = IMPORT import {"," import} ";" .
+ <pre>module = "module" ident ";" [ImportList] DeclarationSequence
+ ["begin" StatementSequence] "end" ident "." .
+ImportList = "import" import {"," import} ";" .
Import = ident [":=" ident].
</pre>
<p>Identifiers that are to be visible in client modules, i.e. which are to be exported, must be marked by an asterisk (export mark) in their declaration. Variables are always exported in read-only mode.</p>
- <p>The statement sequence following the symbol BEGIN is executed when the module is added to a system (loaded). Individual (parameterless) procedures can thereafter be activated from the system, and these procedures serve as commands.</p>
+ <p>The statement sequence following the symbol begin is executed when the module is added to a system (loaded). Individual (parameterless) procedures can thereafter be activated from the system, and these procedures serve as commands.</p>
<p>Example:</p>
- <pre>MODULE Out; (*exported procedures: Write, WriteInt, WriteLn*)
- IMPORT Texts, Oberon;
- VAR W: Texts.Writer;
-
- PROCEDURE Write*(ch: Char);
- BEGIN Texts.Write(W, ch)
- END;
-
- PROCEDURE WriteInt*(x, n: Int);
- VAR i: Int; a: ARRAY 16 OF Char;
- BEGIN i := 0;
- IF x < 0 THEN Texts.Write(W, "-"); x := -x END ;
- REPEAT a[i] := CHR(x MOD 10 + ORD("0")); x := x DIV 10; INC(i) UNTIL x = 0;
- REPEAT Texts.Write(W, " "); DEC(n) UNTIL n <= i;
- REPEAT DEC(i); Texts.Write(W, a[i]) UNTIL i = 0
- END WriteInt;
-
- PROCEDURE WriteLn*;
- BEGIN Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
- END WriteLn;
-
-BEGIN Texts.OpenWriter(W)
-END Out.
+ <pre>module Out; (*exported procedures: Write, WriteInt, WriteLn*)
+ import Texts, Oberon;
+ var W: Texts.Writer;
+
+ procedure Write*(ch: Char);
+ begin
+ Texts.Write(W, ch)
+ end;
+
+ procedure WriteInt*(x, n: Int);
+ var i: Int; a: array 16 of Char;
+ begin
+ i := 0;
+ if x < 0 then
+ Texts.Write(W, "-");
+ x := -x
+ end ;
+ repeat
+ a[i] := AsChar(x mod 10 + AsInt("0"));
+ x := x div 10;
+ Increment(i)
+ until x = 0;
+ repeat
+ Texts.Write(W, " ");
+ Decrement(n)
+ until n <= i;
+ repeat
+ Decrement(i);
+ Texts.Write(W, a[i])
+ until i = 0
+ end WriteInt;
+
+ procedure WriteLn*;
+ begin
+ Texts.WriteLn(W);
+ Texts.Append(Oberon.Log, W.buf)
+ end WriteLn;
+
+begin
+ Texts.OpenWriter(W)
+end Out.
</pre>
<h2><a name="appendix">Appendix</a></h2>
<pre>TypeDeclaration = identdef "=" type.
type = qualident | ArrayType | RecordType | PointerType | ProcedureType.
-ArrayType = ARRAY length {"," length} OF type.
+ArrayType = "array" length {"," length} "of" type.
length = ConstExpression.
-RecordType = RECORD ["(" BaseType ")"] [FieldListSequence] END.
+RecordType = "record" ["(" BaseType ")"] [FieldListSequence] "end".
BaseType = qualident.
FieldListSequence = FieldList {";" FieldList}.
FieldList = IdentList ":" type.
IdentList = identdef {"," identdef}.
-PointerType = POINTER TO type.
-ProcedureType = PROCEDURE [FormalParameters].
+PointerType = "pointer" "to" type.
+ProcedureType = "procedure" [FormalParameters].
</pre>
<pre>VariableDeclaration = IdentList ":" type.
</pre>
<pre>expression = SimpleExpression [relation SimpleExpression].
-relation = "=" | "!=" | "<" | "<=" | ">" | ">=" | IS.
+relation = "=" | "!=" | "<" | "<=" | ">" | ">=" | "is".
SimpleExpression = ["+" | "-"] term {AddOperator term}.
-AddOperator = "+" | "-" | OR.
+AddOperator = "+" | "-" | "or".
term = factor {MulOperator factor}.
-MulOperator = "*" | "/" | DIV | MOD | "&".
-factor = number | string | NIL | TRUE | FALSE |
- designator [ActualParameters] | "(" expression ")" | "~" factor.
+MulOperator = "*" | "/" | "div" | "mod" | "and".
+factor = number | string | "nil" | "true" | "false" |
+ designator [ActualParameters] | "(" expression ")" | "not" factor.
designator = qualident {selector}.
selector = "." ident | "[" ExpList "]" | "^" | "(" qualident ")".
ExpList = expression {"," expression}.
assignment = designator ":=" expression.
ProcedureCall = designator [ActualParameters].
StatementSequence = statement {";" statement}.
-IfStatement = IF expression THEN StatementSequence
- {ELSIF expression THEN StatementSequence}
- [ELSE StatementSequence] END.
-CaseStatement = CASE expression OF case {"|" case} END.
+IfStatement = "if" expression "then" StatementSequence
+ {"elsif" expression "then" StatementSequence}
+ ["else" StatementSequence] "end".
+CaseStatement = "case" expression "of" case {"|" case} "end".
case = [CaseLabelList ":" StatementSequence].
CaseLabelList = LabelRange {"," LabelRange}.
LabelRange = label [".." label].
label = integer | string | qualident.
-WhileStatement = WHILE expression DO StatementSequence
- {ELSIF expression DO StatementSequence} END.
-RepeatStatement = REPEAT StatementSequence UNTIL expression.
-ForStatement = FOR ident ":=" expression TO expression [BY ConstExpression]
- DO StatementSequence END.
+WhileStatement = "while" expression "do" StatementSequence
+ {"elsif" expression "do" StatementSequence} "end".
+RepeatStatement = "repeat" StatementSequence "until" expression.
+ForStatement = "for" ident ":=" expression "to" expression ["by" ConstExpression]
+ "do" StatementSequence "end".
</pre>
<pre>ProcedureDeclaration = ProcedureHeading ";" ProcedureBody ident.
-ProcedureHeading = PROCEDURE identdef [FormalParameters].
-ProcedureBody = DeclarationSequence [BEGIN StatementSequence]
- [RETURN expression] END.
-DeclarationSequence = [CONST {ConstDeclaration ";"}]
- [TYPE {TypeDeclaration ";"}]
- [VAR {VariableDeclaration ";"}]
+ProcedureHeading = "procedure" identdef [FormalParameters].
+ProcedureBody = DeclarationSequence ["begin" StatementSequence]
+ ["return" expression] "end".
+DeclarationSequence = ["const" {ConstDeclaration ";"}]
+ ["type" {TypeDeclaration ";"}]
+ ["var" {VariableDeclaration ";"}]
{ProcedureDeclaration ";"}.
FormalParameters = "(" [FPSection {";" FPSection}] ")" [":" qualident].
-FPSection = [VAR] ident {"," ident} ":" FormalType.
-FormalType = {ARRAY OF} qualident.
+FPSection = ["var"] ident {"," ident} ":" FormalType.
+FormalType = {"array" "of"} qualident.
</pre>
- <pre>module = MODULE ident ";" [ImportList] DeclarationSequence
- [BEGIN StatementSequence] END ident "." .
-ImportList = IMPORT import {"," import} ";".
+ <pre>module = "module" ident ";" [ImportList] DeclarationSequence
+ ["begin" StatementSequence] "end" ident "." .
+ImportList = "import" import {"," import} ";".
import = ident [":=" ident].
</pre>