BaDahRenn1985

CALIFORNIA STATE UNIVERSITY, NORTHRIDGE
MINIPAS -- A COMPREHENSIVE ERROR-CHECKING
COMPILER FOR PASCAL
A graduate project submitted in partial satisfaction of
the requirements for the degree of Master of Science in
Computer Science
by
DahRenn Ba
May 1985
The graduate project of Dah Renn Ba is approved:
Robert Henderson
Michael Barnes
Jack;Alanen, Chairman
California State University, Northridge
111
TABLE OF CONTENTS
Page
DEDICATION • • •
...
iii
........
LIST OF FIGURES
ABSTRACT •
...
CHAPTER 1:
Motivation •
1.2
Goals
CHAPTER 2:
......
1
1
INTRODUCTION •
.......
......
......
4
7
.
2.1
The Language Minipas
2.2
Compiler Options and External Files
2.3
Limitations of Minipas •
7
9
10
....
3.4
.
The Structure of Minipas Compiler .
Error Recovery Strategy . . . . . .
The Treatment of Lexical Errors
..
.
The Treatment of Syntactic Errors
3.5
Error Reporting
25
3.6
Organization of the Symbol Table •
29
3.7
The Treatment of Semantic Errors •
34
CHAPTER 3:
3.1
3.2
3.3
'
vii
MOTIVATION AND GOALS •
1.1
vi
THE MINIPAS COMPILER
CHAPTER 4:
IMPLEMENTATION DEPENDENCIES
CHAPTER 5:
CONCLUSION •
..
..
..
..
..
11
11
14
16
19
39
.....
42
REFERENCES •
44
APPENDICES • •
45
A.
Backus-Naur Form for Minipas
B.
Syntax Diagrams for Minipas •
c.
Program Listing for Minipas • .
d
iv
45
....
50
56
86
06
• • • • • • • • • • • · •
sa6~ssaw ~o~~~
·a
LIST OF FIGURES
Page
An Invalid Program Compiled by Pascal 6000
2
Hierarchical Structure of Primary Compiler
Procedures
12
Pseudo Code of While Statement
23
.......
Pseudo Code for Procedure Test
An Invalid Program Compiled by
Structure of the Symbol Table
vi
........
......
...
...
Mini pas .
...
........
23
28
35
ABSTRACT
MINIPAS -- A COMPREHENSIVE ERROR-CHECKING
COMPILER FOR PASCAL
by
DahRenn Ba
The system described in this report is a comprehensive error-checking compiler for a subset of Pascal
called Minipas.
It is designed for students with limi-
ted experience in debugging erroneous Pascal programs.
The Minipas compiler only handles the early two stages of
the compilation process, that is, lexical analysis and
syntax
analysis~
no object code is generated.
It is
coded in Pascal 6000[4] and implemented on a CDC Cyber
170 with NOS operating system.
Chapter 1 of this report
explains the motivation and goals for the project.
Chapter 2 defines the language
Minipas~
a complete syntax
description in terms of BNF (Backus-Naur Form) and syntax
diagrams is given in an appendix.
The syntax diagrams
closely reflect. the structure of the compiler.
Chapter 3
describes the internal organization of the compiler.
It
starts with an explanation of the error types (lexical,
vii
syntactic, and semantic errors) and their corresponding
recovery strategies.
Various compiler tables (symbol
tables) and their data structures are also discussed in
detail.
These tables are valuable tools in detecting
semantic errors.
Chapter 4 examines machine-dependency
problems, that is, compiler portability.
Typical
problems involve the range of available integers and
character sets.
Chapter 5 concludes the report.
It
discusses the successes and failures of the Minipas
compiler.
The Minipas compiler did achieve its primary
goal--to produce good error messages if errors were
detected.
However, the exclusion of text files and
record structures from Minipas severely limits the
utilization of the compiler.
If Minipas were to be
used by the target users for their more advanced programming assignments, the non-variant record and text
file should be included in the language.
viii
CHAPTER 1
MOTIVATION AND GOALS
1.1
MOTIVATION
The process of correcting compilation-time errors
in an erroneous program can be a painful one.
This is
especially true for a novice student programmer who
lacks the experience to interpret error messages issued
by compilers.
The difficulty comes from the fact that
many error messages issued by a compiler do not deal
with the error directly.
point clear.
An example will make this
Figure 1.1 is a listing of a Pascal
program together with the error messages issued by the
CDC Cyber 170 Pascal 6000 compiler.
Figure 1.1 high-
lights important points when locating and correcting
errors.
1.
Some of the error messages provided by the
Pascal 6000 compiler are very clear.
For
example, error number 55 appearing after
line 10 says "TO or DOWNTO expected".
It
should be clear that neither a TO nor a DOWNTO
is included in line 10.
2.
Unfortunately, many error messages produced by
this compiler are not easy to understand.
This
is often because the error has concealed the
programmer's intention and prevented the
compiler from determining what type of
1
2
I
Q
T
1
PASCAL <D1PILER- E.T.H. ZWUCH
I
UNIVERSITY OF MINNESCYI'A
CALIFORNIA STATE UNIVERSITY CYBER 170
000004
000040
000040
000040
000040
000041
000042
000043
000067
000067
000030
000030
000031
000032
000034
000040
000041
000041
000041
000041
000063
1 PROORAM FIND(ourpur):
2 CDNST
MAX= 20
3
4 VAR
5
FOUND : PDOLEAN:
6
I : INTEGER:
7
KEY : INTEX3ER:
8
LIST : ARRAY[ 1 •• MAX] OF INrEGER:
9 BEGIN
MAX DO LIST[I] ::::I;
FOR I :=1 I
10
'6
'55
*****
11
FOUND := FALSE:
'104
*****
12
KEY :=10:
13
I :=1:
WHILE (I <= MAX) and (Nar FOUND) DO
14
'104'135
*****
IF LIST[I] = KEY THEN
15
16
FOUND := TRUE:
'104
*****
17
ElSE
'6
*****
18
I := I + 1:
19
IF FOUND THEN
'104
*****
WRITE( 'KEY ,KEY, • IN rosiTICN •
20
21 END:
'6
*****
I
*****
INCXlvtPLETE PROGRAM.
<XM'ILER ERroR MESSAGE ( S) •
6:
55:
104:
135:
UNEXPEcrED SYMOOL.
'TO' OR ·~· EXPECI'ED.
IDENTIFIER Nar DECLARED.
TYPE OF OPERAND MUST BE BCX:JLEAN.
Figure 1.1
AN INVALID PROORAM <D1PILED BY PASCAL 6000
I):
3
statement was really wanted.
Some error mes-
sages report nothing but that an error exists.
For example, on line 17, error number 6
(unexpected symbol) is pointing to the reserved keyword ELSE, which is actually legal, but
not in this context.
To determine what went
wrong, the programmer might first compare the
statement in question with the syntax of a
statement of that type, in this case an IF
statement.
Usually, this will locate the source
of the error immediately.
Here, the problem is
that a semicolon appeared before the ELSE.
In
Pascal, semicolons are used only to separate
statements, not to terminate statements.
Since
there is no ELSE statement, a semicolon can
never appear before ELSE.
3.
Error number 104 (identifier not declared)
occurs every time the variable FOUND appears
in the program.
The problem is that the var-
iable FOUND has been misspelled in the variable
declaration (a zero is typed instead of the
letter "0").
4.
There is usually not a one-to-one correspondence
between the number of error messages from the
compiler and corrections to be made.
Often, a
single error will generate multiple error
.
il
4
messages.
For example, line 10 has two error
messages, but both of them can be corrected by
changing the comma to the reserved keyboard TO
(in this example, it is intended to be a TO, not
DOWNTO).
5.
Frequently, the compiler is forced to skip some
program text because of syntax errors.
There-
fore, it might be necessary to run the program
again in order to eliminate all the errors.
6.
Line 21 contains a cryptic phrase "incomplete
program", which was caused by the end of file
mark being unexpectedly encountered while processing the program.
In order to help an inexperienced programmer overcome these problems, Minipas was implemented.
1.2
GOALS
The primary goal is to provide the inexperienced
programmer with a good-error-message Pascal compiler.
The compiler, when invoked, should parse a Pascal program
and produce accurate and meaningful error messages when
errors exist.
If the source program is syntactically
correct, then it should be passed to Pascal 6000 to
create executable code.
Another goal is that the system
must process a strict subset of standard Pascal, that is,
every Minipas program must also be acceptable by any ANSI
Pascal compiler without any modification.
This goal
5
makes it easy for students to switch over to a regular
system without noticing any differences.
Since the primary goal is to produce good error
messages, the following characteristics of good error
messages must be present.
1.
Error messages should be specific, pinpointing
as closely as possible the place in the source
program where the errors were detected.
2.
Error messages should not be written in technical terms significant only to persons already
familiar with Pascal.
3.
An error message should not be redundant.
In
particular, if a variable is not declared, it
is only necessary to report that fact once, not
every time it is referenced.
4.
An error message should indicate the true and
exact nature of the error discovered.
For
example, if a semicolon is inserted before the
symbol ELSE, then the error message should say
just that and not "unexpected symbol".
s.
The compiler should be designed to gracefully
recover from syntax errors and, after reporting
an error message, to continue compiling.
This
policy would allow many errors to be detected
from a single compilation.
6.
Spurious error messages, that is, irregular
situations caused by previously reported errors,
•passa~ddns
9
aq p1noqs
CHAPTER 2
INTRODUCTION
2.1
THE LANGUAGE MINIPAS
The choice of Pascal features to be included in
Minipas is primarily guided by the contents of introductory programming courses.
The power of a language and
its range of application really depend on its data type
and associated operators.
heres to Pascal closely.
In this respect, Minipas adIts primitive data types are:
integer, real, Boolean, and char.
Scalar types and sub-
range types are also included in their full generality.
The only data structure included in Minipas is the
array.
Excluded are the record, set, pointer, and file
data structures.
The two exceptions are the standard
text files input and output which are declared implicitly
(but must appear in the program heading).
Also, none of
the packing operations (packed array, packed record) are
implemented.
The choice of data types, data structures, and associated operators determines the complexity of a language.
Statements and control structures have only a
little share in it.
Minipas includes most of Pascal's
statements (case, for, if, repeat, while, assignment, and
compound statements).
statements.
Excluded are the with and goto
The former is excluded because the corres-
ponding data structure (record) was not implemented.
7
The
8
latter was deliberately excluded, since the primary usage
of Pascal is to encourage structured programming.
Pro-
cedures and functions are fully implemented with the
exception that procedures and functions themselves may
not be passed as parameters.
Recursive procedures and
functions are allowed, but forward reference is not
implemented.
In summary, the standard objects of Pascal available
in Minipas are as follows:
Constants
true, false, char, integer, real,
string (only in write and writein)
Types
integer, real, Boolean, char, scalar,
subrange
Functions
abs, sqr, odd,
chr, ord,
succ, pred,
round, trunc,
sin, cos, exp, ln, sqrt, arctan,
eof, eoln
Procedures -- read, readln,
write, writeln
The programmer is free to define his or her data
structures (arrays, enumerated types) as well as block
structures {procedures and functions).
The statements and control structures of Pascal
available in Minipas follow:
9
program
assignment
case
compound
for
if then else
repeat until
while do
procedure call
The user is referred to three manuals for the
details of these procedures, functions, and control
structures.
The first is the Pascal User Manual and
Report [1], the second is Standard Pascal [2], and the
third is Pascal 6000 [4].
2.2
COMPILER OPTIONS AND EXTERNAL FILES
The Minipas compiler uses 5 external files; they are
INPUT, OUTPUT, AAAAERR, AAAEMSG, and AAAARUN.
The first
four files are of type text while the last file contains
the object code for the compiler itself.
The user should
avoid using these file names when running a Minipas program.
The file INPUT should contain the source program.
The file OUTPUT should contain the source program listing
and the error messages (if any).
are held in file AAAEMSG.
The compiler messages
The compiler will create a
local file called AAAAERR which can be run as a NOS procedure (command) file.
If the source program has no
10
errors, then the NOS global register 1 (RlG) will
be set to 1; otherwise, it will be set to 2.
The file
AAAAERR is referenced by another command file called
MINIPAS which will inspect the value of RlG so that it
will know whether or not the object module can be
executed.
Only two compiler options are available--the option
NL means "no listing" (the default is listing); the
option GO means "to execute the object code" (the default
is not to execute it).
These are the same defaults as
those for Pascal 6000.
2.3
LIMITATIONS OF MINIPAS
When any one of the following limits is reached,
Minipas immediately terminates compilations with the message "your program contains too many identifiers" issued.
1.
The maximum number of identifiers is 200.
2.
The maximum number of blocks (procedures and
functions) is 20.
3.
The maximum number of arrays is 30.
4.
The maximum number of block nesting is 7.
5.
The maximum number of real constants is 20.
6.
The maximum number of dimensions for an array
is 7.
7.
The maximum of subrange types is 30.
8.
The maximum number of case labels in a single
case statement is 30.
'
!l
CHAPTER 3
THE MINIPAS COMPILER
3.1
THE STRUCTURE OF THE MINIPAS COMPILER
Minipas is a language that can be parsed with a
lookahead of a single symbol.
The compiler therefore
uses the simple and easy-to-implement method of top down
parsing known as recursive descent [5,6,7].
The entire
compiler is organized as a set of procedures, where each
represents a specific syntactic construct (nonterminal)
with a specific parsing goal.
each other recursively,
The procedures may call
just as certain syntactic
constructs are defined recursively.
The hierarchical
structure of the compiler is shown in Figure 3.1.
The
procedures in Figure 3.1 closely mirror the syntactic
structure given by the BNF for Minipas.
Before going
into the details of these procedures, it is useful to
consult the syntax diagrams in Appendix B, since they
represent the abstract flow-charts for the compiler procedures.
Some of the syntax diagrams are not used
directly as a model for the corresponding compiler procedures.
The reasons are twofold.
First, there are
distinctions between several types of identifiers,
(constant, type, variable, procedure, and function
identifiers): although they do not differ syntactically
from each other, they do
diffe~
semantically from each
other. For the syntax diagrams where these identifiers
11
12
program minipas
procedure insynibol
procedure block
procedure constant
procedure typ
procedure scalar
procedure subrange
procedure sinple-type
procedure array-type
procedure parameterlist
procedure constant-declaration
procedure type-declaration
procedure procedure-declaration (includes function)
procedure statement
procedure selector
procedure call
procedure expression
procedure sinple-expression
procedure tenn
procedure factor
procedure standard function
procedure assignment-staterrent
procedure case-statement
procedure cacpound-statement
procedure for-statement
procedure repeat-statement
procedure while-statement
procedure standard-procedures
FIGURE 3 .1
HIERARCliiCAL STRUCIURE OF PRIMARY cn1PILER PROCEDURES
13
appear (in factor, simple type, constant, and statement),
the corresponding complier procedures are slightly modified to recognize the semantic differences between the
types of identifiers.
Second, some of the syntax dia-
grams (block and statement) are complex enough that they
were divided up for separate implementation.
Note that several obviously incorrect syntactic
constructs such as:
VAR R
c
1.5 •• 2.5;
0
••
and
'9':
are not excluded from the BNF or syntax diagram.
also true in the Pascal Report by Wirth[!].
This is
However,
Cooper[2] does exclude these ambiguities from the syntax
of ANSI Pascal.
reasons:
Minipas adopts Wirth's approach for two
to keep the syntax as simple as possible and
because such errors do not require the error recovery
necessary for syntactic errors.
A strict rule observed
by the Minipas compiler is that only syntactic errors may
lead to skipping over part of the input program.
For
example, if in a particular program a procedure is
declared with two parameters but is called with three or
more parameters, the extra parameters should be compiled
completely instead of ignoring the program text up to the
closing parenthesis.
14
3.2
ERROR RECOVERY STRATEGY
The Minipas compiler uses the following four stra-
tegies to recover from syntax errors:
1.
Abort the compilation entirely.
This strategy
is only used when limits of various compiler
tables are reached (see Section 2.2).
2.
Ignore the remainder of a statement in which an
error is discovered.
This strategy is often
referred to as panic mode.
It is used when
there is no point to continue compiling the
remainder of a syntactically invalid statement.
In a statement in which an error may occur in a
number of ways, such as an extra comma or missing operand in the example
READLN,N);
it is difficult to continue the analysis of the
statement after the point of error.
For these
types of errors a good way to react is to skip
the remainder of the statement and to resume
compiling after the end of the statement marker,
which in this case is a semicolon.
3.
Attempt to continue compiling the statement in
which the error occurred.
The value of this
strategy is that it might detect additional
errors in the erroneous statement, errors which
would not be detected if the simpler panic mode
is used.
The danger of this strategy is that by
15
misjudging how to analyze the remainder of an
erroneous statement, the compiler could generate
a flock of spurious error messages.
This im-
plies that the compiler must find a "safe" place
to continue the parsing process.
For example,
an obvious safe place in the following illegal
variable declaration is the comma symbol
VAR BEGIN, A : INTEGERr
By reporting the error and skipping to the •,•
the compiler can synchronize with the productions of the grammar which define the correct
form of a variable declaration.
How to find
such safe places for various illegal statements
and declarations is discussed in Section 3.4.
4.
Attempt to repair the statement in which the
error occurred by modifying the incorrect code.
Such an attempt is only a guess with respect to
the intended code at the point in which the
error was found.
For example, when the symbol
DO is expected for a while statement but not
found, the compiler could make the reasonable
assumption that the programmer forgot to type
the DO symbol and so insert the DO (not in the
program text) for her or him.
An error message
would still be issued, but the compilation of
that statement would proceed as if the symbol DO
had been there originally.
16
3.3
THE TREATMENT OF LEXICAL ERRORS
The treatment of syntactic errors are done on the
character level by the lexical analyzer (scanner) and on
the symbol level by the syntax analyzer (parser).
The
scanner converts the external input sequence of characters (source program) into an internal format (tokens
or symbols) more suitable for manipulation by the parser.
It is implemented via a procedure INSYMBOL whose main
task is to get the next valid symbol for the parser.
The
tasks performed by the scanner follow:
1.
It skips the separators, such as blanks, new
lines, conunents, and line numbers (if any).
2.
It recognizes non-reserved words as identifiers.
The actual identifier is assigned to a global
variable called ID.
Identifiers may be of any
length but must differ amongst the first ten
characters, if their difference is to be
recognized.
3.
It recognizes the reserved keywords such as
BEGIN, ELSE, etc.
The reserved keywords are
stored in a sorted linear table called KEY.
Whenever the scanner finds the input sequence of
characters constitutes a word, it first does a
binary search on table KEY.
If it matches a
keyword, then the corresponding symbol for that
keyword is returned; if it does not match, then
17
it is treated as an identifier.
The keyword
symbols are stored in table KSY.
The index for
each keyword in table KEY is in parallel with
the index of its corresponding symbol in table
KSY.
4.
It recognizes sequences of digits as numbers.
The actual value is assigned to global variables
INUM (integer number) and RNUM (real number).
5.
It recognizes string literals.
If the length of
a string literal is unity, then it is classified
as type char.
6.
It recognizes the special symbols, such as
1
*
1
1
<> 1
1
,
:
=
1
,
etc.
1
+
1
,
These special symbols are
stored in a linear table called SPECIALSYMBOL.
Two scanner problems are worth discussing.
The
first one is related to source program comments.
program contains an opening comment
corresponding closing comment
1
*)
1
,
1
(*
1
without a
the rest of the
program would be entirely skipped by the scanner.
is no satisfactory solution for this
If a
problem~
There
it is up
to the programmer to find the location of the closing
comment.
The compiler will give an indication that a
closing comment is missing.
However, it does not know
where the closing comment should be inserted into the
source program.
The second problem is associated with
a missing single quote at the end of a string literal.
The solution to this problem is to impose an artificial
18
limit on the size of a string literal.
The rule is
simple -- a string literal must be completely quoted
within a single line.
In this way, only the rest of the
input line may be treated as part of the string literal.
In order to scan the input sequence of characters,
procedure INSYMBOL uses a local procedure, NEXTCHAR, to
get the next character.
Apart from this main purpose, it
also:
1.
Recognizes and suppresses the end of line
character.
2.
Copies the input onto the output file, thereby
generating the source program listing.
3.
Prints the line number at the beginning of each
line.
4.
Recognizes the end of file mark.
The scanner constitutes the necessary one-symbol
lookahead.
Moreover, the procedure NEXTCHAR represents
an additional lookahead of one character.
Therefore the
total lookahead of the compiler is one symbol plus one
character.
The following errors are processed by the scanner:
1.
Illegal characters, such as '#',
'$',
'%', etc.
Note that these characters are legal if they are
part of a string literal.
2.
Large numbers (integer or real) that do not fall
within the permissible range of the host
machine.
19
3.4
3.
Missing quote at the end of a string literal.
4.
Null string, that is, a string of length zero.
5.
Missing closing comment symbol.
THE TREATMENT OF SYNTACTIC ERRORS
Error recovery on the symbol level is more compli-
cated than that for the character level.
It is a fact
that no error recovery scheme can be foolproof since
that would involve reading the mind of the programmer.
Every error recovery strategy, no matter how reasonably
coded, will inadequately handle some illegal constructs.
However, a good compiler should possess the following
characteristics:
1.
No input sequence will cause the compiler to
blow up.
2.
All illegal constructs are detected and reported.
3.
Frequently occurring errors are correctly
diagnosed and do not cause any further difficulties to the compiler (that is, do not cause
the compiler to produce spurious error
messages).
The Minipas compiler observes these rules.
The
following error recovery strategy is based on the text by
Backhouse[3].
Let T be the set of all terminal symbols of Minipas
extended by the symbol eof (end of file).
T
=
Minipas terminal symbols
U
Thus
{eof}
20
Let S be the set of compiler states, where each
state can be perceived as a syntactic construct, that is,
a statement, a factor, a constant, etc.
B).
(see Appendix
The treatment of syntactic errors consists of ex-
tending the state transition function TRANS : S x T -->
to become a total function.
s
Similarly, the function
LEFT : S x T* --> T* which defines the rest of the program left for analysis when passing from a state to its
successor has to be made total.
The error recovery now
becomes a matter of associating each compiler state s
E
S
with a set of terminal symbols R, namely the symbols
which are relevant when the compiler is in state s.
Should the symbol t E
T returned by the scanner happen
to be unacceptable in the current state, then
1.
An error message is issued:
2.
The rest of the program is skipped until a
symbol t'
E
R is reached.
The functions TRANS and LEFT must be synchronized in
such a way that the compiler will, without skipping t',
advance to a new state s' in which t' is a member of R.
Therefore, each phase of skipping is followed by the
acceptance of at least one symbol so that the compiler
can recover immediately from any syntax error.
The
choice of Rand the next state s' essentially determines
the effectiveness of this error recovery scheme.
Any
choice of R must fall between the following two extremes.
1.
R
=T
for all states s E
s.
21
2.
R = L(s)
U
{eof}, where L(s) is the set of
symbols which can be accepted in state s.
Error
recovery in this case consists of skipping the
rest of the program until an acceptable symbol
or eof is reached.
Clearly, neither of the two extremes should be
employed in practice.
ever be skipped.
In the former, no symbol would
In the latter, only the locally rele-
vant set of states (s) is considered while the globally
relevant set of next states (s'} is not taken into
account.
Under the Minipas implementation, R is always
composed of a set GLOBAL of global relevance -- which is
passed by value parameter to the called procedure (this
parameter is named FSYS in the compiler) -- and a locally
relevant symbol LOCAL depending on the local situation.
Therefore R = GLOBAL
U
LOCAL.
relevant symbol is ever skipped.
In this way, no globally
R is initially equal to
the set { eof, CONST, TYPE, VAR, PROCEDURE, FUNCTION,
BEGIN, CASE, IF, FOR, REPEAT, WHILE}.
Besides eof, which
necessarily belongs to this set, it contains all the
.symbols that uniquely open a declaration or a statement.
In order to keep the compiler as simple as possible,
error recovery is always completed up to the called procedure (instead of the calling one).
For the called
procedure in the parser this means that:
1.
It may not make any assumption about the rest
of the program which was left to it for
22
analysis.
In particular, it may not assume
that the rest of the program starts with a
locally relevant symbol (that is, relevant to
the called procedure).
Therefore, the called
procedure must test the rest of the program at
the very beginning of its procedure body to
make sure that the rest of the program indeed
begins with a locally relevant symbol.
2.
It has to leave the rest of the program to the
calling procedure in such a condition that the
rest of the program starts with a globally relevant symbol (that is, relevant to the calling
procedure).
This implies that the called pro-
cedure must make a test at the end of its
procedure body to ensure that the rest of the
program starts with a globally relevant symbol.
In this way, no information concerning the error
needs to be passed between the calling procedure and the
called one, and the task of the calling procedure is much
simplified.
The treatment of errors does not take place
at the calling procedure but rather completely within the
called one.
This scheme simplifies the compiler con-
siderably, since, generally speaking, the number of calls
significantly exceeds the number of compiler procedures.
To demonstrate the simplicity of this kind of error
recovery, the compiler procedures WHILESTATEMENT and TEST
(in pseudo code) are shown in Figures 3.2 and 3.3,
23
procedure WhileStatement (G : set
ofT)~
begin
expression (G U {DO})~
if next symbol = DO then
get next symbol
else
error(54)~ (*DO is expected*)
end
FIGURE 3.2 PSEUDO CODE OF WHILE STATEMENT
procedure test (LOCAL, GLOBAL : set ofT; N : integer);
begin
if next symbol is not in LOCAL then
begin
error(N);
while next symbol not in LOCAL U GLOBAL do
get next symbol~
end~
end
FIGURE 3.3 PSEUDO CODE FOR PROCEDURE TEST
.
"
24
respectively.
Before procedure WHILESTATEMENT tries to
compile a Boolean expression following the symbol WHILE,
it adds the symbol DO to the set of relevant symbols (G
is the globally relevant set while {DO} is the locally
relevant set).
If an error is detected in compiling the
Boolean expression (the called procedure), the error
recovery will not skip past the symbol DO.
Syntax
analysis can now continue without skipping any further
symbols until it returns to the calling procedure
WHILESTATEMENT.
It may then resume the normal compila-
tion from the recognition of the symbol DO.
The procedure Test has three value parameters:
1.
The set LOCAL consists of acceptable next
symbols under the current construct (that is,
the locally relevant
set)~
if the current
symbol is not a member of this set, an error
is detected.
2.
The set GLOBAL consists of the stopping symbols
which should not be skipped (that is, the
globally relevant set).
3.
The number N for the pertinent error number.
By observing Figure 3.2 and 3.3, the following two
points can be made:
1.
The error recovery scheme makes good use of the
Pascal concept of a set.
As a matter of fact,
this is one major reason why Pascal was chosen
as the implementation language, since other high
. il
25
level languages available under NOS do not
include such a data structure.
2.
Due to the one symbol Lookahead, the first
symbol of every syntactic construct is already
read at the entry point of the associated compiler procedure.
For example, the procedure
WHILESTATEMENT does not ask for the symbol WHILE
(See Figure 3.2).
Similarly, the first symbol
not belonging to the construct has been read at
the exit point of the called procedure.
3.5
ERROR REPORTING
Two formats for reporting errors are frequently used
by compilers.
In the first format, error messages are
interspersed with the source program
listing~
in the
second format, error messages are clustered at the end of
the source program listing.
The advantage of the first
format is that the error message appears at the same
point where the error is detected, so that the programmer
can see both the error message and the cause of that
error message without having to skip through sheets of
paper on the program listing.
The advantage of the
second method is that by clustering all the error messages at one place, it is unlikely that the programmer
would overlook an error message in the program listing.
There is a danger that in a long program, an interspersed
error might be overlooked, especially if the format of
26
that error message did not make a strong distinction
between it and the normal program listing.
Minipas adopts the clustered format, not for its
advantage but for a disadvantage of the implementation
language -- Pascal 6000.
Note that in order to use the
interspersed format, for the sake of compilation time
efficiency, one of the following two conditions must be
met:
1.
The main memory can absorb the entire list of
error messages.
This allows the compiler to
access the desired error message by its number
without any read delay.
2.
If the main memory is not large enough to cover
all error messages, they must be stored on
secondary memory and read into main memory as
needed.
In this case, the compiler must be able
to randomly access an error message by its
respective error number (file index).
Sequen-
tial access is out of the question, since it
considerably slows down the compiler.
Unfortunately, neither of the conditions are satisfied by the Pascal 6000 system.
First, the error
messages are too large to be held in main memory.
Secondly, Pascal 6000 does not support random access
files.
Hence, Minipas uses the clustered format.
In the compiler, every error message is coded by a
number.
The number of the errors encountered during the
27
compilation process are retained in an error table
called ERRORTAB (a packed Boolean array) •
At the termi-
nation of compilation of an erroneous program, the
compiler calls the procedure ERRORMSG which uses the
ERRORTAB and the external error message file AAAEMSG to
write out the error messages with their respective error
numbers.
This allows the output of detailed error
messages without affecting the storage requirements for
the compiler.
The user is referred to Designing
Computer System Messages [8] for the guidelines of how
to produce more appropriate error messages under the
student environment.
Figure 3.4 shows the output resulting from the
compilation of an invalid program by the Minipas
compiler.
The same program has also been compiled by
Pascal 6000 (compare Figure 1.1).
To assist the
programmer in distinguishing an error number from the
normal program listing, the error number is preceded
by asterisks.
Similarly, the position of the error is
marked with a single quote.
Note that the potentially
redundant error message 'identifier not found' associated with the variable FOUND actually appears only once.
Also, the cryptic error messages 'incomplete program'
and 'unexpected symbol' are replaced by the correct
error messages.
•
i
28
1
2
3
4
5
6
7
8
9
10
*****
11
*****
12
13
14
15
16
17
*****
18
19
20
21
*****
PROGRAM FIND(OUTPUT);
CONST
MAX = 20
VAR
FOUND : BOOLEAN;
I : INTEGER;
KEY : INTEGER;
LIST : ARRAY[1 .• MAX] OF INTEGER;
BEGIN
FOR I :=1 , MAX DO LIST[I]
:= I;
1
6
I 55
FOUND := FALSE;
I
0
KEY := 10;
I : = 1;
WHILE (I <= MAX) and (NOT FOUND) DO
IF LIST[I] = KEY THEN
FOUND := TRUE;
ELSE
'77
I := I + 1;
IF FOUND THEN
WRITE( 'KEY I ,KEY, I IN POSITION
END;
'22
I
I.
I);
ERROR MESSAGES:
0:
THE INDICATED IDENTIFIER HAS NOT BEEN DECLARED.
6:
THE PRECEDING EXPRESSION MAY NOT BE FOLLOWED BY
THE INDICATED SYMBOL.
22:
55:
77:
A PERIOD'.' IS EXPECTED AT THE END OF THE PROGRAM.
CHECK THE CORRESPONDING 'BEGIN' AND 'END' SYMBOLS.
THE SYMBOL 'TO' OR 'DOWNTO' IS EXPECTED.
THE SYMBOL ';'MAY NOT PRECEDE AN ELSE.
FIGURE 3.4
AN INVALID PROGRAM COMPILED BY MINIPAS
29
3.6
ORGANIZATION OF THE SYMBOL TABLE
The task of the compiler with respect to semantic
analysis is threefold.
First, it has to build up the
symbol table to describe the internal data structures
(scalar, subrange, array) and data types (integer, real,
Boolean, char) of the language.
Second, the identifiers
occurring in the program must be kept together with their
associated attributes in the symbol table.
Third, in-
formation gathered in the symbol table has to be used
to check the program for semantic errors.
Before describing the details of the symbol table,
a lesson learned by the author during the coding phase
is worth discussing.
The symbol table was originally
organized as a linked list rather than an array, since
arrays have the disadvantage of fixed length, that is,
they are too large for most programs, but too small for
some others.
In the former case, they are uneconomical
with respect to memory space while in the later case they
would make it impossible to proceed with the compilation
process.
Hence, entries for identifiers and data struc-
tures were dynamically created as needed during run-time
through the call of Pascal•s standard procedure NEW.
This strategy does not work under the restrictions of NOS
and Pascal 6000.
While the compiler program is running,
a call of NEW(P) (P describes the data structure for the
symbol table) would cause Pascal 6000 to ask for more
memory space from NOS, and the program would behave
30
normally if the remaining memory space is large enough
to cover P.
However, if there is no more memory space,
the program execution will be terminated by Pascal 6000.
Regrettably, there is no way for the compiler program to
regain control if the call of NEW fails.
Under these
circumstances, the symbol table was reorganized as a
linear table and all statements and routines that access
the symbol table were receded (a painful process).
The compiler can functionally be divided into two
parts:
the part processing declarations and the part
processing statements and expressions.
Their common
interface is the symbol table TAB, and further associated
tables.
These tables are constructed during the
declaration phase, and contain the necessary information
for compiling the program statements.
Knowledge of the
structure of these tables is a must in order to see how
the various semantic errors are detected by the compiler.
The key table is TAB; each declared identifier will
cause an entry in this table.
The meaning and purpose of
each field in the table are discussed below.
1.
Field NAME contains the character code of an
identifier (only the first ten characters).
2.
PREV is used to link together all the entries of
identifiers to a block (procedure or function).
It is equal to zero for the first identifier
declared in a block.
In this case, zero means
no more prior entries for a block.
• cl
Two book-
31
keeping routines -- procedure EnteriD (enter
an identifier into the symbol) and function LOC
(location of an identifier in the symbol
table) -- use the fields NAME and PREV to enforce the Pascal scope rule.
3.
CONS describes the purpose of an identifier.
An
identifier may denote a constant, a variable, a
procedure, or a function name.
4.
TYP specifies the type of an identifier.
It can
be notype, integer, real, Boolean, character,
enumerated, or array.
Notype is added for the
purpose of semantic error recovery.
An
undeclared identifier or a bad expression has
type notype, and the compiler can use this
information to suppress the output of spurious
errors.
5.
BYVAL specifies whether a formal parameter is a
value parameter to be accessed indirectly or a
variable parameter to be accessed directly.
It
is true for a value parameter, and false otherwise.
6.
ISLCV is used to ensure that the loop control
variable is not assigned within the body of a
for statement.
It is set to true upon entry to
a for-statement, and reset to false after the
body of the for-statement is compiled.
The meaning of the remaining fields varies according
32
to the purpose and type of an identifier.
Hence, they
are discussed in conjunction with the fields CONS and
TYP.
7.
VALUES is used to hold the value of an identifier.
If an identifier denotes a constant and
is of type integer, Boolean, or character, then
the VALUES field holds its value.
If it is of
type real, then VALUES is an index to the table
of real numbers called RCON.
8.
HREF (Host type REFerence) is used to enforce
the structural equivalence rule.
Types Tl and
T2 are structurally equivalent if ordinal type
Tl (integer, Boolean, char, enumerated, and
their subranges) is a subrange of T2 (or vice
versa), or both of them are subranges of the
same host ordinal type.
If the type of an
identifier is array, then HREF contains an
index to the table of structures called ATAB:
if it is a simple type (integer, real, char,
Boolean, subrange, or enumerated), then HREF
contains an index to the table of subrange
structures called RTAB.
9.
TREF is used analogous to the field HREF
above.
The purpose for including it in the
symbol table is twofold:
First, to ensure
that the value of an expression does not fall
33
out of its permissible range; second, to
enforce the name equivalence rule.
Two types
are the same if their definitions can be traced
back to a common identifier.
In particular, the
compiler must use this field to test the assignment compatability between
a.
two arrays {entire arrays, not just two
elements).
b.
the formal variable parameters and their
corresponding actual parameters.
The array table ATAB specifies for each array
structure its index type (XTYP), its element type (ETYP),
and its dimension (DIMEN).
The fields XHREF, XTREF (for
index) and the fields EHREF, ETREF (for element) are used
analogous to the fields HREF and TREF above.
Each procedure and each function causes an entry in
the table of blocks called BTAB.
The field LAST is an
index to the last identifier (in TAB} defined local to
the block.
The pair FIRSTPAR and LASTPAR specify the
addresses (in TAB} of the first formal parameter and the
last formal parameter defined in the corresponding procedure or function.
The table RTAB specifies for each subrange its low
value (L) and high value (H).
These two fields are used
to check for range violations.
Note that the compiler
tables are coded without using any dynamic data structures or pointers.
All the entries in various tables
34
can be accessed through the linked chain.
In the symbol table TAB the first 29 locations are
reserved for the predefined data types, constants, procedures, and functions.
Also, the first 4 locations of
the subrange table RTAB are reseved for integer, real,
Boolean, and char, respectively.
Figure 3.5 shows how
identifiers and their associated attributes are retained
in the symbol table.
The following points can be made
with respect to Figure 3.5:
1.
A multi-dimensional array (in the example,
array A is two-dimensional) is represented as a
single-dimensioned array whose elements are·also
arrays.
2.
Machine-dependencies, that is, the set of available integers, reals, and characters, are
handled by program constants.
They are dis-
cussed in Chapter 4.
3.
To retain the attributes of predefined and user
defined identifiers within the symbol, a record
is the most appropriate data structure.
It
allows a suitable representation of the information collected during the declaration analysis
phase of compilation.
3.7
THE TREATMENT OF SEMANTIC ERRORS
Pascal is a strongly typed language.
Its strong
type concept gives a compiler the opportunity and the
35
Function F( I : integer; var J : integer) : real;
Canst IC • 12;
type T • array( 1 •• 5, 6 •• 10) of 'A' •• 'Z';
var A:T;
BEGIN
...
last lastnar firstnar
..
m
name
cons
tvne
i
isle" values
;
false
false
0
variablt intu:ei false
false
0
J
variabl
inte~~:e1
true
false
0
K
cons tan
inte.re~
false
false
12
functioll
F
I
I
...
bvval
'----J I
real
tvneid
arrav
false
false
0
variablt
arrav
false
false
0
T
A
..
.
.
..
tref
href
r
I
T
i
I
~
I
lI
T
I
!
!
.
prev
. -b
-....__
~
1
!
,,. I
I
i
I
I
l
I I
I
I
!!!!
Xtvne
b.nte~ter
nte~ter
!
i
i
dim en
etY]l
2
arrav
1
Xhret
Xtref
ehref
!U!
'tTDe
low~
in teller -NMAX
DIAX
lreal
EMAX
·EMIR
!Boolean
..
.
0
r; l1nte.4Zer
1
5
4 l1nte.~rer
6
10
A
z
char
FIGURE 3.5
I
..
.
...
l
i ;I
!
l-l
"'~
........
char
!
etre!
i
!
"
I
I
I
~
MAX CHAR
I
I
i
~
!
~
i
I
""'~
lL
STRUCTURE OF THE SYMBOL TABLE:
AN EXAMPLE
36
duty to recognize various context-sensitive errors.
In
order to fulfill this duty, Minipas attempts to achieve
the following goals with respect to semantic errors:
1.
Recognition of context sensitive errors at
compilation time.
2.
Sensible reaction to the use of undeclared
identifiers and multi-declared identifiers.
3.
Sensible reaction to misplaced declarations
{const, type, var, procedure, and function).
Five ad hoc additions were thought necessary in
order to accomplish these goals.
First, if an un-
declared identifier is encountered, an entry is made in
the symbol table TAB for that identifier as if it was
declared so that the error will not be repeatedly
reported.
The problem is that its purpose is unknown.
The solution is simple:
if the identifier is used in a
constant declaration, it is assumed to be a constant:
if the identifier is used in a type declaration, it is
taken as a type identifier: if the identifer is used in a
variable declaration, it is treated as a variable: if the
identifier is used in a statement, it is also treated as
a variable and, therefore, as the left-hand-side of an
assignment statement.
There is no attempt to deal with
the undeclared procedure or function identifiers.
Secondly, a multi-declared identifier is handled in
the following fashion:
if the purpose of the identifier
is constant, variable, or type-identifier, then only the
37
first declaration will be recorded in the symbol table;
if its purpose is procedure or function, then only the
last procedure (or function) declaration will be recorded
in the symbol table.
The third addition is caused by the misplaced
declarations.
As in Pascal, Minipas requires that
declarations appear in a specific order, that is, const
section, type section, var section, procedure and
function section.
The solution is to allow declarations
in any order but to make a test at the end of each
section to ensure that the order of declaration was not
violated.
Fourth, the detection of an illegal usage of the
symbol ELSE (the symbol ';'may not precede the symbol
ELSE) is done by peeping one more symbol into the future.
Hence, the lookahead for an if statement is two symbols.
The justification for this addition is apparent, since
this error is committed by almost every programmer, both
experienced and non-experienced.
The fifth addition is concerned with the empty
statement.
Although empty statements are not visible,
they are generally found between the symbol semicolon and
the symbol END.
As a result, a misplaced semicolon can
cause serious semantic errors.
For example, the follow-
ing while statement is syntactically correct but semantically incorrect (note the position of the semicolon).
' &
38
WHILE Cl DO:
Sl
If the condition Cl is false, then statement Sl will
execute once.
However, if Cl is true, then the program
execution will not stop, since it contains an infinite
loop.
In addition to the while statement, the if state-
ment and for statement are similarly checked by the
compiler.
CHAPTER 4
IMPLEMENTATION DEPENDENCIES
A compiler by its very nature cannot be machine
independent.
After all, the compiler must be expressed
in some language, generate code for some machine, and run
under some operating system.
However in the interest of
program portability, it is desirable to hide these
restrictions and to ignore the hardware through the use
of a high level language (in this case Pascal).
But even
when strictly adhering to a machine-independent language
such as standard Pascal, some machine-dependent problems
cannot be completely ignored.
These dependencies are
manifested in the choice of several constants which are
all declared at the beginning of the program (see
Appendix C).
The choice of these constants, explained
below, must be reconsidered if Minipas is implemented on
a different computer system.
IDMAX
defines the number of characters in the
array ALFA.
In a word-oriented computer
such as the CDC Cyber 170, the choice of
this value is critical, and should equal
the number of characters packable into a
word.
LLNG
defines the maximum length of an input line
delivered by the operating system.
39
40
NMAX
is the maximum value for an integer number.
EMAX
is the maximum value for a decimal exponent
of a real number acceptable by the computer.
EMIN
is the minimum value for a decimal exponent.
Smaller numbers are considered as identical
to zero.
DMAX
is the number of significant digits in a
real number.
covers the array index values.
XMAX
The lower
bound and upper bound of an array must be
within the range of -XMAX •• XMAX.
MAXCHAR
equals the number of characters available
in the hardware character set.
KMAX
is the size of the keyword table.
TMAX
is the size of the symbol table.
BMAX
is the size of the block table.
RCMAX
is the size of the real constant table.
LMAX
defines the maximum nesting of blocks.
CSMAX
defines the maximum number of case labels
in a case statement.
The set constants used in the scanner depend on the
assertion that
ch in ['A' •• 'Z']
=
ch is a letter
ch in ['0' •• '9']
=
ch is a digit
Most available character sets satisfy these equivalences.
Several statements in the scanner compute the numeric
41
value of a digit x as ord(x} - ord('O').
This is the
only requirement imposed on the ordering of character
sets.
CHAPTER 5
CONCLUSION
The Minipas compiler has been used and therefore
tested by a small group of students for one semester.
While helping these students in debugging their program
errors, various bugs and insufficiencies of the Minipas
compiler itself were found and corrected by the author.
Most of these bugs and insufficiencies are related to
error recovery strategies.
For example, a misplaced
declaration (canst, type, car, procedure and function)
can cause great confusion to a one-pass compiler like
Minipas, since it does not yet •see• the future.
Gen-
erally speaking, error recovery is the most difficult
part of the parser and the implementation of an error
recovery scheme requires a careful design.
The diffi-
culty of error recovery is caused by spurious errors.
No
matter how carefully the error recovery mechanism is
designed, spurious errors can result if the parts of the
program in which errors were detected contain any
declaration information.
The ad hoc solution adopted by
the Minipas compiler is to allow declaration in any order
but to make a test at the end of each declaration section
to ensure that the order of declarations was not violated.
In summary, the Minipas compiler achieved its primary goal -- produce good error messages when errors are
detected.
This is so because:
42
43
1.
The error recovery strategy is theoretically
sound and reasonably practical.
It allows the
detection of many errors in a single compilation
while at the same time suppressing the spurious
errors.
2.
The error messages are written in clear, unambigious English phrases and complete sentences.
3.
The error messages are not redundant.
4.
The error messages indicate to the extent
possible, the nature of the error discovered.
On the negative side of the compiler, the following
criticisms apply:
1.
The failure to include the record and file
structures in the language limits the utilization of the compiler.
As a bare minimum, the
non-variant record and text file should be
included in the language.
2.
Uninitialized variables are not checked.
Possible solutions are to require that every
variable be initialized when it is declared or
that every variable be assigned in such a way
that the compiler can easily verify that there
are no references to uninitialized variables •
. il
44
REFERENCES
1.
Jensen, K. and Wirth, N.
Pascal User Manual and
Report (1975), 2nd Edition, Springer-Verlag, New
York.
2.
Cooper, D.
w. w.
3.
Standard Pascal User Manual (1983),
Norton & Company, New York.
Strait, J.P., A. B. Mickel and J. T. Easton.
Pascal 6000 Release 3 (1979), University of
Minnesota.
4.
Backhouse, R.
c.
Syntax of Programming Languages
(1980), Prentice-Hall, Englewood Cliffs, New
Jersey.
5.
Aho, A.
v.
and J. D. Ullman.
Principles of Compiler
Design (1977), Addison-Wesley, Reading, Mass.
6.
Aho, A.
v.
and J. D. Ullman.
The Theory of Parsing,
Translation and Compiling (1972), Prentice-Hall,
Englewood Cliffs, New Jersey.
7.
Davie, A. J. T. and R. Morrison.
Recursive Descent
Compiling (1981), Ellis Horwood, New York.
8.
Shneiderman, B.
Designing Computer System Messages
(1982), Comm. ACM 25:9, 610-611.
SVdiNIW
EO~
WEO~
EQVN-SQ~~Va
V XIGN:3:ddV
46
APPENDIX A
BQcKus-Naur Form CBNF> For Hinipas
In order to describe the syntax of Hinipas, the following
meta-symbols are used.
surrounds literal text.
sepQrates alternatives.
(
]
surrounds optionQl parts.
{
}·
surrounds parts which mQY be repeated zero or more times.
used for grouping.
means "is defined to be"•
used to improve the readability of nonterminal names.
progrQa-headin:l block
=
...
pros r•lm-hend i n:l
"program• identifier "C" ["INPUT/,"] "OUTPUT" ")"
identifi.er
letter {letter : digit}
=
blocK
constant-declaration-part
type-declaration-part
variable-declQration-pQrt
procedure-and-function-declQration-part
statement-po.rt
constQnt-declaration-part
constant
=
=
["CONST" constant-definition
<•;• constant-definition}
identifier •=• constant
constant-definition
sign
...,
[sign] unsigned-number
[signJ constant-identifier
"'" character
•t•
unsigned-number
·-·
=
unsigned-integer
unsigned-integer
unsi:led-real
digit {dl.git>
unsigned-integr •.• digit {digit}
["E" scale-factor]
unsigned-integer "E" scale-fQctor
scale-f•1ctor
[si:lnJ unsigned-integer
constant-identifier
=
identifier
•;•J
47
type-declaration-part
['type' type-declaration (•;• type-declaration> •;•J
=
type-definition
type
identifier
•=•
type.
simple-type l array-type
simple-type
scalar-type
sub r•ln se-t, YP e
type-identifier
'(" identifier <•;• identifierr ">"
=
=
subran9e-type
constant • •• • constant
=
type-identifier
identifier
array-type
= "ARRAY" •c• index-type <",• index-type} "1'
'OF" element-type
index-type = simple-type
element-type
=
type
variable-declaration-part
['VAR' variable-declaration
<";' variable-declaration> •;•J
variable-declaration
= identifier {",' identifier} •:• type
procedure-and-function-declaration-part
={procedure-declaration •;• l function-declaration •;•>
procedure-declaration
function-declaration
procedure-headin9 blocK
=
function-headin9 blocK
procedure-headin9
= 'PROCEDURE' identifier parameter-list
func+,ion-head in9
= 'FUNCTION' identifier parameter-list
p ll ronteter-1 i st
= ['('
formal-para~eter-list
<•;•
....
result-type
for•al-parameter-list> ")'J
forffial-parameter-list = C'VAR'J identifier {'," identifierr
type-identifier
resu 1 t··type
type-identifier
statement-part
=
compound-statement
= 'BEGIN' statement
statement
=
compound-statement
<•;•
statement} 'END'
simple-statement
structured-state~ent
simple-statement
assi9nment-statement
procedure-statement
empty-statement
....
48
empty-statement
variable •:=• expression
: function-identifier •:=• expression
assignment-statement
=
function-identifier
identif'ier
enti re-vo:n iob le
indexed -v•:l r i •lb 1 e
V•lrioble
=
entire-variable
variable-identifier
=
variable-identifier
array-variable •r• expression
<•,• expression} "J"
=
indexed-variable
identifier
orray-variable = variable
e:{pressiDn
= simplw-expressiDn [relational-DPHrator
simple-expression]
.........
·=·
relational-operator
·<=·
·>=·
.....
/
simple-expression
= Csignl term {adding-operator term}
addin~-operator
term
=
·-·
= •t•
"OR"
factor <multiplying-operator factor}
= "*"
multiplyin~-operator
"DIV"
f•lctor
•;•
"MOD"
"f'tN[I"
variable : unsigned-constant : "<"expression ")"
function-desi~nator : "NOT" factor
unsigned-number
••• character •••
constant-identifier
unsi~ned-constant
function-designator
function-identifier
= function-identifier ["("
actual-para~eter
<"," actual-parameter} ">"J
actual-paraaeter
variable
=
: expression
procedure-statement
=procedure-identifier["(" actual-paraaeter
(•,• actual-parometer} ")"]
procedure-identifier = identifier
structured-stotement
=
conditional-statement
compound-stotement
conditional-statement
repetitive-statement
if-statement : case-statement
if-stat.ement
"IF" expression "THEN" statement ["ELSE" statement]
=
case-state~~tent
"CASE" expression "OF"
49
case-list-element
<•;• case-list-element}
"END"
case-list-element
=
[case-label-list •:• statement]
case-label-list =constant {"," constant>
repPtitive-statement
wh i le-st,•ltemet
rep eo. t -s to:.\ temet
fo r-s t•l temen t
wh i le-sto:\tement
= "WHILE" expression •no• statement
repeat-statement
"REPEAT" statement
~
<•;• statement} "UNTIL" expression.
for-statement
= "FOR" control-variable
•:=•
for-list •no• statement
control-variable = entire-variable
for-list= initial-value ("TO"
initial-value = expression
final-value
expression
"DOWNTO"J final-value
OS
SVdiNIW
~0~
SW~~VIG
S: XIGN:3:ddV
XV~NXS
51
Identifier
[letter
letter
J
Unsigned integer
---------------tr--~)· digit
J
Unsigned Number
-----~Unsigned
T
integer
digit
tr~.._E_C__:_J_-_u_n_s_~_·
g_n_e_d_i_n_t-eg_e_r-'r
Unsigned constant
--------~)~
constant identifier
-------+)
unsigned number
---------------~{
character
)
_
~
Constant
-r+-----if---~c
con.tant identifier
unsigned nur.ber
--------character
----t
!~T--+)
----------~J
J
-
52
Simple type
type identifier
--""A-~
t
.r
identifier
constant - - -
•• -constant
type
--~-----------------~~ simple type
L
ARRAY
-
sim?le type
Variable
---variable identifier
Factor
--~---------+unsigned
constant
1------+ variable
1----------function identifier
(
~expression
NOT ___,.factor
~)
---------------~~
~
1 -
OF -
type
t
i
53
terl!l
factor
/
"
*
~actor
+/
J,
'll
"'
DIV
z.mo
J.,
,J,
"'
A.~D
,1,
simple expression
L
+
+
term i:-(_
":c
-
OR
__.J._.J,....__.I
expression
---~)
simple expression
1
lllJJJI
=
<>
>
>=
<
<=
~~~l~~*~*~~*~~*L--------
simple expression
J
>
Parameter list
L(
'?'XJ~) ide~~.~~
--,c-llr"--_VAR
_____
l_)__.._t_y_p_e_i_d_e_n_t_if_l._'e-r-L
f_i_:_r__
)
1
54
State:!lent
r
~
,
function identifier --,
T
var~able
procedure identifier
17
~BEGIN
"'
(
statement
I
~~'SE ~ expre••ion->OF~con~t~
;
;
~ FO~
•
)
I
END
ELSE- state;nent
- otate~entt
:
1
E~ID
(
expression
~REPEAT~ statement
~
/
!
:
-
express~on
----'>
expression
------3>
--.IF ""*' expression-THEN- statenent
f----.>- \vHILE
:=
DO -statement
m~TIL
I
----1"" ex[>res s
variable identifier-:= --> expression
r
ion
Dat':NTO
TO
I
I
----1
I
~expression-
no-
statement
•
55
Bloc\
CO~ST
~
i
'
TYPE
PROCEDURE
~ FU~CTIO~ ~
BE3I~
~
identifier
~
identifier
t
---+
identifier
identifier~
1
~
-1
stater:~ent
identifier
type
<
--7 pa rarneter list
parameter list
Prograr:1
PROGR.A:-1
constant
I
~- block
;
H
~
(
_1
VAR
=
identifier
,
~
---+
type identifier
9S
SVdiNIW
~0~
DNiiliSI~
;) XIGN3:ddV
W~DO~d
57
/
00100
00140
00180
00.220
00260
00300
00340
00380
00420
00460
00500
00540
005BO
00620
00660
00700
00740
00780
00820
00830
00860
00'700
00940
00980
01020
0.1060
01100
01140
01180
01220
01260
01300
01340
01380
01420
()1460
01500
01540
01580
01620
01660
01700
01740
01?80
01820
01860
01 '700
01940
01980
02020
02060
02J.OO
0214()
021.80
02220
02260
0::'300
02340
02380
02420
PROGRAM MINIPASCINPUTt,OUTPUT,EMSG,AAAAERR>;
<*
DAHRENN BA DECEMBER 15, 1984 *>
LABEL 99;
CONST
KMAX =
39; <* NUMBER OF KEY WORDS *>
IDMAX =
10; <* NUMBER OF SIGNIFICANT CHARACTERS IN IDENTIFIEI
LLNG =
80; <* INPUT LINE LENGTH *>
EMAX = 322; <* MAXIMUM EXPONENT OF REAL NUMBERS *>
EMIN = -294; <* MINIMUM EXPONENT OF REAL NUMBERS *>
DMAX =
14; <* MAXIMUM NUMBER OF SIGNIFICANT DIGITS *>
TMAX
200; C* SIZE OF SYMBOL TABLE *>
BMAX =
20; <* SIZE OF BLOCK TABLE *>
AMAX =
30; <* SIZE OF ARRAY TABLE *>
RMAX
30; <* SIZE OF RANGE TABLE *>
RCMAX = 20; <* SIZE PF REAL CONSTANT TABLE *>
CSMAX = 30; <* MAXIMUM NUMBER OF CASES *>
LMAX =
7; <* MAXIMUM NUMBER OF LEVELS *>
ERMAX = 100; <* MAXIMUM ERROR NUMBER *>
XMAX
131071; <* 2**17 -1 *>
MAXCHAR
63;
NMAX
281474976710655;
<* MAXINT 2**48 -1 *>
LINELENG = 128; <* OUTF~T LINE LENGTH *>
<**>
TYPE SYMBOL= <EOFSY,RESERVED,INTCON,REALCON,CHARCON,STRING,
NOTSY,PLUS,MINUS,TIMES,IDIV,RDIV,IMOD,ANDSY,ORSY,
EQL,NEQ,GTR,GEQ,LSS,LEQ,
LPARENT,RPARENT,LBRACK,RBRACK,COMMA,SEMICOLON,PERIOD
COLON,BECOMES,CONSTSY,TYPESY,VARSY,FUNCTIONSY,
PROCEDURESY,ARRAYSY,RECORDSY,PROGRAMSY,IDENT,
BEGINSY,IFSY,CASESY,REPEATSY,WHILESY,FORSY,
ENDSY,ELSESY,UNTILSY,OFSY,DOSY,TOSY,DOWNTOSY,THENSY>
INDEX
-XMAX •• tXMAX;
ALFA
PACKED ARRAY [l •• IDMAXJ OF CHAR;
CONSTRUCT = CKONSTANT,VARIABLE,TYPEID,PROZEDURE,FUNKTIONJ;
TYPES = CNOTYP,INTS,REALS,BOOLS,CHARS,ENUMER,ARRAYS);
SYMSET = SET OF SYMBOL;
TYPSET = SET OF TYPES;
ITEM
= RECORD
TYP : TYPES;
CONS : KONSTANT •• VARIABLE;
l·iF:EF : INDEX;
TREF : INDEX;
VALUES : INTEGER;
END;
<**>
VAR
SY : SYMBOL;
<* CURRENT SYMBOL READS IN *>
PSY : SYMBOL;
<* PREVIOUS SYMBOL *>
ID : ALFA;
<* CURRENT IDENTIFIER READS IN *>
INUM : INTEGER;
<* CURRENT INTEGER READS IN *>
RNUM : REAL;
<* CURRENT REAL NUMBER *>
SLENG : I NTEGEf~;
C* LENGTH OF CHAR STRING *>
CH : CHAR;
<* CURRENT CHAR READS IN *>
LINE : ARRAY[1 •• LLNGJ OF CHAR;
GC : INTEGER;
<* CHARACTER COUNT *>
LL : INTEGER;
<* LENGTH OF CURRENT LINE *>
LN : INTEGER;
<* LINE NUHBER *>
ERRPOS : INTEGER;
f'ROGNf'IHE : ALFA;
IFLAG, OFLAG, OK : BDOLEf'IN;
o;,.~46o
CONSTBEGSYS,TYPEBEGSYS,BLOCKBEGSYS : SYMSET;
02500
FACBEGSYS,STATBEGSYS,INDEXBEGSYS
SYMSET;
02540
KEY
ARRAY[1 •• KMAXJ OF ALFA;
02580
KSY : ARRAY(t •• KMAXJ OF SYHBOL;
. v
58
02620
02660
02700
02740
02780
02820
02860
02900
()2'?<10
02~1'80
03020
03060
03100
03140
03180
03220
03260
03300
03340
03380
03420
03460
03500
03540
03580
03620
03660
03700
0:3740
03780
03820
03860
03900
03940
03980
04020
04060
04100
04140
04180
04220
04260
04300
04340
04380
04420
04460
04500
04540
04580
04620
04660
04700
04740
04780
04820
04860
04900
04940
04980
05020
05060
05100
05140
05180
05220
SPS : ARRAY[CHARJ OF SYMBOL; <* SPECIAL SYMBOL *>
Tr A, Dr Rr RC : INTEGER; <* INDEX TO TABLES *>
STANTYPS : TYPSET;
TAB : ARRAY [O •• TMAXJ OF
<*IDENTIFIER TABLE*>
PACKED RECORD
NAME
I'ILFA;
PREV : INDEX;
NEXT : INDEX;
CONS : CONSTRUCT;
TYF' : TYPES;
HREF : INI•EX;
TREF : I NilE X~
BYVAL : BOOLEAN;
ISLCV : BOOLEAN;
VALUES : INTEGER;
END; <* RECORD *>
ATAB
ARRAY [l •• AMAXJ OF
<*ARRAY TABLE*)
PACKED RECORD
XTYP : TYPES;
XHREF : INDEX;
XTREF : INDEX;
ETYP : TYPES~
EHREF : INDEX;
ETREF : INDEX;
DIMEN : INTEGER;
END; <* RECORD *>
ARRAY Il •• BMAXJ OF
<* BLOCK TABLE *>
BTAB
F'ACKEr• RECORD
LAST : INDEX;
FIRSTPAR : INDEX;
LASTPAR : INDEX;
END; <* RECORD *>
RTAB
ARRAY[O •• RMAXJ OF
PACKED RECORD
L : -NMI"'X •• NMAX;
H : -NMAX • • NMI'IX;
END <*RECORD*>;
RCON : ARRAY[l •• RCMAXJ OF REAL;
BLOCKNO : ARRAYCO •• LMAXJ OF INTEGER;
ERTAB : PACKED ARRAYCO •• ERMAXJ OF BOOLEAN;
EMSG,AAAAERR ! FILE OF CHAR;
'**'
PROCEDURE ERRDRCN: INTEGER>;
BEGIN
OK := FALSE;
IF ERRPOS = 1 THEN WRITE<' *****'>;
IF SY = EDFSY THEN
BEGIN
ERTABINl := TRUE;
WRITELNC' ':a,N:2>;
END
ELSE IF CC > ERRPOS THEN
BEGIN
ERTABINJ := TRUE;
WRITE<' •:cc-ERRPOS,'''',N:2>;
ERRPOS != CC t 3;
END
END <*ERROR*>;
'**>
PROCEDURE FATALCN : INTEGER>;
BEGIN
WRITELN;
WRITE<' COMPILER TABLE FOR 'J;
CASE N OF
1
WRITEC'IDENTIFIER'>;
2: WRITEC'PROCEDURE'>;
59
05260
05300
05340
05380
05420
05460
05500
()5540
05580
05620
05660
05700
05740
05780
05820
05860
05900
05940
05980
06020
06060
06100
06110
06140
06180
06220
06260
06300
06340
06380
06420
06460
06470
01.>480
06500
06540
06580
06620
06660
06700
06740
06780
06820
06860
06900
06940
06980
07020
07060
07100
07140
07180
07220
07260
07300
07340
07380
07420
07460
07500
07540
07580
07620
07660
07700
()7740
3
4
5
6
7
8
WRITE<'~RR~YS'>;
WRITE<'LEVELS'>;
WRITE<'C~SES'>;
WRITE<'SUBR~NGES'>;
WRITE<'RE~LS'>;
WRITE<'~RR~Y
DIMENSIONS'>;
END <* C~SE * >;
WRITELN<' IS TOO SMALL'>;
GOTO 99;
END <*FATAL*>;
<**>
PROCEDURE INSYMBOL;
LABEL 1, 9;
VAR Ir J, K, E : INTEGER;
<**'
PROCEDURE NEXTCH;
<* READS IN NEXT CHARACTER *>
BEGIN
IF CC = LL THEN
BEGIN
IF EOS<INPUT> THEN
BEGIN
ERROR<90>;
SY := EOFSY;
CH : = , • I;
END;
IF ERRPOS <> 1 THEN
BEGIN
WRITELN;
ERRPOS := 1;
ENII;
IF SY = EOFSY THEN
GOTO 9
Fl..SE
BEGIN
LN := LN + 1;
WRITE<LN:6,
LL := o; cc := o;
WHILE NOT EOLN<INPUT> DO
BEGIN
LL := LL + 1; READ<CH>;
WRITE<CH>; LINE[LLJ := CH;
END;
WRITELN; LL := LL + 1;
READ<LtNE[LLJ>; <*CLEAR THE END OF LINE *>
END;
END; <* IF CC = LL *>
IF SY <> EOFSY THEN
ItEGIN
cc := cc + 1;
CH := LINHCCJ;
END;
END <* NEXTCH *>;
<**>
PROCEDURE RE~DSTRING;
'JAR C : CHAR;
DONE : [!OOLE~N;
BEGIN
K := o; DONE := FALSE;
WHILE NOT DONE DO
BEGIN
NEXTCH;
IF CH =''''THEN
BEGIN
NEXTCH;
IF CH <> ''''THEN DONE:= TRUE;
I
,
)
;
60
END;
IF NOT DONE THEN
BEGIN
07780
07820
0"?860
0"790()
C I= CH; K I= K + 1;
IF CC = 1 THEN C* NEW LINE MISSING QUOTE *>
()"_7<~40
07980
08020
08060
OBlOO
OB140
08180
08220
OB260
013300
08340
08380
013420
08460
OB500
08540
08580
08620
08.-',60
08700
08740
08780
08820
OB860
013900
08940
013980
09020
09060
09100
09140
09180
09220
09260
09;300
09340
09380
09420
09460
09500
0'1540
09580
09620
09660
09700
09740
09780
09820
BEGIN
K
I= -1;
DONE I= TRUE;
END;
END;
END;
INUM I= o;
IF K = 1 THEN
BEGIN
SY I= CHt"'RCON;
INUM I= ORIICC>;
END
ELSE
IF K = 0 THEN
BEGIN
ERRORC38l;
SY := CHt"'RCON;
END
ELSE
IF K = -1 THEN
BEGIN
ERRORC31l;
SY I= CHt"'RCON;
END
ELSE
SY I= STRING;
END
REt"'DSTRING *>;
( **>
PROCEDURE REt"'DSCt"'LE;
VAR S, SIGN I INTEGER;
BEGIN
NEXTCH; SIGN I= 1; S I= o;
IF CH = ' t ' THEN
NEXTCH
ELSE IF CH = '-' THEN
BEGIN
SIGN := -1;
NEXTCH;
END;
WHILE CHIN ['0'.,'9'J DO
BEGIN
S I= 10
S t ORDCCH> - DRD<'O'>;
NEXTCH;
END;
E I= S * SIGN t E;
END
READSCALE *>;
<*
*
(**)
<*
O'iB60 PROCEDURE ADJUSTSCALE;
09900 VAR S : INTEGER;
09940
D,T I REAL;
CW9BO BEGIN
10020
IF K t E > EMAX THEN
10060
ERRDRC21>
10100
ELSE IF K + E < EMIN THEN
10140
RNUM I= 0.0
10180
ELSE
10220
BEGIN
10260
S I= ABSCE>; T I= 1.0; D I=
1 o:~oo
REPEAT
10340
WHILE NOT ODDCS> DO
1.0380
BEGIN
1o.o;
61
10420
:1.0460
10500
:1.0540
:1.0580
10620
10660
10700
:1.0740
10780
10820
10860
109()()
10940
10980
1.1020
11060
11100
11140
11:1.80
11220
11260
11300
11340
11380
11420
11.460
:1.1500
11540
11580
11620
11660
11700
11?40
11"?BO
11820
11860
11900
11 '140
11.980
12020
12060
12100
12140
12180
12220
. 12260
12300
12340
12380
12420
1 ~!460
12500
12540
12580
12620
1:''(.60
12700
12740
12780
12020
12860
12900
12<140
12980
13020
S
II
END;
:=
:=
S DIV 2;
SGR<Ir>;
·-
·- *
[I
s - 1; T
T
UNTIL s = o;
IF E >= 0 THEN
RNUM
RNUM * T
ELSE
RNUM
RNUM / H
END;
END <* ADJUSTSCALE *>;
<**>
BEGIN <* INSYMBOL *>
IF SY
EOFSY THEN GOTO 9;
1 : WH~LE CH = ' ' DO NEXTCH;
IF SY = EOFSY THEN GOTO 9;
IF CHIN ['A' •• 'Z'J THEN<* IDENTIFIER *)
BEGIN
,
K := o; ID := '
'
REPEAT
IF K < IDMAX THEN
BEGIN
s
··-
=
.
K
:=
K t
1;
ID[KJ := CH;
END;
NEXTCH
UNTIL NOT <CH IN ['A' •• 'Z','0' •• '9'J>;
I := 1; J := KMAX;
REPEAT
K := <I t J) DIU 2~
IF ID <= KEY[KJ THEN J := K - 1;
IF ID >= KEY[KJ THEN I := K t 1
UNTIL I > .J;
IF I - 1 > J THEN
SY := KSHKJ
ELSE
SY := IDENH
END
ELSE IF CHIN ['0'••'9'1 THEN
IF CC = 1 THEN <* LINE NUMBER *>
BEGIN
REPEAT
NEXTCH
UNTIL <CC = 5) OR <NOT CCH IN ['0' •• '9'J>l;
IF CC = 5 THEN NEXTCH;
GOTO l;
END
ELSE
BEGIN
K := O; INUM := o; SY := INTCON;
REPEAT
INUM := INUM * 10 t ORD<CH> - ORD<'O');
K := K t 1; NEXTCH
UNTIL NOT <CHIN ['0' •• '9'J);
IF <K > DMAX) OR <INUM > NMAX) THEN
BEGIN
ERROR<21>;
INUM := 0; K := o;
END;
IF CH = '•' THEN
BEGIN
NEXTCH;
IF CH = '•' THEN <*ARRAY*>
CH := , '
ELSE
BEGIN
.
62
13060
13100
1:3140
13180
. 132?0
13260
13300
13340
1.3380
13420
13460
13500
13540
13580
13620
13660
13700
13'740
13780
1.3820
13B60
13900
13940
13980
14020
14060
14100
1414()
14180
14220
14260
14300
14340
143BO
14420
14460
14500
14540
14580
14620
14660
14/00
14740
14780
. 14820
14860
14900
14940
14980
15020
15060
15100
15140
15180
15220
15260
1~:i300
15340
t::i380
154:W
15460
1.5500
1:'i~·40
15580
15620
15660
SY ;::: REPILCON;
E :::: o; RNUH := INUH;
WHILE CHIN ['0' •• '9'] DO
BEGIN
E:=E-1;
RNUH := RNUH * 10.0 + (ORD<CHJ- ORD<'O'))
NEXTCH;
END;
IF CH = 'E' THEN REPIDSCPILE;
IF E <> 0 THEN PIDJUSTSCPILE;
END;
END <*IF CH = '•' *>
END <* NUMBER *>
ELSE
CASE CH OF
,
BEGIN
NEXTCH;
IF CH == '==' THEN
BEGIN
SY := BECOMES;
NEXTCH;
END
ELSE
SY :::: COLON;
END;
I<
BEGIN
NEXTCH;
IF CH = '=' THEN
BEGIN
SY := LEQ;
NEXTCH;
END
ELSE
IF CH = '>' THEN
BEGIN
SY := NEG;
NEXTCH;
END
ELSE
SY := LSS;
END;
BEGIN
NEXTCH;
IF CH == '=' THEN
BEGIN
SY := GECH
NEXTCH;
END
ELSE
SY := GTR;
...
I
.
nm;
, ,
BEGIN
NEXTCH;
IF CH = '•' THEN
BEGIN
SY := COLON;
NEXTCH;
END
ELSE
SY := PERIOD;
END;
, , , , : REPIIISTRING;
BEGIN
NEXTCH;
IF CH <> '*' THEN
SY := LPPIRENT
I
(
I
:
63
15700
15740
l5'780
15820
t5860
15900
15940
15980
1!>020
16060
16100
16140
16180
16220
16260
16300
16340
16380
16420
16460
1b500
16540
16580
16620
16660
16700
16740
16780
16820
16860
16900
16940
16980
17020
17060
17100
17140
17180
17220
17260
17300
17340
17380
17420
17460
17500
17540
17580
17620
17660
17700
17740
17780
17820
17860
17900
17940
17980
1802()
18060
18100
18140
18180
18220
18260
1.8300
ELSE <* COMMENT *>
BEGIN
NEXTCH;
REPEI'IT
WHILE CH <>
NEXTCH
UNTIL CH = '>';
NEXTCH;
GOTO 1;
END;
END;
't', '-', '*'• '!', ')',
'*'
~=',
',', '[", "J', ' ; '
BEGIN
SY := SPS[CHJ;
NEXTCH;
END;
OTHERWISE
BEGIN
ERROR<24>;
NEXTCH;
GOTO 1;
END;
END <* Cl'ISE *>;
9: END <* INSYMBOL *>;
<**>
PROCEDURE PEEPNEXTSY<PSY,ESY
VAR PCC,PLN : INTEGER;
PCH : CHI'IR;
BEGIN
PCH := CH; PCC := cc;
Pl.N := LN;
INSYMBOL;
IF SY = ESY THEN
ERROR<N>
ELSE
BEGIN
CC := PCC; CH := PCH;
IF PLN <> LN THEN
BEGIN
CC
DO NEXTCH;
:= o;
CH
END;
SY := PSY;
END;
END <* PEEPNEXTSY *>;
( **>
SYMBOL; N
INTEGER>;
:= ' ';
PROCEDURE ENTERID<XO: l'ILFI'I;Xl: CONSTRUCT;
X,., • TYPES;X3 ; INTEGER>;
BEGIN
T := T t 1;
WITH Tt"'EI[TJ DO
BEGIN
NAME := XO; PREV := T - t;CONS := Xl;
TYP := X2; BYVI"'L := TRUE; ISLCV := FALSE;
Vt"'LUES := X3; HREF := ORD<X2>;
TREF := ORD<X2>; NEXT := T t 1;
END;
END <* ENTERID *>;
<**>
PROCEDURE ENTERRI"'NGE<ISI"'RRI"'Y
BOOLEAN;L,H
INTEGER>;
BEGIN
IF L > H THEN
BEGIN
....
L :=
o; H := o;
ERROR<27>;
END;
64
18340
18380
1.8420
18460
18500
18540
18580
18620
lB6.SO
18700
18140
18780
18820
18860
18'700
18940
18980
19020
19060
19100
19140
19180
19220
19260
19300
19340
1 'J380
19420
1.9460
19500
19540
19580
19620
1.9.'-,1.;0
1'J700
19"140
19780
19820
19860
19900
19940
19'i'80
20020
20060
?0100
20140
20180
'20:'20
20260
20300
20:340
20380
IF ISARRAY THEN
IF CABSCLJ > XMAXJ OR <ABS<H>
BEGIN
ERRORC27J;
L
:= o;
H
> XMAXJ THEN
:= o;
END;
IF R = RMAX THEN FATALC6J;
R
:= R
t
1;
RTABCRJ,L := L;
RTAB[RJ,H := H;
END <* ENTERDEX *>;
'**>
PROCEDURE ENTERARRAYCTP : TYPES; HRF,TRF
BEGIN
IF A= AMAX THEN FATALC3J;
A
:=
A t
INTEGER>;
1;
WITH ATAB[AJ DO
BEGIN
XTYP := TP;
XHREF := HRF;
XTREF := TRF;
END;
END <* ENTERARRAY *>;
'**>
PROCEDURE ENTERBLOCK;
BEGIN
IF B = BMAX THEN FATALC2J;
B:=Bt1;
BTABCBJ.LAST := o;
BTABCBJ,LASTPAR := o;
BTABCBJ,FIRSTPAR := o;
END <* ENTERBLOCK *>;
<**>
ENTCRREAL;
BEGIN
IF RC = RCMAX THEN FATALC7J;
RC := RC t 1;
RCONCRCJ := RNUM;
END <* ENTERREAL *>;
P~OCEDURE
'**>
PROCEDURE BLOCKCFSYS: SYMSET; ISFUN : BOOLEAN;
LEVEL,PRT : INTEGER>;
TYPE CONREC = RECORD
TP : TYPES;
I : INTEGER;
RF : INTEGER;
END <*RECORD*>;
VAR PRB : INTEGER; <* B-INDEX OF THIS PROCEDURE *>
X : INTEGER;
'**>
PROCEDURE SKIPCFSYS: SYMSET; N : INTEGER>;
BEGIN
2o4::~o
EF;RORCNJ;
20460
WHILE NOT CSY IN FSYS t CEOFSYJ) DO INSYMBOL;
20500 END <* SKIP *>;
20540
20580 PROCEDURE TESTCS1,S2 : SYMSET;N : INTEGER>;
20620 BEGIN
20660
IF NOT CSY IN S1J THEN
20700
SKIPCS1tS2,NJ;
20740 END <*TEST *>;
20780 '**>
20820 PROCEDURE TESTSEMICOLON<DSYS
SYMSET; N
INTEGER>;
20860 BEGIN
20900
IF SY = SEMICOLON THEN
20940
INSYMBOL
'**'
•
f)
65
20980
21020
~? 1060
21100
. 21140
21180
21220
21260
21300
21340
2L380
21420
21460
21500
21:'i40
ELSE
BEGIN
ERROR<l4>;
IF SY IN [COMMA,COLONJ THEN INSYMBOL;
END;
IF SY <> EOFSY THEN TEST<DSYS,FSYS,N>;
END <* TESTSEMICOLON *>;
<**>
PROCEDURE ENTERID<ID : ALFA; K : CONSTRUCT>;
VAR J, L : INTEGER;
BEGIN
IF T = TMAX THEN FATAL<l>;
TAB[OJ.NAME := ID;
J := BTAB[BLOCKNO[LEVELJJ.LAST;
l.
:= J;
<> ID DO J := TAB[JJ.PREV;
21620
21660
21700
21740
217BO
T := T t 1;
TAB[LJ.NEXT := T;
21.820
WITH TAB[TJ DO
21860
21900
BEGIN
NAME := ID; PREV := L;
21940
CONS := K; TYP := NOTYP;
21980
HREF := o;VALUES := O;ISLCV := FALSE;
22020
TREF := o; BYVAL := TRUE; NEXT := 0;
22060
22100
END;
BTAB[BLOCKNO[LEVELJJ.LAST := T;
22140
22180
END;
22220 END <* ENTERID *>;
;n~iBO
WHILE TAB[JJ.NAME
IF J <> 0 THEN
ERRORC1>
ELSE
BEGIN
**)
2.2:?60 (
22300 FIJNCTJDN
LDC< ID : 1'\LFA> : INTEGER;
22340 <* LOCATION OF ID IN TABLE *>
22380 VAR I, J : INTEGER;
22420 BEGIN
22460
I : = LE'v'EL;
TAB[OJ.NAME := ID; <* SENTINEL CASE *>
22500
22540
REPEAT
J := BTAB[BLOCKNOCIJJ.LAST;
22580
WHILE TABCJJ.NAME <> ID DO J := TABCJJ.PREV;
22620
22660
I := I - 1
UNTIL CI < 0) OR (J <> 0);
22700
22740
IF J = 0 THEN ERRORCO>;
LOC := ,J;
22780
22820 END <* LOC *>;
22860 <**>
22900 PROCEDURE ENTERVARIABLE;
22'140 BEGIN
22980
IF SY = IDENT THEN
23020
BEGIN
23060
ENTERIDCID,VARIABLE>;
INSYMBOL;
23100
23140
END
23180
ELSE
ERRDRC2>;
23220
23260 END <* ENTERVARIABLE *>;
23300 '**>
CONREC>;
23340 PROCEDURE CONSTANTCFSYS
SYMSET; VAR C
23380 VAR X, SIGN : INTEGER;
23420 BEGIN
23460
C.TP := NOTYP; C.I := o; C.RF := o;
235()0
TESTCCONSTBEGSYS,FSYS,SO>;
23540
IF SY IN CONSTBEGSYS THEN
2~3580
BEGIN
66
SIGN := 0;
IF SY IN CPLUS,MINUSJ THEN
BEGIN
IF SY = PLUS THEN
SIGN := 1
ELSE
2:5620
23660
23"700
2~~740
23780
23820
23860
23900
23940
239BO
24020
;>4()60
24100
24140
24180
24220
24260
24300
24:540
~>IGN
:= -1;
INSYMBOL;
END;
IF SY = CHARCON THEN
BEGIN
IF SIGN<> 0 THEN ERRORCB2>;
C.TP := CHARS; C.I := INUM;
C.RF := 4; INSYMBOL;
END
ELSE IF SY = !DENT THEN
BEGIN
X : = LOC CIII);
IF X = 0 THEN
ENTERID<ID,KONSTANT>
ELSE
IF TABCXJ,CONS <> KONSTANT THEN
ERROR<25)
ELSE
BEGIN
C.TP := TABCXJ,TYP; C.RF := TABCXJ.HREF;
IF NOT CTABCXJ.TYP IN CNOTYP,INTS,REALSJ) THEN
BEGIN
IF SIGN <> 0 THEN ERROR<82>;
C.I := TABCXJ.VALUES;
END
ELSE
BEGIN
IF SIGN = 0 THEN SIGN := 1;
IF C.TP
INTS THEN
C.I := SIGN
TABCXJ,VALUES
ELSE
RNUM := SIGN
RCONCTAB[XJ.VALUESJ;
END;
END;
INSYMBOL;
END
ELSE IF SY = INTCON THEN
BEGIN
C.TP := INTS; C.RF := 1;
IF SIGN = 0 THEN SIGN := 1;
C.I := SIGN
INUM;
INSYM-BOL;
END
ELSE IF SY = REALCON THEN
BEGIN
C.TP := REALS; C.RF := 2;
IF SIGN = 0 THEN SIGN := 1;
RNUM := SIGN
RNUM;
INSYMBOL;
EN II
ELSE
SKIP<FSYS,50>;
IF SY <> EOFSY THEN TEST<FSYS,CJ,B3>;
END;
24:~80
24420
24460
24500
'24540
24:"iBO
24620
24660
24700
24740
24780
24820
24860
24900
24940
24980
25020
25060
25100
25140
2!:!180
*
*
25220
25260
25300
25~140
25~380
25420
*
25460
25500
2~j~J40
25580
25620
'25660
25/00
25740
25'780
*
25820
25860
25900
25940
25980
26020 END
CONST~NT *>;
26060
26100 PROCEDURE TYPCFSYS : SYMSET;VAR TP : TYPES;
VAR HRF, TRF : INTEGER;D : INTEGER>;
26140
26180
26220 PROCEDURE SCALARCISARRAY : BOOLEAN;VAR HRF,TRF : INTEGER>;
<**>
<**>
<*
67
26260 VAR TO, I : INTEGER;
26300 BEGIN
TO := T; I := o;
26340
TESTC[IDENTl,FSYSt[RPARENTJ-[COMMAJ,2>;
26380
WHILE SY = !DENT DO
26420
BEGIN
26460
ENTERIDCID,KONSTANTJ;
26500
INSYMBDL;
26540
IF SY <> RPARENT THEN
26580
BEGIN
26620
IF SY = COMMA THEN
26660
INSYMliOL
26700
ELSE
26140
ERROR< 61>;
26"780
TESTCIIDENTJ,FSYSt[RPARENTJ-[COMMAJ,2J;
26820
END;
26860
END;
26900
IF TO = T THEN
26940
ENTERRANGECISARRAY,O,OJ
26980
ELSE
27020
ENTERRANGECISARRAY,O,T-T0-1>;
27060
27100
WHILE TO < T DO
27140
BEGIN
TO := TO t 1;
27180
WITH TAB[JOJ DO
27220
27260
BEGIN
TYP := ENUMER; ISLCV := FALSE;
27300
HREF := R; TREF t= R;
27340
BYVAL := TRUE; VALUES := I;
27380
ENI•;.
27420
27460
I := I t 1;
END;
27500
27540
TRF := R; HRF := R;
2"75BO
IF SY = RPARENT THEN
27620
INSYMBOL
27660
ELSE
ERRORC4J;
27700
27740 END <* SCALAR *>;
27780 <**>
TYPES;
27820 PROCEDURE SUBRANGECISARRAY : BOOLEAN; VAR TP
VAR HRF, TRF : INTEGER>;
27860
27900 VAR LOW, HIGH : CONREC;
LOWFSYS,HIGHFSYS : SYMSET;
27940
27980 BEGIN
28020
IF ISARRAY THEN <* ARRAY INDEX TYPE *>
28060
BEGIN
LOWFSYS := ICOLON,RBRACK,RPARENT,OFSYJ;
.28100
HIGHFSYS := IRBRACK,RPARENT,COMMA,OFSYJ;
28140
213180
END
28220
ELSE
28260
BEGIN
LOWFSYS := (COLONJ;
28300
HIGHFSYS := (];
28340
2B~~ao
END;
28420
CONSTANTCLOWFSYStFSYS,LOW>;
28460
IF LOW,TP = REALS THEN
28500
BEGIN
28540
ERRORC27>;
LOW,TP := INTS;
28580
28620
LOW.I := ·-XMAX;
28660
END;
28700
IF SY = COLON THEN
INSYMBOL
28740
28780
ELSE
ERRORC13J;
28820
CONSTANTCHlGHFSYStFSYS,HIGH>;
28860
68
28900
28940
2B'J80
290:.'()
. 2')060
291.00
29140
29180
29:.?20
29260
2'1300
29340
29380
294~'0
29460
29500
29540
2'1580
29620
29660
29700
29740
29780
29820
29860
29900
29940
29980
30020
30060
:~01.00
30140
30180
30220
30260
30300
:~0340
3<H80
30420
30460
30500
30540
30580
30620
30660
30700
30740
30780
30820
30860
30900
30940
30980
31020
31060
31100
31140
311.80
31220
31260
31300
31340
31380
31420
31460
3.1 ::; 00
IF CHIGH.TP <> LOW.TP) OR CHIGH.RF
BEGIN
ERF;QR ( 27) ;
HIGH.I := ~BS<LOW.I>;
ENII;
ENTERR~NGECISARRAY,LOW.I,HIGH.I>;
<> LOW.RF> THEN
TRF := R;
TP := LOW,TP;
HRF :::: LOW,RF;
END <* SUBRANGE *>;
<**'
TYPES;
PRDCEIIURE SIMPLETYP<ISARRAY : BOOLEAN; VAR TP
VAR HRF,TRF : INTEGER>;
VAR X : INTEGER;
BEGIN <* SIMPLETYP *>
TP := NOTYP; HRF := o; TRF := o;
IF ISARRAY THEN
TEST<CREALCONJ+INIIEXBEGSYS,
CCOMMA,RPARENT,RBRACK,OFSYJ+FSYS,62>;
IF SY IN <CREALCONJ + INIIEXBEGSYS) THEN
IF SY = IDENT THEN
BEGIN
X := LOC<ID>;
IF X = 0 THEN
BEGIN
ENTERIDCIII,TYPEID>;
INSYMBOL;
END
ELSE
WITH TABCXJ DO
IF CONS = KONSTANT THEN
SUBRANGECISARRAY,TP,HRF,TRF>
ELSE IF CONS = TYPEID THEN
BEGIN
IF ISARRAY THEN
BEGIN
IF TYP = ARRAYS THEN
ERRORC65)
ELSE IF TREF IN C1 •• 2J THEN
BEGIN
ERRORC66);
TP := INTS;
HRF := 1; TRF := ~;
END
ELSE
BEGIN
TP := TYP; HRF := HREF; TRF := TREF;
IF CABSCRTABCTREFJoL> > XMAX) OR
CABSCRT~BCTREFJ.H> > XM~X> THEN
BEGIN
ERRORC27>;
TREF := 5;
END;
END;
END
ELSE
BEGIN
TP := TYP; HRF := HREF; TRF := TREF;
END;
IF TP = NOTYP THEN ERRORC30>;
INSYMBOL;
END
ELSE
BEGIN
ERRORC67>; INSYMBOL;
END;
69
31540
31580
:u.s2o
:31 b60
31700
~H 740
31.780
31820
318.SO
31900
31940
31980
32020
32060
32100
:32140
32180
3222()
32260
32300
3?340
32380
::32420
324\SO
END
ELSE IF SY = LPARENT THEN
.BEGIN
INSYMBOL;
Tf' := ENUMER;
SCALARCISARRAY,HRF,TRF>;
END
ELSE IF SY IN [f'LUS,MINUS,INTCON,CHARCON,REALCONJ THEN
SUBRANGECISARRAY,Tf',HRF,TRF>;
END <* SIMPLETYPE *>;
<**>
PROCEDURE ARRAYTYPCVAR HRF,TRF : INTEGER;D :INTEGER>;
VAR ETP, XTP : TYPES;
EHRF, ETRF, XHRF, XTRF : INTEGER;
BEGIN
IF D > LMAX THEN FATALCB>;
SIMPLETYP(TRUE,XTP,XHRF,XTRF);
ENTERARRAYCXTP,XHRF,XTRF>; HRF :=A; TRF :=A;
IF SY = COMMA THEN
BEGIN
INSYMBOL; ETP := ARRAYS;
ARRAYTYPCEHRF,ETRF,D+1>;
EN II
ELSE
BEGIN
IF SY = RBRACK THEN
INSYMBOL
ELSE
BEGIN
ERRORC12>;
IF SY = RPARENT THEN INSYMBOL;
END;
IF SY = OFSY THEN
INSYMBOL
ELSE
ERRORCB>;
TYPCFSYS,ETP,EHRF,ETRF,D>;
END;
32500
32540
32580
32620
32660
32700
32740
32780
32820
3;!860
32900
32940
32980
33020
33060
[I := 1;
IF ETP = ARRAYS THEN
33100
D := D t ATABCETRFJ.DIMEN;
33140
33180
IF D > LMAX THEN FATALes>;
33220
WITH ATABCHRFJ DO
BEGIN
33260
ETYP := ETP; EHREF := EHRF;
33300
:s3340
ETREF := ETRF; DIMEN := D;
33380
END;
33420 END <* ARRAYTYP *>;
3~H60
<**>
33500 BEGIN <* TYP *>
33540
TP := NOTYP; HRF := o; TRF := o;
:33580
TESTCTYPEBEGSYStCREALCONJ,FSYS,lO>;
33620
IF SY IN CTYPEBEGSYStCREALCONJ) THEN
:33660
33700
3~"P4()
33780
33820
33860
3~~(100
33940
~~3980
34020
34060
34100
34140
BEGIN
IF SY IN CCREALCONJ t INDEXBEGSYS> THEN
SIMPLETYPCFALSE,TP,HRF,TRF>
ELSE IF SY = A~RAYSY THEN
BEGIN
INSYMBOL;
IF SY = LBRACK THEN
INSYMBOL
ELSE
BEGIN
ERROR< 11) ~
IF SY = LPARENT THEN INSYMBOL;
END;
70
TP
34180
:=
ARRAYS;
ARRAYTYPCHRF,TRF,Dt1>;
34220
END;
:H?60
TEST<[SEMICOLONJ,FSYS,64>;
34300
END;
34340
34380 END C TYP *>;
34420 (**)
34460 PROCEDURE PARAMETERLIST;
34500 <* FORMAL PARAMETER LIST *)
*
34540 VAR TF' : TYPES;
HRF, TRF, X, TO : INTEGER;
34580
VALPAR : BOOLEAN;
34620
34660 BEGIN
INSYMBOL;
34700
TEST<[IDENT,VARSYJ,FSYSt[RPARENTJ,7);
34740
WHILE SY IN [IDENT,VARSYJ DO
:~4780
:34820
BEGIN
34860
TP := NOTYP;
TRF := o; HRF := o;
34900
34940
IF SY <> VARSY THEN
VALF'AR := TRUE
34980
35020
ELSE
35060
BEGIN
INSYMBOL; VALPAR := FALSE;
35100
35140
END;
TO := T; ENTERVARIABLE;
:35180
WHILE SY = COMMA DO
35220
BEGIN
35260
INSYMBOL; ENTERVARIABLE;
35300
35340
END;
35380
IF SY = COLON THEN
35420
BEGIN
INSYMBDL;
35460
IF SY <> IDENT THEN
35500
ERROR<60)
3~5540
35580
ELSE
BEGIN
35620
35660
X := LOCC III>;
IF X = 0 THEN ENTERIDCID,TYPEID>;
3!":i700
35740
INSYMBOL;
35780
IF X <> 0 THEN
WITH TAB[XJ ItO
35820
:55860
IF CONS <> TYPEID THEN
35900
EF:ROR <60 >
35940
ELSE
35980
BEGIN
36020
TP := TYP; HRF := HREF;
36060
TRF := TREF;
36100
END;
36140
ENit;
TESTC[SEMICOLON,RPARENTJ,[COMMA,IDENTJtFSYS,14);
:36180
36220
END <* IF SY = COLON *>
36260
ELSE
36300
ERROR(5);
36340
WHILE TO < T DO
36380
BEGIN
36420
36460
36500
:36540
36580
36620
3666()
36700
36740
36780
.
"
TO
:=
TO
+
l;
WITH TAB[TOJ DO
BEGIN
TYP := TP; HREF := HRF; TREF := TRF;
BYVAL := VAL.PAR; VALUES := BLOCKNOILEVELJ;
ISLCV := FALSE;
END;
END;
IF SY <> RPARENT THEN
BEGIN
71
36820
36860
36900
36940
·36980
37020
3"?060
37100
3'7140
37180
37220
37260
37300
37340
37:380
.37420
37460
37500
37540
37580
37,'>20
37660
37700
37740
37780
37820
37860
37900
37940
37980
38020
38060
~~81
00
38140
38180
38220
38~'60
38300
38340
38380
38420
38460
38500
38540
38580
38620
38660
3B700
38740
38780
38820
38860
38900
38940
38980
39020
39060
39100
39140
39180
39220
39260
:39300
39340
39380
:~9420
IF SY = SEMICOLON THEN
INSYMBOL
ELSE
BEGIN
ERROR< 14);
IF SY = COMMA THEN INSYMBOL;
END;
fESTCCIDENT,VARSYJ,(RPARENTJtFSYS,7);
END;
END <*WHILE SY IN CIDENT,VARSYJ *>;
IF SY = RPARENT THEN
BEGIN
INSYMBOL;
TESTCCSEMICOLON,COLONJ,FSYS,BB>;
END
ELSE
ERRORC4);
END <* PARAMETERLIST *>;
<**'
PROCEDURE CONSTANTDECLARATION;
VAR C : CONREC;
Tl, T2 : INTEGER;
BEGIN
INSYMBOL;
TESTCCIDENTJ,BLOCKBEGSYS,2>;
WHILE SY = !DENT DO
BEGIN
Tl
:=
T;
ENTERIDCID,KONSTANT>;
T2 != T;
INSYMBOL;
IF SY = EQL THEN
INSYMBDL
ELSE
BEGIN
ERRORC16);
IF SY = BECOMES THEN INSYMBOL;
END;
CONSTANTCCSEMICOLON,COMMA,IDENTJtFSYS,C>;
IF T2 > T1 THEN
BEGIN
TABCT2J,TYP != C,TP; TABCT2J,HREF != C.RF;
TAB[T2J,TREF != C.RF; TABCT2J,BYVAL != TRUE;
TAB[T2J,ISLCV != FALSE;
IF C.TP = REALS THEN
BEGIN
ENTERREAL;
TABCT2J,VALUES != RC;
END
ELSE
TABCT2J.VALUES != C,I;
END;
TESTSEMICOLONCBLOCKBEGSYS-CCONSTSYJ+CIDENTJ,84>;
END;
END <* CONSTANTDECLARATION *>;
<**>
PROCEDURE TYPEDECLARATION;
VAR TF' : TYPES;
HRF, TRF, Tl, T2 ! INTEGER;
BEGIN
INSYMBOL; TESTCCIDENTJ,BLOCKBEGSYS,2>;
WHILE SY = !DENT DO
BEGIN
Tl != T; ENTERIDCID,TYPEID>;
T2 != T; INSYMBOL;
IF SY = EQL THEN
72
39460
39500
39540
39580
39620
39660
39700
39740
3?780
;:W820
;39B60
39900
39940
39980
40020
40060
40100
40140
40180
40220
40260
40300
40340
40380
40420
40460
40500
40540
40580
40620
40660
40700
40?40
40780
40820
40860
40900
40940
40980
41020
41060
41100
41140
41180
41.220
41260
41:300
41340
41380
41420
41460
41500
. 41540
41580
41620
41660
41700
41740
41780
41820
41860
41900
41940
41980
42020
42060
INSYMBOL
ELSE
BEGIN
ERROR<16>;
IF SY ~ BECOMES THEN INSYMBOL;
END;
TYPC[SEMICOLON,COMMA,IDENTJtFSYS,TP,HRF,TRF,Ol;
IF T2 > T1 THEN
WITH TABCT2J DO
BEGIN
TYP := TP; HREF := HRF;
TREF := TRF; BYVAL := TRUE;
VALUES := o; ISLCV := FALSE;
END;
TESTSEMICOLONCCVARSY,~ROCEDURESY,FUNCTIONSY,BEGINSY,IDENTJ,85)
END;
END <* TYPEDECLARATION *>;
<**>
PROCEDURE VARIABLEDECLARATION;
VAR TO, T1, HRF, TRF : INTEGER;
TP : TYPES;
BEGIN
INSYMBOL; TESTC[IDENTJ,BLOCKBEGSYS,2>;
WHILE SY = IDENT DO
BEGIN
TO := T; ENTERVARIABLE;
WHILE SY = COMMA DO
BEGIN
JNSYMBOL; ENTERVARIABLE;
END;
IF SY = COLON THEN
INSYMBOL
ELSE
EF;F;OF~
T1
:=
<5 > ;
T;
TYP([SEMICOLON,COMMA,IDENTJtFSYS,TP,HRF,TRF,Ol;
WHILE TO < Tl DO
BEGIN
TO
:=
TO t
1;
WITH TABCTOJ DO
BEGIN
TYP := TP; HREF := HRF;
TREF := TRF; BYVAL := TRUE;
VALUES := BLOCKNOCLEVELJ; ISLCV := FALSE
nm;
END;
TESTSEMICOLONCCIDENT,PROCEDURESY,FUNCTIONSY,BEGINSYJ,86);
END;
END <* VARIABLEDECLARATIDN *>;
<**>
PROCEDURE PROCDECLARATIDN;
VAR ISFUN : BOOLEAN;
I : INTEGER;
BEGIN
ISFUN := SY = FUNCTIONSY; INSYMBOL;
IF SY <> IDENT THEN
BEGIN
,
ERRORC2>; ID := '
.,
ENit;
IF ISFUN THEN
ENTERIDCID,FUNKTION>
ELSE
ENTERID<ID,PROZEDURE>;
I := L.OCCID>; INSYMBOL;
BLDCKC[SEMICOLONltFSYS,ISFUN,LEVELtl,I>;
IF SY = SEMICOLON THEN
73
42100
42140
42180
42220
42260
42300
42:340
4231'10
42420
42460
42500
42540
42580
42620
42660
42700
42740
42780
42820
42860
42900
42'?40
42980
43020
43060
43100
43140
43180
43220
4:3260
43300
4:3340
43380
43420
43460
4:3500
43540
4:3580
43620
4:3660
43"700
4:3740
43"780
43820
43860
43900
43940
43rmo
44020
44060
44100
44140
44l80
44220
44260
44300
44:%,40
44380
44420
44460
44500
44540
44580
44620
44660
44700
INBYMBOL
ELSE
ERROR<14>;
END <* PROCDECLARATION *>;
'**'
PROCEDURE STATEMENT<FSYS: SYMSET>;
VfiR I : INTEGER;
X : ITEM;
<**'
PROCEDURE EXPRESSION<FSYS: SYMSET;VfiR X : ITEM>; FORWARD;
<**'
PROCEDURE SELECTOR<FSYS: SYMSET; VAR V : ITEM>;
Vf'IR X : ITEM;
A, J : INTEGER;
BEGIN
<* SY IN [LPfiRENT,LBRACKJ *>
REF'EAT
BEGIN <* fiRRfiY *>
IF SY <> LBRfiCK THEN ERROR<11>;
REPEfiT
INSYMBOL;
EXPRESSIONCFSYSt[COMMfi,RBRACKJ,X>;
IF VofYP <> ARRfiYS THEN
ERROR<28>
ELSE
BEGIN
A := V.TREF;
.IF CfiTAB[fiJ.XTYP <> X.TYP> OR <fiTAB[AJ.XHREF <> X.HREF>
BEGIN
IF <X.TYP <> NOTYP> AND <fiTfiB[fiJ.XTYP <> NOTYP> TH
ERRORC26>;
END
ELSE IF X.CONS = KONSTANT THEN
IF <X.VALUES < RTAB[ATAB[AJ.XTREFJ.L) OR
<X.VALUES > RTAB[f'ITAB[fiJ.XTREFJ.H> THEN
ERROR<73>;
V.TYP := f'ITAB[f'IJ.ETYP; VoHREF := ATf'IB[f'IJ.EHREF;
V.TREF := ATf'IB[AJ.ETREF;
EN£1
UNTIL SY <> COMMfl;
IF SY = RBRf'ICK THEN
INSYMBOL
ELSE
BEGIN
ERROR< 12);
IF SY = RPf'IRENT THEN INSYMBOL;
END;
END <* ARRAY *)
UNTIL NOT (SY IN [LBRACK,LPARENTJ>;
IF SY <> EOFSY THEN TEST<FSYS,[J,89>;
END<* SELECTOR*>;
<**'
PROCEDURE CfiLL<FSYS: SYMSET; I : INTEGER>;
VAR AP : ITEM;
LASTP, FP, K : INTEGER;
P : BOOLEAN;
BEGIN
LASTP := BTAB[TAB[IJoVALUESJoLASTPfiR;
FP := BTAB[TAB[IJ.VALUESJ.FtRSTPfiR;
IF SY = LPARENT THEN
BEGIN <* ACTUfiL PARAMETER LIST *>
REF'EAT
INSYMBOL;
IF FP >= LASTP THEN
BEGIN
ERR DR< 39 >.;
74
44740
44780
44820
44860
44900
44940
44980
45020
450.'!0
4~'j 100
451.40
45180
45220
4:':;260
45300
4~:;340
45380
4~j420
EXF'RESSIONCFSYSHCOMMI'I,COLON,RPI'IRENTJ,I'IP>;
EN II
ELSE
BEGIN
FF' : = FP + 1;
IF TI'IB[FPJ.BYVI'IL THEN
BEGIN
<* VALUE PARAMETER *>
EXPRESSIDNCFSYSt[COMMA,COLON,RPARENTJ,AP>;
WITH TAB[FPJ DO
BEGIN
P := CCI'IP.TYP = TYP> AND CAP.HREF = HREF>> OR
CCAP.TYP = INTS> AND CTYP = REALS))
OR
CAP.TYP = NOTYP>;
IF NOT P THEN
BEGIN
IF TYP <> NOTYP THEN ERRORC36);
EN II
ELSE IF AP.CONS = KONSTANT THEN
IF CAP.VALUES < RTI'IB[TAB[FPJ.TREFJ.L> OR
CAP.VALUES > RTAB[TAB[FPJ.TREFJ.H) THEN
ERRORC74>;
END;
END
ELSE
BEGIN <* VARIABLE PARAMETERS *>
IF SY <> IIIENT THEN
ERRORC2)
ELSE
BEGIN
K := LOCC !It);
IF K = 0 THEN
BEGIN
ENTERIDCID,VARIABLE>;
TAB[TJ.VALUES := BLDCKNO[LEVELJ;
END;
INSYMBOL;
IF K <> () THEN
BEGIN
IF TAB[KJ.CONS <> VARIABLE THEN ERRORC7
AP.TYP := TAB[KJ.TYP;
AP.HREF := TAB[KJ,HREF;
AP.TREF := TAB[KJ.TREF;
IF SY IN [LBRACK,LPI'IRENTJ THEN
SELECTORCFSYStCCOMMA,COLON,RPARENTJ,
P := <<AP.TYP = TABCFPJ.TYP> AND
<AP.TREF = TABCFPJ.TREF>> OR
CAP.TYP = NOTYP>
OR
<TABCFPJ,TYP = NOTYP>;
IF NOT P THEN ERRORC29>;
IF TABCKJ.ISLCV THEN ERRORC69>;
END;
END;
END;
END;
TESTC[COMMA,RPARENTJ,FSYS,49)
UNTIL SY <> COMMA;
IF SY = RPARENT THEN
T.NSYMBOL
ELSE
ERROR<4>;
END;
IF FP < LASTP THEN ERRORC39);
END <*CALL *>;
45460
45500
4:'j540
45580
4!:i620
45660
45700
45740
45780
45820
45860
45900
45940
45'?80
46020
460..SO
461.00
46140
46180
4..S:220
46260
46300
46340
46380
46420
46460
46500
46540
46580
46620
46660
46700
46740
46780
46820
46860
46900
46940
46'780
47020
47060
47100
47140
47180
47220
47260
47300 <**>
47340 PROCEDURE SElNOTYPCVAR T
ITEM>;
75
47380 BEGIN
47420
T.TYP := NOTYP;
47460
T.HREF := o;
47500
T.TREF := o;
47540
T.VALUES := o;
47580
T,CONS := VARIABLE;
47620 END <* SETNOTYP *>;
47660 <**>
49660
49700
49740
49780
49820
49860
INTEGER);
PRO~FDURE SETINTSIVAR T
BEGlN
T.TYP := INTS;
T.HREF := 1;
T.TREF := 1;
T. VI"'LIJES : = N;
T.CONS := KONSTANT;
END;
<**>
ITEM>;
PROCEDURE SETREALS<VAR T
BEGIN
T.TYP := REAL.S;
T .HREF := 2;
T.TREF := 2;
T.CONS := KONSTANT;
T.VI"'LUES := 0
END;
<**>
ITEM>;
PROCEDURE SETCHI"'RS<VAR T
BEGIN
T.TYP := CHI"'RS;
T.HREF := 4;
T.TREF := 4;
T.VI"'LUES := INUM;
T.CONS := KDNSTANT;
END;
<**>
INTEGER>;
PROCEDURE TYPEMI"'TCHINd<VI"'R X,Y : ITEM;T : TYPES;N
BEGIN
IF NOT<<X.TYP = T> I"'ND <Y.TYP = T>> THEN
BEGIN
IF <X,TYP <> NOTYPJ I"'ND <Y.TYP <> NOTYPJ THEN
ERROR<N>;
SETNOTYP<X>;
END;
END;
<**>
PROCEDURE RESULTTYPE<VAR A,B : ITEM>;
BEGIN
IF (I"',TYP > REALS) OR <B.TYP > REALS) THEN
.BEGIN
ERROR<33>; SETNOTYP<A>;
END
ELSE
IF (f'I,TYP = NOTYP> OR <B.TYP = NOTYP> THEN
SETNOTYP<A>
ELSE
IF A,TYP = INTS THEN
IF B.TYP = INTS THEN
SETINTS<A,O>
ELSE
SETREI"'LS (A>
ELSE
SETREALS<A>;
END <* RESULTTYPE *>;
49~00
(**)
47700
4?/40
47"780
47820
4?860
4?900
4?940
47980
48020
48060
48100
48140
48180
48220
48~~60
48300
48340
48380
48420
48460
48500
48540
48580
48620
4B660
48700
48740
48780
48820
48860
48900
48940
48980
49020
49060
49100
49140
49180
49~'20
49260
49300
49340
49380
49420
49460
49500
49540
49580
496.20
49940 PROCEDURE EXPRESSION;
49980 VAR Y : ITEM;
76
!"j()020
50060
50100
50140
50180
50220
50260
50300
50340
~i0380
50420
50460
50500
50540
50580
50620
50660
50700
50740
50780
50820
50860
50900
50940
50980
51020
51060
51100
51140
51180
51220
51260
51300
51340
51380
51420
51460
51500
51540
51580
51620
51660
51700
51740
51780
51820
51860
51'i'00
51940
51980
52020
52060
52100
!"J2140
52180
~i2220
52260
52300
52340
:':'2380
52420
52460
52500
::;2540
52~80
52620
OF' : SYM[{OL;
C~ : BDOLEf'IN;
f',
<**>
ITEM>;
PROCEDURE SIMPLEEXPRESSIONCFSYS: SYMSET; Vf'IR X
VAR Y : ITEM;
<**>
PROCEDURE TERM<FSYS: SYMSET; VAR X
ITEM>;
Vf'IR Y : ITEM;
OP : SYMBOL;
( **)
PROCEDURE Ff'ICTOR<FSYS: SYMSET; VAR X
ITEM>;
VAR I : INTEGER;
<**>
PROCEDURE STANDFCT<N : INTEGER>;
Vf'IR TS : TYPSET;
BEGIN <* STANDARD FUNCTION NUMBER N *>
N := N - BMAX;
IF SY = LPARENl THEN
INSYMBOL
ELSE
ERROR(9);
IF N < 16 THEN
BEGIN
EXPRESSION<FSYStCRPARENTJ,X>;
CASE N OF
1,2 : TS := CINTS,REALSJ; <* ABS, SQR *>
3,4 : TS := CINTSJ; <* ODD,CHR *>
8,9 : TS := CREALSJ; <* ROUND, TRUNC *>
5,6,7 : TS := [INTS,BOOLS,CHf'IRS,ENUMERJ; <* ORD,PRED,SUCC
10,11,12,13,14,15 :
BEGIN
TS := CINTS,REALSJ;
END;
END <* CASE *>;
IF NOT CX.TYP IN TS) THEN
BEGIN
IF XoTYP <> NOTYP THEN
BEGIN
ERROR<48>;
SETNOTYP<X>;
END;
END
ELSE
IF N = 5 THEN <* ORD *>
BEGIN
X.TYP := INTS;
XoHREF := 1;
END
ELSE
IF NOT <N IN [1 •• 2,6 •• 7]) THEN
BEGIN
X.TYP := TABCIJ.TYP;
X.TREF := Tf'IB[IJ.TREF;
X.HREF := TABCIJ.HREF;
END;
END
ELSE
BEGIN <* EOF, EOLN *>
IF SY <> IDENT THEN
ERRDR<2>
ELSE IF ID <> 'INPUT
' THEN
ERROR<O>
ELSE
INSYMBOL;
X.TYP := BOOLS; X.TREF := 3; X.HREF := 3;
END;
77
52660
52700
5'2740
52780
52H20
52B60
52900
";;:-";>40
52980
53020
::iJ060
53100
53140
53180
53220
~;~3260
53300
5;3340
53380
53420
53460
53500
53540
53580
53620
53660
53'700
53740
53780
5;3820
~i3f~60
53'JOO
53940
53980
54o;~o
54060
54100
54140
54180
~i42:?0
~;42b0
54;300
54:340
54380
54420
:".•4460
54500
:"i4540
54580
541>20
54660
54700
54740
54780
~;49:•o
~j4860
~)4900
54940
54980
55020
55060
5~j100
55140
55180
5~)220
!15260
. v
IF SY = RPARENT THEN
INSYMBOL
ELSE
ERROR<4>;
FND <* STANDFCT *>;
<**>
BEGIN <* FACTOR *>
~:;ETNDTYP <X);
TEST<FACBEGSYS,FSYS,5B>;
WHILE SY IN FACBEGSYS DO
BEGIN
IF SY = IDENT THEN
BEGIN
I := LOC< ID>;
IF I = 0 THEN
BEGIN
ENTERID<ID,VARIABLE>; I := T;
TAB[IJ.VALUES := BLOCKNO[LEVELJ;
END;
INSYMBOL;
X.TYP := TAB[IJ.TYP;
X.HREF := TAB[IJ.HREF;
X.TREF := TAB(IJ.TREF;
WITH TAB[! J DO
CASE CONS OF
KONSTANT : BEGIN
X.CONS := KONSTANT;
x.VALUES := VALUES;
IF TYP = RF.ALS THEN
X.VALIJES := o;
END;
VARIABLE
BEGIN
IF SY IN (LBRACK,LPARENTJ THEN
SELECTOR<FSYS,X>;
END;
TYPEID,PROZEDURE : ERROR<44>;
FUNKTION : BEGIN
IF VALUES > BMAX THEN
STANDFCT<VALUES>
ELSE
CALL< FSYS ,I) ;
END;
END <*CASE*>;
END
ELSE
IF SY IN [CHARCON,INTCON,REALCONJ THEN
BEGIN
IF SY = REALCON THEN
SETREALS<X>
ELSE
IF SY = CHARCON THEN
SETCHARS<X>
ELSE
SETINTS <X, INUM >;
INSYHBOL;
END
ELSE IF SY = LPARENT THEN
BEGIN
INSYMBOL;
EXPRESSION<FSYS+CRPARENTJ,X>;
IF SY = RPARENT THEN
INSYMBOL
ELSE
ERROR(4);
END
ELSE IF SY = NOTSY THEN
78
55300
~';:"i340
~j~.i~~fJ()
~j~j420
55460
55500
55540
5~i580
~-.)~j,-:,20
~j5,·~H~()
55700
5:i740
55780
~55820
55860
5~j900
~;5940
55980
56020
!'j6060
56100
56140
56180
56220
56260
56300
56340
56380
56420
56460
56500
56540
5tJ5BO
BEGIN
lNSYMBUL; FACTORCFSYS,X>;
IF CX.TYP <> BOOLSJ AND CX.TYP <> NOTYPJ THEN
ERROR(32J;
END;
IF SY <> EOFSY lHEN TESTCFSYS,FACBEGSYS,6J;
END C* WHILE *>;
END <*FACTOR*>;
<**'
BEGIN <* TERM *>
FACTORCFSYStCTIMES,RDlV,IDIU,IMOD,ANDSYJ,X>;
WHILE SY IN [TIMES,RDIU,IDIU,IMOD,ANDSYl DO
BEGIN
OP := SY; INSYMBOL;
FACTORCFSYSt[TlMES,RDIU,IDIU,IMOD,ANDSYl,Y);
IF OP = TIMES THEN
RESULTTYPECX,Y>
ELSE IF OP = RDIV THEN
BEGIN
IF X.TYP = INTS THEN
SETREALS (X);
IF YoTYP = INTS THEN
SETREALS<Y>;
TYPEMATCHINGCX,Y,REALS,33J;
END
ELSE IF OP = ANDSY THEN
TYPEMATCHINGCX,Y,BOOLS,32)
ELSE <* OP IN [IDIV,IMODJ *>
TYPEMATCHING<X,Y,INTS,34>;
X.CONS := VARIABLE;
END <*WHILE*>;
END <*TERM*>;
<**>
BEGIN <* SIMPLEEXPRESSION *>
IF SY IN [PLUS,MINUSJ THEN
BEGIN
OP := SY; INSYMBOL;
5.'>620
56660
56700
56740
56780
TERM<FSYSt[f~US,MINUSlrX>;
56820
IF X.TYP > REALS THEN
"ERROR< 33);
56B60
56900
END
56'740
ELSE
TERM<FSYSt[PLUS,MINUS,ORSYl,XJ;
56980
WHILE SY IN CPLUS,MINUS,ORSYJ DO
57020
57060
BEGIN
57100
OP := SY; INSYMBOL;
TERM<FSYSt[PLUS,MINUS,ORSYl,Y>;
57140
57180
IF OP = ORSY THEN
57220
TYPEMATCHINGCX,Y,BOOLS,32>
57260
ELSE
57300
RESULTTYPECX,Y>;
X.CONS := VARIABLE;
57340
57380
END <*WHILE *>;
57420 END <* SIMPLEEXPRESSION *>;
57460 <**>
57500 BEGIN <* EXPRESSION *>
5"7~40
~i75BO
57620
57660
57700
57740
57780
57820
5/860
57900
SIMPLEEXPRESSION<FSYSt[EQL,NEG,LSS,LEQ,GEQ,GTRl,X>;
IF SY IN CEQL,NEQ,LSS,LEQ,GEG,GTRJ THEN
BEGIN
INSYMBOL;
SIMPLEEXPRESSIONCFSYS,Y>;
P := CX.TYP <> Y.TYP> OR <X.HREF <> YoHREF>;
Q := CX.TYP = NOTYP> OR
CY.TYP = NOTYP> OR
<<X.TYP
INTS> AND CY.TYP = REALS>J OR
CCX.TYP = REALS) AND <Y.TYP = INTS>>;
79
IF P AND NOT Q THEN ERRORC35J;
5"7940
X.TYP := FOOLS; X.TREF := 3; X.HREF := 3;
5"7980
X.CDNS := VARIABLE;
58020
END;
58060
58100 END <*EXPRESSION*>;
58140 '**>
581BO PROCEDURE ASSIGNMENT;
58220 'v'AR X, Y : ITEM;
P : BOOLEAN;
5D2b0
5BJOO <* TABCIJ.CONS IN [VARIABLE,FUNCTION *>
513340 BEGIN
X.TYP := TABCIJ.TYP; X.HREF := TABCIJ.HREF;
58380
X.TREF := TAB[IJ.TREF;
58420
IF TAB[IJ.ISLCV THEN ERRORC69J;
58460
IF SY IN (LBRACK,LPARENTJ THEN
58500
SELEClORClBECOMES,EULJ+FSYS,XJ;
5B540
IF SY = BECOMES THEN
58580
INSYMBOL
58620
ELSE
58660
BEGIN
58700
FRF:OR< 51>;
58740
IF SY = EQL THEN INSYMBOL;
58780
END;
58820
5HB60
EXPRESSIONCFSYS,YJ;
58900
P := <<X.TYP = Y.TYP> AND CX.HREF = Y.HREF>> OR
:'"il3940
<<X.TYP = REALSJ AND <Y.TYP
INTSJJ;
58980
IF NOT P THEN
59020
BE. GIN
IF CX.TYP <> NOTYP> AND CY.TYP <> NOTYP> THEN
59060
ERRORC46>;
59100
59140
END
591.80
ELSE IF Y.CONS = KONSTANT THEN
IF <Y.UALUES < RTAB[X.TREFJ.LJ OR
59220
CY.VALUES > RTAB[X.TREFJ~H> THEN
59260
59300
ERRORC68J;
59340 END <*ASSIGNMENT *>;
5'J380 '**>
59420 PROCEDURE COMPOUNDSTATEMENT;
59460 BEGIN
59500
INSYMBOL;
59540
STATEMENTC[S~MICOLON,ENDSYJ+FSYS>;
59580
WHILE SY IN <STATBEGSYS+CSEMICOLONJ> DO
59620
BEGIN
59660
IF SY = SEMICOLON THEN
59"700
INSYMBOL
59740
ELSE
59780
ERROF:< 14);
59820
STATEMENTCSTATBEGSYS+fSEMICOLON,ENDSYJJ;
END;
59860
59900
IF SY = ENDSY THEN
59940
INSYMBOL
59980
F..LSE:
60020
E:F:F:OR <57);
60060 END <* COMPOUNDSTATEMENT
60100 <**>
60140 PROCEDURE IFSTATEMENT;
60180 VAR X : ITEM;
60220 BEGIN
60260
INSYMBOL;
60300
EXPRESSION<FSYS+CTHENSY,DOSYJ,X>;
60:340
IF NOT <X.TYP IN CBOOLS,NOTYPJ> THEN ERRORC17>;
60:380
PSY := SY;
60420
IF SY = THENSY THEN
6()460
INSYMBOL
60~i00
ELSE
(·0540
~F. GIN
=
80
6()~j80
60620
60660
60700
60740
60780
60820
60860
60900
60940
60980
61020
61060
61100
6l140
61180
61220
61260
61 ~300
61:>:40
61380
61420
61460
61500
61540
61580
61620
61660
61700
61740
61780
61820
61l~60
61900
61940
61980
62020
62060
62100
62140
62180
62220
62260
62300
62340
62380
62420
62460
62500
62540
62580
62620
62660
62/00
62740
62780
62820
62860
62900
b2940
629l~O
63020
63060
6:HOO
63140
63180
ERRDRC52>;
IF SY = DOSY THEN INSYMBOL;
ENit;
IF PSY IN [THENSY,DOSYJ THEN
IF SY =SEMICOLON THEN ERRORC76>;
SlATEMENT<FSYStCELSESYJ>;
IF SY = SEMICOLON THEN
PEEPNEXTSYCSEMICDLON,ELSESY,77>;
IF SY = ELSESY THEN
BEGIN
INSYMBOL;
STATEMENT<FSYS>;
END;
ENII <* IFSTATEMENT *>;
<**>
PROCEDURE CASESTATEMENT;
Vf'IR X : ITEM;
I : INTEGER;
CASETAB : ARRAY[l,.CSMAXJ OF
PACKED RECORD
VAL : INDEX;
END;
<**>
PROCEDURE CASELf'IBEL;
VAR LAB : CONREC;
K : INTEGER;
BEGIN
CONSTf'INTCFSYS+CCOMMA,COLONJ,LAB>;
IF CLf'IB,TP <> X.TYP> OR CLAB,RF <> X.HREF> THEN
BEGIN
IF <LAB.TP <> NOTYP> ANI! CX,TYP <> NOTYP> THEN
ERRORC47>;
END
ELSE lF I = CSMAX THEN
FATAL<5>
ELSE
BEGIN
I
:=
I t t; K
CASETABCIJ.VAL
REF'EAT
K
:=
:= o;
:= LAB.I;
K t 1
UNTIL CASETAB[KJ,VAL = LAB.I;
IF K < I THEN ERRORC7BJ;
END;
END <* CASELABEL *>;
'**>
PROCEDURE ONECASE;
B£GIN
CASELf'IBEL;
WHILE SY = COMMA DO
BEGIN
INSYMBOL;
CASELABEL;
END;
IF SY = COLON THEN
INSYMBOL
ELSE
ERRORCSJ;
STf'ITEMENT<[SEMICOLON,ENDSYJtFSYS>;
END<* ONECASE *>;
<**>
BEGIN <* CASESTATEMENT *>
INSYM~OL; I := o;
EXPRESSIONCFSYStCOFSY,COMMA,CDLONJ,XJ;
IF NOT <X.TYP IN [INTS,BOOLS,CHARS,ENUMER,NOTYPJ> THEN
ERROR<23>;
81
63220
63260
63300
63340
63380
63420
6:3460
6~~500
b3~'i40
63580
63620
63660
6:3700
63740
63780
6:~820
IF SY = OFSY THEN
INSYMBOL
ELSE
ERRDR<B>;
ONECASE;
WHILE SY = SEMICOLON DO
BEGIN
INSYMBOL;
IF NOT <SY IN [EOFSY,ENDSYJ> THEN. ONECASE;
END;
IF SY = ENDSY THEN
INSYMBOL
ELSE
ERROR<57>;
END <* CASESTATEMENT *>;
<**>
PROCEDURE REPEATSTATEMENT;
VAR X : ITEM;
BEGIN
INSYMBOL;
STATEMENT<fSEMICOLON,UNTILSYJtFSYSJ;
WHILE SY IN ([SEMICOLON] t STATBEGSYS> DO
BEGIN
IF SY = SEMICOLON THEN
INSYMBOL
ELSE
ERROR<14>;
STATEMENTC[SEHICOLON,UNTILSYJtFSYS>;
END;
IF SY = UNTILSY THEN
BEGIN
INSYMBOL;EXPRESSION<FSYS,X>;
IF NOT CX,TYP IN [BOOLS,NOTYPJJ THEN ERROR<17J;
END
ELSE
ERRORC53>;
END <* REPEATSTATEMENT *>;
<**>
PROCEDURE ~HILESTATEMENT;
'JI'IR X : ITEM;
BEGIN
INSYMBOL;
EXPRESSION<[DOSYJtFSYS,X>;
IF NOT <X.TYP IN [BOOLS,NOTYPJ> THEN ERRORC17>;
PHY := SY;
IF SY = DOSY THEN
INSYMBOL
ELSE
ERROR<54>;
IF PSY = DOSY THEN
IF SY = SEMICOLON THEN ERROR<76>;
STI'ITEMENT<FSYS>;
END <* WHILESTATEMENT *>;
6:3!360
63?00
63940
63980
64020
64060
64100
64140
64180
64220
64260
64300
64340
64380
6442()
64460
64500
64540
64580
64620
64660
64700
64740
64'780
64820
64860
64900
64940
64980
65020
65060
65100
65140
65180
65220
65260
65300
65340
65380 PROCEDURE FORSTATEMENT;
65420 VAR LCV : ITEM;
X : ITEM;
65460
65500
I : INTEGER;
65540 BEGIN
SETNOTYPCLCV>; INSYMBOL;
65580
6~')620
IF SY = !DENT THEN
BEGIN
65660
I := LOC< ID>;
65700
IF I = 0 THEN
65740
BEGIN
65780
65820
ENTERID<ID,VARIABLE>; I
'**'
:=
T;
82
6!:j860
65900
6~)940
65980
66020
66060
6.?100
66140
66180
66220
6.?260
66300
66340
66:380
66420
66460
66~)00
66~_;40
TABCTJ.VALUES := BLUCKNOCLEVELJ;
END;
INSYMBOL;
IF TABCIJ.CONS = VARIABLE THEN
BEGIN
LCV.TYP I= TABCIJ.TYP;
LCV.HREF I= TABCIJ.HREF;
LCV.TREF := TABCIJ.TREF;
IF CTABCIJ.VALUES <> BLOCKNOCLEVELJ> AND
CTABCIJ.VALUES <> 2> THEN
ERRORC70J;
IF NOT TABCIJ.BYVAL THEN ERRORC70>;
IF LCV.TYP = ARRAYS THEN .
IF SY IN CLPARENT,LBRACKJ THEN
BEGIN
ERRORC72J;
SELECTOR<CBECOMES,TOSY,DOWNTOSY,DOSYltFSYS,LCV>
END;
IF NOT CLCV.TYP IN CNOTYP,INTS,BOOLS,CHARS,ENUMERJ> THEi
ERROR< 18);
IF TABCIJ.ISLCV THEN
ERRORC69)
ELSE
TABCIJ.ISLCV I= TRUE;
END
ELSE
ERROR< 71>;
END
ELSE
SKIPC[BECOMES,TOSY,DOWNTOSY,DOSYltFSYS,2J;
IF SY = BECOMES THEN
BEGIN
INSYMBOU
EXPRESSION<CTOSY,DOWNTOSY,DOSYltFSYS,XJ;
IF <<LCV.TYP <> X.TYP> OR CLCV.HREF <> X.HREF>> AND
CX.TYP <> NOTYP> AND <LCV.TYP <> NOTYP> THEN
ERROR< 19>;
END
ELSE
SKIP<CTOSY,DOWNTOSY,DOSYJ+FSY8,51);
IF SY IN CTOSY,UOWNTOSYJ THEN
BEGIN
INSYMBOL;
EXPRESBION<CDOSYJtFSYS,XJ;
IF CCLCV.TYP <> X.TYP> OR <LCV.HREF <> X.HREF>> AND
<X.TYP <> NOTYP> AND CLCV.TYP <> NOTYPJ THEN
ERROR< 19);
END
ELSE
SKIPCCDOSYJtFSYS,55>;
PSY := SY;
IF SY = DOSY THEN
INSYMBOL
ELSE
ERRORC54>;
IF PSY = DOSY THEN
IF SY =SEMICOLON THEN ERRORC76);
:n ATEMENT <FSYS);
TABCIJ.ISLCV := FALSE;
END <* FORSTATEMENT *>;
66580
66620
66660
66700
66740
b6780
66B20
66860
66900
66940
66980
67020
67060
67100
67140
67180
67220
67260
67300
6?340
67380
67420
67460
67500
67540
67580
67620
67660
.ST700
67740
67780
67820
67860
67900
67940
67'180
68020
68060
68100
6!Jl.40
68180
68220
68260 <**>
68300 F'ROCEDURE STANDPROC CN : INTEGER) ;
68340 VAR I : INTEGER;
.:SB:380
X, Y
ITFM;
68420 BEGT.N
6B460
N := N - BMAX;
83
68~<00
68540
68~i80
68b20
68660
68700
68740
68780
68820
6BB60
68900
68940
68980
69020
69060
b9100
69140
69180
69220
6'7260
69300
b9340
69380
69420
69460
69500
69540
69580
69620
69660
69700
69740
69780
69820
69860
69900
69940
69'?80
70020
70060
70100
70140
70180
70220
70260
70300
70340
'?0380
70420
70460
70~.<00
70540
70580
70620
?0660
70700
70740
70780
70820
70860
70900
70940
70980
71020
?1060
711 ()()
• d
IF <N = 1) OR <N = 3) THEN <* READ, WRITE *>
TESTC[LPARENTJ,FSYS,9>;
CASE N OF
1, 2 : BEGIN <*READ *>
IF NOT !FLAG THEN
ERROR<80J;
!FLAG := TRUE;
IF SY = LPARENT THEN
BEGIN
REF'EAT
INSYMBDL;
IF SY <> !DENT THEN
ERRORC2)
ELSE
BEGIN
I := LDC<ID>;
IF I = 0 THEN
BEGIN
ENTERIDCID,Vf'IRIABLE>;
TABCTJ.VALUES := BLDCKNOCLEVELJ;
END;
INSYMBOL;
IF I <> 0 THEN
IF TAB[IJ.CONS <> VARIABLE THEN
ERRORC37J
ELSE
BEGIN
X.TYP := Tf'IB[IJ.TYP;
X.HREF := Tf'IB[!J.HREF;
X.TREF := TABCIJ.TREF;
IF SY IN [LPARENT,LBRACKJ THEN
SELECTORCFSYSt[COMMA,RPARENTJ,X
IF NOT <X.T'l'P IN
CINTS,REALS,CHARS,NOTYPJJ THEN
ERROR< 40 > ;
IF TAB[IJ.ISLCV THEN ERRORC69>;
END;
END;
TESTC[COMMA,RPARENTJ,FSYS,49)
UNTIL SY <> COMMA;
IF SY = RPARENT THEN
INSYMBOL
ELSE
ERRORC4J;
END;
END <* READ*>;
3, 4
BEGIN <* WRITE *>
IF SY = LPARENT THEN
BEGIN
REPEAT
INSYMBOL;
IF SY = STRING THEN
BEGIN
X.TYP := NOTYP;
INSYMBOL;
END
ELSE
EXPRESSION<FSYSt[COMMA,COLON,RPARENTJ,X>;
IF NOT CX.TYP IN STANTYPS> THEN
ERRDR<41>;
IF SY = COLON THEN
BEGIN
INSYMBOL;
EXPRESSIONCFSYSt[COMMA,COLON,RPARENTJ,Y>;
IF Y.TYP <> INTS THEN ERRORC43>;
IF SY = COLON THEN
84
BEGIN
IF X.TYP <> REALS THEN ERRORC42>;
INSYMBOL;
EXPRESSIONCFSYSt[COMMA,RPARENTJ,Y>;
IF Y.TYP <> INTS THEN ERRORC43>;
END;
71140
71WO
71220
"ll260
?BOO
7134()
71380
71420
71460
71 ~500
71540
71580
71620
71660
71700
71740
"717BO
?uno
71860
71900
71940
71980
72020
72060
72100
72140
72180
72220
72260
72300
72340
72380
72420
72460
72500
72540
72580
72620
72660
72700
72740
72780
72820
72860
72900
72940
72980
73020
73060
73100
73140
73180
73220
73260
73300
7:3340
73~~80
73420
73460
73500
73540
73580
73620
7:3660
7~1700
73.740
•
<)
END;
TESTCLCOMMA,RPARENTJ,FSYS,49>;
UNTIL SY <> COMMA;
IF SY = RPARENT THEN
INSYMBOL
ELSE
ERRORC4>;
END;
END <* WRITE *>:
END <* CASE*>;
END <* STANDPROC *>;
<**>
BEGIN <* STATEMENT *>
IF SY IN ([IDENTJ t STATBEGSYS> THEN
CASE SY OF
!DENT : BEGIN
I := LOCCID>;
IF I = 0 THEN
BEGIN
ENTERID<ID,VARIABLE>; I := T;
TAB[TJ.VALUES := BLOCKNO[LEVELJ;
END;
INSYMBOL;
CASE TAB[IJ,CONS OF
KONSTANT, TYPEID : ERRORC45);
VARIABLE : ASSIGNMENT;
PROZEDURE : IF TAB[IJ.VALUES <= BMAX THEN
CALLCFSYS,I>
ELSE
STANDPROCCTAB[IJ.VALUES>;
IF TAB[IJ.VALUES = BLOCKNO[LEVELJ THE
FUNKTION
BEGIN
TAB[IJ.BYVAL := TRUE;
ASSIGNMENT;
END
ELSE
ERRORC45>;
END <*CASE *>;
END;
BEGINSY : COMPOUNDSTATEMENT;
IFSY : IFSTATEMENT;
CASESY : CASESTATEMENT;
WHILESY : WHILESTATEMENT;
REPEATSY : REPEATSTATEMENT;
FORSY : FORSTATEMENT;
END <* CASE*>;
IF SY <> EOFSY THEN TESTCFSYS,[J,59>;
END <* STATEMENT*>;
<**>
BEGIN <* BLOCK *>
IF LEVEL> LMAX THEN FATALC4>;
IF SY <> EOFSY THEN
TESTC[LPARENT,COLON,SEMICOLONJ,FSYS,7>;
ENTERBLDCK;
BLOCKNO[LEVELJ := B;
F'RB
:=
B;
TAB[PRTJ,TYP := NOTYP;
TAB[PRTJ.HREF := o;
TAB[PRTJ,TREF := o;
TABlPRTl.VALUES := PRB;
85
73780
731~20
73860
TWOO
7:W40
73980
74020
74060
74100
74140
74180
74220
74260
74300
74340
74380
74420
74460
74500
74540
74580
74620
746.'>0
74700
74740
74780
74820
74860
74900
74940
74'i'80
75020
/5060
75100
75140
75180
75220
75260
75300
75340
75380
75420
75460
75500
75540
.75580
75620
75660
75700
75740
75780
75820
75860
75900
75940
75980
76020
76060
76100
76140
761.80
76220
76260
76300
76340
76380
fABCPRTl.BYVAL := NOT ISFUN;
TAB[PRTJ,CONS := PROZEDURE;
IF ISFUN THEN TABCPRTJ.CONS := FUNKTION;
BTAB[PRBJ,FIRSTPAR := T;
IF SY = LPARENT THEN PARAMETERLIST;
BTABCPRBJ,LASTPAR := T;
IF ISFUN THEN
IF SY = COLON THEN
BEGIN
INSYMBOL; <* FUNCTION TYPE *>
IF SY = IDENT THEN
BEGIN
X := LOCCID>;
IF X = 0 THEN ENTERIDCID,TYPEID>;
INSYMBOL;
IF X <> 0 THEN
IF TABCXJ,CONS <> TYPEID THEN
ERRORC15)
ELSE IF TABCXJ,TYP IN STANTYPS t CENUHERJ THEN
BEGIN
TAB[PRTl.TYP := TABCXJ.TYP;
TABCPRTJ.TREF := TABCXJ.TREF;
TABCPRTJ.HREF := TAB[XJ.HREF;
END
ELSE
ERROR( 15);
END
ELSE
· SKIP<CSEMICOLONJtFSYS,15>;
ENt:l
ELSE
EF:FmRC5);
IF SY = SEMICOLON THEN
INSYMBOL
ELSE
EF:ROR< 14>;
REPEAT
IF SY = COHSTSY THEN CONSTANTDECLARATION;
IF SY = TYPESY THEN TYPEDECLARATION;
IF SY = VARSY THEN VARIABLEDECLARATION;
WHILE SY IN CPROCEDURESY,FUNCTIONSYJ DO PROCDECLARATION;
IF SY <> EOFSY THEN
TESTCCBEGINSY,PROCEDURESY,FUNCTIONSYJ,BLOCKBEGSYStSTATBEGSYS
UNTIL SY IN CSTATBEGSYS t CEOFSYJ>;
IF SY = BEGINSY THEN
T.NSYMBOL
ELSE
ERRORC56>;
STATEMENT<CSEMICOLON,ENDSYJtFSYS>;
WHILE SY IN ([SEMICOLON] t STATBEGSYS> DO
BEGIN
IF SY = SEMICOLON THEN
HiSYMBOL
ELSE
ERRORC14>;
STATEHENTCCSEMICOLON,ENDSYJtFSYS>;
ENI.;
IF NOT TABCPRTJ.BYVAL THEN ERRORC81>;
IF SY = ENDSY THEN
INSYHBOL
ELSE
ERRORC57>;
IF BLOCKNOCLEVELJ = 2 THEN
TESTC[PERIODJ,[J,22>
ELSE
TEST<FSYS,CJ,14>;
86
76420 END <* BLOCK *H
76460 <**)
76~.i0() f'ROCEDIJRE INITII'ILIZE;
76540 BEGIN
,
1\EYf. 1]
'AND
7f·!"i80
' ,
KEY[ 2]
'ARRAY
76620
' ,
/b660
1\EYI: 3]
'BEGIN
' ,
76700
KEY[ 4]
'CASE
,,
76740
1\EYr 5]
'CONST
,,
KEY[ 6]
'DIV
76780
',
1\EY[ 7J
'DOWNTO
76820
,
76860
KEH 8] := '[10
,
KEY[ 9]
7l:.900
'DYNAMIC
,
KEY[10J
76940
'ELSE
,
KEY[11J
'END
76980
,,
'FILE
77020
KEYC12J
' ,
KEY[L3J
'FOR
7"7060
'
77100
KEY[14J
'FUNCTION
' ,
'GOTO
77140
KEH15J
,
77180
KEY[16J
'IF
, ',
'IN
T7220
KEH17J
'.,
77260
KEYC18J := 'LABEL
,
KEY[19J
77300
'MOD
, ',
KEY[20J
77340
'NIL
,,
7?380
KEY[2l.J
'NOT
,,
KEY[22J
77420
'OF
,
'OR
77460
KEYI:23J
KEY[24J := 'OTHERWISE ,
77500
,,
I\EY[25J
'PACKED
T7540
KEY[26J
77580
'PROCEDURE ' ,
' ,
I\EY[27J
77620
'F'ROGRI'IM
'
776b0
1\F.Y[28J
'RECORD
,
77700
KEH29J := 'REPEAT
77740
KEY(30J
'SEGMENTEr• , ,
' ,
7T780
'SET
KEYC31J
' ,
77820
KEY[32J := 'THEN
,
KEY[33J
77860
'TO
,,
?7900
KEY[34J
'TYPE
,,
77940
'UNTIL
KEH35J
,,
77980
KEY[36J
'VALUE
,
KEY[37J
78020
'VAR
' ',
KEY[38]
78060
'WHILE
,,
KE.Y[39J
78100
'WITH
KSY[ 1]
78140
ANDSY;
78180
KSYE 2]
ARRAYSY;
KSY[ 3]
?8220
BEGINSY;
KSY[ 4]
78260
CI'ISESY;
78:300
KSY[ 5J
CONSTSY;
7H340
KSYI: 6]
IDIV;
7fJ380
KSY[ 7]
OOWNTOSY;
KSY[ 8]
[ICISY;
78420
KSY[ 9]
78460
r~ESERVED;
78500
I<SY[10J
ELSESY;
78540
KSHllJ
ENDSY;
KSY[ 12J
7B580
RESERVED;
78620
KSY[13J
FORSY;
"/8660
FUNCTIONSv;
KSY1:14J
RESERVED;
78700
KSH15J
7B740
KSY[16J
IFSY;
78780
RESERVED;
KSYCl7J
78820
KSY[18J
RESERVED;
78860
KSY[19J
IMOD;
713900
KSY[20J
RESERVED;
7f:l940
~~SY[ 21J
Norsv;
lB980
KSY[22J
OFSY;
7?020
K':>Y[23J
ORSY;
.-·-·-··-·-.·-·-.·-.-·-··-·-..-·-··-
·-·-
·-·-·-··-.-·-..-·-··-····.-·-.-·-··-··-··-·-···-·.-·-·-·.-···-··-··-·.-·-··-·-···-·-
..,
...
.
.,.
...,,
..,
..,.
.
..
..,.
..,
..
.,,.
..
..,
..
..
..
87
79060
79100
79140
7?180
79220
79260
79300
79340
79380
79420
79460
79500
79~i40
79580
79620
79660
7S'700
79740
79780
79820
79060
79900
79940
79980
80020
80060
80100
8()140
801.80
80220
80260
BO~WO
80340
80380
80420
80460
80500
80540
B0580
130620
80660
80700
80740
!30780
80820
80860
80900
80'i'40
80980
01020
81060
81100
81140
1]1180
81220
B1260
fl1300
!31340
81380
8142()
81460
131500
81540
81580
B1620
81660
KSY[24J != RESt::RVED;
KSY[25J
RESERVED;
KSY[2.'JJ
F'ROCEDURESY;
KSYC27J
PROGRI'IMSY;
RECORDSY;
KSYC28J
KSYr29J
REF'EI'ITSY;
KSY[30J
RESERVED;
~:SYL51 J
RESERVED;
I\SYC32J
THENSY;
KSYC33J ·- TOSY;
KSY[34J
TYPESY;
KSY[35J
UNTILSY;
RESERVED;
KSYC36J
VI'IRSY;
KSYC37J
WHILESY;
KSYC38J
KSYC39J
RESERVEI•;
SF'S[ ' t ' J
PLUS;
SF'SC'-'J
MINUS;
TIMES;
SPSC'*'J
SPSC'/'J := RIIIV;
SF'S['('J := LPI'IRENT;
SF'S[ I) '1 := RPI"'RENT;
SF'SC'='J != EGL;
SPSC','J !=COMMA;
SF'S['['J != LBRI'ICK;
SF'S['J'J := RBRI'ICK;
SPSr';'J :=SEMICOLON;
CONSTBEGSYS != lf'LUS,MINIJS,INTCON,REI"'LCON,CHI'IRCON,IDENTJ;
TYPEBEGSYS := CPLUS,MINUS,IDENT,I'IRRI'IYSY,INTCON,CHI'IRCON,LPI'IRENTJ;
INDEXBEGSYS != CIDENT,PLUS,MINUS,CHI"'RCON,INTCON,LPI'IRENTJ;
BLOCKBEGSYS != CCONSTSY,TYPESY,Vi'IRSY,PROCEDURESY,FUNCTIONSY,BEGIN~
FI'ICBEGSYS != CINTCON,REI'\LCON,CHI'IRCON,IDENT,LF'I'IRENT,NOTSYJ;
STI'IfBEGSYS != CBEGINSY,IFSY,WHILESY,REPEI'ITSY,FORSY,CI'ISESYJ;
STANTYPS != CNOTYP,INTS,REALS,BOOLS,CHI'IRSJ;
FOR CC := 0 TO ERMI'IX DO ERTI'IBCCCJ := Fi'ILSE;
LL : = 0; CC : = 0; CH. : = ' ' ;
ERRPOS := 1; LN != o;
T := -1; 1'\ := o; B := 1;
BLOCKNO[OJ := 1; R != -1;
IFLI'IG :~ Fi'ILSE; OFLI'\G != Fi'ILSE;
OK != TRUE; RC := o; INSYMBOL;
ENTERIDC'
',VARIABLE,NOTYP,O>;
ENTERIDC'FI"'LSE
',KONSTANT,BOOLS,O);
ENlERID<'TRUE
',KONSTANT,BOOLS,1>;
ENTERID<'REI"'L
',TYPEID,REI'ILS,O>;
ENlERID<'CHI"'R
',TYPEID,CHARS,O>;
ENTERIDC'BOOLEAN
',TYPEID,BOOLS,O>;
ENTERIDC'INTEGER
',TYPEID,INTS,O>;
ENTERIDC'ABS
',FUNKTION,REI'\LS,21>;
ENTERID<'SQR
',FUNKTION,REI'\LS,22>;
ENTERIDC'ODD
',FUNKTION,BOOLS,23>;
ENTERIDC'CHR
',FIJNKTION,CHI'\RS,24);
ENTERIDC'ORD
',FUNKTION,INTS,25>;
FNTERIDC'SUCC
',FUNKTION,CHI'\RS,26);
ENTERIDC'PRED
',FUNKTION,CHI'IRS,27>;
ENTER HI( 'ROUND
,FUNKTION, INTS,28);
ENTERIDC'TRUNC
',FUNKTION,INTS,29);
ENlERIDC'SIN
',FUNK1ION,REI'ILS,30>;
ENTERIDC'COS
',FUNKTION,REALS,31>;
ENTERID<'EXP
',FUNKTION,REI"'LS,32>;
ENTERID('LN
',FUNKTION,REI'ILS,33>;
ENTERID<'SORT
',FUNKTION,REALS,34);
ENTERID<'f'IRCTAN
',FUNKTION,REALS,35>;
ENTERIDC'EOF
',FUNKTION,BOOLS,36>;
ENTERID<'EOLN
',FUNKTION,BOOLS,37>;
ENTERID<'REI"'D
',PROZEDURE,NOTYP,21);
·-.-·.-·-·.-·-.-·-·.··-.···-··-·-·-··-·-
I
88
81700
81740
81780
Wl820
81860
81900
81940
B1980
8~~0~~()
82060
82100
82140
82180
82220
82260
82300
82340
82380
82420
132460
82~.i00
B:?540
82580
02620
82660
82700
82740
82780
82820
82860
82900
82940
82980
B3020
8.~060
83100
83140
83180
83220
!33260
83300
83340
83380
83420
83460
83500
83540
83580
83620
83660
83700
83740
83780
B3820
83860
83900
',PROZEDURE,NOTYP,22>;
ENTERIDC'READLN
ENTER HI ( WRITE
',PROZEDURE,N01YP,23J;
',PROZEDURE,NOTYP,24J;
ENTERIDC'WRITELN
',PROZEDURE,NOTYP,OJ;
ENTERID<'
TABCTJ.NEXT := o;
WITH IHABC1J DO
BEGIN
LAST := T; LASTPAR := 1;
END;
ENTERRANGECFALSE,O,OJ;
ENTERRANGECFALSE,-NMAX,NMAX>; ENTERRANGECFALSE,EMIN,EMAXJ;
ENTERRANGECFALSE,0,1>; ENTERRANGECFALSE,O,MAXCHAR>;
ENTERRANGE<FALSE,-XMAX,XMAX>;
END C* INITIALIZE*>;
<**>
PROCEDURE PROGRAMHEADING;
BEGIN
IF SY <> PROGRAMSY THEN
ERRORC3)
ELSE
BEGIN
INSYMBOL;
IF SY <> IDENT THEN
ERROk<2>
ELSE
BEGIN
F'ROGNAME : = I II;
INSYMBOL;
IF SY <> LPARENT THEN
ERRORC9J
ELSE
REPEAT
INSYM:OOL.;
IF SY <> IDENT THEN
ERROR<2>
ELSE
BEGIN
IF ID = 'INPUT
THEN
!FLAG := TRUE
ELSE IF ID = 'OUTPUT
THEN
DFL.AG := TRUE
ELSE
ERROR<O>;
INSYMBOL;
IF SY = RDIV THEN INSYMBOL;
END
UNTIL SY <> COMMA;
IF SY = RPARENT THEN
INSYMBOL
ELSE
ERROR<4>;
IF NOT OFLAG THEN ERRORC20>;
END;
END;
END (* PROGRAMHEADING *>;
I
I
I
(**)
a:3940 PRDCEDURE ERRORMSG;
!M980 VAk I, N : INTEGER;
84020
C : CHI'IR;
84060 BEGIN
84100
WRITELN;WRITELN;WRITELN<' ERROR MESSAGES'>;
RESETCEMSG>; READ<EMSG,N,C,C,CJ;
84140
FOR I := 0 TO ERMAX DO
84180
IF ERTABCIJ THEN
84220
84260
BEGIN
84300
WHILE N < I DO
89
84;340
84380
84420
84460
84500
84540
84580
046?0
134660
B4700
8474()
84780
84820
84860
84900
84940
8498()
85020
85060
85100
8:H40
8~i1. 80
85260
85300
B5340
B5380
85420
85460
85500
8:':i540
l:l5!:'i80
8!':i620
85660
85700
85740
85780
858~~0
85860
85900
85940
85~80
86020
86060
86100
86140
86180
86220
86260
86300
86340
86380
86420
86460
86500
86540
B6:"j80
86620
86660
86700
BEGIN
WHILE NOT EOLNCEMSG) DO
READCEMSG,C>;
REAli CEMSG, C) ;
READCEMSG,C>;
IF C tN ['0',,'9'J THEN
BEGIN
N := ORDCC> - ORD C'O'>;
READCEMSG,C>;
IF C IN ['0',,'9'J THEN
N := N * 10 t ORD<C> - ORD ('0'>;
READCEMSG,C,C>;
END;
END;
WRITECN:3,': '>;
REPEAT
WHILE NOT EOLNCEMSG> DO
BEGIN
REf'I[I(EMSG,C>;
WRITE<C>;
END;
READCEMSG,C>;
WRJTELN;
REI'IDCE:MSG,C>;
IF C IN ['0',,'9'] THEN
BEGIN
N := ORDCC) - ORDC'O'>;
REI'IDCEMSG,C>;
IF C IN ['0',,'9'1 THEN
N := N * 10 t ORDCC> - ORDC'O'>;
READCEMSG,C,C>;
END
ELSE
BEGIN
READ<EMSG,C,c,c>;WRITEC' ':5>;
END;
UNTIL N > I;
END;
WRITELN; WRITELN;
END <* ERRORMSG *>;
'**>
BEGIN <* MAIN *>
INITIALIZE;
f'ROGRI'IMHEAD I NG;
BLOCKCBLOCKBEGSYS+STATBEGSYS,FALSE,l,T>;
IF NOT EOSCINPUT> THEN
BEGIN
WRITELN;
WRITELN<'THE FOLLOWING PROGRAM TEXT ARE NOT PROCESSED'>;
REPEAT
INSYMBOL;
UNTIL SY = EOFSY;
END;
99: REWRITECAAAAERR>;
WRITELNCAAAAERR,'.PROC,AAAAEOR,'>;
IF OK THEN
WRITELN<AAAAERR,'SET,RlG=l,')
El.SF.
BEGIN
WRITELNCAAAAERR,'SET,R1G=2.');
ERRDRMSG;
END;
86740
86780
WRITELNC~AAAERR,'REVERT,');
86B20
86860 ENII <*MAIN *>•
06
Q .
SVdiNIW
~0~
S2DVSS2W
G XIGN2ddV
~0~~2
91
. &
0
THE INDICATED IDENTIFIER HAS NOT BEEN DECLARED.
1
THE INDICATED IDENTIFIER IS DECLARED MORE THAN ONCE
IN THE SAME SCOPE.
2
AN IDENTIFIER IS EXPECTED. THE FOLLOWING RESERVED
KEYWORDS MAY NOT BE USED AS AN IDENTIFIER:
'AND',
'ARRAY', 'BEGIN', 'CASE', 'CONST', 'DIV', 'DOWNTO',
'DO', 'DYNAMIC' I 'ELSE', 'END' I 'FILE', 'FOR',
'FUNCTION', 'GOTO', 'IF', 'IN', 'LABEL', 'MOD',
'NIL' I 'NOT', 'OF' I 'OR', 'OTHERWISE', 'PACKED',
'PROCEDURE', 'PROGRAM', 'RECORD', 'REPEAT', 'SEGMENTED' I 'SET', 'THEN', 'TO', 'TYPE', 'UNTIL',
11
I VALUE. I
VAR. I • WHILE I , • WITH I •
NOTE • DYNAMIC I I
'VALUE', 'OTHERWISE', AND 'SEGMENTED' ARE NOT STANDARD RESERVED KEYWORDS, THEY ARE RESERVED BY CDC
PASCAL3, HOWEVER.
3
EVERY PROGRAM MUST BEGIN WITH THE SYMBOL 'PROGRAM'.
4
A CLOSING RIGHT PARENTHESIS')' IS EXPECTED.
5
A COLON':' IS EXPECTED.
IN DECLARATIONS, COLON IS
FOLLOWED BY A TYPE.
(REAL,. INTEGER, BOOLEAN, CHAR,
ETC.).
6
THE INDICATED SYMBOL MAY NOT FOLLOW THE PRECEDING
EXPRESSION.
7
IN A FORMAL PARAMETER LIST OF PROCEDURE DECLARATION,
EACH SECTION MUST BEGIN WITH AN IDENTIFIER OR THE
SYMBOL 'VAR', DEPENDING ON WHETHER THE PARAMETER IS
A VALUE PARAMETER OR A VARIABLE PARAMETER.
8
THE SYMBOL 'OF' IS EXPECTED.
9
AN OPENING LEFT PARENTHESIS '(' IS EXPECTED.
10
A TYPE DEFINITION MUST BEGIN WITH THE FOLLOWING
SYMBOLS: PLUS '+',MINUS '-', 'ARRAY', OPEN LEFT
PARENTHESIS '(', INTEGER CONSTANT, CHARACTER CONSTANT, OR PREVIOUSLY DEFINED IDENTIFIER.
11
AN OPENING LEFT SQUARE BRACKET '[' IS EXPECTED.
12
A CLOSING RIGHT SQUARE BRACKET ']' IS EXPECTED.
13
THE SYMBOL ' •• • IS EXPECTED (NO BLANKS ARE ALLOWED
BETWEEN THE DOTS) •
14
A SEMICOLON • ,• • IS EXPECTED.
92
15
THE RESULT TYPE OF A FUNCTION MUST BE A SIMPLE TYPE.
THE SIMPLE TYPES INCLUDE STANDARD TYPE IDENTIFIER
(INTEGER, REAL, BOOLEAN, CHAR), PREVIOUSLY DEFINED
TYPE IDENTIFIER (ENUMERATED TYPE, SUBRANGE OF
INTEGER, BOOLEAN, CHAR, OR ENUMERATED). IT MAY NOT
BE A STRUCTURED DATA TYPE (ARRAY).
16
AN EQUALS SIGN'=' IS EXPECTED. THE SYMBOL 1 := 1 IS
USED IN ASSIGNMENT STATEMENTS ONLY, AND NOT IN THE
DECLARATION PART.
17
ANY EXPRESSION FOLLOWING THE SYMBOL 'IF',
OR 'UNTIL' MUST BE OF TYPE 'BOOLEAN'.
18
THE CONTROL VARIABLE FOLLOWING THE SYMBOL 'FOR'
MUST BE OF TYPE INTEGER, CHAR, BOOLEAN, ENUMERATED,
OR THE SUBRANGE OF INTEGER, CHAR, BOOLEAN, AND
ENUMERATED.
19
BOTH EXPRESIONS WHICH SPECIFY THE INITIAL AND FINAL
VALUES FOR THE CONTROL VARIABLE IN A 'FOR' STATEMENT
MUST BE OF THE SAME TYPE AS THE CONTROL VARIABLE.
20
THE FILE 'OUTPUT' MUST BE DECLARED IN THE PROGRAM
HEADING.
21
THE INDICATED NUMBER IS TOO LARGE. FOR THE CDC IMPLEMENTATION OF PASCAL, THE MAXIMUM NUMBER OF DIGITS
IS 14; THE ABSOLUTE VALUE OF AN INTEGER NUMBER MAY
NOT EXCEED 2**48 - 1; THE ABSOLUTE VALUE OF A REAL
NUMBER MAY NOT EXCEED 10**323.
22
A PERIOD •.• IS EXPECTED AT THE END OF THE PROGRAM.
CHECK FOR MATCHING 'BEGIN' AND 'END' SYMBOLS.
23
THE EXPRESSION FOLLOWING THE SYMBOL 'CASE' MUST BE
OF TYPE CHAR, INTEGER, BOOLEAN, OR ENUMERATED.
24
THE INDICATED CHARACTER IS NOT IN THE PASCAL CHARACTER SET.
25
IN A CONSTANT DEFINITION, THE EQUALS SIGN '=' MUST
BE FOLLOWED BY A CONSTANT. IF AN IDENTIFIER IS
USED, IT MUST DENOTE A CONSTANT. IT MAY NOT BE A
PROCEDURE, TYPE IDENTIFIER, VARIABLE, OR FUNCTION.
26
THE TYPE OF AN INDEX EXPRESSION MUST BE IDENTICAL
TO THE INDEX TYPE SPECIFIED IN THE ARRAY DECLARATION.
'WHILE',
93
27
IN AN INDEX DECLARATION, THE LOWER BOUND MAY NOT
EXCEED THE UPPER BOUND. ALSO, BOTH BOUNDS MUST HAVE
IDENTICAL TYPE, EITHER 'INTEGER', 'CHAR', 'BOOLEAN',
OR ENUMERATED. REAL NUMBERS ARE NOT ACCEPTABLE FOR
ARRAY BOUNDS. THE PERMISSIBLE RANGE OF VALUES FOR
AN ARRAY INDEX IS -131071 •• 131071.
28
EVERY INDEXED VARIABLE MUST BE DECLARED AS AN ARRAY.
29
THE TYPES OF CORRESPONDING ACTUAL AND FORMAL
'VARIABLE' PARAMETERS MUST BE IDENTICAL. THEY MUST
POSSESS THE SAME TYPE IDENTIFIER AS THEIR UNDERLYING
DATA TYPES.
30
THIS TYPE IS NOT DEFINED.
TIONS ARE NOT ALLOWED).
31
STRING CONSTANTS MUST BE CONTAINED ON A SINGLE LINE.
CHECK THE CLOSING APOSTROPHE '.
32
THE OPERANDS OF THE LOGICAL OPERATORS ('NOT, 'AND',
'OR') MUST BE OF TYPE 'BOOLEAN'. NOTE THAT THE
LOGICAL OPERATORS (NOT, AND, OR) HAVE HIGHER PRECEDENCE THAN RELATIONAL OPERATORS('<', '<=', '=',
'<>', '>', '>='). THUS, AN EXPRESSION OF THE FORM
X > Y OR X < Z (ASSUME X~ Y, AND Z ARE INTEGER OR
REAL) WILL BE INTERPRETED AS X > (Y OR X) < Z, WHICH
IS INCORRECT PASCAL. A CORRECT FORM IS (X > Y) OR
(X< Z).
33
THE OPERANDS OF AN ARITHMETIC EXPRESSION MUST BE OF
TYPE INTEGER OR REAL. NOTE THAN AN ENTIRE ARRAY MAY
NOT BE AN OPERAND OF A LOGICAL OR ARITHMETIC OPERATOR.
34
BOTH OPERANDS OF 'DIV' AND 'MOD' MUST BE OF TYPE
'INTEGER'.
35
THE TYPES OF COMPARANDS ARE NOT COMPATIBLE. THEY
MUST BE COMPATIBLE, UNLESS ONE COMPARAND IS OF TYPE
'INTEGER' AND THE OTHER OF TYPE 'REAL'. ARRAYS MUST
BE COMPARED ELEMENT BY ELEMENT.
36
THE TYPES OF CORRESPONDING ACTUAL AND FORMAL VALUE
PARAMETERS MUST BE COMPATIBLE.
IF THEIR TYPES ARE
STRUCTURED TYPES (ARRAYS), THEN THEY MUST POSSESS
THE SAME TYPE IDENTIFER AS THEIR UNDERLYING DATA
TYPES. AN EXCEPTION IS MADE IF THE FORMAL VALUE
PARAMETER IS OF TYPE REAL, THEN THE ACTUAL VALUE
PARAMETER MAY ALSO BE AN INTEGER OR SUBRANGE OF
INTEGERS.
(RECURSIVE TYPE DEFINI-
94
37
PARAMETERS OF THE STANDARD PROCEDURES READ AND
READLN MUST DENOTE A VARIABLE IDENTIFIER. THEY MAY
NOT BE A CONSTANT, TYPE IDENTIFIER, PROCEDURE, OR
FUNCTION.
38
A STRING MUST CONTAIN AT LEAST ONE CHARACTER.
39
THE NUMBER OF ACTUAL PARAMETERS IN A PROCEDURE OR
FUNCTION CALL MUST BE EQUAL TO THE NUMBER OF FORMAL
PARAMETERS IN ITS DECLARATION.
40
PARAMETERS OF THE STANDARD PROCEDURE 'READ' AND
'READLN' MUST BE OF TYPE 'CHAR', 'INTEGER', OR
'REAL'.
41
PARAMETERS OF THE STANDARD PROCEDURE 'WRITE' AND
'WRITELN' MUST BE OF TYPE 'CHAR', 'INTEGER', 'REAL',
OR 'BOOLEAN'.
42
IF A STATEMENT HAS THE FORM WRITE(X:M:N), THEN X
MUST BE AN EXPRESSION OF TYPE 'REAL'.
43
IF A STATEMENT HAS THE FORM WRITE(X:M:N) OR
WRITE(X:N), THEN M AND N MUST BE EXPRESSIONS OF TYPE
'INTEGER'.
44
'PROCEDURE' OR 'TYPE' IDENTIFIERS MAY NOT BE PART OF
AN EXPRESSION.
45
A STATEMENT MAY NOT BEGING WITH A 'TYPE' OR 'FUNCTION' IDENTIFIER. AN EXCEPTION IS THE ASSIGNMENT OF
A RESULT VALUE TO A 'FUNCTION' IDENTIFIER. IN THIS
CASE, THE ASSIGMENT STATEMENT MUST BE PART OF THE
FUNCTION BODY.
46
IN AN ASSIGNMENT STATEMENT X := E, THE TYPES OF
VARIABLE X AND EXPRESSION E MUST BE IDENTICAL. ONE
EXCEPTION: IF X OF TYPE 'REAL', THEN E MAY ALSO BE
OF TYPE 'INTEGER'.
47
A 'CASE' LABEL MUST BE A CONSTANT OF THE SAME TYPE
AS THE SELECTOR EXPRESSION IN THE 'CASE' CLAUSE.
48
THE INDICATED ARGUMENT OF THE STANDARD FUNCTION IS
OF AN ILLEGAL TYPE.
49
IN A PROCEDURE OR FUNCTION CALL, EACH ACTUAL PARAMETER MUST BE FOLLOWED BY THE SYMBOL COMMA',' OR
THE SYMBOL CLOSE PARENTHESIS ')'.
50
A CONSTANT MUST BEGIN WITH ONE OF THE FOLLOWING
SYMBOLS:
'+', '-', REAL CONSTANT, INTEGER CONSTANT,
CHARACTER CONSTANT, OR IDENTIFIER.
95
51
THE ASSIGNMENT SYMBOL':=' IS EXPECTED.
ARE ALLOWED BETWEEN':' AND'=').
(NO BLANKS
52
THE SYMBOL 'THEN' IS EXPECTED.
53
THE SYMBOL 'UNTIL' IS EXPECTED.
54
THE SYMBOL 'DO' IS EXPECTED.
55
THE SYMBOL 'TO' OR 'DOWNTO' IS EXPECTED.
56
THE SYMBOL 'BEGIN' IS EXPECTED.
57
THE SYMBOL 'END' IS EXPECTED
58
AN EXPRESSION MUST BEGIN WITH ONE OF THE FOLLOWING
SYMBOLS:
'NOT', OPEN PARENTHESIS '( ', INTEGER
CONSTANT, REAL CONSTANT, CHARACTER CONSTANT, OR
IDENTIFIER.
59
THE ONLY SYMOBLS THAT MAY FOLLOW A STATEMENT ARE:
'ELSE', 'UNTIL',
'END', AND SEMICOLON ':'•
60
IN A FORMAL PARAMETER LIST DECLARATION SUCH AS
'PROCEDURE P(X,Y:TYPEl) ', TYPEl MUST DENOTE A PREVISOULS DEFINED IDENTIFIER. IT MAY NOT BE A COMPLEX
DATA STRUCTURE DEFINED ON THE SPOT. THIS MEANS THAT
TYPEl MAY NOT BE AN ARRAY, ENUMERATED, OR SUBRANGE
TYPE DECLARATION.
61
THE SYMBOL COMMA',' IS EXPECTED.
62
AN ARRAY INDEX DECLARATION MUST BEGIN WITH ONE OF
FOLLOWING SYMBOLS: PLUS '+',MINUS '-',OPEN
PARENTHESIS '( ', INTEGER CONSTANT, CHARACTER CONSTANT, PREVIOUSLY DEFINED TYPE IDENTIFIER.
64
A TYPE DEFINITION MAY ONLY BE ENDED BY THE SYMBOL
SEMICOLON':'.
65
THE INDEX TYPE OF AN ARRAY MAY NOT BE AN ARRAY.
66
THE STANDARD TYPE IDENTIFIERS 'INTEGER' AND 'REAL'
MAY NOT BE DECLARED AS THE INDEX OF AN ARRAY.
67
FOR A TYPE DEFINITION IN THE FORM OF 'TYPE X= Y',
'VAR X : y•' OR "FUNCTION X(PARAMETER LIST) : y• I
Y MUST DENOTE A TYPE IDENTIFIER. IT MAY NOT BE A
CONSTANT, VARIABLE, PROCEDURE, OR FUNCTION.
68
IN AN ASSIGNMENT STATEMENT 'X:= Y', THE VALUE OF Y
MUST BE WITHIN THE PERMISSIBLE RANGE OF X.
96
69
IN A FOR STATEMENT OF THE FORM 'FOR I := X TO Y DO
STATEMENT!', THE VALUE OF THE LOOP CONTROL VARIABLE
MAY NOT BE CHANGED WITHIN THE STATEMENTl. THIS
MEANS THAT THE FOLLOWING STATEMENTS MAY NOT BE USED
FOR STATEMENTl: READ(I), I := I + J, FOR I := Xl
TO Yl DO STATEMENT2, OR P(I) (* WHERE I IS AN
ACTUAL VARIABLE PARAMETER IN THE CALL OF PROCEDURE
p *).
70
A LOOP CONTROL VARIABLE MUST BE DECLARED IN THE
VARIABLE DECLARATION PART (OR FORMAL PARAMETER LIST)
OF THE MAIN PROGRAM OR SUBPROGRAM THAT IMMEDIATELY
CONTAINS IT. IT MAY NOT BE A FORMAL VARIABLE PARAMETER (PASS BY VAR).
71
THE LOOP CONTROL VARIABLE MUST DENOTE A 'VARIABLE'.
IT MAY NOT BE A CONSTANT, TYPE IDENTIFIER, PROCEDURE, OR FUNCTION.
72
THE LOOP CONTROL VARIABLE MUST BE A 'SIMPLE'
VARIABLE, IT MAY NOT BE A STRUCTURED VARIABLE. AN
INDEXED VARIABLE LIKE A[I] CAN NOT BE USED AS A LOOP
CONTROL VARIABLE.
73
FOR AN INDEXED VARIABLE 'A[I]' (A IS AN ARRAY), THE
VALUE OF INDEX I MUST BE WITHIN THE PERMISSIBLE
RANGE OF THE INDEX-TYPE FOR ARRAY A.
74
IN A PROCEDURE OR FUNCTION CALL, THE VALUE OF AN
ACTUAL 'VALUE' PARAMETER MUST BE WITHIN THE PERMISSIBLE RANGE OF THE CORRESPONDING FORMAL 'VALUE'
PARAMETER.
75
IN A PROCEDURE OR FUNCTION CALL, THE ACTUAL VARIABLE PARAMETER MUST DENOTE A 'VARIABLE'.
IT MAY
NOT BE A CONSTANT, TYPE IDENTIFIER, PROCEDURE, OR
FUNCTION.
76
THE FOLLOWING STATEMENTS ARE SYNTATICALLY CORRECT,
BUT USUALLY SEMANTICALLY INCORRECT (NOTE THE POSITION OF SEMICOLONS):
IF Cl THEN; Sl
(* Sl WILL ALWAYS BE EXECUTED *)
FOR I := X TO Y DO; S2
(* S2 WILL BE EXECUTED ONLY ONCE *)
WHILE Cl DO; Sl
(* EITHER Cl IS FALSE AND Sl WILL BE EXECUTED
ONCE, OR Cl WILL BE TRUE AND WHILE Cl DO;
WILL BE AN INFINITE LOOP *)
77
THE SYMBOL SEMICOLON
'ELSE'.
I
0
I
I
MAY NOT PRECEED THE SYMBOL
97
78
FOR A CASE STATEMENT IN THE FORM OF
CASE EXPRESSION OF
Lll,Ll2, •••
Sl;
L2l,L22, •••
S2;
.
.
. ... . .. . . . . ... . . . . .
END
ALL THE LABEL CONSTANTS (Lll, Ll2,
DIFFERENT.
'
f)
••. ) MUST BE
80
THE FILE 'INPUT' MUST BE INCLUDED IN THE PROGRAM
HEADING IN ORDER TO USE 'READ', OR 'READLN'.
81
EVERY FUNCTION MUST CONTAIN AT LEAST ONE ASSIGNMENT
TO ITS IDENTIFIER WITHIN THE FUNCTION BODY.
82
A CHARACTER, BOOLEAN, OR ENUMERATED CONSTANT MAY
NOT BE PRECEDED BY A SIGN('+' or '-').
83
A CONSTANT MAY NOT BE FOLLOWED BY THE INDICATED
SYMBOL.
84
THE ONLY SYMBOLS THAT MAY FOLLOW THE CONSTANT
DECLARATION ARE:
'TYPE', 'VAR', 'PROCEDURE', 'FUNCTION', 'BEGIN', AND IDENTIFIER.
85
THE ONLY SYMBOLS THAT MAY FOLLOW THE TYPE DECLARATION ARE:
'VAR', 'PROCEDURE', 'FUNCTION', 'BEGIN',
AND IDENTIFIER.
86
THE ONLY SYMBOLS THAT MAY FOLLOW THE VARIABLE
DECLARATION ARE:
'PROCEDURE', 'FUNCTION', 'BEGIN',
AND IDENTIFIER.
87
THE ONLY SYMBOLS THAT MAY FOLLOW THE PROCEDURE OR
FUNCTION DECLARATION ARE:
'PROCEDURE', 'FUNCTION',
'BEGIN'.
88
A PROCEDURE OR FUNCTION PARAMETER LIST DECLARATION
MUST BE FOLLOWED BY THE SYMBOL SEMICOLON';'
(PROCEDURE) OR COLON':' (FUNCTION).
89
AN INDEXED VARIABLE MAY NOT BE FOLLOWED BY THE INDICATED SYMBOL.
90
END OF FILE MARK UNEXPECTEDLY ENCOUNTERED: CHECK THE
CLOSING COMMENT.
86
SVdiNIW
~0~
~DVQDNV~
~
XIGN~ddV
~O~iliNO~
aor
99
I
,PROC,PASCAL,SOURCE,NL=$Lt$/$L-$,GO=$G-$/$Gt$,
RETURN,AAAPOUT,AAAMOUT,AAAEMSG,LGO,AAAARUN,AAAAERR.
IFE,FILECSOURCE,.NOT.<LO.OR.PT>>,Ll.
GET,SOURCE/NA.
ENDIF,Ll.
IFE,FILE<SOURCE,.NOT.<LO.OR.PT>>,L2.
RFVERT,ABORT. SOURCE IS NOT FOUND IN YOUR ACCOUNT.
FNDIF,L2,
GET,AAAARUN,AAAEMSG/UN=RBDR07L,NA.
SET,RlG=O.
SET,EF=O.
NOEXIT.
AAAARUN,SOURCE,AAAMOUT,AAAEMSG.
REWIND,*·
IFE,EF.EQ.O,L5.
AAAAERR.
ELSE,L5.
SET,EF=O.
NOTE,/ SORRY, ERRORS IN MINIPAS.
ENDIF,L5.
PASrALJ,SOURCE,AAAPOUT/NL.
ONEXIT.
REWIND,*•
IFE,R1G.E0.2,L13,
IFE,EF.EQ,O,Ll4o
APPEND,SURVEY,SOURCE/UN=RBDR090,NA.
IFE,$NL$=$Lt$,L21,
COPY,AAAPOUT,
ENDIF,L21.
IFE,$GOI.EQ.SGt$,L15.
LGO,
ENDIF,L15.
REVERT,
ELSE,L14.
COPY,AAAMOUT.
COPY,AAAPOUT,
APPEND,SURVEY,SOURCE/UN=RBDR090,NA,
REVERT,ABORT, ERRORS IN PASCAL PROGRAM.
ENDIF,L14.
ENDIF,L13.
IFE,R1G.EQ.t,L10.
IFE,EF.EQ,O,Lllo
IFE,$NL$=$Lt$,L30.
COPY,AAAPOUT,
ENDIF,L30.
IFE,$GO$.EQ,$Gt$,L12.
LGO.
ENDIF,L12.
REVERT.
ELSE,Lll.
APPEND,SURVEY,SOURCE/UN=RBDR090,NA.
COPY,AAAPOUJ,
REVERT,ABORT, ERRORS IN PASCAL PROGRAM.
ENDIF,Lll.
ENDIF,LJO,
IFE,R1G.EQ,O,L7.
APPEND,SURVEY,SOURCE/UN=RBDR090,NA.
IFE,EF.EQ,O,LB.
IFE,$NL$=SLt$,L20.
CUPY,AAAPOUT.
ENDIF,L20.
IFE,$GQ$.EQ,$Gt$,L9.
LGO,
ENDIF,L9.
"WV~00~d
lV8SVd NI
S~OYY3
'll'~IGN3
'8l'AIGN3'
"lYO~W'lY3n3Y
"lnOdWWW"Ad03
"81'3813
"lH3n3Y
001