1 |
/* |
2 |
BISON Parser to recognise name definition records. |
3 |
A name definiton record ( or def ) has form |
4 |
|
5 |
variable(s) :: decription text |
6 |
|
7 |
It is only recognised when in the comment section of a |
8 |
code. All lines of the form above are treat as def |
9 |
records. All other comment or executable statements are |
10 |
ignored. |
11 |
|
12 |
*/ |
13 |
%{ |
14 |
#include "stdio.h" |
15 |
#include "string.h" |
16 |
int Lno; int Cno; |
17 |
int i; |
18 |
#include "GLOBALS.h" |
19 |
%} |
20 |
|
21 |
|
22 |
%union { |
23 |
int LineNo; |
24 |
char *symbolName; |
25 |
} |
26 |
|
27 |
%token <LineNo> COMMENT_START |
28 |
%token <LineNo> DESCRIP_DELIM |
29 |
%token <LineNo> COMMA |
30 |
%token <LineNo> SPACE |
31 |
%token <LineNo> PUNCT |
32 |
%token <LineNo> EOL |
33 |
%token <symbolName> NAME |
34 |
%token <symbolName> DESCRIP_TEXT |
35 |
|
36 |
%% |
37 |
|
38 |
input: /* empty */ |
39 |
| input comment_statement |
40 |
; |
41 |
|
42 |
/* |
43 |
Definition statements |
44 |
*/ |
45 |
comment_statement: def_with_terminal_names |
46 |
| def_with_to_be_continued_names |
47 |
| def_with_no_names |
48 |
| other_comment |
49 |
; |
50 |
|
51 |
def_with_terminal_names: COMMENT_START general_text descript { /* Cases that are possible : Actions |
52 |
1. Names open && descrip open : add names, add descrip, close names |
53 |
2. Names closed && descrip open : close descrip, close previous, |
54 |
log previous, start new, open descrip, |
55 |
add descrip, open names, add names, |
56 |
close names. |
57 |
3. Names closed && descrip closed: start new, open descrip, |
58 |
add descrip, open names, add names, |
59 |
close names. |
60 |
*/ |
61 |
/* fprintf(stdout,"def_with_terminal_names: line %d\n",Lno); */ |
62 |
/* Get the current line names */ |
63 |
/* Get the current line description text */ |
64 |
def_with_terminal_names(); |
65 |
/* Free names and descript */ |
66 |
for(i=namecount-1;i>=0;--i) { |
67 |
free(namearr[i]); |
68 |
} |
69 |
namecount=0; |
70 |
for(i=descriptcount-1;i>=0;--i) { |
71 |
free(descriparr[i]); |
72 |
} |
73 |
descriptcount=0; |
74 |
} |
75 |
; |
76 |
|
77 |
def_with_to_be_continued_names: COMMENT_START general_text COMMA descript { |
78 |
/* |
79 |
Cases that are possible : Actions |
80 |
1. Names open && descrip open : add names, add descrip |
81 |
2. Names closed && descrip open : close descrip, close previous, |
82 |
log previous, start new, open descrip, |
83 |
add descrip, open names, add names. |
84 |
3. Names closed && descrip closed: start new, open descrip, |
85 |
add descrip, open names, add names. |
86 |
*/ |
87 |
/* fprintf(stdout,"def_with_to_be_continued_names: line %d\n",Lno); */ |
88 |
/* Get the current line names */ |
89 |
/* Get the current line description text */ |
90 |
def_with_to_be_continued_names(); |
91 |
/* Free names and descript */ |
92 |
for(i=namecount-1;i>=0;--i) { |
93 |
free(namearr[i]); |
94 |
} |
95 |
namecount=0; |
96 |
for(i=descriptcount-1;i>=0;--i) { |
97 |
free(descriparr[i]); |
98 |
} |
99 |
descriptcount=0; |
100 |
} |
101 |
; |
102 |
|
103 |
def_with_no_names: COMMENT_START punct_only_text descript {/* |
104 |
Cases that are possible : Actions |
105 |
1. Names open && descrip open : add descrip |
106 |
2. Names closed && descrip open : add descrip |
107 |
3. Names closed && descrip closed: syntax error |
108 |
*/ |
109 |
/* fprintf(stdout,"def_with_no_names: line %d\n",Lno); */ |
110 |
/* Get the current line description text */ |
111 |
def_with_no_names(); |
112 |
/* Free names and descript */ |
113 |
for(i=namecount-1;i>=0;--i) { |
114 |
free(namearr[i]); |
115 |
} |
116 |
namecount=0; |
117 |
for(i=descriptcount-1;i>=0;--i) { |
118 |
free(descriparr[i]); |
119 |
} |
120 |
descriptcount=0; |
121 |
} |
122 |
| COMMENT_START descript {/* fprintf(stdout,"def_with_no_names: line %d\n",Lno); */ |
123 |
/* Get the current line description text */ |
124 |
def_with_no_names(); |
125 |
/* Free names and descript */ |
126 |
for(i=namecount-1;i>=0;--i) { |
127 |
free(namearr[i]); |
128 |
} |
129 |
namecount=0; |
130 |
for(i=descriptcount-1;i>=0;--i) { |
131 |
free(descriparr[i]); |
132 |
} |
133 |
descriptcount=0; |
134 |
} |
135 |
; |
136 |
|
137 |
other_comment: COMMENT_START general_text EOL { /* Free names and descript */ |
138 |
for(i=namecount-1;i>=0;--i) { |
139 |
free(namearr[i]); |
140 |
} |
141 |
namecount=0; |
142 |
for(i=descriptcount-1;i>=0;--i) { |
143 |
free(descriparr[i]); |
144 |
} |
145 |
descriptcount=0; |
146 |
} |
147 |
| COMMENT_START EOL { /* Free names and descript */ |
148 |
for(i=namecount-1;i>=0;--i) { |
149 |
free(namearr[i]); |
150 |
} |
151 |
namecount=0; |
152 |
for(i=descriptcount-1;i>=0;--i) { |
153 |
free(descriparr[i]); |
154 |
} |
155 |
descriptcount=0; |
156 |
} |
157 |
; |
158 |
|
159 |
/* |
160 |
One record of the name_list block |
161 |
*/ |
162 |
general_text: general_text general_text_element |
163 |
| general_text_element {} |
164 |
; |
165 |
|
166 |
general_text_element: NAME {} |
167 |
| punct_only_text {} |
168 |
; |
169 |
|
170 |
punct_only_text : punct_only_text punct_text_element |
171 |
| punct_text_element {} |
172 |
; |
173 |
|
174 |
punct_text_element: COMMA {} |
175 |
| non_comma_punct_text {} |
176 |
; |
177 |
|
178 |
non_comma_punct_text: space_list {} |
179 |
| PUNCT {} |
180 |
; |
181 |
|
182 |
space_list: space_list space_element |
183 |
| space_element |
184 |
; |
185 |
|
186 |
space_element: SPACE {} |
187 |
; |
188 |
|
189 |
descript: DESCRIP_DELIM general_text EOL { /* Get the description text */ } |
190 |
| DESCRIP_DELIM EOL {} |
191 |
; |
192 |
|
193 |
%% |
194 |
|
195 |
/* Buffers for storing name blocks and definition blocks */ |
196 |
#define MAX_NLIST 1000 |
197 |
char *nlist[MAX_NLIST]; |
198 |
int nlc=0; |
199 |
|
200 |
#define MAX_DLIST 10000 |
201 |
char *dlist[MAX_DLIST]; |
202 |
int dlc=0; |
203 |
|
204 |
Getcommerror(s) |
205 |
char *s; |
206 |
{ |
207 |
printf("Error: %s. Line no. %d\n",s,Lno); |
208 |
} |
209 |
|
210 |
def_with_terminal_names() |
211 |
/* |
212 |
== Take action when a "def_with_terminal_names" pattern is recognised == |
213 |
|
214 |
Cases that are possible : Actions |
215 |
================================:===================================== |
216 |
1. Names open && descrip open : add names, add descrip, close names |
217 |
This is the last record of a : |
218 |
name block. It will have been : |
219 |
preceeded by one or more name : |
220 |
block records with continue : |
221 |
markers. : |
222 |
: |
223 |
2. Names closed && descrip open : close descrip, close previous, |
224 |
This is the start of a new : log previous, start new, open descrip, |
225 |
name block. This name block : add descrip, open names, add names, |
226 |
only has one name record. : close names. |
227 |
Need to write out the : |
228 |
preceeding name and descript : |
229 |
blocks. : |
230 |
: |
231 |
3. Names closed && descrip closed : start new, open descrip, |
232 |
This is right at start of : add descrip, open names, add names, |
233 |
execution and this is the : close names. |
234 |
first name block record. : |
235 |
*/ |
236 |
{ |
237 |
int i,j,k;/* Loop counters */ |
238 |
int sl; /* String length */ |
239 |
|
240 |
if ( name_open == 1 && descript_open == 1 ) { |
241 |
/* Append to existing block and close names for that block */ |
242 |
for (i=0;i<namecount;++i) { |
243 |
nlist[i+nlc] = strdup(namearr[i]); |
244 |
} |
245 |
nlc=nlc+namecount; |
246 |
for (i=0;i<descriptcount;++i) { |
247 |
dlist[i+dlc] = strdup(descriparr[i]); |
248 |
} |
249 |
dlc=dlc+descriptcount; |
250 |
/* Close names */ |
251 |
name_open = 0; |
252 |
} |
253 |
|
254 |
if ( name_open == 0 && descript_open == 1 ) { |
255 |
/* Flush previous name block and descrip block and start new blocks. */ |
256 |
/* New name block is closed after this name record is added. */ |
257 |
for (j=0;j<nlc;++j) { |
258 |
fprintf(stdout,"%-50s",nlist[j]); |
259 |
fprintf(stdout," {TEXT=\""); |
260 |
for (i=0;i<dlc;++i) { |
261 |
/* Substitue " with a space for now because VarDic parser gets confused */ |
262 |
sl=strlen(dlist[i]); |
263 |
for (k=0;k<sl;++k) { |
264 |
if ( dlist[i][k] == '"' ) { |
265 |
dlist[i][k] = ' '; |
266 |
} |
267 |
} |
268 |
fprintf(stdout,"%s",dlist[i]); |
269 |
} |
270 |
fprintf(stdout,"\";}\n"); |
271 |
} |
272 |
|
273 |
/* Free up block strings */ |
274 |
for (i=nlc-1;i>=0;--i){ free(nlist[i]); } ; nlc = 0; |
275 |
for (i=dlc-1;i>=0;--i){ free(dlist[i]); } ; dlc = 0; |
276 |
|
277 |
/* Start new name block and descrip block */ |
278 |
name_open=0; descript_open=1; |
279 |
nlc=0; dlc=0; |
280 |
for (i=0;i<namecount;++i) { |
281 |
nlist[i] = strdup(namearr[i]); |
282 |
} |
283 |
nlc=nlc+namecount; |
284 |
for (i=0;i<descriptcount;++i) { |
285 |
dlist[i] = strdup(descriparr[i]); |
286 |
} |
287 |
dlc=dlc+descriptcount; |
288 |
} |
289 |
|
290 |
if ( name_open == 0 && descript_open == 0 ) { |
291 |
/* Start new name block and descrip block. */ |
292 |
/* New name block is closed after this name record is added. */ |
293 |
name_open=0; descript_open=1; |
294 |
nlc=0; dlc=0; |
295 |
for (i=0;i<namecount;++i) { |
296 |
nlist[i] = strdup(namearr[i]); |
297 |
} |
298 |
nlc=nlc+namecount; |
299 |
for (i=0;i<descriptcount;++i) { |
300 |
dlist[i] = strdup(descriparr[i]); |
301 |
} |
302 |
dlc=dlc+descriptcount; |
303 |
} |
304 |
} |
305 |
def_with_to_be_continued_names() |
306 |
/* |
307 |
Cases that are possible : Actions |
308 |
=================================:====================================== |
309 |
1. Names open && descrip open : add names, add descrip |
310 |
This is a continuation of an : leave names open. |
311 |
already open name and : |
312 |
description block. : |
313 |
2. Names closed && descrip open : close descrip, close previous, |
314 |
This is the start of a new : log previous, start new, open descrip, |
315 |
name and description block. : add descrip, open names, add names. |
316 |
: leave names open. |
317 |
: |
318 |
3. Names closed && descrip closed: start new, open descrip, |
319 |
Beginning of parsing. First : add descrip, open names, add names. |
320 |
block encountered has cont. : leave names open. |
321 |
style name record. : |
322 |
*/ |
323 |
{ |
324 |
int i,j,k;/* Loop counters */ |
325 |
int sl; /* String length */ |
326 |
|
327 |
|
328 |
if ( name_open == 1 && descript_open == 1 ) { |
329 |
/* Append to existing block. Leave block open */ |
330 |
for (i=0;i<namecount;++i) { |
331 |
nlist[i+nlc] = strdup(namearr[i]); |
332 |
} |
333 |
nlc=nlc+namecount; |
334 |
for (i=0;i<descriptcount;++i) { |
335 |
dlist[i+dlc] = strdup(descriparr[i]); |
336 |
} |
337 |
dlc=dlc+descriptcount; |
338 |
} |
339 |
|
340 |
if ( name_open == 0 && descript_open == 1 ) { |
341 |
/* Flush previous name block and descrip block and start new blocks. */ |
342 |
/* New name block left open. */ |
343 |
for (j=0;j<nlc;++j) { |
344 |
fprintf(stdout,"%-50s",nlist[j]); |
345 |
fprintf(stdout," {TEXT=\""); |
346 |
for (i=0;i<dlc;++i) { |
347 |
/* Substitue " with a space for now because VarDic parser gets confused */ |
348 |
sl=strlen(dlist[i]); |
349 |
for (k=0;k<sl;++k) { |
350 |
if ( dlist[i][k] == '"' ) { |
351 |
dlist[i][k] = ' '; |
352 |
} |
353 |
} |
354 |
fprintf(stdout,"%s",dlist[i]); |
355 |
} |
356 |
fprintf(stdout,"\";}\n"); |
357 |
} |
358 |
|
359 |
/* Free up block strings */ |
360 |
for (i=nlc-1;i>=0;--i){ free(nlist[i]); } ; nlc = 0; |
361 |
for (i=dlc-1;i>=0;--i){ free(dlist[i]); } ; dlc = 0; |
362 |
|
363 |
/* Start new name block and descrip block */ |
364 |
/* Leave both open. */ |
365 |
name_open=1; descript_open=1; |
366 |
nlc=0; dlc=0; |
367 |
for (i=0;i<namecount;++i) { |
368 |
nlist[i] = strdup(namearr[i]); |
369 |
} |
370 |
nlc=nlc+namecount; |
371 |
for (i=0;i<descriptcount;++i) { |
372 |
dlist[i] = strdup(descriparr[i]); |
373 |
} |
374 |
dlc=dlc+descriptcount; |
375 |
} |
376 |
|
377 |
if ( name_open == 0 && descript_open == 0 ) { |
378 |
/* Start new name block and descrip block. */ |
379 |
/* Leave both open. */ |
380 |
name_open=1; descript_open=1; |
381 |
nlc=0; dlc=0; |
382 |
for (i=0;i<namecount;++i) { |
383 |
nlist[i] = strdup(namearr[i]); |
384 |
} |
385 |
nlc=nlc+namecount; |
386 |
for (i=0;i<descriptcount;++i) { |
387 |
dlist[i] = strdup(descriparr[i]); |
388 |
} |
389 |
dlc=dlc+descriptcount; |
390 |
} |
391 |
|
392 |
} |
393 |
|
394 |
def_with_no_names() |
395 |
/* |
396 |
Cases that are possible : Actions |
397 |
==============================:============== |
398 |
1. Names open && descrip open : add descrip |
399 |
: |
400 |
2. Names closed && descrip open : add descrip |
401 |
: |
402 |
3. Names closed && descrip closed: syntax error |
403 |
|
404 |
*/ |
405 |
{ |
406 |
if ( descript_open == 1 ) { |
407 |
/* Append to existing block */ |
408 |
for (i=0;i<descriptcount;++i) { |
409 |
dlist[i+dlc] = strdup(descriparr[i]); |
410 |
} |
411 |
dlc=dlc+descriptcount; |
412 |
} |
413 |
|
414 |
if ( descript_open == 0 ) { |
415 |
/* Description but no names */ |
416 |
/* Ignore with warning */ |
417 |
fprintf(stderr,"WARNING: Line no. %d looks like a description, but no name block is active.\n",Lno-1); |
418 |
} |
419 |
|
420 |
} |