Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / mbkspf / spf.y
1 /****************************************************************************/
2 /* */
3 /* Chaine de CAO & VLSI AVERTEC */
4 /* */
5 /* Produit : SPF Version 1.00 */
6 /* Fichier : spf.yac */
7 /* */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
10 /* */
11 /* Auteur(s) : Gilles Augustins */
12 /* */
13 /****************************************************************************/
14
15 %{
16 #include AVT_H
17 #include SPF_H
18 #include "spf_actions.h"
19 #include "spf_annot.h"
20 #include "spf_util.h"
21
22 static double spfgetval(char *txt, int line, char *err, int capa);
23
24 /*****************************************************************************
25 * private *
26 *****************************************************************************/
27
28 /*****************************************************************************
29 * function declarations *
30 *****************************************************************************/
31
32 int yyerror();
33 int yylex();
34 static char *circuitname;
35
36 union
37 {
38 long int dval;
39 double ival;
40 } toto;
41 %}
42
43 %union
44 {
45 char text[1024] ;
46 double real ;
47 struct
48 {
49 int integer ;
50 char text[512];
51 } I;
52 struct chain *ch_l ;
53 } ;
54
55 /* general */
56 %token _LEFTPAR _ENDOFSPICELINE
57 %token _RIGHTPAR
58 %token <text> _TEXT
59 %token <text> _QSTRING
60 %token <I> _INTEGER
61 %token _NVER
62
63 /* DSPF statements */
64 %token _DESIGN
65 %token _DATE
66 %token _VENDOR
67 %token _PROGRAM
68 %token _VERSION
69 %token _DSPF
70 %token <text> _DIVIDER
71 %token <text> _DELIMITER
72 %token <text> _BUSBIT
73 %token _GROUND_NET
74 %token _NET
75 %token _PIN
76 %token _SUB
77 %token _INST
78 /* native SPICE statements */
79 %token _SUBCKT
80 %token _END
81 %token _ENDS
82 %token <text> _RESISTANCE
83 %token <text> _CAPACITANCE
84 %token <text> _SUBCKTCALL
85
86 %start dspf_file
87
88 %type <text> qstring
89 %type <text> chipname
90 %type <text> nodename
91 %type <text> pinname
92 %type <text> instname
93 %type <text> instpinname
94 %type <text> subnodename
95 %type <real> netcap
96 %type <real> pincap
97 %type <real> cvalue
98 %type <real> rvalue
99 %type <ch_l> extnodes_list
100
101 %%
102
103
104 dspf_file : spf_version header_elements body end { } ;
105
106 .endofspiceline. : _ENDOFSPICELINE
107 ;
108
109 header_elements : design_name header_elements
110 | date vendor header_elements
111 | program_name header_elements
112 | program_version header_elements
113 | hierarchy_divider header_elements
114 | name_delimiter header_elements
115 | busbit header_elements
116 |
117 ;
118
119 spf_version : _DSPF _TEXT .endofspiceline.
120 | error _ENDOFSPICELINE
121 ;
122
123 design_name : _DESIGN qstring .endofspiceline.
124 {
125 circuitname=spf_deqstring($2);
126 }
127 | error _ENDOFSPICELINE
128 ;
129
130 date : _DATE qstring .endofspiceline.
131 | error _ENDOFSPICELINE
132 ;
133
134 vendor : _VENDOR qstring .endofspiceline.
135 | error _ENDOFSPICELINE
136 ;
137
138 program_name : _PROGRAM qstring .endofspiceline.
139 | error _ENDOFSPICELINE
140 ;
141
142 program_version : _VERSION qstring .endofspiceline.
143 | error _ENDOFSPICELINE
144 ;
145
146 hierarchy_divider : _DIVIDER .endofspiceline.
147 {
148 char *s;
149 s=strchr($1, ' ');
150 if (s!=NULL) while (*s==' ' || *s=='\t') s++;
151 if (s==NULL)
152 {
153 avt_errmsg(SPF_ERRMSG, "005", AVT_WARNING, spf_Line-1);
154 spf_setDivider('/');
155 }
156 else
157 spf_setDivider(*s);
158 }
159 | error _ENDOFSPICELINE
160 ;
161
162 name_delimiter : _DELIMITER .endofspiceline.
163 {
164 char *s;
165 s=strchr($1, ' ');
166 if (s!=NULL) while (*s==' ' || *s=='\t') s++;
167 if (s==NULL)
168 {
169 avt_errmsg(SPF_ERRMSG, "006", AVT_WARNING, spf_Line-1);
170 spf_setDelimiter(':');
171 }
172 else
173 spf_setDelimiter(*s);
174 }
175 | error _ENDOFSPICELINE
176 ;
177
178 busbit : _BUSBIT .endofspiceline.
179 {
180 char temp[1024], temp1[1024];
181 sscanf($1,"%s%s", temp, temp1);
182 if (strlen(temp1)==2)
183 spf_setBUSDelimiters(temp1[0], temp1[1]);
184 else
185 if ((strlen(temp1)==4) && (temp1[0] == '"') && (temp1[3] == '"'))
186 spf_setBUSDelimiters(temp1[1], temp1[2]);
187 else
188 avt_errmsg(SPF_ERRMSG, "007", AVT_WARNING, spf_Line-1);
189 }
190 | error _ENDOFSPICELINE
191 ;
192
193 qstring : empty { strcpy($$, "") ; }
194 | _QSTRING { strcpy($$ ,$1) ; }
195 | _TEXT { strcpy($$ ,$1) ; } ;
196
197 body : subCircuit
198 | gnet_def_list
199 {
200 char *name = circuitname;
201 if (name==NULL)
202 {
203 avt_errmsg(SPF_ERRMSG, "008", AVT_WARNING);
204 YYACCEPT;
205 }
206 if (spf_Lofig!=NULL) fprintf(stdout, "LOADING FILE %s.%s\n", name, IN_PARASITICS);
207 if (spf_Lofig==NULL || strcmp(name, spf_Lofig->NAME))
208 {
209 if ((spf_Lofig = getloadedlofig(name))==NULL)
210 {
211 avt_errmsg(SPF_ERRMSG, "009", AVT_WARNING, name);
212 YYACCEPT;
213 }
214 }
215 spf_prepare_lofig(spf_Lofig);
216 }
217 net_block_list
218 ;
219
220 subCircuit : subckt_def gnet_def_list net_block_list inst_block_list end_subckt
221 ;
222
223 end : empty
224 | _END .endofspiceline.
225 ;
226
227 subckt_def : _SUBCKT _TEXT extnodes_list .endofspiceline.
228 {
229 char *name = namealloc($2);
230
231 if (spf_Lofig!=NULL) fprintf(stdout, "LOADING FILE %s.%s\n", name, IN_PARASITICS);
232 if (spf_Lofig==NULL || strcmp(name, spf_Lofig->NAME))
233 {
234 if ((spf_Lofig = getloadedlofig(name))==NULL)
235 {
236 avt_errmsg(SPF_ERRMSG, "009", AVT_WARNING, name);
237 YYACCEPT;
238 }
239 }
240 spf_prepare_lofig(spf_Lofig);
241 #ifdef SPF_DEBUG
242 printf("Circuit : %s\n",$2) ;
243 #endif
244 }
245 | error _ENDOFSPICELINE
246 ;
247
248 extnodes_list : empty { $$ = NULL ; }
249 | extnodes_list nodename
250 {
251 /*$$ = addchain($1, $2)*/
252 } ;
253
254 gnet_def_list : empty
255 | gnet_def_list gnet_def
256 ;
257
258 gnet_def : _GROUND_NET nodename .endofspiceline.
259 {
260 spf_SetGroundSignal($2);
261 }
262 | error _ENDOFSPICELINE
263 ;
264
265 net_block_list : empty
266 | net_block_list net_block
267 ;
268
269 net_block : net_def node_def_list res_capa_def_list
270 ;
271
272 node_def_list : empty
273 | node_def_list node_def
274 ;
275
276 res_capa_def_list : empty
277 | res_capa_def_list capacitor_def
278 | res_capa_def_list resistor_def
279 ;
280
281 inst_block_list : empty
282 | inst_block_list inst_block
283 ;
284
285 inst_block : _SUBCKTCALL extnodes_list .endofspiceline. /* native SPICE */
286 {}
287 ;
288
289 end_subckt : _ENDS chipname .endofspiceline.
290 {
291 spf_ResetLocalHTable();
292 }
293 | _ENDS .endofspiceline.
294 {
295 spf_ResetLocalHTable();
296 }
297 ;
298
299 net_def : _NET nodename netcap .endofspiceline.
300 {
301 spf_NewNet($2,$3);
302 }
303 | error _ENDOFSPICELINE
304 ;
305
306 node_def : pin_def
307 | instpin_def
308 | subnode_def
309 ;
310
311 pin_def : _PIN pin_element .endofspiceline.
312 | error _ENDOFSPICELINE
313 ;
314
315 pin_element : _LEFTPAR pinname pintype pincap coord_list _RIGHTPAR
316 {
317 spf_AddConnector($2);
318 }
319 ;
320
321 coord_list : empty
322 | coord_list coord
323 ;
324
325 instpin_def : _INST instpin_element .endofspiceline.
326 | error _ENDOFSPICELINE
327 ;
328
329 instpin_element : _LEFTPAR instpinname instname pinname pintype pincap coord_list _RIGHTPAR
330 {
331 spf_AddInstanceConnector($2,$3,$4);
332 }
333 ;
334
335 subnode_def : _SUB subnode_element .endofspiceline.
336 ;
337
338
339 subnode_element : _LEFTPAR subnodename coord_list _RIGHTPAR
340 {
341 spf_AddSubNode($2);
342 }
343 ;
344
345 capacitor_def : _CAPACITANCE nodename nodename cvalue .endofspiceline.
346 {
347 spf_AddCapacitance($2,$3,$4);
348 }
349 | error _ENDOFSPICELINE
350 ;
351
352 resistor_def : _RESISTANCE nodename nodename rvalue .endofspiceline.
353 {
354 spf_AddResistor($2,$3,$4);
355 }
356 | error _ENDOFSPICELINE
357 ;
358
359 netcap : cvalue { $$ = $1 ; } ;
360
361 pintype : _TEXT
362 {
363 if ($1[1]!='\0' || strchr("IiOoSsBbJjXx", $1[0])==NULL)
364 avt_errmsg(SPF_ERRMSG, "001", AVT_WARNING, $1, spf_Line);
365 }
366 ;
367
368 pincap : cvalue { $$ = $1 ; }
369 | cvalue _LEFTPAR rcpair_list _RIGHTPAR
370 {
371 $$ = $1 ; /* Elmore ? */
372 }
373 ;
374
375 rcpair_list : rcpair
376 | rcpair_list rcpair
377 ;
378
379 rcpair : rvalue cvalue
380 {};
381
382 coord : xcoord ycoord
383 ;
384
385 xcoord : _TEXT
386 {};
387
388 ycoord : _TEXT
389 {};
390
391 cvalue : _TEXT
392 {
393 $$=spfgetval($1, spf_Line, "010", 1)*1e12;
394 }
395 ;
396
397 rvalue : _TEXT
398 {
399 $$=spfgetval($1, spf_Line, "011", 0);
400 }
401 ;
402
403 nodename : _TEXT
404 {
405 strcpy($$, $1);
406 }
407 ;
408
409 chipname : _TEXT { strcpy($$, $1) ; }
410 ;
411
412 pinname : _TEXT { strcpy($$, $1) ; }
413 ;
414
415 instname : _TEXT { strcpy($$, $1) ; }
416 ;
417
418 instpinname : _TEXT { strcpy($$, $1) ; }
419 ;
420
421 subnodename : _TEXT { strcpy($$, $1) ; }
422 ;
423
424 empty : {}
425 ;
426 %%
427
428 extern char *spftext;
429
430 int yyerror()
431 {
432 char *tok=spftext;
433 if (*tok=='\n') tok="<CR>";
434 avt_errmsg(SPF_ERRMSG, "002", AVT_WARNING, spf_Line, tok);
435 return 0;
436 }
437
438 static double spfgetval(char *txt, int line, char *err, int capa)
439 {
440 char *endptr;
441 double dval, factor;
442 int l;
443 dval=strtod(txt, &endptr);
444 if (*endptr!='\0')
445 {
446 if ((l=strlen(endptr))==1 || (capa && l==2 && tolower(endptr[1])=='f'))
447 {
448 switch(tolower(endptr[0]))
449 {
450 case 'f': factor = spf_femto(); break;
451 case 'p': factor = spf_pico(); break;
452 case 'n': factor = spf_nano(); break;
453 case 'u': factor = spf_micro(); break;
454 case 'm': factor = spf_milli(); break;
455 case 'k': factor = spf_kilo(); break;
456 default:
457 avt_errmsg(SPF_ERRMSG, err, AVT_WARNING, txt, line);
458 factor = spf_pico();
459 }
460 }
461 else
462 {
463 avt_errmsg(SPF_ERRMSG, err, AVT_WARNING, txt, line);
464 factor = spf_pico();
465 }
466 }
467 else
468 {
469 factor=1;
470 }
471 return dval*factor;
472 }
473