! PATLANGSP.REQ ! ! ! ! COPYRIGHT (c) 1982 BY ! DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. ! ! 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 WHICH 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. ! This file is provided with the PAT parser package and provides ! an example of a particular implementation of the interface ! specification. ! ! Logical name PAT_LANGSP_LIBRARY should be defined as the ! library file produced by ! ! BLISS/LIB PATLANGSP.REQ ! ! This file defines all of the language specific ! interfaces needed by the language independent portion ! of the parser. ! ! Note everything in PATLANGSP.BLI is referenced via macros ! in PATLANGSP.REQ. As a result it is possible to redefine ! the macros in this file to refer to routines in a number of ! language specific modules. ! ! ! THIS FILE MUST BE ALTERED TO USE WITH OTHER COMPILERS ! ! ! ENVIRONMENT: VAX/VMS user mode ! ! AUTHOR: Harvey Alcabes, CREATION DATE: 18-Nov-80 ! ! MODIFIED BY: ! ! Charlie Mitchell, 12-Nov-1981 : VERSION X2-001 ! 001 - Use new PAT/BLISS interface. Add misc. new interface macros. ! Reorganize and document. Move local recovery tuning to ! PATLSTUNE.REQ. ! ! Paul Calato, 10-Jun-1987 : VERSION X2-002 ! 002 - Use new PAT/BLISS interface. Add misc. new interface macros. ! Reorganize and document. Move local recovery tuning to ! PATLSTUNE.REQ. !-- ! ! INCLUDE FILES ! require 'PATREQPRO_REQ'; require 'SDLTOKDEF_REQ'; library 'XPORT_LIB'; library 'PATDATA_LIB'; ! !+ ! IMPORTANT NOTE ! ! This file is language specific. It defines an interface that must ! be implemented to use the language independent portion of the parser. ! Naming conventions have been adopted to help identify those declarations ! that define the interface: ! ! o Macros and literals that define the interface begin with ! the prefix "LS_". You must define these appropriately. ! ! o Macros and literals that do not define the interface begin ! with "LSLOCAL_" or "TKN_". There is no direct reference to them ! in the language independent portion of the parser. Thus, you ! are free to delete them if you wish. ! ! o Global routines in PATLANGSP.REQ are prefixed with "PAT$LSLOCAL_". ! They are not part of the interface, and they are not referenced ! directly in the language independent portion of the parser. !- ! !+ ! This file is divided into six sections, all of which are ! ***LANGUAGE SPECIFIC*** ! ! 1. Interface to lexical analyzer and lexical tokens. ! ! 2. Terminal and non-terminal symbol interpretation. ! ! 3. Action routine interface ! ! 4. Error message interface (local and scope recovery) ! ! 5. Error message interface (global recovery) ! ! 6. Other definitions ! !- ! !+ ! Section 1 ! ! Interface to lexical analyer and lexical tokens: ! ! - Call to lexical analyzer ! ! - Obtain the text for a lexical token ! ! - Dump a lexical token (debugging) ! ! - Lexical token interpretation ! ! - Translation of source locator to line number and column ! position. ! !- ! macro LS_GET_LEX_TOKEN = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_GET_LEX_TOKEN gets the next lexical token. ! The lexical analyzer which it calls is expected to ! store tokens in separate locations so that the parser ! can manipulate several tokens at once. ! Because only a few tokens are considered at once, ! it is acceptable for the lexical analyzer to keep ! a ring buffer of LS_LEX_RING_BUFFER_SIZE tokens ! (see below) and to reuse storage for old tokens. ! ! FORMAL PARAMETERS: ! ! NONE ! ! VALUE: ! ! Returns a pointer to the new token. ! !-- begin external sdl$shr_address; !pointer to the sdl shared data structure ! sdl$_shr_data external routine LEX ; LEX (.sdl$shr_address); TOKEN [.TOKEN_INDEX] end %; !+ ! The size of the lexical token ring buffer mentioned in ! LS_GET_LEX_TOKEN is specified by the literal ! LS_LEX_RING_BUFFER_SIZE. Currently a value of 10 or ! more is required. (At the current time there is no ! advantage to having value greater than 10.) !- literal LS_LEX_RING_BUFFER_SIZE = 10; ! macro LS_SAVE_TOKEN (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_SAVE_TOKEN is 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 saved token. The saved token is then used ! in constructing the error message: ! ! Found 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 ! ! VALUE: ! ! NONE !-- begin external routine PAT$LSLOCAL_SAVE_TOKEN : novalue; PAT$LSLOCAL_SAVE_TOKEN (TOKEN_PTR); end %; ! macro LS_RETURN_SAVED_TOKEN = !++ ! FUNCTIONAL DESCRIPTION: ! ! See LS_SAVE_TOKEN. ! ! FORMAL PARAMETERS: ! ! NONE ! ! VALUE: ! ! TOKEN_PTR !-- begin external routine PAT$LSLOCAL_RETURN_SAVED_TOKEN; PAT$LSLOCAL_RETURN_SAVED_TOKEN () end %; ! %if PATBLSEXT_DEBUGGING %then macro LS_DUMP_TOK (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_DUMP_TOK outputs the lexical token pointed to by TOKEN_PTR. ! (Only called by debugging routines) ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Pointer to the lexical token which is to be dumped. ! ! VALUE: ! ! NONE ! !-- begin external routine PAT$LSLOCAL_DUMP_TOK : novalue; PAT$LSLOCAL_DUMP_TOK (TOKEN_PTR); end %; %fi ! !+ ! Interpretation of lexical tokens ! ! Given the address of a lexical token macros that follow must be ! able to return: ! ! 1. The terminal symbol number that corresponds to the ! terminal defined in the PAT grammar. ! ! 2. A source locator. This is intended to represent the ! line number and column position of the token in the source. ! The parser assumes that a BLISS value (32 bits on VAX, ! 16 on the -11) is allocated for a locator. However, all ! interpretation of the locator is done by language specific ! macros in PATLANGSP. Thus, the locator can be an encoded ! value or a pointer. ! ! 3. A string descriptor for the text (spelling) of identifiers ! and literals. ! ! 4. A boolean indicating a synthetic token (one created during ! error recovery). Note that semantics action routines should ! be prepared to check this boolean. ! ! 5. (optional) A boolean indicating that a token is the first ! one on a line. ! ! A structure definition follows for a lexical token. Note that ! the TKN_* fields are not refered to directly in the language ! independent portion of the parser. Rather, macros that follow ! return the values of particular fields. ! ! The structure of a lexical token is **LANGUAGE SPECIFIC**. ! Information which must be accessable for any language is indicated ! with "**" in the following comment ! $FIELD TKN_BASE = [$SUB_BLOCK ()], ! Placeholder to indicate base of token--uses no storage TKN_TERM = [$INTEGER], ! **Terminal symbol number TKN_LOCATOR = [$INTEGER], ! **Encoded column and line in source TKN_LENGTH = [$INTEGER], ! %added for SDL - token length TKN_TEXT = [$ADDRESS], ! **Text in source - for literals ! See macro LS_LEX_TEXT TKN_START_LINE = [$BYTE], ! Token is at start of line TKN_SYNTHETIC = [$BYTE]; ! **TRUE if token was created by error recovery ! routines instead of lexical analyzer literal TKN_SIZE = $FIELD_SET_SIZE*%upval; ! Size of lexical token (in BYTES) macro ! Field names--**LANGUAGE SPECIFIC** TKN_FIELDS = TKN_BASE, TKN_TERM, TKN_LOCATOR, TKN_LENGTH, TKN_TEXT, TKN_START_LINE, TKN_SYNTHETIC %; macro TKN_STR = block [TKN_SIZE/%upval] field (TKN_FIELDS) %; undeclare %quote $DESCRIPTOR; ! due to current xport problem ! macro LS_TKN_SIZE = !++ ! FUNCTIONAL DESCRIPTION: ! ! Expands to the number of BYTES in a lexical token stucture ! ! FORMAL PARAMETERS: ! ! NONE ! !-- TKN_SIZE %; ! macro LS_LEX_TERM (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns the value of the terminal symbol number. ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; .TOKEN_PTR [TKN_TERM] end %; ! macro LS_LEX_LOCATOR (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns the value of a source locator associated with a ! lexical token. ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; .TOKEN_PTR [TKN_LOCATOR] end %; ! macro LS_LEX_TEXT (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns the text (spelling) associated with a lexical token ! (for identifiers and literals). ! ! The parser expects to get the address of a VMS static string ! descriptor. ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; ! .TOKEN_PTR [TKN_TEXT] TOKEN_PTR [TKN_LENGTH] end %; ! %if PATBLSEXT_EXTRA_STACK_FIELD %then macro LS_LEX_EXTRA_INFO (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns extra info associated with lexical token that is ! to be stacked on the parse stack. (See PATBLSEXT.REQ.) ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; ! .TOKEN_PTR [TKN_COMMENTS] 0 end %; %fi ! macro LS_LEX_START_LINE (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns a boolean indicating if a lexical token is the first ! one on a line. This macro is only used when trying to insert ! a semicolon at the end of a line. ! ! This macro should expand to FALSE for languages that don't ! often have semicolon's at the end of lines. ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; .TOKEN_PTR [TKN_START_LINE] end %; ! macro LS_LEX_SYNTHETIC (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Returns a boolean indicating if a lexical token is synthetic ! (was created by the error recovery routines). ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; .TOKEN_PTR [TKN_SYNTHETIC] end %; ! macro LS_LEX_SET_TERM (TOKEN_PTR, TERMINAL) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Sets the field of TOKEN_PTR which contains its terminal symbol ! to TERMINAL. This is used when the parser is creating a ! synthetic lexical token. ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! ! TERMINAL - Terminal symbol number ! !-- begin map TOKEN_PTR : ref TKN_STR; TOKEN_PTR [TKN_TERM] = TERMINAL end %; ! macro LS_LEX_SET_SYNTHETIC (TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Sets the field of TOKEN_PTR which indicates that a lexical ! token is synthetic to TRUE, meaning that it was created by ! the error recovery routines. ! ! In addition, if the locator is set to a value that indicates ! a synthetic token, a better scope recovery error message ! can be produced. (See LSLOCAL_LOCATOR_IS_SYNTHETIC and ! LS_ERROR_SCOPE_MATCH.) ! ! FORMAL PARAMETERS: ! ! TOKEN_PTR - Address of a pointer variable which contains ! the address of a lexical token. ! !-- begin map TOKEN_PTR : ref TKN_STR; TOKEN_PTR [TKN_SYNTHETIC] = TRUE; TOKEN_PTR [TKN_LOCATOR] = LSLOCAL_SYNTHETIC_LOCATOR end %; ! macro LSLOCAL_LOCATOR_IS_SYNTHETIC (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LSLOCAL_LOCATOR_IS_SYNTHETIC has value TRUE if it can be ! determined that a locator is associated with a synthetic ! token. (See LS_LEX_SET_SYNTHETIC and LS_ERROR_SCOPE_MATCH.) ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator ! ! VALUE: ! ! TRUE if synthetic; FALSE if not or if cannot determine. ! !-- begin (SLOC) eql LSLOCAL_SYNTHETIC_LOCATOR end %; literal ! Locator value that indicates a synthetic locator LSLOCAL_SYNTHETIC_LOCATOR = 0; ! macro LS_LEX_LINE_NUMBER (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_LEX_LINE_NUMBER converts a source locator to a line number. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator ! ! VALUE: ! ! Line number extracted from source locator. ! !-- begin ! external routine ! PAR_LINE_NUMBER; ! PAR_LINE_NUMBER (SLOC) SLOC <0,16> end %; ! macro LS_LEX_COLUMN_NUMBER (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_LEX_COLUMN_NUMBER converts a source locator to a column number. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator ! ! VALUE: ! ! Column number extracted from source locator. ! !-- begin ! external routine ! PAR_COLUMN_NUMBER; ! PAR_COLUMN_NUMBER (SLOC) SLOC <16,16> end %; ! !++ ! Section 2 ! ! Macros to interpret terminal and non-terminal symbols. ! !-- ! !+ ! LS_STOP_PARSING_NT--**LANGUAGE SPECIFIC** ! ! The parser stops when it does a reduction to the production with the ! left hand side of LS_STOP_PARSING_NT. ! ! PAT_SENTENCE_CD is automatically defined to be the first production ! in the grammar (the one containing GOALSY). ! !- literal !***LANGUAGE SPECIFIC*** LS_STOP_PARSING_NT = NT_PROGRAM; ! Stop when have seen a program ! macro LS_IS_EOF (SYMBOL_NUM) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Return TRUE if SYMBOL_NUM represents the end of a file, ! FALSE otherwise ! ! FORMAL PARAMETERS: ! ! SYMBOL_NUM ! !-- ((SYMBOL_NUM) eql T_EOF) %; ! macro LS_IS_IDENTIFIER (SYMBOL_NUM) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Return TRUE if SYMBOL_NUM represents an identifier, ! FALSE otherwise ! ! FORMAL PARAMETERS: ! ! SYMBOL_NUM ! !-- ((SYMBOL_NUM) eql T_NAME or (SYMBOL_NUM) eql T_LOCAL_NAME) %; ! macro LS_IS_RESERVED_WORD (SYMBOL_NUM) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Return TRUE if SYMBOL_NUM represents a terminal symbol ! which is a reserved word, FALSE otherwise. ! ! FORMAL PARAMETERS: ! ! SYMBOL_NUM ! !-- begin external routine PAT$LSLOCAL_IS_RESERVED_WORD; PAT$LSLOCAL_IS_RESERVED_WORD (SYMBOL_NUM) end %; ! macro LS_IS_NON_TERM (SYMBOL_NUM) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Return TRUE if SYMBOL_NUM represents a non-terminal symbol, ! FALSE otherwise ! ! FORMAL PARAMETERS: ! ! SYMBOL_NUM ! !-- begin external routine PAT$LSLOCAL_IS_NON_TERM; PAT$LSLOCAL_IS_NON_TERM (SYMBOL_NUM) end %; ! macro LS_T_IDENTIFIER = !++ ! FUNCTIONAL DESCRIPTION: ! ! Language independent name for identifier token. ! ! FORMAL PARAMETERS: ! ! NONE ! !-- T_NAME %; ! macro LS_T_SEMICOLON = !++ ! FUNCTIONAL DESCRIPTION: ! ! Language independent name for semicolon token. ! If macro LS_LEX_START_LINE always returns false, then the value of ! this macro is irrelevant. ! ! FORMAL PARAMETERS: ! ! NONE ! !-- T_SEMICOLON %; ! macro LS_T_ERRORMARK = !++ ! FUNCTIONAL DESCRIPTION: ! ! Language independent name for errormark token. ! ! FORMAL PARAMETERS: ! ! NONE ! !-- T_ERRORMARK %; ! !++ ! Section 3 ! ! Interface to action routines ! !-- ! macro LS_REDUCE_ACTION (code, LEFT, RIGHT, SLOC, RIGHT_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro is called by the parser when a reduction is ! done for which a semantics action is specified. ! ! The best way to understand these parameters is to run ! the sample parser provided with the PAT package. In the ! sample parser, calls to this macro result in a display ! of the parse stack and of the actual parameters of this ! macro. ! ! FORMAL PARAMETERS: ! ! CODE - A code indicating which action is to be performed ! (the action specified in the input to PAT). ! ! LEFT - The index into the parse stack corresponding ! to the left hand end of the "handle", i.e. the string ! of terminals and non-terminals corresponding to the ! right hand side of a production. ! ! Note that this stack index can be used to ! index a parallel semantics stack maintained ! by the semantics action routine. ! ! RIGHT - Similar to LEFT, but corresponding to the right hand ! end of the handle. ! ! SLOC - Source locator ! ! RIGHT_TOKEN_PTR - If the last symbol in the reduction is a terminal, ! this is a pointer to the token containing that ! symbol. If it is a non-terminal then this value ! is undefined. ! ! VALUE: ! ! MAY_BACKUP - Boolean value; if TRUE, error recovery will ! be allowed to backup over this reduction ! !-- begin external sdl$shr_address; !pointer to the sdl shared data structure ! sdl$_shr_data external routine PAR_ABST : novalue; PAR_ABST (..sdl$shr_address, code, LEFT, RIGHT, SLOC, RIGHT_TOKEN_PTR); TRUE end %; ! macro LS_REDUCE_NO_ACTION (LEFT, RIGHT) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro is called by the parser when a production has ! been recognized which does not have a semantics action ! associated with it. ! ! FORMAL PARAMETERS: ! ! LEFT - Left stack position of handle ! ! RIGHT - Right stack position of handle ! ! ! VALUE: ! ! MAY_BACKUP - Boolean value; if TRUE, error recovery will ! be allowed to backup over this reduction ! !-- begin TRUE end %; ! macro LS_LOCAL_RECOVERY_INFORM (BACKED_OVER_TOKEN, MAY_HAVE_BACKED_OVER_REDUCTIONS, POPPED_STACK, STACK_INDEX_AFTER, STACK_INDEX_BEFORE) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro is called by the parser when local error ! recovery (which includes scope recovery) has been successfully ! completed. It provides information that the action routines can ! use to compensate for the behavior of the error recovery. ! ! FORMAL PARAMETERS: ! ! BACKED_OVER_TOKEN - Boolean indicating whether or not the ! error recovery backed up over a ! lexical token ! ! MAY_HAVE_BACKED_OVER_REDUCTION - Boolean indicating whether the error ! recovery could have backed up over ! a reduction ! ! POPPED_STACK - Boolean indicating whether or not the ! parse stack was popped by error ! recovery ! ! STACK_INDEX_AFTER - Size of parse stack after error ! recovery. ! INVALID IF POPPED_STACK IS FALSE ! ! STACK_INDEX_BEFORE - Size of parse stack before error ! recovery. ! INVALID IF POPPED_STACK IS FALSE ! ! VALUE: ! ! NONE ! !-- begin 0 end %; ! macro LS_GLOBAL_RECOVERY_INFORM (STACK_INDEX_AFTER, STACK_INDEX_BEFORE) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro is called by the parser when global error ! recovery has been performed. It provides information that ! the action routines can use to compensate for the behavior ! of the error recovery. ! ! FORMAL PARAMETERS: ! ! STACK_INDEX_AFTER - Size of parse stack after error recovery ! ! ! STACK_INDEX_BEFORE - Size of parse stack before error recovery ! ! ! VALUE: ! ! NONE ! !-- begin 0 end %; ! !++ ! Section 4 ! ! Error message interface (internal errors, local and scope recovery ! errors) ! !-- macro LS_ERROR_PARSE_STACK_OVERFLOW (ERROR_LOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro is called if a parse stack overflow occurs. ! (See later definition of LS_PARSE_STACK_SIZE.) ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator when overflow occured. ! !++ begin DEB_ASSERT (FALSE, 'Parse stack overflow') end %; ! ! ! The next group of macros are used to specify the format of the ! error messages for local and scope recovery. ! They may be left intact or changed. ! !-- macro LS_ERROR_EOL (ERROR_LOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing an end-of-line ! correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! !-- begin LSLOCAL_SYNTAX_ERRORM (ERROR_LOC, 'Inserted ";" at the end of the previous line'); end %; ! macro LS_ERROR_MERGE (ERROR_LOC, FIRST_TOKEN_PTR, SECOND_TOKEN_PTR, NEW_TERMINAL) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing a token merge correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! FIRST_TOKEN_PTR - Pointer to first of the two merged tokens. ! ! SECOND_TOKEN_PTR - Pointer to second of the two merged tokens. ! ! NEW_TERMINAL - Terminal formed by merging the two tokens. ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TERM, PAT$LSLOCAL_OUTPUT_TOKEN; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Merged ', PAT$LSLOCAL_OUTPUT_TOKEN (FIRST_TOKEN_PTR, 0)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' and ', PAT$LSLOCAL_OUTPUT_TOKEN (SECOND_TOKEN_PTR, 1)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' to form ', PAT$LSLOCAL_OUTPUT_TERM (NEW_TERMINAL, TRUE, 2)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_ABBREV (ERROR_LOC, ID_TOKEN_PTR, RW_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing an abbreviation ! correction (a form of spelling correction). ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! ID_TOKEN_PTR - Pointer to token containing identifier ! (which is the abbreviated reserved word). ! ! RW_TOKEN_PTR - Pointer to token containing reserved word ! (which had been abbreviated). ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TOKEN; local ID_TOKEN; ID_TOKEN = ID_TOKEN_PTR; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Spelling corrector replaced abbreviation '); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, LS_LEX_TEXT (ID_TOKEN)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' with ', PAT$LSLOCAL_OUTPUT_TOKEN (RW_TOKEN_PTR, 0)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_SPELL (ERROR_LOC, ID_TOKEN_PTR, RW_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing a spelling correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! ID_TOKEN_PTR - Pointer to token containing identifier ! (which is the misspelled reserved word). ! ! RW_TOKEN_PTR - Pointer to token containing the reserved word ! (which had been misspelled). ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TOKEN; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Spelling corrector replaced '); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, PAT$LSLOCAL_OUTPUT_TOKEN (ID_TOKEN_PTR, 0)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' with ', PAT$LSLOCAL_OUTPUT_TOKEN (RW_TOKEN_PTR, 1)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_SUBST (ERROR_LOC, INIT_TOKEN_PTR, NEW_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing a token ! substitution correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! INIT_TOKEN_PTR - Pointer to token containing initial token ! (which is being replaced). ! ! NEW_TOKEN_PTR - Pointer to token containing new token ! (which is being inserted in place of ! INIT_TOKEN_PTR). ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TERM, PAT$LSLOCAL_OUTPUT_TOKEN; local NEW; ! Need pointer variable to call LS_LEX_TERM NEW = NEW_TOKEN_PTR; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Replaced ', PAT$LSLOCAL_OUTPUT_TOKEN (INIT_TOKEN_PTR, 0)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' with ', PAT$LSLOCAL_OUTPUT_TERM (LS_LEX_TERM (NEW), TRUE, 1)) ; LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_INSERT (ERROR_LOC, INSERTED_TOKEN_PTR, FOLLOWING_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing an insertion correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! INSERTED_TOKEN_PTR - Pointer to token containing inserted token. ! ! FOLLOWING_TOKEN_PTR - Pointer to token containing token following ! inserted token. ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TERM, PAT$LSLOCAL_OUTPUT_TOKEN; local INSERTED; ! Need pointer variable to call LS_LEX_TERM INSERTED = INSERTED_TOKEN_PTR; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Inserted ', PAT$LSLOCAL_OUTPUT_TERM (LS_LEX_TERM (INSERTED), TRUE, 0)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' before ', PAT$LSLOCAL_OUTPUT_TOKEN (FOLLOWING_TOKEN_PTR, 1)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_DELETED (ERROR_LOC, DELETED_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing an deletion correction. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! DELETED_TOKEN_PTR - Pointer to token containing deleted token. ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TOKEN; local DELETED; ! Need pointer variable to call LS_LEX_LOCATOR DELETED = .DELETED_TOKEN_PTR; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Unexpected '); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, PAT$LSLOCAL_OUTPUT_TOKEN (DELETED,TRUE, 0)); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' deleted'); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_SCOPE_NO_MATCH (ERROR_LOC, CLOSER_TEXT, FOLLOWING_TOKEN_PTR) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing a scope recovery ! correction for which no matching symbol was provided for the closer. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! CLOSER_TEXT - String descriptor to text describing the ! inserted scope closer. ! ! FOLLOWING_TOKEN_PTR - Pointer to token containing token following ! inserted closer. ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TOKEN; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Inserted ', CLOSER_TEXT); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' before ', PAT$LSLOCAL_OUTPUT_TOKEN (FOLLOWING_TOKEN_PTR, 0)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! macro LS_ERROR_SCOPE_MATCH (ERROR_LOC, CLOSER_TEXT, MATCHING_SYMBOL, MATCH_LOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro writes an error message describing a scope recovery ! correction for which a matching symbol was provided for the closer. ! ! FORMAL PARAMETERS: ! ! ERROR_LOC - Source locator of error. ! ! CLOSER_TEXT - String descriptor to text describing the ! inserted scope closer. ! ! MATCHING_SYMBOL - Symbol number of the terminal symbol which ! opens the scope being closed. ! ! MATCH_LOC - Source locator of the token containing the ! matching symbol which opened the scope being ! closed. ! !-- begin external routine PAT$LSLOCAL_OUTPUT_TERM, PAT$LSLOCAL_LOC_TEXT; LSLOCAL_SYNTAX_ERROR_START (ERROR_LOC); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, 'Inserted '); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, CLOSER_TEXT); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' to match '); LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, PAT$LSLOCAL_OUTPUT_TERM (MATCHING_SYMBOL, FALSE, 0)); if LSLOCAL_LOCATOR_IS_SYNTHETIC (MATCH_LOC) then LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' inserted earlier') else LSLOCAL_SYNTAX_ERROR_TEXTM (ERROR_LOC, ' ', PAT$LSLOCAL_LOC_TEXT (MATCH_LOC)); LSLOCAL_SYNTAX_ERROR_END (ERROR_LOC); end %; ! !+ ! The next group of macros are local to PATLANGSP and are not part of ! the interface. !- macro LSLOCAL_SYNTAX_ERROR_START (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro indicates the start of a syntax or lexical error message. ! A call to this macro must be followed by one or more calls to ! LSLOCAL_SYNTAX_ERROR_TEXT and finally by a call to ! LSLOCAL_SYNTAX_ERROR_END. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator. ! !-- begin PUT_MSG ('Error on line '); PUT_NUMBER (LS_LEX_LINE_NUMBER (SLOC)); PUT_MSG (' column '); PUT_NUMBER (LS_LEX_COLUMN_NUMBER (SLOC)); PUT_MSG (': '); end %; ! external routine SDL$WRITELIST; external IOS_TERDESC : vector [2]; external IOS_TERRBF; macro LSLOCAL_SYNTAX_ERROR_TEXT (SLOC, STRING) = !++ ! FUNCTIONAL DESCRIPTION: ! ! Append text to a syntax error message. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator. ! ! STRING - Address of a string descriptor. ! !-- begin external sdl$shr_address; !pointer to the sdl shared data structure ! sdl$_shr_data local IOS_TERDESC_COPY : vector [2]; bind S = (STRING) : ref SD_STR; if PUT_LINE_FULL (S [SD_LENGTH]) ! if would overflow the line then begin IOS_TERDESC_COPY [0] = .IOS_TERDESC [1] - IOS_TERRBF; IOS_TERDESC_COPY [1] = IOS_TERRBF; SDL$WRITELIST (IOS_TERDESC_COPY, ..sdl$shr_address); PUT_EOL (); PUT_MSG (' '); ! tab end; PUT_STRING (S); end %; ! macro LSLOCAL_SYNTAX_ERROR_END (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This macro ends a syntax error message started ! by a call to LSLOCAL_SYNTAX_ERROR_START. It automatically ends ! the current line. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator. ! !-- begin external sdl$shr_address; !pointer to the sdl shared data structure ! sdl$_shr_data local IOS_TERDESC_COPY : vector [2]; IOS_TERDESC_COPY [0] = .IOS_TERDESC [1] - IOS_TERRBF; IOS_TERDESC_COPY [1] = IOS_TERRBF; SDL$WRITELIST (IOS_TERDESC_COPY, ..sdl$shr_address); PUT_EOL (); end %; ! macro LSLOCAL_SYNTAX_ERRORM (SLOC) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This is a macro interface that permits an syntax error ! to be reported in a single call. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator. ! ! %remaining - list of quoted strings or expressions. The ! value of each expression should be the address ! of a string descriptor. The strings are ! appended to form the error message text. ! !-- begin external sdl$shr_address; !pointer to the sdl shared data structure ! sdl$_shr_data LSLOCAL_SYNTAX_ERROR_START (SLOC); LSLOCAL_SYNTAX_ERROR_TEXTM (SLOC, %remaining); LSLOCAL_SYNTAX_ERROR_END (SLOC); end %; ! macro LSLOCAL_SYNTAX_ERROR_TEXTM (SLOC, TEXT) = !++ ! FUNCTIONAL DESCRIPTION: ! ! This is a macro interface to LSLOCAL_SYNTAX_ERROR_TEXT and has the same ! effect as a sequence of calls to LSLOCAL_SYNTAX_ERROR_TEXT. ! ! FORMAL PARAMETERS: ! ! SLOC - Source locator. ! ! %remaining - list of quoted strings or expressions. The ! value of each expression should be the address ! of a string descriptor. ! !-- begin LSLOCAL_SYNTAX_ERROR_TEXTM2 (SLOC, TEXT %if not %null (%remaining) %then , %remaining %fi ) end %; macro LSLOCAL_SYNTAX_ERROR_TEXTM2 (SLOC, TEXT) [] = !++ ! This macro is only called by LSLOCAL_SYNTAX_ERROR_TEXTM !-- %if %count neq 0 %then ; %fi LSLOCAL_SYNTAX_ERROR_TEXT (SLOC %if %isstring (TEXT) %then , SD_REF (TEXT) %else , TEXT %fi )LSLOCAL_SYNTAX_ERROR_TEXTM2(SLOC, %remaining) %; ! !++ ! ! Section 5 ! ! Error message interface (global recovery) ! ! In preparation for issuing a global recovery message, ! LS_EXPECTED_SYMBOL is called for each terminal and non- ! terminal symbol that could have led to a correct parse ! instead of an error. A bit vector is set to indicate ! those terminals that were expected, and another bit ! vector can be used to remember special non-terminal ! symbols that were expected. ! ! LS_GLOBAL_ERROR_MSG is called to issue the error message. ! Addresses of the bit vectors set in LS_EXPECTED_SYMBOL are ! passed as parameters. Information in the two bit vectors ! can be used to improve the error message. For example, ! information in the terminals expected vector can be used to ! produce an error message of the form ! ! Found ... when expecting {arithmetic operator} ! ! instead of ! ! Found ... when expecting {"rem", "mod", "+", "-", ...} ! ! ! Information in the non-terminals expected vector can be ! used to "edit" the terminals expected vector and produce ! errors such as ! ! Found ... when expecting {statement} ! ! instead of ! ! Found ... when expecting {"if", "loop", "begin", ...} !-- !+ ! The parser allocates the bit vector used to remember special ! non-terminal symbols. LS_NUM_GROUP_NONTERMS specifies the number ! of bits in this vector. This bit vector is cleared by the parser, ! but otherwise it is up to language specific routines to set and ! interpret the bits. LS_NUM_GROUP_NONTERMS must have a value of 1 ! or greater even if the user does not wish to use this bit vector. !- literal !! LS_NUM_GROUP_NONTERMS = 3; LS_NUM_GROUP_NONTERMS = 1; ! macro LS_EXPECTED_SYMBOL (SYM, REF_GROUP_NONTERMS_SEEN, REF_TERMS_TO_PRINT) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_EXPECTED_SYMBOL adds the symbol SYM to the set of ! symbols to be listed as 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. ! ! VALUE: ! ! NONE ! !-- begin external routine PAT$LSLOCAL_EXPECTED_SYMBOL : novalue; PAT$LSLOCAL_EXPECTED_SYMBOL (SYM, REF_GROUP_NONTERMS_SEEN, REF_TERMS_TO_PRINT); end %; ! macro LS_GLOBAL_ERROR_MSG (BAD_NON_TERM, ERROR_TOKEN_PTR, REF_GROUP_NONTERMS_SEEN, REF_TERMS_TO_PRINT, BYTES_FOR_TERMS) = !++ ! FUNCTIONAL DESCRIPTION: ! ! LS_GLOBAL_ERROR_MESSAGE outputs an error message for global ! error recovery. ! ! The global error recovery that has been done will eventually ! result in the recognition of some production containing an ! errormark: ! ! LHS_NON_TERMINAL_NAME = ... errormark ... ; ! ! where ... indicates a sequence of terminal/non-terminal ! 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 error of the form ! ! Invalid statement--Found ... when expecting ... ! ! instead of ! ! Found ... when expecting ... ! ! ! FORMAL PARAMETERS: ! ! BAD_NON_TERM - Number of non-terminal symbol (see above) ! ! ERROR_TOKEN_PTR - Pointer to token at which error was ! encountered ! ! REF_GROUP_NONTERMS_SEEN - Pointer to bit vector indicating which ! important group non-terminal symbol ! were expected. (See LS_EXPECTED_SYMBOL.) ! Note that this vector can be modified. ! ! REF_TERMS_TO_PRINT - Pointer to bit vector which indicating which ! terminal symbols were expected. (See ! LS_EXPECTED_SYMBOL.) Note that this vector ! can be modified. ! ! BYTES_FOR_TERMS - Number of bytes used by TERMS_TO_PRINT ! ! VALUE: ! ! NONE ! !-- begin external routine PAT$LSLOCAL_GLOBAL_ERROR_MSG; PAT$LSLOCAL_GLOBAL_ERROR_MSG (BAD_NON_TERM, ERROR_TOKEN_PTR, REF_GROUP_NONTERMS_SEEN, REF_TERMS_TO_PRINT, BYTES_FOR_TERMS); end %; !+ ! LS_UNAVAILABLE_NT is sometimes passed as the value of parameter ! BAD_NON_TERM. (See description of LS_GLOBAL_ERROR_MSG.) ! !- literal LS_UNAVAILABLE_NT = -2; ! !++ ! Section 6 ! ! Other definitions ! !-- !+ ! LS_PARSE_STACK_SIZE--**LANGUAGE SPECIFIC** ! ! This constant specifies the size (number of elements) in the parse ! stack. !- literal LS_PARSE_STACK_SIZE = 256; macro LS_PARSE_STACK_DECL = !++ ! FUNCTIONAL DESCRIPTION ! ! ! NOTE: Probably you do not read any more about this macro. ! Just leave it the way it is and everything will be fine. ! ! This is a special macro for a PDP-11 user of the ! PAT parser. This macro usually expands to LOCAL meaning ! that the parse stack is declared as a local variable. This macro ! generally does not need to be changed for other implementations. !-- local %; ! End of PATLANGSP.REQ