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
|
# Copyright(c) 1986 Association of Universities for Research in Astronomy Inc.
# Parser for yacc output, translated to the IRAF SPP language. The contents
# of this file form the bulk of the source of the parser produced by Yacc.
# Yacc recognizes several macros in the yaccpar input source and replaces
# them as follows:
# A user suppled "global" definitions and declarations
# B parser tables
# C user supplied actions (reductions)
# The remainder of the yaccpar code is not changed.
define yystack_ 10 # statement labels for gotos
define yynewstate_ 20
define yydefault_ 30
define yyerrlab_ 40
define yyabort_ 50
define YYFLAG (-1000) # defs used in user actions
define YYERROR goto yyerrlab_
define YYACCEPT return (OK)
define YYABORT return (ERR)
# YYPARSE -- Parse the input stream, returning OK if the source is
# syntactically acceptable (i.e., if compilation is successful),
# otherwise ERR. The parameters YYMAXDEPTH and YYOPLEN must be
# supplied by the caller in the %{ ... %} section of the Yacc source.
# The token value stack is a dynamically allocated array of operand
# structures, with the length and makeup of the operand structure being
# application dependent.
int procedure yyparse (fd, yydebug, yylex)
int fd # stream to be parsed
bool yydebug # print debugging information?
int yylex() # user-supplied lexical input function
extern yylex()
short yys[YYMAXDEPTH] # parser stack -- stacks tokens
pointer yyv # pointer to token value stack
pointer yyval # value returned by action
pointer yylval # value of token
int yyps # token stack pointer
pointer yypv # value stack pointer
int yychar # current input token number
int yyerrflag # error recovery flag
int yynerrs # number of errors
short yyj, yym # internal variables
pointer yysp, yypvt
short yystate, yyn
int yyxi, i
errchk salloc, yylex
$A # User declarations go here.
$B # YACC parser tables defining the finite automaton go here.
begin
call smark (yysp)
call salloc (yyv, (YYMAXDEPTH+2) * YYOPLEN, TY_STRUCT)
# Initialization. The first element of the dynamically allocated
# token value stack (yyv) is used for yyval, the second for yylval,
# and the actual stack starts with the third element.
yystate = 0
yychar = -1
yynerrs = 0
yyerrflag = 0
yyps = 0
yyval = yyv
yylval = yyv + YYOPLEN
yypv = yylval
yystack_
# SHIFT -- Put a state and value onto the stack. The token and
# value stacks are logically the same stack, implemented as two
# separate arrays.
if (yydebug) {
call printf ("state %d, char 0%o\n")
call pargs (yystate)
call pargi (yychar)
}
yyps = yyps + 1
yypv = yypv + YYOPLEN
if (yyps > YYMAXDEPTH) {
call sfree (yysp)
call eprintf ("yacc stack overflow\n")
return (ERR)
}
yys[yyps] = yystate
YYMOVE (yyval, yypv)
yynewstate_
# Process the new state.
yyn = yypact[yystate+1]
if (yyn <= YYFLAG)
goto yydefault_ # simple state
# The variable "yychar" is the lookahead token.
if (yychar < 0) {
yychar = yylex (fd, yylval)
if (yychar < 0)
yychar = 0
}
yyn = yyn + yychar
if (yyn < 0 || yyn >= YYLAST)
goto yydefault_
yyn = yyact[yyn+1]
if (yychk[yyn+1] == yychar) { # valid shift
yychar = -1
YYMOVE (yylval, yyval)
yystate = yyn
if (yyerrflag > 0)
yyerrflag = yyerrflag - 1
goto yystack_
}
yydefault_
# Default state action.
yyn = yydef[yystate+1]
if (yyn == -2) {
if (yychar < 0) {
yychar = yylex (fd, yylval)
if (yychar < 0)
yychar = 0
}
# Look through exception table.
yyxi = 1
while ((yyexca[yyxi] != (-1)) || (yyexca[yyxi+1] != yystate))
yyxi = yyxi + 2
for (yyxi=yyxi+2; yyexca[yyxi] >= 0; yyxi=yyxi+2) {
if (yyexca[yyxi] == yychar)
break
}
yyn = yyexca[yyxi+1]
if (yyn < 0) {
call sfree (yysp)
return (OK) # ACCEPT -- all done
}
}
# SYNTAX ERROR -- resume parsing if possible.
if (yyn == 0) {
switch (yyerrflag) {
case 0, 1, 2:
if (yyerrflag == 0) { # brand new error
call eprintf ("syntax error\n")
yyerrlab_
yynerrs = yynerrs + 1
# fall through...
}
# case 1:
# case 2: incompletely recovered error ... try again
yyerrflag = 3
# Find a state where "error" is a legal shift action.
while (yyps >= 1) {
yyn = yypact[yys[yyps]+1] + YYERRCODE
if ((yyn >= 0) && (yyn < YYLAST) &&
(yychk[yyact[yyn+1]+1] == YYERRCODE)) {
# Simulate a shift of "error".
yystate = yyact[yyn+1]
goto yystack_
}
yyn = yypact[yys[yyps]+1]
# The current yyps has no shift on "error", pop stack.
if (yydebug) {
call printf ("error recovery pops state %d, ")
call pargs (yys[yyps])
call printf ("uncovers %d\n")
call pargs (yys[yyps-1])
}
yyps = yyps - 1
yypv = yypv - YYOPLEN
}
# ABORT -- There is no state on the stack with an error shift.
yyabort_
call sfree (yysp)
return (ERR)
case 3: # No shift yet; clobber input char.
if (yydebug) {
call printf ("error recovery discards char %d\n")
call pargi (yychar)
}
if (yychar == 0)
goto yyabort_ # don't discard EOF, quit
yychar = -1
goto yynewstate_ # try again in the same state
}
}
# REDUCE -- Reduction by production yyn.
if (yydebug) {
call printf ("reduce %d\n")
call pargs (yyn)
}
yyps = yyps - yyr2[yyn+1]
yypvt = yypv
yypv = yypv - yyr2[yyn+1] * YYOPLEN
YYMOVE (yypv + YYOPLEN, yyval)
yym = yyn
# Consult goto table to find next state.
yyn = yyr1[yyn+1]
yyj = yypgo[yyn+1] + yys[yyps] + 1
if (yyj >= YYLAST)
yystate = yyact[yypgo[yyn+1]+1]
else {
yystate = yyact[yyj+1]
if (yychk[yystate+1] != -yyn)
yystate = yyact[yypgo[yyn+1]+1]
}
# Perform action associated with the grammar rule, if any.
switch (yym) {
$C # YACC replaces this line by the user supplied actions.
}
goto yystack_ # stack new state and value
end
|