Trailing-Edge
-
PDP-10 Archives
-
tops20-v7-ft-dist1-clock
-
7-sources/diulan.bli
There are 4 other files named diulan.bli in the archive. Click here to see a list.
MODULE DIULAN (ident = '253'
%REQUIRE ('DIUPATSWITCH')
) =
begin
!++
! COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1986.
! ALL RIGHTS RESERVED.
!
! THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND
! COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE AND WITH
! THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE OR
! ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE
! AVAILABLE TO ANY OTHER PERSON. NO TITLE TO AND OWNERSHIP OF THE
! SOFTWARE IS HEREBY TRANSFERRED.
!
! THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
! NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL
! EQUIPMENT CORPORATION.
!
! DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF
! ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY DIGITAL.
!
! FACILITY: Pat Parser
!
! ABSTRACT:
!
! PATLANGSP.REQ defines the interface between the user of the
! PAT Parser and the language independent portion of the parser.
! PATLANGSP.REQ and .BLI are provided with the PAT parser package
! and provide an example of a particular implementation of the
! interface specification.
!
! Nothing in this module is referenced directly by the language
! independent portion of the parser.
!
! THIS FILE MUST BE ALTERED TO USE WITH OTHER COMPILERS !
!
! ENVIRONMENT: VAX/VMS user mode
!
! AUTHOR: H. Alcabes, CREATION DATE: 3-Dec-80
!
! MODIFIED BY:
!
! Charlie Mitchell, 02-Nov-1981 : VERSION X2-001
! 001 - Modify to use new PATDATA and remove direct references from
! parser.
!
! 002 - Remove VMS dependencies. 25-May-84 C. Richardson
!
! 64 Make PAT PARSER signal parsing errors correctly. Change TEXT_BUFn
! to TEXT_nBUF in PATPAR.BLI so that DDT can distinguish the symbols.
! Sandy Clemens 15-Jan-86
!
! 253 Rename file to DIULAN.
! Gregory A. Scott 1-Jul-86
!
!--
! INCLUDE FILES:
require 'DIUPATPROLOG'; !
%BLISS36 (
library 'FAO';
UNDECLARE TRUE, FALSE;
library 'DIU';
)
library 'BLI:XPORT';
library 'DIUPATLANGSP';
library 'DIUPATDATA';
library 'DIUDEB'; ! Debug routines
!
! TABLE OF CONTENTS:
! This file is divided into the same six sections as PATLANGSP.REQ.
! Section 1. Interface to lexical analyzer and lexical tokens.
forward routine
PAT$LSLOCAL_SAVE_TOKEN : novalue, ! Save a lexical token
PAT$LSLOCAL_RETURN_SAVED_TOKEN, ! Return the saved token
PAT$LSLOCAL_OUTPUT_TOKEN, ! Return string descriptor containing token description
PAT$LSLOCAL_LOC_TEXT; ! Return text for locator
%if PATBLSEXT_DEBUGGING
%then
forward routine
PAT$LSLOCAL_DUMP_TOK : novalue; ! Dump particular lexical token
%fi
! Section 2. Terminal and non-terminal symbol interpretation.
macro ! 002
sd_base = 0, 0, 0, 0 %; ! 002
forward routine
PAT$LSLOCAL_SYMBOL_CLASS, ! Return symbol class
PAT$LSLOCAL_IS_NON_TERM, ! Check for a non-terminal
PAT$LSLOCAL_IS_RESERVED_WORD, ! Check for a reserved word
PAT$LSLOCAL_OUTPUT_TERM; ! Return string descriptor containing token type
! Section 3. Action routine interface - no routines in this category
! Section 4. Error message interface (local and scope recovery) - no
! routines in this category
! Section 5. Error message interface (global recovery)
forward routine
PAT$LSLOCAL_EXPECTED_SYMBOL : novalue, ! Add expected symbol to tables
PAT$LSLOCAL_GLOBAL_ERROR_MSG : novalue; ! Print global error message
! Section 6. Other definitions (misc. utility routines)
forward routine
APPEND_TO_TEXT : novalue, ! Append a contents of a string descriptor to TEXT_SD
DOWN_CASE : novalue; ! Create a lowercase of a string descriptor
! MACROS:
! Define a macro for the token structure to minimize
! use of TKN_*.
macro
LSLOCAL_TKN_STR =
TKN_STR %; ! Token structure
! See text buffers below and routine APPEND_TO_TEXT
macro
APPEND_TO_TEXTM (BUFNUM, SSTRING) =
begin ! 002
%if %isstring (SSTRING) ! 002
%then ! 002
local s: $str_descriptor (string=sstring); ! 002
%else ! 002
bind s = sstring; ! 002
%fi ! 002
APPEND_TO_TEXT (BUFNUM, S); ! 002
end ! 002
%;
! See text buffers below and routine APPEND_TO_TEXT
macro
CLEAR_TEXTM (BUFNUM) =
begin
TEXT_BUF_FULL [BUFNUM] = FALSE;
TEXT_SD [BUFNUM, STR$H_LENGTH] = 0 ! 002
end
%;
! OWN STORAGE:
! Text buffers managed by routine APPEND_TO_TEXT and
! macros APPEND_TO_TEXTM and CLEAR_TEXTM. Three text buffers
! are used to hold text prior to an actual call to report the
! error.
literal
TEXT_BUF0_SIZE = 128,
TEXT_BUF1_SIZE = 128,
TEXT_BUF2_SIZE = 128;
own
TEXT_BUF_SIZE : vector [3] preset (
[0] = TEXT_BUF0_SIZE,
[1] = TEXT_BUF1_SIZE,
[2] = TEXT_BUF2_SIZE),
TEXT_BUF_FULL : vector [3 %BLISS32 (, byte)]; ! 002
GLOBAL
TEXT_0BUF : vector [ch$allocation (TEXT_BUF0_SIZE)], ! 002
TEXT_1BUF : vector [ch$allocation (TEXT_BUF1_SIZE)], ! 002
TEXT_2BUF : vector [ch$allocation (TEXT_BUF2_SIZE)]; ! 002
own
TEXT_SD : blockvector [3, STR$K_F_BLN] ! 002
field (STR$B_CLASS, STR$B_DTYPE, STR$H_LENGTH, STR$A_POINTER) ! 002
preset ( ! 002
[0, STR$A_POINTER] = ch$ptr (TEXT_0BUF), ! 002
[1, STR$A_POINTER] = ch$ptr (TEXT_1BUF), ! 002
[2, STR$A_POINTER] = ch$ptr (TEXT_2BUF)); ! 002
! Temporary text buffer for down casing reserved words.
own
TEMP_BUF : vector [ch$allocation (132)], ! 002
TEMP_TEXT : $STR_DESCRIPTOR (string = (132, ch$ptr (TEMP_BUF))); ! 002
! Storage used by PAT$LSLOCAL_SAVE_TOKEN to save a lexical token.
own
SAVED_TOKEN : LSLOCAL_TKN_STR;
! EQUATED SYMBOLS
! Literals representing possible symbol classes
ENUMERATION ('SYMCLASS', 1, !
SYMCLASS_RW, ! Reserved word
SYMCLASS_SPECIALCH, ! Special character
SYMCLASS_PATH_NAME, ! CDD path name
SYMCLASS_CDD_NAME, ! CDD name
SYMCLASS_DESCR_TEXT, ! DESCRIPTION text
SYMCLASS_STRING, ! Character string
SYMCLASS_NUMBER, ! Number (integer or real)
SYMCLASS_EOF, ! End of file
SYMCLASS_NONTERM); ! Non-terminal
! Section 1
! Interface to lexical analyer and lexical tokens:
global routine PAT$LSLOCAL_SAVE_TOKEN (TOKEN_PTR) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! See LS_SAVE_TOKEN macro in PATLANGSP.REQ.
! LS_SAVE_TOKEN is used whenever an error is detected at the
! very start of error recovery with a pointer to a
! lexical token. (The current token when the error was detected.)
! LS_SAVE_TOKEN must save the token (including auxiliary information
! that is associated with the token). This is necessary because
! the global recovery algorithm can skip an arbitrarily large number
! of tokens (more than fit in the ring buffer required by
! LS_GET_LEX_TOKEN).
!
! After global error recovery has been completed but before an error
! message is issued, LS_RETURN_SAVED_TOKEN is called to return a
! pointer to the save token. The saved token is then used in
! constructing the error message:
!
! Found <description-of-saved-token> when expecting ...
!
! Two consecutive calls are never made to LS_SAVE_TOKEN without an
! intervening call to LS_RETURN_SAVED_TOKEN.
!
! FORMAL PARAMETERS:
!
! TOKEN_PTR Pointer to token to save.
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! SAVED_TOKEN gets saved token.
!
! ROUTINE VALUE:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
map
token_ptr: ref lslocal_tkn_str;
saved_token [tkn_term] = .token_ptr [tkn_term];
saved_token [tkn_locator] = .token_ptr [tkn_locator];
saved_token [tkn_text] = .token_ptr [tkn_text];
saved_token [tkn_clean_text] = .token_ptr [tkn_clean_text];
saved_token [tkn_comments] = .token_ptr [tkn_comments];
saved_token [tkn_intvalue] = .token_ptr [tkn_intvalue];
saved_token [tkn_realvalue] = .token_ptr [tkn_realvalue];
saved_token [tkn_start_line] = .token_ptr [tkn_start_line];
saved_token [tkn_synthetic] = .token_ptr [tkn_synthetic];
end;
global routine PAT$LSLOCAL_RETURN_SAVED_TOKEN (TOKEN_PTR) =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! See LS_RETURN_SAVED_TOKEN macro in PATLANGSP.REQ.
! LS_RETURN_SAVED_TOKEN returns the token saved by LS_SAVE_TOKEN.
!
! FORMAL PARAMETERS:
!
! TOKEN_PTR (not used)
!
! IMPLICIT INPUTS:
!
! SAVED_TOKEN The saved token.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! Address of SAVED_TOKEN.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
return SAVED_TOKEN
end;
global routine PAT$LSLOCAL_OUTPUT_TOKEN (TOKEN_PTR, BUFNUM) =
!++
! FUNCTIONAL DESCRIPTION:
!
! PAT$LSLOCAL_OUTPUT_TOKEN stores text describing a lexical token in
! a string descriptor and returns that string descriptor.
!
! FORMAL PARAMETERS:
!
! TOKEN_PTR - Pointer to a lexical token
!
! BUFNUM - Number of text buffer to be used
!
! IMPLICIT INPUTS:
!
! Text buffer indexed by BUFNUM.
!
! IMPLICIT OUTPUTS:
!
! Text buffer indexed by BUFNUM.
!
! ROUTINE VALUE:
!
! TEXT_PTR - Pointer to string descriptor containing description
! of token
!
! SIDE EFFECTS:
!
! NONE
!
!--
begin
map
TOKEN_PTR : ref LSLOCAL_TKN_STR;
local
TERM_NUM;
TERM_NUM = LS_LEX_TERM (TOKEN_PTR);
CLEAR_TEXTM (.BUFNUM);
selectone PAT$LSLOCAL_SYMBOL_CLASS (.TERM_NUM) of
set
[SYMCLASS_RW] :
begin
APPEND_TO_TEXTM (.BUFNUM, 'keyword ');
DOWN_CASE (PAT$DATA_SYMBOL_TEXT (.TERM_NUM), TEMP_TEXT);
APPEND_TO_TEXTM (.BUFNUM, '"');
APPEND_TO_TEXTM (.BUFNUM, TEMP_TEXT);
APPEND_TO_TEXTM (.BUFNUM, '"');
end;
[SYMCLASS_SPECIALCH] :
begin
APPEND_TO_TEXTM (.BUFNUM, '"');
APPEND_TO_TEXTM (.BUFNUM, PAT$DATA_SYMBOL_TEXT (.TERM_NUM));
APPEND_TO_TEXTM (.BUFNUM, '"');
end;
[SYMCLASS_PATH_NAME, SYMCLASS_CDD_NAME] :
begin
if PAT$LSLOCAL_SYMBOL_CLASS (.TERM_NUM) eqlu SYMCLASS_PATH_NAME
then APPEND_TO_TEXTM (.BUFNUM, 'path-name')
else APPEND_TO_TEXTM (.BUFNUM, 'variable-name');
if not LS_LEX_SYNTHETIC (TOKEN_PTR)
then
begin
APPEND_TO_TEXTM (.BUFNUM, ' ');
APPEND_TO_TEXTM (.BUFNUM, LS_LEX_TEXT (TOKEN_PTR));
end;
end;
[SYMCLASS_NUMBER] :
begin
if .TOKEN_PTR [TKN_TERM] eqlu T_HEX_NUMBER
then APPEND_TO_TEXTM (.BUFNUM, 'hex-number')
else if .TOKEN_PTR [TKN_TERM] eqlu T_OCTAL_NUMBER
then APPEND_TO_TEXTM (.BUFNUM, 'octal-number')
else APPEND_TO_TEXTM (.BUFNUM, 'number');
if not LS_LEX_SYNTHETIC (TOKEN_PTR)
then
begin
APPEND_TO_TEXTM (.BUFNUM, ' ');
APPEND_TO_TEXTM (.BUFNUM, LS_LEX_TEXT (TOKEN_PTR));
end;
end;
[SYMCLASS_STRING, SYMCLASS_DESCR_TEXT] :
begin
if .TOKEN_PTR [TKN_TERM] eqlu T_QUOTED_STRING
then APPEND_TO_TEXTM (.BUFNUM, 'string-literal')
else APPEND_TO_TEXTM (.BUFNUM, 'description');
if not LS_LEX_SYNTHETIC (TOKEN_PTR)
then
begin
APPEND_TO_TEXTM (.BUFNUM, ' ');
APPEND_TO_TEXTM (.BUFNUM, LS_LEX_TEXT (TOKEN_PTR));
end;
end;
[SYMCLASS_EOF] :
APPEND_TO_TEXTM (.BUFNUM, 'end-of-file');
[SYMCLASS_NONTERM] :
0;
tes;
return TEXT_SD [.BUFNUM, SD_BASE]
end;
%if PATBLSEXT_DEBUGGING
%then
global routine PAT$LSLOCAL_DUMP_TOK (TOKEN_PTR) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! PAT$LSLOCAL_DUMP_TOK outputs the lexical token pointed to by TOKEN_PTR.
! This routine is only called by the debugging routines and only via
! the LS_DUMP_TOK macro.
!
! FORMAL PARAMETERS:
!
! TOKEN_PTR - Pointer to the lexical token which is to be dumped.
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! NONE
!
! SIDE EFFECTS:
!
! NONE
!
!--
begin
map
TOKEN_PTR : ref LSLOCAL_TKN_STR;
macro
OUTPUT_TEXT =
PUT_STRING (LS_LEX_TEXT (TOKEN_PTR)) %;
macro
OUTPUT_CLEAN =
PUT_STRING (.TOKEN_PTR [TKN_CLEAN_TEXT]) %;
local
NUM;
NUM = LS_LEX_TERM (TOKEN_PTR);
PUT_MSG ('PAT$LSLOCAL_DUMP_TOK ');
if not LS_LEX_SYNTHETIC (TOKEN_PTR)
then
begin
selectone PAT$LSLOCAL_SYMBOL_CLASS (.NUM) of
set
[SYMCLASS_RW] :
begin
PUT_MSG ('Keyword: ');
PUT_STRING (PAT$DATA_SYMBOL_TEXT (.NUM));
end;
[SYMCLASS_SPECIALCH] :
begin
PUT_MSG ('Special character(s): "');
PUT_STRING (PAT$DATA_SYMBOL_TEXT (.NUM));
PUT_MSG ('"');
end;
[SYMCLASS_PATH_NAME] :
begin
PUT_MSG ('Path name: ');
OUTPUT_TEXT;
end;
[SYMCLASS_CDD_NAME] :
begin
PUT_MSG ('CDD name: ');
OUTPUT_TEXT;
end;
[SYMCLASS_DESCR_TEXT] :
begin
PUT_MSG ('Description: ');
OUTPUT_TEXT;
end;
[SYMCLASS_STRING] :
begin
PUT_MSG ('Character string: ');
OUTPUT_TEXT;
PUT_EOL ();
end;
[SYMCLASS_NUMBER] :
begin
if .num eqlu T_HEX_NUMBER
then PUT_MSG ('Hex number: ')
else if .num eqlu T_OCTAL_NUMBER
then PUT_MSG ('Octal number: ')
else PUT_MSG ('Number: ');
OUTPUT_TEXT;
PUT_EOL ();
if .num eqlu T_SIGNED_INTEGER or
.num eqlu T_UNSIGNED_INTEGER
then begin
PUT_MSG (' Base 10 value is ');
PUT_NUMBER (.TOKEN_PTR [TKN_INTVALUE]);
end;
end;
[SYMCLASS_EOF] :
begin
PUT_MSG_EOL ('End of file token');
return
end;
[OTHERWISE] :
begin
PUT_MSG ('Invalid token. TKN_TERM field = ');
PUT_NUMBER (.NUM);
end;
tes;
PUT_EOL ();
PUT_MSG ('Locator: Line number: ');
PUT_NUMBER (LS_LEX_LINE_NUMBER (LS_LEX_LOCATOR (TOKEN_PTR)));
PUT_MSG (' Column number: ');
PUT_NUMBER (LS_LEX_COLUMN_NUMBER (LS_LEX_LOCATOR (TOKEN_PTR)));
PUT_EOL ();
if LS_LEX_START_LINE (TOKEN_PTR)
then PUT_MSG ('First token on text line. ')
else PUT_MSG (' ');
PUT_MSG ('Comments pointer: ');
if .TOKEN_PTR [TKN_COMMENTS] eql NULL
then PUT_MSG ('NULL')
else PUT_HEX_LONG (.TOKEN_PTR [TKN_COMMENTS]);
PUT_EOL ();
end
else ! Synthetic token (inserted by error recovery)
begin
PUT_MSG ('Synthetic ');
selectone PAT$LSLOCAL_SYMBOL_CLASS (.NUM) of
set
[SYMCLASS_RW] :
begin
PUT_MSG ('keyword: ');
PUT_STRING (PAT$DATA_SYMBOL_TEXT (.NUM));
end;
[SYMCLASS_SPECIALCH] :
begin
PUT_MSG ('special character(s): "');
PUT_STRING (PAT$DATA_SYMBOL_TEXT (.NUM));
PUT_MSG ('"');
end;
[SYMCLASS_PATH_NAME] :
PUT_MSG ('path name');
[SYMCLASS_CDD_NAME] :
PUT_MSG ('CDD name');
[SYMCLASS_DESCR_TEXT] :
PUT_MSG ('description');
[SYMCLASS_STRING] :
PUT_MSG ('character string');
[SYMCLASS_NUMBER] :
if .num eqlu T_HEX_NUMBER
then PUT_MSG ('hex number')
else if .num eqlu T_OCTAL_NUMBER
then PUT_MSG ('octal number')
else PUT_MSG ('number');
[SYMCLASS_EOF] :
PUT_MSG_EOL ('end of file token');
[OTHERWISE] :
begin
PUT_MSG ('token. The token type is invalid. TKN_TERM field = ');
PUT_NUMBER (.NUM);
end;
tes;
PUT_EOL ();
end;
end;
%fi
global routine PAT$LSLOCAL_LOC_TEXT (SLOC) =
!++
! FUNCTIONAL DESCRIPTION:
!
! This routine converts source locator information to a text
! string of the form:
!
! on line 10
!
! The text does not have leading or trailing spaces.
!
! Static storage is used for the text string. Thus, a call
! to LS_LOC_TEXTM destroys the text string from the previous call
! to LS_LOC_TEXTM.
! Note, however, that LS_LOC_TEXTM can be used multiple times in
! a single call to LSLOCAL_SYNTAX_ERROR_TEXTM since each string is
! moved to a buffer.
!
! FORMAL PARAMETERS:
!
! SLOC - Encoded source locator.
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! Address of a string descriptor for the text.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
%BLISS32 ( ! 002
library 'SYS$LIBRARY:STARLET'; ! for FAOL
) ! 002
literal
MAX_LOC_LENGTH = 60;
own
LOC_TEXT : vector [ch$allocation (MAX_LOC_LENGTH)], ! 002
LOC:$STR_DESCRIPTOR(string=(MAX_LOC_LENGTH, ch$ptr(LOC_TEXT))), ! 002
CTL: $STR_DESCRIPTOR (string = 'on line !ZL'); ! 002
local
ACTUAL,
LINE;
ACTUAL = 0;
LOC [STR$H_LENGTH] = MAX_LOC_LENGTH; ! 002
LINE = LS_LEX_LINE_NUMBER (.SLOC);
$FAOL (CTRSTR = CTL, OUTLEN = ACTUAL, OUTBUF = LOC, PRMLST = LINE);
LOC [STR$H_LENGTH] = .ACTUAL; ! 002
return LOC
end; ! End of PAT$LSLOCAL_LOC_TEXT
! Section 2
! Macros to interpret terminal and non-terminal symbols.
global routine PAT$LSLOCAL_SYMBOL_CLASS (SYMBOL) =
!++
! FUNCTIONAL DESCRIPTION:
!
! PAT$LSLOCAL_SYMBOL_CLASS returns the class of a symbol (reserved word,
! non-terminal, special character, etc.).
!
! Note that a bitvector implementation would provide a faster and
! more compact implementation.
!
! FORMAL PARAMETERS:
!
! SYMBOL - Terminal or non terminal symbol type
!
! IMPLICIT INPUTS:
!
! NONE
!
! IMPLICIT OUTPUTS:
!
! NONE
!
! ROUTINE VALUE:
!
! Symbol class (e.g. SYMCLASS_RW, SYMCLASS_SPECIALCH, etc.)
!
! SIDE EFFECTS:
!
! NONE
!
!--
begin
selectone .SYMBOL of
set
[T_ALIGNED to T_ZONED] :
return SYMCLASS_RW;
[T_STAR, T_DOT, T_COLON, T_SEMICOLON] :
return SYMCLASS_SPECIALCH;
[T_PATH_NAME] :
return SYMCLASS_PATH_NAME;
[T_CDD_NAME] :
return SYMCLASS_CDD_NAME;
[T_DESCR_TEXT] :
return SYMCLASS_DESCR_TEXT;
[T_UNSIGNED_INTEGER, T_SIGNED_INTEGER, T_FIXED_POINT, T_FLOATING_POINT,
T_HEX_NUMBER, T_OCTAL_NUMBER] :
return SYMCLASS_NUMBER;
[T_QUOTED_STRING] :
return SYMCLASS_STRING;
[T_EOF] :
return SYMCLASS_EOF;
[otherwise] :
return SYMCLASS_NONTERM;
tes;
end;
global routine PAT$LSLOCAL_IS_NON_TERM (SYMBOL_NUM) =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! Determine if symbol is a nonterminal.
! Called only by macro LS_IS_NON_TERM.
!
! FORMAL PARAMETERS:
!
! SYMBOL_NUM symbol number.
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! TRUE if SYMBOL_NUM is a nonterminal, FALSE otherwise.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
PAT$LSLOCAL_SYMBOL_CLASS (.SYMBOL_NUM) eql SYMCLASS_NONTERM
end;
global routine PAT$LSLOCAL_IS_RESERVED_WORD (SYMBOL_NUM) =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! Determine if symbol is a reserved word.
! Called only by macro LSLOCAL_IS_RESERVED_WORD.
!
! FORMAL PARAMETERS:
!
! SYMBOL_NUM symbol number.
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! TRUE if SYMBOL_NUM is a reserved word, FALSE otherwise.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
PAT$LSLOCAL_SYMBOL_CLASS (.SYMBOL_NUM) eql SYMCLASS_RW
end;
global routine PAT$LSLOCAL_OUTPUT_TERM (TERM_NUM, FULL, BUFNUM) =
!++
! FUNCTIONAL DESCRIPTION:
!
! PAT$LSLOCAL_OUTPUT_TERM stores text describing a terminal symbol in
! a string descriptor and returns that string descriptor.
!
! FORMAL PARAMETERS:
!
! TERM_NUM - Terminal or non-terminal number
!
! FULL - If TRUE return the terminal symbol
! and whatever additional
! descriptive information is desired
! If FALSE, return text for terminal only.
! For example, assume that TERM_NUM was
! the number of the reserved word LOOP.
! If TRUE, this routine might return the
! text string
!
! reserved word "loop"
!
! If FALSE, it would just return
!
! "loop"
!
! BUFNUM - Number of text buffer to be used
!
! IMPLICIT INPUTS:
!
! Text buffer indexed by BUFNUM.
!
! IMPLICIT OUTPUTS:
!
! Text buffer indexed by BUFNUM.
!
! ROUTINE VALUE:
!
! TEXT_PTR - Pointer to string descriptor containing description
! of token
!
! SIDE EFFECTS:
!
! NONE
!
!--
begin
CLEAR_TEXTM (.BUFNUM);
selectone PAT$LSLOCAL_SYMBOL_CLASS (.TERM_NUM) of
set
[SYMCLASS_RW] :
begin
if .FULL then APPEND_TO_TEXTM (.BUFNUM, 'keyword ');
DOWN_CASE (PAT$DATA_SYMBOL_TEXT (.TERM_NUM), TEMP_TEXT);
APPEND_TO_TEXTM (.BUFNUM, '"');
APPEND_TO_TEXTM (.BUFNUM, TEMP_TEXT);
APPEND_TO_TEXTM (.BUFNUM, '"');
end;
[SYMCLASS_SPECIALCH] :
begin
APPEND_TO_TEXTM (.BUFNUM, '"');
APPEND_TO_TEXTM (.BUFNUM, PAT$DATA_SYMBOL_TEXT (.TERM_NUM));
APPEND_TO_TEXTM (.BUFNUM, '"');
end;
[SYMCLASS_PATH_NAME, SYMCLASS_CDD_NAME] :
begin
if PAT$LSLOCAL_SYMBOL_CLASS (.TERM_NUM) EQLU T_PATH_NAME then
APPEND_TO_TEXTM (.BUFNUM, 'path-name')
else
APPEND_TO_TEXTM (.BUFNUM, 'variable-name');
APPEND_TO_TEXTM (.BUFNUM, ' ');
APPEND_TO_TEXTM (.BUFNUM, PAT$DATA_SYMBOL_TEXT (.TERM_NUM));
end;
[SYMCLASS_NUMBER] :
begin
if .TERM_NUM eqlu T_HEX_NUMBER then
APPEND_TO_TEXTM (.BUFNUM, 'hex-number')
else
if .TERM_NUM eqlu T_OCTAL_NUMBER then
APPEND_TO_TEXTM (.BUFNUM, 'octal-number')
else
APPEND_TO_TEXTM (.BUFNUM, 'number');
APPEND_TO_TEXTM (.BUFNUM, ' ');
APPEND_TO_TEXTM (.BUFNUM, PAT$DATA_SYMBOL_TEXT (.TERM_NUM));
end;
[SYMCLASS_STRING, SYMCLASS_DESCR_TEXT] :
begin
if .TERM_NUM eqlu T_QUOTED_STRING then
APPEND_TO_TEXTM (.BUFNUM, 'string-literal')
else
APPEND_TO_TEXTM (.BUFNUM, 'description');
APPEND_TO_TEXTM (.BUFNUM, ' "');
APPEND_TO_TEXTM (.BUFNUM, PAT$DATA_SYMBOL_TEXT (.TERM_NUM));
APPEND_TO_TEXTM (.BUFNUM, '"');
end;
[SYMCLASS_EOF] :
APPEND_TO_TEXTM (.BUFNUM, 'end-of-file');
[SYMCLASS_NONTERM] :
0;
tes;
return TEXT_SD [.BUFNUM, SD_BASE] ! 002
end;
! Section 5
! Error message interface (global recovery)
! Declarations for tables for global error recovery messages:
! Collection-type enumeration:
! This is a list of the collections whose names can substitute
! for a list of individual terminal symbols in the list
! of possible symbols printed by PAT$LSLOCAL_GLOBAL_ERROR_MSG.
!
! The contents of this list are **LANGUAGE SPECIFIC**
ENUMERATION ('COLLECTION_TYPE', 0,
GR_COL_NUMBER, ! Some kind of a number
GR_COL_CDD_NAME, ! Some kind of a CDD name
GR_COL_FIELD_ATT); ! Some field attribute
! Number of literals in COLLECTION_TYPE
literal
GR_NUM_COLLECTIONS = LAST_COLLECTION_TYPE - FIRST_COLLECTION_TYPE + 1;
! Non-Terminals-for-Terminal-Groupings Enumeration:
! This is a list of the non-terminals symbols whose names can substitute
! for a list of individual terminal symbols in the list
! of possible symbols printed by PAT$LSLOCAL_GLOBAL_ERROR_MSG.
! Note that LS_NUM_GROUP_NONTERMS in PATLANGSP.REQ should indicate
! number of groupings.
! The contents of this list are **LANGUAGE SPECIFIC**
ENUMERATION ('GROUPING_NONTERM', 0);
! None for this grammar.
!,
! GR_GNT_DECL, ! Declarations
! GR_GNT_STM, ! Statements
! GR_GNT_EXP); ! Expressions
! Data Structures Used by Later Lists:
! This structure definition is used for GR_COLLECTION_LISTS and
! GR_GROUP_NONTERM_LISTS.
!
! For explanation of this data structure, see LR_BITMATRIX in PATLRTUNE.REQ.
structure
ALIGNED_BITMATRIX [ROWNUM, BITNUM; ROWS, BITS] =
[ROWS*((BITS + (%bpunit - 1))/%bpunit)]
(ALIGNED_BITMATRIX + (ROWNUM*((BITS + (%bpunit - 1))/%bpunit))
+ ((bitnum + %bpunit)/ %bpunit) - 1)
<((BITNUM + %bpunit) mod %bpunit), 1>;
! Collection Lists:
! This table is used in PAT$LSLOCAL_GLOBAL_ERROR_MSG when printing
! an error message for global recovery.
! Its indices are literals declared in the enumeration COLLECTION_TYPE
! and literals for terminals declared by PATTABLE.
! For each collection it has a bit set for each terminal included
! in the collection.
! For example, for Ada the collection NUMBER includes the terminals NUMBER
! and REAL.
! The contents of this table are **LANGUAGE SPECIFIC**
own
GR_COLLECTION_LISTS : ALIGNED_BITMATRIX [GR_NUM_COLLECTIONS, PAT$DATA_NUM_TERM]
preset (
! Numbers:
[GR_COL_NUMBER, T_UNSIGNED_INTEGER] = TRUE,
[GR_COL_NUMBER, T_SIGNED_INTEGER] = TRUE,
[GR_COL_NUMBER, T_FIXED_POINT] = TRUE,
[GR_COL_NUMBER, T_FLOATING_POINT] = TRUE,
[GR_COL_NUMBER, T_HEX_NUMBER] = TRUE,
[GR_COL_NUMBER, T_OCTAL_NUMBER] = TRUE,
! CDD names:
[GR_COL_CDD_NAME, T_ALIGNED] = TRUE,
[GR_COL_CDD_NAME, T_ARE] = TRUE,
[GR_COL_CDD_NAME, T_ARRAY] = TRUE,
[GR_COL_CDD_NAME, T_AS] = TRUE,
[GR_COL_CDD_NAME, T_ASCII_7] = TRUE,
[GR_COL_CDD_NAME, T_ASCII_8] = TRUE,
[GR_COL_CDD_NAME, T_ASCII_9] = TRUE,
[GR_COL_CDD_NAME, T_BASE] = TRUE,
[GR_COL_CDD_NAME, T_BASIC] = TRUE,
[GR_COL_CDD_NAME, T_BIT] = TRUE,
[GR_COL_CDD_NAME, T_BLANK] = TRUE,
[GR_COL_CDD_NAME, T_BOUNDARY] = TRUE,
[GR_COL_CDD_NAME, T_BY] = TRUE,
[GR_COL_CDD_NAME, T_BYTE] = TRUE,
[GR_COL_CDD_NAME, T_BYTES] = TRUE,
[GR_COL_CDD_NAME, T_CDD_NAME] = TRUE,
[GR_COL_CDD_NAME, T_CHARACTER] = TRUE,
[GR_COL_CDD_NAME, T_CHARACTERS] = TRUE,
[GR_COL_CDD_NAME, T_COBOL] = TRUE,
[GR_COL_CDD_NAME, T_COLUMN_MAJOR] = TRUE,
[GR_COL_CDD_NAME, T_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_COMPUTED] = TRUE,
[GR_COL_CDD_NAME, T_CONDITION] = TRUE,
[GR_COL_CDD_NAME, T_COPY] = TRUE,
[GR_COL_CDD_NAME, T_DATATRIEVE] = TRUE,
[GR_COL_CDD_NAME, T_DATATYPE] = TRUE,
[GR_COL_CDD_NAME, T_DATE] = TRUE,
[GR_COL_CDD_NAME, T_DECIMAL] = TRUE,
[GR_COL_CDD_NAME, T_DEFAULT_VALUE] = TRUE,
[GR_COL_CDD_NAME, T_DEFINE] = TRUE,
[GR_COL_CDD_NAME, T_DEPENDING] = TRUE,
[GR_COL_CDD_NAME, T_DESCRIPTION] = TRUE,
[GR_COL_CDD_NAME, T_DIGIT] = TRUE,
[GR_COL_CDD_NAME, T_DIGITS] = TRUE,
[GR_COL_CDD_NAME, T_DTR] = TRUE,
[GR_COL_CDD_NAME, T_D_FLOATING] = TRUE,
[GR_COL_CDD_NAME, T_D_FLOATING_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_EBCDIC_8] = TRUE,
[GR_COL_CDD_NAME, T_EBCDIC_9] = TRUE,
[GR_COL_CDD_NAME, T_EDIT_STRING] = TRUE,
[GR_COL_CDD_NAME, T_FIELD] = TRUE,
[GR_COL_CDD_NAME, T_FLOATING] = TRUE,
[GR_COL_CDD_NAME, T_FLOATING_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_FOR] = TRUE,
[GR_COL_CDD_NAME, T_FRACTION] = TRUE,
[GR_COL_CDD_NAME, T_FRACTIONS] = TRUE,
[GR_COL_CDD_NAME, T_F_FLOATING] = TRUE,
[GR_COL_CDD_NAME, T_F_FLOATING_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_G_FLOATING] = TRUE,
[GR_COL_CDD_NAME, T_G_FLOATING_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_H_FLOATING] = TRUE,
[GR_COL_CDD_NAME, T_H_FLOATING_COMPLEX] = TRUE,
[GR_COL_CDD_NAME, T_IF] = TRUE,
[GR_COL_CDD_NAME, T_INDEXED] = TRUE,
[GR_COL_CDD_NAME, T_INITIAL_VALUE] = TRUE,
[GR_COL_CDD_NAME, T_JUSTIFIED] = TRUE,
[GR_COL_CDD_NAME, T_LEFT] = TRUE,
[GR_COL_CDD_NAME, T_LONGWORD] = TRUE,
[GR_COL_CDD_NAME, T_MISSING_VALUE] = TRUE,
[GR_COL_CDD_NAME, T_NAME] = TRUE,
[GR_COL_CDD_NAME, T_NUMERIC] = TRUE,
[GR_COL_CDD_NAME, T_OCCURS] = TRUE,
[GR_COL_CDD_NAME, T_OCTAWORD] = TRUE,
[GR_COL_CDD_NAME, T_OF] = TRUE,
[GR_COL_CDD_NAME, T_OVERPUNCHED] = TRUE,
[GR_COL_CDD_NAME, T_PACKED] = TRUE,
[GR_COL_CDD_NAME, T_PICTURE] = TRUE,
[GR_COL_CDD_NAME, T_PLI] = TRUE,
[GR_COL_CDD_NAME, T_POINTER] = TRUE,
[GR_COL_CDD_NAME, T_QUADWORD] = TRUE,
[GR_COL_CDD_NAME, T_QUERY_HEADER] = TRUE,
[GR_COL_CDD_NAME, T_QUERY_NAME] = TRUE,
[GR_COL_CDD_NAME, T_RIGHT] = TRUE,
[GR_COL_CDD_NAME, T_ROW_MAJOR] = TRUE,
[GR_COL_CDD_NAME, T_SCALE] = TRUE,
[GR_COL_CDD_NAME, T_SEPARATE] = TRUE,
[GR_COL_CDD_NAME, T_SIGNED] = TRUE,
[GR_COL_CDD_NAME, T_SIXBIT] = TRUE,
[GR_COL_CDD_NAME, T_STRING] = TRUE,
[GR_COL_CDD_NAME, T_STRUCTURE] = TRUE,
[GR_COL_CDD_NAME, T_SYNC] = TRUE,
[GR_COL_CDD_NAME, T_SYNCHRONIZED] = TRUE,
[GR_COL_CDD_NAME, T_TEXT] = TRUE,
[GR_COL_CDD_NAME, T_THRU] = TRUE,
[GR_COL_CDD_NAME, T_TIME] = TRUE,
[GR_COL_CDD_NAME, T_TIMES] = TRUE,
[GR_COL_CDD_NAME, T_TO] = TRUE,
[GR_COL_CDD_NAME, T_TYPE] = TRUE,
[GR_COL_CDD_NAME, T_UNSIGNED] = TRUE,
[GR_COL_CDD_NAME, T_UNSPECIFIED] = TRUE,
[GR_COL_CDD_NAME, T_VALID] = TRUE,
[GR_COL_CDD_NAME, T_VALUE] = TRUE,
[GR_COL_CDD_NAME, T_VALUES] = TRUE,
[GR_COL_CDD_NAME, T_VARIANT] = TRUE,
[GR_COL_CDD_NAME, T_VARYING] = TRUE,
[GR_COL_CDD_NAME, T_VIRTUAL] = TRUE,
[GR_COL_CDD_NAME, T_WHEN] = TRUE,
[GR_COL_CDD_NAME, T_WORD] = TRUE,
[GR_COL_CDD_NAME, T_ZERO] = TRUE,
[GR_COL_CDD_NAME, T_ZONED] = TRUE,
! Field attributes:
[GR_COL_FIELD_ATT, T_ALIGNED] = TRUE,
[GR_COL_FIELD_ATT, T_ARRAY] = TRUE,
[GR_COL_FIELD_ATT, T_BLANK] = TRUE,
[GR_COL_FIELD_ATT, T_COLUMN_MAJOR] = TRUE,
[GR_COL_FIELD_ATT, T_COMPUTED] = TRUE,
[GR_COL_FIELD_ATT, T_CONDITION] = TRUE,
[GR_COL_FIELD_ATT, T_DATATYPE] = TRUE,
[GR_COL_FIELD_ATT, T_DEFAULT_VALUE] = TRUE,
[GR_COL_FIELD_ATT, T_EDIT_STRING] = TRUE,
[GR_COL_FIELD_ATT, T_INITIAL_VALUE] = TRUE,
[GR_COL_FIELD_ATT, T_JUSTIFIED] = TRUE,
[GR_COL_FIELD_ATT, T_MISSING_VALUE] = TRUE,
[GR_COL_FIELD_ATT, T_NAME] = TRUE,
[GR_COL_FIELD_ATT, T_OCCURS] = TRUE,
[GR_COL_FIELD_ATT, T_PICTURE] = TRUE,
[GR_COL_FIELD_ATT, T_QUERY_HEADER] = TRUE,
[GR_COL_FIELD_ATT, T_QUERY_NAME] = TRUE,
[GR_COL_FIELD_ATT, T_ROW_MAJOR] = TRUE,
[GR_COL_FIELD_ATT, T_SYNC] = TRUE,
[GR_COL_FIELD_ATT, T_SYNCHRONIZED] = TRUE,
[GR_COL_FIELD_ATT, T_TYPE] = TRUE,
[GR_COL_FIELD_ATT, T_VALID] = TRUE);
! Terminals-Into-Non-Terminal-Groups List:
! This table is used in PAT$LSLOCAL_GLOBAL_ERROR_MSG when printing
! an error message for global recovery.
! Its indices are literals declared in the enumeration GROUPING_NONTERM
! and literals for terminals declared by PATTABLE.
! For each non-terminal it has a bit set for each terminal included
! in the non-terminal.
! For example, for Ada the collection STATEMENT includes all the terminal
! symbols that can appear at the start of a statement.
! The contents of this list are **LANGUAGE_SPECIFIC.**
! None for this grammar.
own
GR_GROUP_NONTERM_LISTS : ALIGNED_BITMATRIX [LS_NUM_GROUP_NONTERMS, PAT$DATA_NUM_TERM];
!preset (
! Declarations:
! [GR_GNT_DECL, T_ENTRY] = TRUE,
! [GR_GNT_DECL, T_FOR] = TRUE,
! [GR_GNT_DECL, T_FUNCTION] = TRUE,
! [GR_GNT_DECL, T_GENERIC] = TRUE,
! [GR_GNT_DECL, T_PACKAGE] = TRUE,
! [GR_GNT_DECL, T_PRAGMA] = TRUE,
! [GR_GNT_DECL, T_PROCEDURE] = TRUE,
! [GR_GNT_DECL, T_SUBTYPE] = TRUE,
! [GR_GNT_DECL, T_TASK] = TRUE,
! [GR_GNT_DECL, T_TYPE] = TRUE,
! [GR_GNT_DECL, T_USE] = TRUE,
! [GR_GNT_DECL, T_IDENTIFIER] = TRUE,
! Statements:
! [GR_GNT_STM, T_ABORT] = TRUE,
! [GR_GNT_STM, T_ACCEPT] = TRUE,
! [GR_GNT_STM, T_BEGIN] = TRUE,
! [GR_GNT_STM, T_CASE] = TRUE,
! [GR_GNT_STM, T_DECLARE] = TRUE,
! [GR_GNT_STM, T_DELAY] = TRUE,
! [GR_GNT_STM, T_EXIT] = TRUE,
! [GR_GNT_STM, T_FOR] = TRUE,
! [GR_GNT_STM, T_GOTO] = TRUE,
! [GR_GNT_STM, T_IF] = TRUE,
! [GR_GNT_STM, T_LOOP] = TRUE,
! [GR_GNT_STM, T_NULL] = TRUE,
! [GR_GNT_STM, T_PRAGMA] = TRUE,
! [GR_GNT_STM, T_RAISE] = TRUE,
! [GR_GNT_STM, T_RETURN] = TRUE,
! [GR_GNT_STM, T_SELECT] = TRUE,
! [GR_GNT_STM, T_WHILE] = TRUE,
! [GR_GNT_STM, T_LESS_LESS] = TRUE,
! [GR_GNT_STM, T_IDENTIFIER] = TRUE,
! [GR_GNT_STM, T_CHARACTER_STR] = TRUE,
! Expressions:
! [GR_GNT_EXP, T_NEW] = TRUE,
! [GR_GNT_EXP, T_NOT] = TRUE,
! [GR_GNT_EXP, T_NULL] = TRUE,
! [GR_GNT_EXP, T_L_PAREN] = TRUE,
! [GR_GNT_EXP, T_PLUS] = TRUE,
! [GR_GNT_EXP, T_MINUS] = TRUE,
! [GR_GNT_EXP, T_IDENTIFIER] = TRUE,
! [GR_GNT_EXP, T_NUMBER] = TRUE,
! [GR_GNT_EXP, T_CHARACTER_STR] = TRUE,
! [GR_GNT_EXP, T_CHARACTER_LIT] = TRUE,
! [GR_GNT_EXP, T_REAL] = TRUE);
! Collection texts:
! This table is used in PAT$LSLOCAL_GLOBAL_ERROR_MSG when printing
! an error message for global recovery.
! Its indices are literals declared in the enumeration COLLECTION_TYPE.
! For each collection it has a pointer to a string descriptor containing the
! text to be printed instead of the names of the terminals in the collection.
! For example, for Ada the text for the collection ARITHOP is
! "arithmetic-operator".
! The contents of this table are **LANGUAGE SPECIFIC**
own
gr_col_txt_number : $str_descriptor (string = 'number'),
gr_col_txt_CDD_name : $str_descriptor (string = 'variable-name'),
gr_col_txt_field_att : $str_descriptor (string = 'field-attribute');
own
GR_COLLECTION_TEXT : vector [GR_NUM_COLLECTIONS]
preset (
[GR_COL_NUMBER] = gr_col_txt_number,
[GR_COL_CDD_NAME] = gr_col_txt_CDD_name,
[GR_COL_FIELD_ATT] = gr_col_txt_field_att );
! Terminals-Into-Non-Terminal Groups Text Table:
! This table is used in PAT$LSLOCAL_GLOBAL_ERROR_MSG when printing
! an error message for global recovery.
! Its indices are literals declared in the enumeration GROUPING_NONTERM.
! For each non-terminal symbol it has a pointer to a string descriptor
! containing the text to be printed instead of the names of the terminals
! in the non-terminal symbol. For example, for Ada the text for
! the non-terminal symbol DECL is "declaration".
! The contents of this table are **LANGUAGE SPECIFIC**.
! None for this grammar.
!own
! gr_gnt_txt_decl : $str_descriptor (string = 'declaration'),
! gr_gnt_txt_stm : $str_descriptor (string = 'statement'),
! gr_gnt_txt_exp : $str_descriptor (string = 'expression');
own
GR_GROUP_NONTERM_TEXT : vector [LS_NUM_GROUP_NONTERMS];
!preset (
! [GR_GNT_DECL] = gr_gnt_txt_decl,
! [GR_GNT_STM] = gr_gnt_txt_stm,
! [GR_GNT_EXP] = gr_gnt_txt_exp );
! Group Non-Terminal Names:
! This table is used in PAT$LSLOCAL_GLOBAL_ERROR_MSG when printing
! an error message for global recovery.
! The GR_NONTERM_SYMBOL field of each pair is a non-terminal
! symbol which could be formed by a production containing an
! errormark so it might be formed during global error recovery.
! The corresponding GR_NONTERM_TEXT field contains a pointer to
! a string descriptor containing text which describes that
! non-terminal symbol.
! The literals are used in defining and referencing the table.
! A (less extensive) error message can be printed even if this
! table is empty.
! The contents of this table are **LANGUAGE SPECIFIC**.
! None for this grammar.
literal
GR_NUM_NONTERM_NAMES = 0, ! **LANGUAGE SPECIFIC**
GR_NONTERM_SYMBOL = 0,
GR_NONTERM_TEXT = 1;
structure
LS_MATRIX [ROWNUM, COLNUM; ROWS, COLS] =
[(ROWS*COLS)*%upval]
(LS_MATRIX + ((ROWNUM*COLS) + COLNUM)*%upval);
! own
! gr_ntm_nam_decl : $str_descriptor (string = 'declaration'),
! gr_ntm_nam_stm : $str_descriptor (string = 'statement');
own
GR_NONTERM_NAMES : LS_MATRIX [GR_NUM_NONTERM_NAMES, 2];
!preset (
! [0, GR_NONTERM_SYMBOL] = NT_DECL,
! [0, GR_NONTERM_TEXT] = gr_ntm_nam_decl,
! [1, GR_NONTERM_SYMBOL] = NT_UNLABELLED_STM,
! [1, GR_NONTERM_TEXT] = gr_ntm_nam_stm );
global routine PAT$LSLOCAL_EXPECTED_SYMBOL (SYM, REF_GROUP_NONTERMS_SEEN, REF_TERMS_TO_PRINT) : novalue =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! See LS_EXPECTED_SYMBOL macro in PATLANGSP.REQ.
! LS_EXPECTED_SYMBOL adds the symbol SYM to the set of symbols expected
! in a global recovery error message by setting fields in
! GR_GROUP_NONTERMS_SEEN and GR_TERMS_TO_PRINT appropriately.
!
! FORMAL PARAMETERS:
!
! SYM Terminal or non-terminal symbol
! REF_GROUP_NONTERMS_SEEN Pointer to table of important grouping
! non-terminals, indicating which have been seen
! REF_TERMS_TO_PRINT Pointer to table of terminals,
! indicating which were expected
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
bind
GR_GROUP_NONTERMS_SEEN = .REF_GROUP_NONTERMS_SEEN : bitvector [],
GR_TERMS_TO_PRINT = .REF_TERMS_TO_PRINT : bitvector [];
if PAT$LSLOCAL_SYMBOL_CLASS (.SYM) eql SYMCLASS_NONTERM
then ! Non-terminal
! **LANGUAGE-SPECIFIC** case for each group non-terminal:
! (None for this grammar.)
selectone .SYM of
set
! [NT_DECL] : ! Declaration
! GR_GROUP_NONTERMS_SEEN [GR_GNT_DECL] = TRUE;
!
! [NT_STM] : ! Statement
! GR_GROUP_NONTERMS_SEEN [GR_GNT_STM] = TRUE;
!
! [NT_SIMPLE_EXP] : ! Expression
! GR_GROUP_NONTERMS_SEEN [GR_GNT_EXP] = TRUE;
[otherwise] :
; ! Other non-terminal--do nothing
tes
else ! Ordinary terminal symbol
GR_TERMS_TO_PRINT [.SYM] = TRUE;
end;
global routine PAT$LSLOCAL_GLOBAL_ERROR_MSG (BAD_NON_TERM, ERROR_TOKEN_PTR, REF_GROUP_NONTERMS_SEEN,
REF_TERMS_TO_PRINT, BYTES_FOR_TERMS) : novalue =
!++
! FUNCTIONAL DESCRIPTION:
!
! See LS_GLOBAL_ERROR_MSG macro in PATLANGSP.REQ.
! LS_GLOBAL_ERROR_MSG outputs an error message for global error
! recovery.
!
! The global error recovery that has been done will evenutally
! result in the recognition of some production containing an
! errormark:
!
! LHS_NON_TERMINAL_NAME = ... errormark ... ;
!
! where ... indicates a sequence of terminal/nonterminal symbols.
! The symbol number of the non-terminal on the left hand side
! (LHS_NON_TERMINAL_NAME above) will be passed as parameter
! BAD_NON_TERM if it can be determined easily. (It can be determined
! easily if the "..." on the right of the errormark consists of a
! single terminal symbol.) Otherwise LS_UNAVAILABLE_NT will be passed.
!
! This information permits errors of the form:
!
! Invalid statement--Found ... when expecting ...
!
! instead of
!
! Found ... when expecting ...
!
! FORMAL PARAMETERS:
!
! BAD_NON_TERM Number of non-terminal symbol
! ERROR_TOKEN_PTR Pointer to token at which error
! was encountered
! REF_GROUP_NONTERMS_SEEN Pointer to bit-vector indicating which
! important group non-terminals
! were expected (can be modified)
! REF_TERMS_TO_PRINT Pointer to bit-vector indicating which
! terminal symbols were expected
! (can be modified)
! BYTES_FOR_TERMS Number of bytes used by TERMS-TO-PRINT
!
! IMPLICIT INPUTS:
!
! None
!
! IMPLICIT OUTPUTS:
!
! None
!
! ROUTINE VALUE:
!
! None.
!
! SIDE EFFECTS:
!
! The error message is printed.
!
!--
begin
map
ERROR_TOKEN_PTR : ref LSLOCAL_TKN_STR;
bind
GROUP_NONTERMS_SEEN = .REF_GROUP_NONTERMS_SEEN : bitvector [],
TERMS_TO_PRINT = .REF_TERMS_TO_PRINT : bitvector [];
local
ERROR_LOC,
NUM_GROUP_NONTERMS_TO_PRINT,
NUM_COLLECTIONS_TO_PRINT,
NUM_TERMS_TO_PRINT,
NUM_ITEMS_TO_PRINT,
COLLECTIONS_SEEN : bitvector [GR_NUM_COLLECTIONS + 1], ! + 1 so size isn't 0
UNACCEPTED_TERMS_IN_COLLECTION : bitvector [PAT$DATA_NUM_TERM],
TERMS_SEEN_IN_COLLECTION : bitvector [PAT$DATA_NUM_TERM];
literal
BUF0 = 0,
BUF1 = 1,
BUF2 = 2;
! Macros
! Given two bitvectors, DST (destination) and SRC (source),
! each of which occupies NUM_BYTES storage, this macro performs the
! vector operation:
!
! DST = DST and not SRC
macro
BLOCK_DST_AND_NOT_SRC (SRC, DST, NUM_BYTES) =
begin
bind
SBV = SRC : bitvector [], ! 002
DBV = DST : bitvector []; ! 002
incr OFFSET from 0 to (NUM_BYTES - 1) do
DBV [.OFFSET] = .DBV [.OFFSET] and (not .SBV [.OFFSET]);
end
%;
! Given three bit vectors SRC1, SCR2, and DST, each of which
! occupies NUM_BYTES storage, this macro performs the
! vector operation:
!
! DST = SRC1 and SRC2
macro
BLOCK_SRC1_AND_SRC2_TO_DST (SRC1, SRC2, DST, NUM_BYTES) =
begin
bind
SBV1 = SRC1 : bitvector [], ! 002
SBV2 = SRC2 : bitvector [], ! 002
DBV = DST : bitvector []; ! 002
incr OFFSET from 0 to (NUM_BYTES - 1) do
DBV [.OFFSET] = .SBV1 [.OFFSET] and .SBV2 [.OFFSET];
end
%;
! Given three bit vectors SRC1, SCR2, and DST, each of which
! occupies NUM_BYTES storage, this macro performs the
! vector operation:
!
! DST = SRC1 and not SRC2
macro
BLOCK_SRC1_AND_NOT_SRC2_TO_DST (SRC1, SRC2, DST, NUM_BYTES) =
begin
bind
SBV1 = SRC1 : bitvector [], ! 002
SBV2 = SRC2 : bitvector [], ! 002
DBV = DST : bitvector []; ! 002
incr OFFSET from 0 to (NUM_BYTES - 1) do
DBV [.OFFSET] = .SBV1 [.OFFSET] and (not .SBV2 [.OFFSET]);
end
%;
! This macro counts the number of bits set turned on in a
! bitvector at address START of length NUM_BITS.
macro
COUNT (START, NUM_BITS) =
begin
local
TOT;
TOT = 0;
incr LOOP_INDEX from 0 to (NUM_BITS - 1) do
if .START [.LOOP_INDEX] then TOT = .TOT + 1;
.TOT
end
%;
! Start of code for PAT$LSLOCAL_GLOBAL_ERROR_MSG
! Determine what's expected.
! If group non-terminals are expected, say a statement,
! suppress output for all terminals that can begin a
! statement (for example, "for", "loop") by turning off the bits
! in TERMS_TO_PRINT bitvector. (Note that TERMS_TO_PRINT
! in indexed by the terminal symbol number.
incr GROUP_NONTERM_INDEX from FIRST_GROUPING_NONTERM to LAST_GROUPING_NONTERM do
if (.GROUP_NONTERMS_SEEN [.GROUP_NONTERM_INDEX])
then
BLOCK_DST_AND_NOT_SRC ( !
GR_GROUP_NONTERM_LISTS [.GROUP_NONTERM_INDEX, PAT$DATA_FIRST_TERM],
TERMS_TO_PRINT, .BYTES_FOR_TERMS);
! If some of the terminals that are expected form a
! collection (for example "+", "-", "*", ... in collection
! "arithmetic-operator"), suppress output for these terminals
! ("+", etc.) by turning off the associated bits in TERMS_TO_PRINT
! bitvector. Set bit in COLLECTIONS_SEEN bitvector to
! indicate that "arithmetic-operator" is to be output.
! ZEROBYTE (%allocation (COLLECTIONS_SEEN), COLLECTIONS_SEEN);
incr counter from 0 to GR_NUM_COLLECTIONS
do collections_seen [.counter] = 0;
incr COLLECTION_INDEX from FIRST_COLLECTION_TYPE to LAST_COLLECTION_TYPE do
begin
BLOCK_SRC1_AND_SRC2_TO_DST (
GR_COLLECTION_LISTS [.COLLECTION_INDEX, PAT$DATA_FIRST_TERM],
TERMS_TO_PRINT, TERMS_SEEN_IN_COLLECTION, .BYTES_FOR_TERMS);
BLOCK_SRC1_AND_NOT_SRC2_TO_DST (
GR_COLLECTION_LISTS [.COLLECTION_INDEX, PAT$DATA_FIRST_TERM],
TERMS_TO_PRINT, UNACCEPTED_TERMS_IN_COLLECTION, .BYTES_FOR_TERMS);
if (COUNT (TERMS_SEEN_IN_COLLECTION, PAT$DATA_NUM_TERM) gtr 0) and
(COUNT (UNACCEPTED_TERMS_IN_COLLECTION, PAT$DATA_NUM_TERM) eql 0)
then
begin
COLLECTIONS_SEEN [.COLLECTION_INDEX] = TRUE;
BLOCK_DST_AND_NOT_SRC (
GR_COLLECTION_LISTS [.COLLECTION_INDEX, PAT$DATA_FIRST_TERM],
TERMS_TO_PRINT, .BYTES_FOR_TERMS);
end;
end;
! Determine the number of items expected
NUM_GROUP_NONTERMS_TO_PRINT = COUNT (GROUP_NONTERMS_SEEN, LS_NUM_GROUP_NONTERMS);
NUM_COLLECTIONS_TO_PRINT = COUNT (COLLECTIONS_SEEN, GR_NUM_COLLECTIONS);
NUM_TERMS_TO_PRINT = COUNT (TERMS_TO_PRINT, PAT$DATA_NUM_TERM);
NUM_ITEMS_TO_PRINT = .NUM_GROUP_NONTERMS_TO_PRINT + .NUM_COLLECTIONS_TO_PRINT + .NUM_TERMS_TO_PRINT;
DEB_ASSERT ((.NUM_ITEMS_TO_PRINT gtr 0),
'Nothing "expected" for global error recovery');
! Create a text string in text buffer 0 (BUF0) containing a
! general header if expecting something important; for example
!
! Illegal statement-- ...
CLEAR_TEXTM (BUF0);
if .BAD_NON_TERM neq LS_UNAVAILABLE_NT
then
incr LOOP_INDEX from 0 to (GR_NUM_NONTERM_NAMES - 1) do
if .GR_NONTERM_NAMES [.LOOP_INDEX, GR_NONTERM_SYMBOL] eql .BAD_NON_TERM
then
begin
APPEND_TO_TEXTM (BUF0, 'Illegal ');
APPEND_TO_TEXTM (BUF0, .GR_NONTERM_NAMES [.LOOP_INDEX, GR_NONTERM_TEXT]);
APPEND_TO_TEXTM (BUF0, '--');
exitloop;
end;
! Create a text string in buffer 1 (BUF1) consisting of items expected.
! If more than one item is expected, bracket them with curly braces.
CLEAR_TEXTM (BUF1);
if .NUM_ITEMS_TO_PRINT gtr 1 then APPEND_TO_TEXTM (BUF1, 'one of { ');
! First list important group nonterminals expected (for example, statement).
if .NUM_GROUP_NONTERMS_TO_PRINT neq 0
then
incr GROUP_NONTERM_INDEX from FIRST_GROUPING_NONTERM to LAST_GROUPING_NONTERM do
if (.GROUP_NONTERMS_SEEN [.GROUP_NONTERM_INDEX])
then
begin
APPEND_TO_TEXTM (BUF1, .GR_GROUP_NONTERM_TEXT [.GROUP_NONTERM_INDEX]);
APPEND_TO_TEXTM (BUF1, ' ');
end;
! Then comes the collections (for example, arithmetic-operator)
if .NUM_COLLECTIONS_TO_PRINT neq 0
then
incr COL_INDEX from FIRST_COLLECTION_TYPE to LAST_COLLECTION_TYPE do
if (.COLLECTIONS_SEEN [.COL_INDEX])
then
begin
APPEND_TO_TEXTM (BUF1, .GR_COLLECTION_TEXT [.COL_INDEX]);
APPEND_TO_TEXTM (BUF1, ' ');
end;
! Then individual terminals.
if .NUM_TERMS_TO_PRINT neq 0
then
incr TERM_INDEX from PAT$DATA_FIRST_TERM to PAT$DATA_LAST_TERM do
if (.TERMS_TO_PRINT [.TERM_INDEX])
then
begin
APPEND_TO_TEXTM (BUF1, PAT$LSLOCAL_OUTPUT_TERM (.TERM_INDEX, FALSE, BUF2));
APPEND_TO_TEXTM (BUF1, ' ');
end;
if .NUM_ITEMS_TO_PRINT gtr 1 then APPEND_TO_TEXTM (BUF1, '}');
! Output the error message.
ERROR_LOC = LS_LEX_LOCATOR (ERROR_TOKEN_PTR);
LSLOCAL_SYNTAX_ERROR_START (.ERROR_LOC);
! Put out general header.
LSLOCAL_SYNTAX_ERROR_TEXTM (.ERROR_LOC,TEXT_SD[BUF0,STR$H_LENGTH]); ! 002
! Put out
!
! Found ... when expecting ...
LSLOCAL_SYNTAX_ERROR_TEXTM (.ERROR_LOC, 'Found ', PAT$LSLOCAL_OUTPUT_TOKEN (.ERROR_TOKEN_PTR, BUF2));
LSLOCAL_SYNTAX_ERROR_TEXTM (.ERROR_LOC, ' when expecting ');
LSLOCAL_SYNTAX_ERROR_TEXTM(.ERROR_LOC,TEXT_SD[BUF1,STR$H_LENGTH]); ! 002
LSLOCAL_SYNTAX_ERROR_END (.ERROR_LOC);
%IF %BLISS (BLISS36) %THEN
BEGIN
library 'fao';
EXTERNAL pinfile : $STR_DESCRIPTOR(); ! defined in PATPOR.BLI
LOCAL errstr : $STR_DESCRIPTOR(CLASS = DYNAMIC),
loc_desc : REF $STR_DESCRIPTOR();
$STR_DESC_INIT (DESC = errstr, CLASS = DYNAMIC);
$STR_APPEND (STRING =
$STR_CONCAT ('Error on line ',
$STR_ASCII(LS_LEX_LINE_NUMBER(.error_loc),BASE10),
' column ',
$STR_ASCII (LS_LEX_COLUMN_NUMBER (.error_loc),
BASE10),
' of ',
pinfile,
': '),
TARGET = errstr);
CLEAR_TEXTM (BUF0);
! IF .bad_non_term NEQ LS_UNAVAILABLE_NT
! THEN
INCR loop_index FROM 0 TO (GR_NUM_NONTERM_NAMES - 1) DO
IF .gr_nonterm_names [.loop_index, GR_NONTERM_SYMBOL] EQL .bad_non_term
THEN BEGIN
APPEND_TO_TEXTM (BUF0, 'Illegal ');
APPEND_TO_TEXTM (BUF0, .gr_nonterm_names[.loop_index,
GR_NONTERM_TEXT]);
APPEND_TO_TEXTM (BUF0, '--');
EXITLOOP;
END;
$STR_APPEND (STRING = (.text_sd [BUF0, STR$H_LENGTH], text_0buf),
TARGET = errstr);
loc_desc = PAT$LSLOCAL_OUTPUT_TOKEN(.error_token_ptr, BUF2);
$STR_APPEND (STRING =
$STR_CONCAT (%CHAR (13,10), ! <crlf>
'Found ',
(.text_sd [BUF2, STR$H_LENGTH],
.text_sd [BUF2, STR$A_POINTER]),
' when expecting ',
(.text_sd [BUF1, STR$H_LENGTH],
.text_sd [BUF1, STR$A_POINTER])
),
TARGET = errstr);
! SIGNAL the error...
SIGNAL (DIU$_PATPAR, 1, errstr, 0);
END;
%FI
end; ! Of routine PAT$LSLOCAL_GLOBAL_ERROR_MSG
! Section 6
! Other definitions
routine APPEND_TO_TEXT (BUFNUM, NEW_TEXT) : novalue =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! Add more text to an error message.
!
! FORMAL PARAMETERS:
!
! BUFNUM Buffer number to build message in.
! NEW_TEXT String descriptor to the next text.
!
! IMPLICIT INPUTS:
!
! Text buffer.
!
! IMPLICIT OUTPUTS:
!
! Text buffer.
!
! ROUTINE VALUE:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
local ! 002
dots: $STR_DESCRIPTOR (string = ' ...'); ! 002
map
NEW_TEXT : ref $STR_DESCRIPTOR (); ! 002
if .TEXT_BUF_FULL [.BUFNUM] then return;
if .TEXT_SD [.BUFNUM, STR$H_LENGTH] + .NEW_TEXT [STR$H_LENGTH] ! 002
gtr .TEXT_BUF_SIZE [.BUFNUM] - 4 ! 002
then
begin
TEXT_BUF_FULL [.BUFNUM] = TRUE;
ch$move (4, dots [STR$A_POINTER], ! 002
ch$plus (.TEXT_SD [.BUFNUM, STR$A_POINTER], ! 002
.TEXT_SD [.BUFNUM, STR$H_LENGTH]) ); ! 002
TEXT_SD [.BUFNUM, STR$H_LENGTH] = ! 002
.TEXT_SD [.BUFNUM, STR$H_LENGTH] + 4; ! 002
return
end;
ch$move (.NEW_TEXT [STR$H_LENGTH], .NEW_TEXT [STR$A_POINTER], ! 002
ch$plus (.TEXT_SD [.BUFNUM, STR$A_POINTER], ! 002
.TEXT_SD [.BUFNUM, STR$H_LENGTH]) ); ! 002
TEXT_SD [.BUFNUM, STR$H_LENGTH] = ! 002
.TEXT_SD [.BUFNUM, STR$H_LENGTH] + .NEW_TEXT [STR$H_LENGTH]; ! 002
end;
routine DOWN_CASE (IN, OUT) : novalue =
!++
!
! FUNCTIONAL DESCRIPTION:
!
! Convert a string to all lower case.
!
! FORMAL PARAMETERS:
!
! IN XPORT descriptor of original string
! OUT XPORT descriptor of resultant string
!
! IMPLICIT INPUTS:
!
! None.
!
! IMPLICIT OUTPUTS:
!
! None.
!
! ROUTINE VALUE:
!
! None.
!
! SIDE EFFECTS:
!
! None.
!
!--
begin
bind
DOWNCASE_TABLE = ch$transtable (! 002
%c' ', %c' ', %c' ', %c' ', ! 002 NUL, SOH, STX, ETX
%c' ', %c' ', %c' ', %c' ', ! 002 EOT, ENQ, ACK, BEL
%c' ', %c' ', %c' ', %c' ', ! 002 BS, HT, LF, VT
%c' ', %c' ', %c' ', %c' ', ! 002 FF, CR, SO, SI
%c' ', %c' ', %c' ', %c' ', ! 002 DLE, DC1, DC2, DC3
%c' ', %c' ', %c' ', %c' ', ! 002 DC4, NAK, SYN, ETB
%c' ', %c' ', %c' ', %c' ', ! 002 CAN, EM, SUB, ESC
%c' ', %c' ', %c' ', %c' ', ! 002 FS, GS, RS, US
%c' ', %c' ', %c' ', %c' ', ! 002 SP, !, ", #
%c'$', %c' ', %c' ', %c' ', ! 002 $, %, &, '
%c' ', %c' ', %c' ', %c' ', ! 002 (, ), *, +
%c' ', %c'-', %c'-', %c' ', ! 002 ,, -, ., /
%c'0', %c'1', %c'2', %c'3', ! 002 0, 1, 2, 3
%c'4', %c'5', %c'6', %c'7', ! 002 4, 5, 6, 7
%c'8', %c'9', %c' ', %c';', ! 002 8, 9, :, ;
%c' ', %c' ', %c' ', %c' ', ! 002 <, =, >, ?
%c' ', %c'a', %c'b', %c'c', ! 002 @, A, B, C
%c'd', %c'e', %c'f', %c'g', ! 002 D, E, F, G
%c'h', %c'i', %c'j', %c'k', ! 002 H, I, J, K
%c'l', %c'm', %c'n', %c'o', ! 002 L, M, N, O
%c'p', %c'q', %c'r', %c's', ! 002 P, Q, R, S
%c't', %c'u', %c'v', %c'w', ! 002 T, U, V, W
%c'x', %c'y', %c'z', %c' ', ! 002 X, Y, Z, [
%c' ', %c' ', %c' ', %c'_', ! 002 \, ], ^, _
%c' ', %c'a', %c'b', %c'c', ! 002 `, a, b, c
%c'd', %c'e', %c'f', %c'g', ! 002 d, e, f, g
%c'h', %c'i', %c'j', %c'k', ! 002 h, i, j, k
%c'l', %c'm', %c'n', %c'o', ! 002 l, m, n, o
%c'p', %c'q', %c'r', %c's', ! 002 p, q, r, s
%c't', %c'u', %c'v', %c'w', ! 002 t, u, v, w
%c'x', %c'y', %c'z', %c' ', ! 002 x, y, z, {
%c' ', %c' ', %c' ', %c' ');! 002 |, }, ~, DEL
map
IN : ref $STR_DESCRIPTOR (), ! 002
OUT : ref $STR_DESCRIPTOR (); ! 002
OUT [STR$H_LENGTH] = .IN [STR$H_LENGTH]; ! 002
ch$translate (DOWNCASE_TABLE, .IN [STR$H_LENGTH], ! 002
.IN [STR$A_POINTER], 0, .OUT [STR$H_LENGTH], ! 002
.OUT [STR$A_POINTER]); ! 002
end;
end ! End of module
eludom