1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
.\"/*
.\" * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
.\" *
.\" * Licensed under the Apache License, Version 2.0 (the "License");
.\" * you may not use this file except in compliance with the License.
.\" * You may obtain a copy of the License at
.\" *
.\" * http://www.apache.org/licenses/LICENSE-2.0
.\" *
.\" * Unless required by applicable law or agreed to in writing, software
.\" * distributed under the License is distributed on an "AS IS" BASIS,
.\" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.\" * See the License for the specific language governing permissions and
.\" * limitations under the License.
.\" *
.\" */
.NS 4 "Parser"
.lp
The Parser (\c
.i parser.c )
performs an LR(1) parse of the input source
using parse tables generated
by the Parse Table Generator utility
and tokens returned by the Scanner.
For a description of the LR parsing method used, see
references [6] and [7].
.lp
Refer to Appendix I for a listing of the grammar
which drives the Parser.
.sh 2 "Data Structures"
.us "Parse Stack"
contains parse states and is maintained by the Parser.
When a 'read transition' occurs, a state is added to the stack.
When a reduction occurs, the stack is reduced by the number of
tokens on the right hand side of the reduction minus one.
.us "Semantic Stack"
is maintained in parallel with the Parse Stack, and is
described in detail in section 5 since it is only used by the
Semantic Analyzer.
The variable,
.cw stktop ,
is used to point to the current top of the semantic stack.
Whenever a read transition occurs, the Parser adds to the
semantic stack, information on the current token (for example symbol table
pointer) which the Scanner passed to it.
.us "Parse Tables"
tables created by the utility PRSTAB and which control the
parsing process.
These tables are described in the PRSTAB Maintenance and Operation
Document, [7].
.sh 2 "Processing Overview"
The Parser uses parse tables generated by the Parse Table Generator
utility (PRSTAB), and tokens returned by the Scanner.
As each parse reduction is made, the Semantic Analyzer is
called to perform the function associated with the
particular reduction.
.lp
The parser maintains the parse stack.
Semantic actions are done in parallel with reductions
involving the parse stack.
Figure 4-1 gives a pseudo-code description of the operation of the
Parser.
.(z
.hl
.CS
loop for each statement in subprogram unit {
parse_init();
repeat /* once for each input token in the statement */ {
get token;
while (a reduction can be made using the current
token as a look-ahead symbol) {
call Semantic Analyzer for this reduction;
if (sem.ignore_stmt) {
/* skip this statement */
goto next_statement;
}
replace on the parse stack, the right hand side
symbols by the left hand side symbol for
this reduction;
current_state = new value determined from
Parse Tables;
stack current_state on Parse Stack;
}
if (there is a valid read transition) {
current_state = new value determined using
current_state, token, and Parse Tables;
stack current_state information on
Parse Stack.
}
else
error;
if (token == end_of_line) {
if end-of-program-unit return;
if at end-of-file { error; return; }
break;
}
}
next_statement:;
}
.CE
.sp
.ce
Figure 4-1: Parser Operation
.hl
.)z
.lp
The
.cw parse_init
routine sets the Parse Stack to its initial
state.
.cw parse_init
calls the
.i reset
routine in the lexical analyzer to begin processing tokens
from the next statement.
.lp
During semantic analysis, the semantic analyzer,
while processing reductions, may detect an error for which it's
useless to process the remaining tokens in the statement.
For example, if an executable statement appears in an interface,
there's no need to semantically analyze the statement.
The semantic analyzer can direct the parser to ignore the
remaining portion of the statement and to move on to the
next statement;
the global variable (a flag) for effecting this is
.cw sem.ignore_stmt .
.lp
The last token processed by the parser for a statement is
the
.i "end of line"
(
.cw TK_EOL
)
token.
When this token is seen, the parser determines if the
.cw END
statement is the current statement.
If it is, the parser returns to the caller (main)
since this represents the end of the current subprogram.
.sh 2 "Parse Table Generator (PRSTAB)"
.sh 3 Overview
The main function of PRSTAB is to generate data initializations
for the Parse Tables used by the Parser.
In addition, it generates three files of C
.cw #define
directives
used to coordinate the operation of the Scanner, Parser, and
Semantic Analyzer, and two files of static character information
used for error messages and debugging.
PRSTAB generates a listing and cross reference of the grammar
which is used as Appendix I of this document.
.sh 3 Inputs
PRSTAB requires two input files:
.np
Grammar Definition File.
This file defines the grammar used by \*(SC.
Reference [6] describes the format of this file;
a short example is given here:
.(b
.CS
<entry statement> ::= <entry id> |
<entry id> ( ) |
<entry id> ( <id list> )
<entry id> ::= ENTRY <ident>
.CE
.)b
If the semantic actions (see section 5) are divided into
multiple C source files, this file contains a
.cw .BR
directive
at the points in the grammar where the breaks occur.
.np
Token Definition File.
This file contains one line for each terminal symbol of
the grammar (token).
Each line consists of the token name as it appears in the
grammar definition file, followed by the name which will be used
for the C constant symbol representing the token id number
within \*(SC.
These names must differ in the first 8 characters, and
begin with
.cw TK_ .
Example:
.(b
.CS
<ident> TK_IDENT
CALL TK_CALL
+ TK_PLUS
.CE
.)b
.sh 3 Outputs
There are six output files:
.np
Parse Table Definition File.
This file contains the C data definitions and initialization
code for the Parse Tables.
It is included directly into the Parser source module.
.np
Token Id Number Definition File.
This file contains a series of
.cw #define
directives for the token
id numbers.
The symbol names used are those specified in the Token Definition File.
.np
Semantic Actions Definition File.
This file contains a series of
.cw #define
directives for the
semantic action case labels (see section 5).
There is one definition for each production of the grammar.
The names for these symbols are constructed from the
name of the symbol on the left hand side of each production,
using an algorithm described in [6].
.np
Non-terminal Number Definition File.
This file contains a series of
.cw #define
directives for the grammar's non-terminal symbols. The names for these
symbols are of the form
.cw NT_<name>
where name is constructed from the symbol's name in the grammar in an
obvious fashion.
.np
Token Name Definition File.
This file contains a statically initialized array indexed by terminal and
non-terminal number giving the name (exactly as in the grammar) of each
terminal and non-terminal symbol. It is used for error messages and
debugging.
.np
Grammar Listing and Cross Reference File.
Lists grammar with alphabetic cross reference of grammar symbols
at end. Used to create Appendix I of this document.
|