NAPA Compiler V4.50
Author: Yves Leduc, yves.leduc.be@gmail.com
Loading...
Searching...
No Matches
C:/Simulate/Napados/Source/sx.c
Go to the documentation of this file.
1/* ** SYNTAX UTILITIES ********************************************************************************************************** */
2
3#undef EXTERN
4#define EXTERN extern
5
6#include "./napa.h"
7#include "./proto.h"
8
9
10/* *** In this file: ************************************************************************************************************ */
11
12/* long check_syntax(long to_be, long no_sign, const char *sgn, char *tok, long id, const char *txt) */
13/* long something_else(const char *tok, long id) */
14
15/* void authorize_option(long num, long id) */
16/* void C_syntax_checker(char *str, unsigned long *mlin, unsigned long *mfil) */
17/* void sanity_check(char *s, const unsigned long *mlin, const unsigned long *mfil) */
18/* void syntax_command_line(void) */
19/* void syntax_directives(void) */
20/* void syntax_fs(void) */
21/* void syntax_nodes(void) */
22/* void syntax_posts(void) */
23/* void syntax_records(void) */
24/* void syntax_segment_value(void) */
25/* void syntax_terminate(void) */
26/* void syntax_updates(void) */
27/* void syntax_variables(void) */
28
29
30/* ****************************************************************************************************************************** */
31/* The goal of "syntax_nodes" is to check the syntax of the nodes by inspection. */
32/* Mandatory parameters, their nature (node, variable or constant) and their number are verified here. */
33/* The presence of a sign is also verified. */
34
35/* This process is done after node redefinition, before determination of the node type. */
36/* It takes one pass through the list of nodes. */
37
38/* Types (analog, digital or string) and values of inputs are not verified here. */
39
40/* The goal of "syntax_arrays" is to verify the list of variables for the array of pointers. */
41
42
43/* ****************************************************************************************************************************** */
44
46 char tok1[STRLENGTH] = {'\0'};
47 char tok2[STRLENGTH] = {'\0'};
48 char *s = (char*) NULL;
49 char *t = (char*) NULL;
50 long i, j, nu, nv;
51 if (!Cmdline_Flag) {
52 return;
53 }
54 for (i = 0L; i < Num_Cmdlines; i++) { /* analyze each expected command line parameter */
55 if (0 == strcmp(Cmdline_List[i].parms, "fs")) {
56 if (ISNOTEQUAL(1.0, Sampling_List.frequency)) { /* compare with default value */
57 print_warning_location("command_line", Cmdline_List[i].mline, Cmdline_List[i].mfile);
58 (void) fprintf(STDERR, " the sampling frequency <fs> defined in NAPA netlist\n");
60 (void) fprintf(STDERR, " will be superseded by user input at execution\n\n");
61 Sampling_List.frequency = 1.0;
62 }
63 continue;
64 }
65 if (0 == strcmp(Cmdline_List[i].parms, "ts")) {
66 if (ISNOTEQUAL(1.0, Sampling_List.frequency)) { /* compare with default value */
67 print_warning_location("command_line", Cmdline_List[i].mline, Cmdline_List[i].mfile);
68 (void) fprintf(STDERR, " the sampling period <ts> defined in NAPA netlist\n");
70 (void) fprintf(STDERR, " will be superseded by user input at execution\n\n");
71 Sampling_List.frequency = 1.0;
72 }
73 continue;
74 }
75 nv = var_id(Cmdline_List[i].parms);
76 if (UNDEFINED != nv) { /* defined, as definition already checked in "pr.c" */
77 for (j = 1L; j < Num_FileCells; j++) { /* 0L corresponds to the file name of the main */
78 if (STRING_DATA_TYPE == Var_List[nv].type) { /* a cell pathname cannot be part of command line */
79 (void) strcpy(tok1, Record_Cell_File_Table[j]);
80 (void) strcpy(tok2, Var_List[nv].value);
81 strip_quotes(tok1);
82 strip_quotes(tok2);
83 s = tok1;
84 t = tok2;
85#if (IS_WIN64 == PLATFORM) /* case-insensitive OS */
86 s = upper_to_lower(s);
87 t = upper_to_lower(t);
88#endif
89 if (0 == strcmp(s, t)) {
90 print_error_location("command_line", Cmdline_List[i].mline, Cmdline_List[i].mfile);
91 (void) fprintf(STDERR, " String parameter <%s> was used during the compilation of a NAPA cell.\n", Cmdline_List[i].parms);
92 (void) fprintf(STDERR, " Its value is currently set to <%s>.\n", Var_List[nv].value);
93 (void) fprintf(STDERR, " It cannot be redefined at execution and therefore cannot be a command line parameter.\n");
94 }
95 }
96 }
97 nu = update_id(Cmdline_List[i].parms, 1);
98 if (UNDEFINED != nu) {
99 if (0 != Var_List[nv].event) { /* an event is automatically updated */
100 print_error_location("event", Update_List[nu].mline, Update_List[nu].mfile);
101 (void) fprintf(STDERR, " <%s>, being a variable of the command line, cannot be an event\n", Cmdline_List[i].parms);
102 } else {
103 print_error_location("update", Update_List[nu].mline, Update_List[nu].mfile);
104 (void) fprintf(STDERR, " <%s>, being a variable of the command line, cannot be updated\n", Cmdline_List[i].parms);
105 }
106 }
107 }
108 }
109 return;
110}
111
112
114 long i;
115 char *s = (char*) NULL;
116 char tok[STRLENGTH] = {'\0'};
117 for (i = 0L; i < Num_Directives; i++) {
118 s = Directive_List[i].value;
119 for (;;) {
120 s = get_token(s, tok, true);
121 if (ISEMPTY(tok)) {
122 break;
123 }
124 if (UNDEFINED != node_id(tok)) {
125 print_error_location("directive", Directive_List[i].mline, Directive_List[i].mfile );
126 (void) fprintf(STDERR, " <%s>, a node cannot be used in a directive\n", tok );
127 }
128 if ((UNDEFINED != var_id(tok)) && (STRING_DATA_TYPE != get_type(tok))) { /* string is ok */
129 print_error_location("directive", Directive_List[i].mline, Directive_List[i].mfile );
130 (void) fprintf(STDERR, " <%s>, a variable cannot be used in a directive\n", tok);
131 }
132 }
133 }
134 return;
135}
136
137
138void syntax_fs(void) {
139 long d;
140 if ((!Fs_Flag) && (!Ts_Flag) && (Periodic_Flag) && (0 == Error_Flag)) {
141 if ((Terminate_Flag) && (Loop_Flag) && (!Fs_Ext_Flag) && (!Ts_Ext_Flag)) {
142 Sampling_List.frequency = 1.0;
143 Sampling_List.period = 1.0;
144 for (d = 0L; d < MAXDEPTH; d++) {
145 Sampling_List.mline[d] = 0UL;
146 Sampling_List.mfile[d] = 0UL;
147 }
148 print_warning_location("fs", NULL, NULL);
149 (void) fprintf(STDERR, "\n No sampling frequency definition in netlist...\n");
150 (void) fprintf(STDERR, " Using default frequency %.1f Hz\n", Sampling_List.frequency);
151 }
152 Fs_Flag = true;
153 Ts_Flag = false;
154 }
155 return;
156}
157
158
159void syntax_nodes(void) {
160 long out;
161 long kd;
162 long a, i, m, n;
163 char *s = (char*) NULL;
164 char *str1 = (char*) NULL;
165 char *str2 = (char*) NULL;
166 char msg[STRLENGTH] = {'\0'};
167 char tok1[STRLENGTH] = {'\0'};
168 char tok2[STRLENGTH] = {'\0'};
169 char sgn[2] = {'\0'};
170 char brck[3] = {'\0'};
171 char *tg = (char*) NULL;
172 unsigned long *ml = (unsigned long*) NULL;
173 unsigned long *mf = (unsigned long*) NULL;
174
175 for (out = 0L; out < Num_Nodes; out++) {
176 str1 = Node_List[out].value;
177 kd = Node_List[out].kind;
178 ml = Node_List[out].mline;
179 mf = Node_List[out].mfile;
180 tg = Node_List[out].tag;
181
182 switch (kd) {
183
184 case DELAY1_KIND :
185 case DELAY2_KIND :
186 case DELAY3_KIND :
187 authorize_option(NO, out);
188 str1 = get_sign_and_token(str1, sgn, tok1); /* skip number of delays */
189 str1 = get_sign_and_token(str1, sgn, tok1);
190 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
191 break;
192 }
193 if (0 != something_else(str1, out)) {
194 break;
195 }
196 break;
197
198 case DELAY_KIND :
199 authorize_option(NO, out);
200 str1 = get_sign_and_token(str1, sgn, tok1);
201 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "number of delays")) {
202 break;
203 }
204 str1 = get_sign_and_token(str1, sgn, tok1);
205 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
206 break;
207 }
208 if (0 != something_else(str1, out)) {
209 break;
210 }
211 break;
212
214 authorize_option(NO, out);
215 str1 = get_sign_and_token(str1, sgn, tok1);
216 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
217 break;
218 }
219 if (0 != something_else(str1, out)) {
220 break;
221 }
222 break;
223
224 case INTEGRATOR_KIND :
225 authorize_option(NO, out);
226 str1 = get_sign_and_token(str1, sgn, tok1);
227 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
228 break;
229 }
230 if (0 != something_else(str1, out)) {
231 break;
232 }
233 break;
234
235 case OSC_KIND :
236 authorize_option(NO, out);
237 str1 = get_sign_and_token(str1, sgn, tok1);
238 if (0 != check_syntax(VARIABLE | NODE | NUMBER, DONTCARE, sgn, tok1, out, "offset" )) {
239 break;
240 }
241 str1 = get_sign_and_token(str1, sgn, tok1);
242 if (0 != check_syntax(VARIABLE | NODE | NUMBER, NOSIGN, sgn, tok1, out, "amplitude")) {
243 break;
244 }
245 str1 = get_sign_and_token(str1, sgn, tok1);
246 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "frequency")) {
247 break;
248 }
249 str1 = get_sign_and_token(str1, sgn, tok1);
250 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "phase" )) {
251 break;
252 }
253 if (0 != something_else(str1, out)) {
254 break;
255 }
256 break;
257
258 case SIN_KIND :
259 case COS_KIND :
260 authorize_option(NO, out);
261 str1 = get_sign_and_token(str1, sgn, tok1);
262 if (0 != check_syntax(VARIABLE | NODE | NUMBER, DONTCARE, sgn, tok1, out, "offset" )) {
263 break;
264 }
265 str1 = get_sign_and_token(str1, sgn, tok1);
266 if (0 != check_syntax(VARIABLE | NODE | NUMBER, NOSIGN, sgn, tok1, out, "amplitude")) {
267 break;
268 }
269 str1 = get_sign_and_token(str1, sgn, tok1);
270 if (0 != check_syntax(VARIABLE | NODE | NUMBER, NOSIGN, sgn, tok1, out, "frequency")) {
271 break;
272 }
273 str1 = get_sign_and_token(str1, sgn, tok1);
274 if (0 != check_syntax(VARIABLE | NODE | NUMBER, DONTCARE, sgn, tok1, out, "phase" )) {
275 break;
276 }
277 if (0 != something_else(str1, out)) {
278 break;
279 }
280 break;
281
282 case TRIANGLE_KIND :
283 case SQUARE_KIND :
284 authorize_option(NO, out);
285 str1 = get_sign_and_token(str1, sgn, tok1);
286 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "offset" )) {
287 break;
288 }
289 str1 = get_sign_and_token(str1, sgn, tok1);
290 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "amplitude")) {
291 break;
292 }
293 str1 = get_sign_and_token(str1, sgn, tok1);
294 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "frequency")) {
295 break;
296 }
297 str1 = get_sign_and_token(str1, sgn, tok1);
298 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "delay" )) {
299 break;
300 }
301 str1 = get_sign_and_token(str1, sgn, tok1); /* duty cycle is optional */
302 if (ISNOTEMPTY(tok1)) {
303 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "duty cycle")) {
304 break;
305 }
306 }
307 if (0 != something_else(str1, out)) {
308 break;
309 }
310 break;
311
312 case STEP_KIND :
313 authorize_option(NO, out);
314 str1 = get_sign_and_token(str1, sgn, tok1);
315 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "first level" )) {
316 break;
317 }
318 str1 = get_sign_and_token(str1, sgn, tok1);
319 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "second level")) {
320 break;
321 }
322 str1 = get_sign_and_token(str1, sgn, tok1);
323 if (ISEMPTY(str1)) {
324 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "step time" )) {
325 break;
326 }
327 } else {
328 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "first step time" )) {
329 break;
330 }
331 str1 = get_sign_and_token(str1, sgn, tok1);
332 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "second step time")) {
333 break;
334 }
335 }
336 if (0 != something_else(str1, out)) {
337 break;
338 }
339 break;
340
341 case CLOCK_KIND :
342 authorize_option(NO, out);
343 str1 = get_sign_and_token(str1, sgn, tok1);
344 if (0 == strcmp(tok1, "\"\"")) {
345 print_error_location(tg, ml, mf);
346 (void) fprintf(STDERR, " pattern descriptor is empty\n");
347 flag_node(out);
348 break;
349 }
350 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "pattern descriptor")) {
351 break;
352 }
353 str1 = get_sign_and_token(str1, sgn, tok1);
354 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "width descriptor")) {
355 break;
356 } /* other checks will be made when building C code */
357 if (0 != something_else(str1, out)) {
358 break;
359 }
360 break;
361
362 case CONST_KIND :
363 case DC_KIND :
364 authorize_option(-1, out); /* no check, as a C expression is expected */
365 C_syntax_checker(str1, ml, mf);
366 break;
367
368 case GAIN_KIND :
369 case OFFSET_KIND :
370 authorize_option(NO, out);
371 str1 = get_sign_and_token(str1, sgn, tok1);
372 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "parameter")) {
373 break;
374 }
375 str1 = get_sign_and_token(str1, sgn, tok1);
376 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "input")) {
377 break;
378 }
379 if (0 != something_else(str1, out)) {
380 break;
381 }
382 break;
383
384 case ITOB_KIND :
385 authorize_option(NO, out);
386 str1 = get_sign_and_token(str1, sgn, tok1);
387 if (0 != check_syntax(NUMBER, NOSIGN, sgn, tok1, out, "bit number")) {
388 break;
389 }
390 str1 = get_sign_and_token(str1, sgn, tok1);
391 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "")) {
392 break; /* empty msg "" and not msg "input" to be compatible with bit field automatic node */
393 }
394 if (0 != something_else(str1, out)) {
395 break;
396 }
397 break;
398
399 case CLIP_KIND :
400 authorize_option(NO, out);
401 str1 = get_sign_and_token(str1, sgn, tok1);
402 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "clipping level low")) {
403 break;
404 }
405 str1 = get_sign_and_token(str1, sgn, tok1);
406 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "clipping level high")) {
407 break;
408 }
409 str1 = get_sign_and_token(str1, sgn, tok1);
410 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
411 break;
412 }
413 if (0 != something_else(str1, out)) {
414 break;
415 }
416 break;
417
418 case NOISE_KIND :
419 authorize_option(NO, out);
420 str2 = str1;
421 str2 = get_sign_and_token(str2, sgn, tok1); /* DC level */
422 str2 = get_sign_and_token(str2, sgn, tok1); /* RMS level */
423 str1 = get_sign_and_token(str1, sgn, tok1);
424 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "DC value")) {
425 break;
426 }
427 str1 = get_sign_and_token(str1, sgn, tok1);
428 if (0 != check_syntax(VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "RMS value")) {
429 break;
430 }
431 break;
432
433 case RSHIFT_KIND :
434 case RSHIFT1_KIND :
435 case RSHIFT2_KIND :
436 authorize_option(NO, out);
437 if (!verify_rshift()) {
438 if (0 == is_node_flagged(out)) {
439 print_error_location(tg, ml, mf);
440 (void) fprintf(STDERR, " this platform (%s) does not support sign extension on right shifts!\n", MACHINE);
441 flag_node(out);
442 }
443 }
444 str1 = get_sign_and_token(str1, sgn, tok1);
445 if (0 != check_syntax(NUMBER | NODE | VARIABLE, NOSIGN, sgn, tok1, out, "rshift value")) {
446 break;
447 }
448 str1 = get_sign_and_token(str1, sgn, tok1);
449 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
450 break;
451 }
452 if (0 != something_else(str1, out)) {
453 break;
454 }
455 break;
456
457 case BSHIFT_KIND :
458 case LSHIFT_KIND :
459 authorize_option(NO, out);
460 str1 = get_sign_and_token(str1, sgn, tok1);
461 if (BSHIFT_KIND == kd) {
462 if (0 != check_syntax(NUMBER | NODE | VARIABLE, DONTCARE, sgn, tok1, out,"bshift value")) {
463 break;
464 }
465 } else {
466 if (0 != check_syntax(NUMBER | NODE | VARIABLE, NOSIGN, sgn, tok1, out, "lshift value")) {
467 break;
468 }
469 }
470 str1 = get_sign_and_token(str1, sgn, tok1);
471 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
472 break;
473 }
474 if (0 != something_else(str1, out)) {
475 break;
476 }
477 break;
478
479 case RECT_KIND :
480 authorize_option(NO, out);
481 str1 = get_sign_and_token(str1, sgn, tok1);
482 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "input" )) {
483 break;
484 }
485 if (0 != something_else(str1, out)) {
486 break;
487 }
488 break;
489
490 case COPY_KIND :
491 authorize_option(NO, out);
492 str1 = get_sign_and_token(str1, sgn, tok1);
493 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
494 break;
495 }
496 if (0 != something_else(str1, out)) {
497 break;
498 }
499 break;
500
501 case DIV_KIND :
502 case MOD_KIND :
503 authorize_option(YES, out);
504 str1 = get_sign_and_token(str1, sgn, tok1);
505 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input #1")) {
506 break;
507 }
508 str1 = get_sign_and_token(str1, sgn, tok1);
509 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "input #2")) {
510 break;
511 }
512 if (((char*) NULL == strstr(Node_List[out].option, "none")) && ((char*) NULL == strstr(Node_List[out].option, "nocheck"))) {
513 print_error_location(tg, ml, mf);
514 replace_dollar(tok1);
515 (void) fprintf(STDERR, " (%s) is not a valid trigger qualifier\n\n", Node_List[out].option);
516 (void) fprintf(STDERR, " optional valid qualifier is (nocheck)\n");
517 flag_node(out);
518 break;
519 }
520 str1 = get_sign_and_token(str1, sgn, tok1);
521 if (0 != something_else(str1, out)) {
522 break;
523 }
524 break;
525
526 case QUANT_KIND :
527 authorize_option(NO, out);
528 str1 = get_sign_and_token(str1, sgn, tok1);
529 if (0 != check_syntax(NODE | VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "quantification")) {
530 break;
531 }
532 str1 = get_sign_and_token(str1, sgn, tok1);
533 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
534 break;
535 }
536 if (0 != something_else(str1, out)) {
537 break;
538 }
539 break;
540
541 case SUB_KIND :
542 authorize_option(NO, out);
543 str1 = get_sign_and_token(str1, sgn, tok1);
544 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input #1")) {
545 break;
546 }
547 str1 = get_sign_and_token(str1, sgn, tok1);
548 if (0 != check_syntax(NODE | NUMBER, DONTCARE, sgn, tok1, out, "input #2")) {
549 break;
550 }
551 if (0 != something_else(str1, out)) {
552 break;
553 }
554 break;
555
556 case SUM_KIND :
557 case PROD_KIND :
558 case MIN_KIND :
559 case MAX_KIND :
560 authorize_option(NO, out);
561 i = 0L;
562 for (;;) {
563 str1 = get_sign_and_token(str1, sgn, tok1);
564 if (ISEMPTY(tok1)) {
565 break;
566 }
567 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
568 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, msg)) {
569 break;
570 }
571 i++;
572 }
573 if ((0 == is_node_flagged(out)) && (2L > i)) {
574 print_error_location(tg, ml, mf);
575 (void) fprintf(STDERR, " at least two input nodes are required\n");
576 flag_node(out);
577 }
578 break;
579
580 case AVERAGE_KIND :
581 authorize_option(YES, out);
582 i = 0L;
583 for (;;) {
584 str1 = get_sign_and_token(str1, sgn, tok1);
585 if (ISEMPTY(tok1)) {
586 break;
587 }
588 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
589 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, msg)) {
590 break;
591 }
592 i++;
593 }
594 if ((0 == is_node_flagged(out)) && (2L > i)) {
595 print_error_location(tg, ml, mf);
596 (void) fprintf(STDERR, " at least two input nodes are required\n");
597 flag_node(out);
598 }
599 if (((char*) NULL == strstr(Node_List[out].option, "arithmetic"))
600 && ((char*) NULL == strstr(Node_List[out].option, "geometric" ))
601 && ((char*) NULL == strstr(Node_List[out].option, "harmonic" ))
602 && ((char*) NULL == strstr(Node_List[out].option, "rms" ))) {
603 print_error_location(tg, ml, mf);
604 (void) fprintf(STDERR, " (%s) is not a valid qualifier for node 'average'\n\n", Node_List[out].option);
605 (void) fprintf(STDERR, " valid qualifiers are:\n");
606 (void) fprintf(STDERR, " (arithmetic)\n");
607 (void) fprintf(STDERR, " (geometric)\n");
608 (void) fprintf(STDERR, " (harmonic)\n");
609 (void) fprintf(STDERR, " (rms)\n");
610 flag_node(out);
611 break;
612 }
613 break;
614
615 case WSUM_KIND :
616 authorize_option(NO, out);
617 i = 0L;
618 for (;;) {
619 str1 = get_sign_and_token(str1, sgn, tok1);
620 if (ISEMPTY(tok1)) {
621 break;
622 }
623 (void) snprintf(msg, (size_t) 31, "parameter #%ld", i+1L);
624 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, msg)) {
625 break;
626 }
627 str1 = get_sign_and_token(str1, sgn, tok1);
628 if (ISEMPTY(tok1)) {
629 if (0 == is_node_flagged(out)) {
630 print_error_location(tg, ml, mf);
631 (void) fprintf(STDERR, " input node is missing\n");
632 flag_node(out);
633 }
634 break;
635 }
636 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
637 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, msg)) {
638 break;
639 }
640 i++;
641 }
642 if ((0 == is_node_flagged(out)) && (2L > i)) {
643 print_error_location(tg, ml, mf);
644 (void) fprintf(STDERR, " at least two input nodes are required\n");
645 flag_node(out);
646 }
647 break;
648
649 case ALU_KIND :
650 authorize_option(NO, out);
651 str1 = get_sign_and_token(str1, sgn, tok1);
652 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "owner name")) {
653 break;
654 }
655 str1 = get_sign_and_token(str1, sgn, tok1);
656 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "opcode")) {
657 break;
658 }
659 i = 0L;
660 for (;;) {
661 str1 = get_sign_and_token(str1, sgn, tok1);
662 if (ISEMPTY(tok1)) {
663 break;
664 }
665 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
666 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, msg)) {
667 break;
668 }
669 i++;
670 }
671 if ((0 == is_node_flagged(out)) && (1L > i)) {
672 print_error_location(tg, ml, mf);
673 (void) fprintf(STDERR, " at least one input node is required\n");
674 flag_node(out);
675 }
676 break;
677
678 case RIP_KIND :
679 authorize_option(NO, out);
680 str1 = get_sign_and_token(str1, sgn, tok1);
681 if (0 != check_syntax(NUMBER, NOSIGN, sgn, tok1, out, "mask")) {
682 break;
683 }
684 str1 = get_sign_and_token(str1, sgn, tok1);
685 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
686 break;
687 }
688 if (0 != something_else(str1, out)) {
689 break;
690 }
691 break;
692
693 case BUF_KIND :
694 case INV_KIND :
695 case BWINV_KIND :
696 authorize_option(NO, out);
697 str1 = get_sign_and_token(str1, sgn, tok1);
698 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
699 break;
700 }
701 if (0 != something_else(str1, out)) {
702 break;
703 }
704 break;
705
706 case TOGGLE_KIND :
707 authorize_option(NO, out);
708 str1 = get_sign_and_token(str1, sgn, tok1);
709 if (ISNOTEMPTY(tok1)) {
710 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
711 break;
712 }
713 if (0 != something_else(str1, out)) {
714 break;
715 }
716 }
717 break;
718
719 case AND_KIND :
720 case OR_KIND :
721 case XOR_KIND :
722 case NAND_KIND :
723 case NOR_KIND :
724 case XNOR_KIND :
725 case MULLER_KIND :
726 authorize_option(NO, out);
727 i = 0L;
728 for (;;) {
729 str1 = get_sign_and_token(str1, sgn, tok1);
730 if (ISEMPTY(tok1)) {
731 break;
732 }
733 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
734 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, msg)) {
735 break;
736 }
737 i++;
738 }
739 if ((0 == is_node_flagged(out)) && (2L > i)) {
740 print_error_location(tg, ml, mf);
741 (void) fprintf(STDERR, " at least two input nodes are required\n");
742 flag_node(out);
743 }
744 break;
745
746 case BWAND_KIND :
747 case BWOR_KIND :
748 case BWXOR_KIND :
749 case BWNAND_KIND :
750 case BWNOR_KIND :
751 case BWXNOR_KIND :
752 authorize_option(NO, out);
753 str1 = get_sign_and_token(str1, sgn, tok1);
754 if ((0 == is_node_flagged(out)) && ISEMPTY(tok1)) {
755 print_error_location(tg, ml, mf);
756 (void) fprintf(STDERR, " input node or mask is missing\n");
757 flag_node(out);
758 break;
759 }
760 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input #1")) {
761 break;
762 }
763 i = 1L;
764 for (;;) {
765 str1 = get_sign_and_token(str1, sgn, tok1);
766 if (ISEMPTY(tok1)) {
767 break;
768 }
769 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
770 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, msg)) {
771 break;
772 }
773 i++;
774 }
775 if ((0 == is_node_flagged(out)) && (1L > i)) {
776 print_error_location(tg, ml, mf);
777 (void) fprintf(STDERR, " at least two input nodes are required\n");
778 flag_node(out);
779 }
780 break;
781
782 case FZINV_KIND :
783 case FZBUF_KIND :
784 authorize_option(NO, out);
785 str1 = get_sign_and_token(str1, sgn, tok1);
786 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
787 break;
788 }
789 if (0 != something_else(str1, out)) {
790 break;
791 }
792 break;
793
794 case FZAND_KIND :
795 case FZOR_KIND :
796 case FZNAND_KIND :
797 case FZNOR_KIND :
798 authorize_option(NO, out);
799 i = 0L;
800 for (;;) {
801 str1 = get_sign_and_token(str1, sgn, tok1);
802 if (ISEMPTY(tok1)) {
803 break;
804 }
805 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
806 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, msg)) {
807 break;
808 }
809 i++;
810 }
811 if ((0 == is_node_flagged(out)) && (2L > i)) {
812 print_error_location(tg, ml, mf);
813 (void) fprintf(STDERR, " at least two input nodes are required\n");
814 flag_node(out);
815 }
816 break;
817
818 case FZXOR_KIND :
819 case FZXNOR_KIND :
820 authorize_option(NO, out);
821 i = 0L;
822 for (;;) {
823 str1 = get_sign_and_token(str1, sgn, tok1);
824 if (ISEMPTY(tok1)) {
825 break;
826 }
827 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
828 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, msg)) {
829 break;
830 }
831 i++;
832 }
833 if ((0 == is_node_flagged(out)) && (2L != i)) {
834 print_error_location(tg, ml, mf);
835 (void) fprintf(STDERR, " two input nodes are required\n");
836 flag_node(out);
837 }
838 break;
839
840 case HOLD_KIND :
841 case TRACK_KIND :
842 authorize_option(NO, out);
843 str1 = get_sign_and_token(str1, sgn, tok1);
844 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "control")) {
845 break;
846 }
847 str1 = get_sign_and_token(str1, sgn, tok1);
848 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "input")) {
849 break;
850 }
851 if (0 != something_else(str1, out)) {
852 break;
853 }
854 break;
855
856 case RELAY_KIND :
857 authorize_option(NO, out);
858 str1 = get_sign_and_token(str1, sgn, tok1);
859 if (0 != check_syntax(NODE | VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "control")) {
860 break;
861 }
862 str1 = get_sign_and_token(str1, sgn, tok1);
863 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "input")) {
864 break;
865 }
866 if (ISNOTEMPTY(str1)) {
867 str1 = get_sign_and_token(str1, sgn, tok1);
868 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "setting value")) {
869 break;
870 }
871 if (0 != something_else(str1, out)) {
872 break;
873 }
874 }
875 break;
876
877 case ZERO_KIND :
878 authorize_option(NO, out);
879 str1 = get_sign_and_token(str1, sgn, tok1);
880 if (0 != check_syntax(NUMBER, NOSIGN, sgn, tok1, out, "decimation factor")) {
881 break;
882 }
883 str1 = get_sign_and_token(str1, sgn, tok1);
884 if (0 != check_syntax(NUMBER, NOSIGN, sgn, tok1, out, "decimation offset")) {
885 break;
886 }
887 str1 = get_sign_and_token(str1, sgn, tok1);
888 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "input")) {
889 break;
890 }
891 if (0 != something_else(str1, out)) {
892 break;
893 }
894 break;
895
896 case COMP_KIND :
897 authorize_option(NO, out);
898 str1 = get_sign_and_token(str1, sgn, tok1);
899 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "input #1")) {
900 break;
901 }
902 m = node_id(tok1);
903 str1 = get_sign_and_token(str1, sgn, tok1);
904 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "input #2")) {
905 break;
906 }
907 n = node_id(tok1);
908 if ((UNDEFINED == m) && (UNDEFINED == n)) {
909 print_error_location(tg, ml, mf);
910 (void) fprintf(STDERR, " at least one of the inputs #1 or #2 must be a node\n");
911 flag_node(out);
912 }
913 if (0 != something_else(str1, out)) {
914 break;
915 }
916 break;
917
918 case EQUAL_KIND :
919 authorize_option(NO, out);
920 str1 = get_sign_and_token(str1, sgn, tok1);
921 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "input #1")) {
922 break;
923 }
924 m = node_id(tok1);
925 str1 = get_sign_and_token(str1, sgn, tok1);
926 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "input #2")) {
927 break;
928 }
929 n = node_id(tok1);
930 if ((UNDEFINED == m) && (UNDEFINED == n)) {
931 print_error_location(tg, ml, mf);
932 (void) fprintf(STDERR, " at least one of the inputs #1 or #2 must be a node\n");
933 flag_node(out);
934 }
935 if (0 == strcmp(str1, "")) {
936 break;
937 }
938 str1 = get_sign_and_token(str1, sgn, tok1);
939 if (0 != check_syntax(NODE | VARIABLE | NUMBER, NOSIGN, sgn, tok1, out, "precision")) {
940 break;
941 }
942 if (0 != something_else(str1, out)) {
943 break;
944 }
945 break;
946
947 case LATCH_KIND :
948 authorize_option(NO, out);
949 str1 = get_sign_and_token(str1, sgn, tok1);
950 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "set")) {
951 break;
952 }
953 str1 = get_sign_and_token(str1, sgn, tok1);
954 if (0 != check_syntax(NODE, NOSIGN, sgn, tok1, out, "reset")) {
955 break;
956 }
957 if (0 != something_else(str1, out)) {
958 break;
959 }
960 break;
961
962 case ALGEBRA_KIND :
963 case DALGEBRA_KIND :
964 case IALGEBRA_KIND :
965 case TEST_KIND :
966 authorize_option(-1, out); /* no check, as a C expression is expected */
967 C_syntax_checker(str1, ml, mf);
968 break;
969
970 case ADC_KIND :
971 case DAC_KIND :
972 case UADC_KIND :
973 case UDAC_KIND :
974 authorize_option(NO, out);
975 str1 = get_sign_and_token(str1, sgn, tok1);
976 if (0 != check_syntax(NUMBER, NOSIGN, sgn, tok1, out, "number of levels")) {
977 break;
978 }
979 str1 = get_sign_and_token(str1, sgn, tok1);
980 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
981 break;
982 }
983 str1 = get_sign_and_token(str1, sgn, tok1);
984 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "reference")) {
985 break;
986 }
987 if (0 != something_else(str1, out)) {
988 break;
989 }
990 break;
991
992 case MUX_KIND :
993 authorize_option(NO, out);
994 str1 = get_sign_and_token(str1, sgn, tok1);
995 if (0 != check_syntax(NODE | VARIABLE| NUMBER, NOSIGN, sgn, tok1, out, "control")) {
996 break;
997 }
998 i = 0L;
999 for (;;) {
1000 str1 = get_sign_and_token(str1, sgn, tok1);
1001 if (0 == strcmp(tok1, "void")) {
1002 continue;
1003 }
1004 if (ISEMPTY(tok1)) {
1005 break;
1006 }
1007 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
1008 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, msg)) {
1009 break;
1010 }
1011 i++;
1012 }
1013 if ((0 == is_node_flagged(out)) && (2L > i)) {
1014 print_error_location(tg, ml, mf);
1015 (void) fprintf(STDERR, " at least two input nodes are requested\n");
1016 flag_node(out);
1017 break;
1018 }
1019 break;
1020
1021 case MERGE_KIND :
1022 authorize_option(YES, out);
1023 i = 0L;
1024 for (;;) {
1025 str1 = get_sign_and_token(str1, sgn, tok1);
1026 if (ISEMPTY(tok1)) {
1027 break;
1028 }
1029 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
1030 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, msg)) {
1031 break;
1032 }
1033 i++;
1034 }
1035 if ((0 == is_node_flagged(out)) && (2L > i)) {
1036 print_error_location(tg, ml, mf);
1037 (void) fprintf(STDERR, " at least two input nodes are requested\n");
1038 flag_node(out);
1039 break;
1040 }
1041 break;
1042
1043 case TRIG_KIND :
1044 authorize_option(YES, out);
1045 str1 = get_sign_and_token(str1, sgn, tok1);
1046 if (0 != check_syntax(VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, "trigger threshold")) {
1047 break;
1048 }
1049 str1 = get_sign_and_token(str1, sgn, tok1);
1050 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
1051 break;
1052 }
1053 if (((char*) NULL == strstr(Node_List[out].option, "dual"))
1054 && ((char*) NULL == strstr(Node_List[out].option, "positive"))
1055 && ((char*) NULL == strstr(Node_List[out].option, "negative"))) {
1056 print_error_location(tg, ml, mf);
1057 replace_dollar(tok1);
1058 (void) fprintf(STDERR, " (%s) is not a valid trigger qualifier\n\n", Node_List[out].option);
1059 (void) fprintf(STDERR, " valid qualifiers are:\n");
1060 (void) fprintf(STDERR, " (negative)\n");
1061 (void) fprintf(STDERR, " (positive)\n");
1062 (void) fprintf(STDERR, " (dual)\n");
1063 flag_node(out);
1064 break;
1065 }
1066 str1 = get_sign_and_token(str1, sgn, tok1);
1067 if (0 != something_else(str1, out)) {
1068 break;
1069 }
1070 break;
1071
1072 case SIGN_KIND :
1073 authorize_option(NO, out);
1074 str1 = get_sign_and_token(str1, sgn, tok1);
1075 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
1076 break;
1077 }
1078 if (0 != something_else(str1, out)) {
1079 break;
1080 }
1081 break;
1082
1083 case CHG_KIND :
1084 authorize_option(YES, out);
1085 str1 = get_sign_and_token(str1, sgn, tok1);
1086 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
1087 break;
1088 }
1089 if (0 != something_else(str1, out)) {
1090 break;
1091 }
1092 if (((char*) NULL == strstr(Node_List[out].option, "dual" ))
1093 && ((char*) NULL == strstr(Node_List[out].option, "both" ))
1094 && ((char*) NULL == strstr(Node_List[out].option, "positive"))
1095 && ((char*) NULL == strstr(Node_List[out].option, "negative"))) {
1096 print_error_location(tg, ml, mf);
1097 (void) fprintf(STDERR, " (%s) is not a valid qualifier for node 'change'\n\n", Node_List[out].option);
1098 (void) fprintf(STDERR, " valid qualifiers are:\n");
1099 (void) fprintf(STDERR, " (dual)\n");
1100 (void) fprintf(STDERR, " (both)\n");
1101 (void) fprintf(STDERR, " (positive)\n");
1102 (void) fprintf(STDERR, " (negative)\n");
1103 flag_node(out);
1104 break;
1105 }
1106 break;
1107
1108 case DTOI_KIND :
1109 case ITOD_KIND :
1110 authorize_option(NO, out);
1111 str1 = get_sign_and_token(str1, sgn, tok1);
1112 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, "input")) {
1113 break;
1114 }
1115 if (0 != something_else(str1, out)) {
1116 break;
1117 }
1118 break;
1119
1120 case BTOI_KIND :
1121 authorize_option(NO, out);
1122 i = 0L;
1123 for (;;) {
1124 str1 = get_sign_and_token(str1, sgn, tok1);
1125 if (ISEMPTY(tok1)) {
1126 break;
1127 }
1128 (void) snprintf(msg, (size_t) 31, "input #%ld", i+1L);
1129 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok1, out, msg)) {
1130 break;
1131 }
1132 i++;
1133 }
1134 if ((0 == is_node_flagged(out)) && (2L > i)) {
1135 print_error_location(tg, ml, mf);
1136 (void) fprintf(STDERR, " at least two inputs are required\n");
1137 flag_node(out);
1138 }
1139 break;
1140
1141 case POLY_KIND :
1142 authorize_option(NO, out);
1143 s = str1;
1144 n = 0L;
1145 for (;;) {
1146 str1 = get_sign_and_token(str1, sgn, tok1);
1147 if (ISEMPTY(tok1)) {
1148 break;
1149 }
1150 n++;
1151 }
1152 if ((0 == is_node_flagged(out)) && (2L > n)) {
1153 print_error_location(tg, ml, mf);
1154 (void) fprintf(STDERR, " at least two inputs are required\n");
1155 flag_node(out);
1156 break;
1157 }
1158 str1 = s;
1159 for (i = 0L; i < n-1L; i++) {
1160 str1 = get_sign_and_token(str1, sgn, tok1);
1161 (void) snprintf(msg, (size_t) 31, "coefficient of x^%ld", i);
1162 if (0 != check_syntax(NODE | VARIABLE | NUMBER, DONTCARE, sgn, tok1, out, msg)) {
1163 break;
1164 }
1165 }
1166 str1 = get_sign_and_token(str1, sgn, tok1);
1167 if (0 != check_syntax(NODE, DONTCARE, sgn, tok1, out, "input")) {
1168 break;
1169 }
1170 break;
1171
1172 case ROM_KIND :
1173 case ROM2_KIND :
1174 authorize_option(NO, out);
1175 str1 = get_sign_and_token(str1, sgn, tok1);
1176 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "ROM name")) {
1177 break;
1178 }
1179 a = record_id(tok1);
1180 if (UNDEFINED != a) {
1181 print_error_location(tg, ml, mf);
1182 (void) fprintf(STDERR, " the array <%s[]> is not a ROM but an array of pointers\n", tok1);
1183 flag_node(out);
1184 break;
1185 }
1186 a = array_id(tok1);
1187 if (UNDEFINED == a) {
1188 print_error_location(tg, ml, mf);
1189 (void) fprintf(STDERR, " ROM array <%s[]> is not declared\n", tok1);
1190 process_array_error(tok1);
1191 flag_node(out);
1192 break;
1193 }
1194 if ((0 == is_node_flagged(out)) && ((RAM_KIND == Array_List[a].kind) || (RAM2_KIND == Array_List[a].kind))) {
1195 print_error_location(tg, ml, mf);
1196 (void) fprintf(STDERR, " the array <%s[]> is already used as a RAM\n", tok1);
1197 flag_node(out);
1198 break;
1199 }
1200 if ((0 == is_node_flagged(out)) && (kd != Array_List[a].kind) && (0L < Array_List[a].port)) {
1201 print_error_location(tg, ml, mf);
1202 (void) fprintf(STDERR, " ROM <%s[]> port definitions are not consistent (single or dual port?)\n", tok1);
1203 flag_node(out);
1204 break;
1205 }
1206 Array_List[a].kind = kd;
1207 (Array_List[a].port)++; /* number of ports */
1208 if ((0 == is_node_flagged(out)) && (ROM_KIND == Array_List[a].kind) && (1L < Array_List[a].port)) {
1209 print_error_location(tg, ml, mf);
1210 (void) fprintf(STDERR, " <%s[]>: single-port ROM cannot be used as a dual port ROM\n", tok1);
1211 flag_node(out);
1212 break;
1213 }
1214 Array_List[a].used = true;
1215 str1 = get_token_between_braces(str1, brck, tok2);
1216 if (((0 != strcmp(brck, "[]")) || ISEMPTY(tok2)) && (0 == is_node_flagged(out))) {
1217 print_error_location(tg, ml, mf);
1218 (void) fprintf(STDERR, " address of ROM <%s[]> is not correct\n", tok1);
1219 flag_node(out);
1220 break;
1221 }
1222 if (0 != check_syntax(NODE | NUMBER, NOSIGN, " ", tok2, out, "address of ROM")) {
1223 break;
1224 }
1225 str1 = get_sign_and_token(str1, sgn, tok2);
1226 if (0 != check_syntax(NODE | VARIABLE | NUMBER, NOSIGN, sgn, tok2, out, "ROM chip select")) {
1227 break;
1228 }
1229 if (0 != something_else(str1, out)) {
1230 break;
1231 }
1232 break;
1233
1234 case RAM_KIND :
1235 case RAM2_KIND :
1236 authorize_option(NO, out);
1237 str1 = get_sign_and_token(str1, sgn, tok1);
1238 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "RAM name")) {
1239 break;
1240 }
1241 a = record_id(tok1);
1242 if (UNDEFINED != a) {
1243 print_error_location(tg, ml, mf);
1244 (void) fprintf(STDERR, " the array <%s[]> is not a RAM but an array of pointers\n", tok1);
1245 flag_node(out);
1246 break;
1247 }
1248 a = array_id(tok1);
1249 if (UNDEFINED == a) {
1250 print_error_location(tg, ml, mf);
1251 (void) fprintf(STDERR, " RAM array <%s[]> is not declared\n", tok1);
1252 process_array_error(tok1);
1253 flag_node(out);
1254 break;
1255 }
1256 if ((0 == is_node_flagged(out)) && ((ROM_KIND == Array_List[a].kind) || (ROM2_KIND == Array_List[a].kind))) {
1257 print_error_location(tg, ml, mf);
1258 (void) fprintf(STDERR, " the array <%s[]> is already used as a ROM\n", tok1);
1259 flag_node(out);
1260 break;
1261 }
1262 if ((0 == is_node_flagged(out)) && (kd != Array_List[a].kind) && (0L < Array_List[a].port)) {
1263 print_error_location(tg, ml, mf);
1264 (void) fprintf(STDERR, " RAM <%s[]> port definitions are not consistent (single or dual port?)\n", tok1);
1265 flag_node(out);
1266 break;
1267 }
1268 Array_List[a].kind = kd;
1269 (Array_List[a].port)++;
1270 if ((0 == is_node_flagged(out)) && (RAM_KIND == Array_List[a].kind) && (1L < Array_List[a].port)) {
1271 print_error_location(tg, ml, mf);
1272 (void) fprintf(STDERR, " <%s[]>: single-port RAM cannot be used as a dual port RAM\n", tok1);
1273 flag_node(out);
1274 break;
1275 }
1276 str1 = get_token_between_braces(str1, brck, tok2);
1277 if ((0 == is_node_flagged(out)) && ((0 != strcmp(brck, "[]")) || ISEMPTY(tok2))) {
1278 print_error_location(tg, ml, mf);
1279 (void) fprintf(STDERR, " address node of RAM <%s[]> is not correct\n", tok1);
1280 flag_node(out);
1281 break;
1282 }
1283 if (0 != check_syntax(NODE | NUMBER, NOSIGN, " ", tok2, out, "address of RAM")) {
1284 break;
1285 }
1286 str1 = get_sign_and_token(str1, sgn, tok2);
1287 if (0 != check_syntax(NODE | VARIABLE | NUMBER, NOSIGN, sgn, tok2, out, "RAM chip select")) {
1288 break;
1289 }
1290 str1 = get_sign_and_token(str1, sgn, tok2);
1291 if (0 != check_syntax(NODE | NUMBER, NOSIGN, sgn, tok2, out, "read/write of RAM")) {
1292 break;
1293 }
1294 str1 = get_sign_and_token(str1, sgn, tok2);
1295 if (0 != check_syntax(NODE, NOSIGN, sgn, tok2, out, "input of RAM")) {
1296 break;
1297 }
1298 if (0 != something_else(str1, out)) {
1299 break;
1300 }
1301 break;
1302
1303 case DTOOL_KIND :
1304 case ITOOL_KIND :
1305 authorize_option(999, out);
1306 str1 = get_sign_and_token(str1, sgn, tok1);
1307 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "user defined tool")) {
1308 break;
1309 }
1310 for (;;) {
1311 str1 = get_sign_and_token(str1, sgn, tok1);
1312 if (ISEMPTY(tok1)) {
1313 break;
1314 }
1315 a = array_id(tok1);
1316 if (UNDEFINED != a) {
1317 print_error_location("user defined tool", ml, mf);
1318 (void) fprintf(STDERR, " <%s[]> is declared as a memory array, arrays of \n", tok1);
1319 (void) fprintf(STDERR, " pointers are the only arrays allowed as parameters\n" );
1320 break;
1321 }
1322 }
1323 break;
1324
1325 case DUSER_KIND :
1326 case IUSER_KIND :
1327 authorize_option(999, out);
1328 str1 = get_sign_and_token(str1, sgn, tok1);
1329 if (0 != check_syntax(DONTCARE, NOSIGN, sgn, tok1, out, "user defined function")) {
1330 break;
1331 }
1332 for (;;) {
1333 str1 = get_sign_and_token(str1, sgn, tok1);
1334 if (ISEMPTY(tok1)) {
1335 break;
1336 }
1337 a = array_id(tok1);
1338 if (UNDEFINED != a) {
1339 print_error_location("user defined function", ml, mf);
1340 (void) fprintf(STDERR, " <%s[]> is declared as a memory array, arrays of\n", tok1);
1341 (void) fprintf(STDERR, " pointers are the only arrays allowed as parameters\n");
1342 break;
1343 }
1344 }
1345 break;
1346
1347 case UNKNOWN_KIND :
1348 default :
1349 print_error_location(tg, ml, mf);
1350 (void) fprintf(STDERR, " node kind is not recognized\n");
1351 process_node_error(tok1);
1352 flag_node(out);
1353 Node_List[out].type = UNKNOWN_TYPE;
1354 break;
1355
1356 }
1357 }
1358 return;
1359}
1360
1361
1362void syntax_records(void) {
1363 long i, j, n, r, v;
1364 char *s = (char*) NULL;
1365 char *t = (char*) NULL;
1366 char sgn[2] = {'\0'};
1367 char tok[STRLENGTH] = {'\0'};
1368 for (i = 0L; i < Num_Records; i++) {
1369 j = 0L;
1370 s = Record_List[i].list1; /* list of parameters */
1371 for (;;) {
1372 s = get_sign_and_token(s, sgn, tok);
1373 if ((0 == strcmp(sgn, "-")) || (0 == strcmp(sgn, "+"))) {
1374 if (is_an_identifier(tok)) {
1375 print_error_location("record", Record_List[i].mline, Record_List[i].mfile);
1376 (void) fprintf(STDERR, " no sign is allowed in the list of parameters of a record\n");
1377 }
1378 }
1379 if (ISEMPTY(tok)) {
1380 break;
1381 }
1382 t = strstr(tok, "::");
1383 if ((char*) NULL != t) {
1384 (void) strcpy(tok, t+2); /* passing by name, extract the variable for verification */
1385 }
1386 n = node_id(tok);
1387 r = record_id(tok);
1388 v = var_id(tok);
1389 if ((UNDEFINED==n) && (UNDEFINED==r) && (UNDEFINED==v) && (UNKNOWN_TYPE==constant_type(tok)) && (0!=strcmp(tok, "void"))) {
1390 print_error_location("array", Record_List[i].mline, Record_List[i].mfile);
1391 (void) fprintf(STDERR, " in array of pointers <%s[%ld]>,\n", Record_List[i].name, Record_List[i].size);
1392 (void) fprintf(STDERR, " <%s> is not an array of pointers, a variable, a node identifier, a number nor a string\n", tok);
1395 continue;
1396 }
1397 j++;
1398 }
1399 if (0L == Record_List[i].size) { /* store size if size was not indicated */
1400 Record_List[i].size = j;
1401 Record_List[i].nrow = 1L;
1402 Record_List[i].ncol = j;
1403 } else if ((j != Record_List[i].size) && (0 == Error_Flag)) {
1404 print_error_location("array", Record_List[i].mline, Record_List[i].mfile);
1405 (void) fprintf(STDERR, " Mismatch in array of pointers <%s[%ld]>,\n", Record_List[i].name, Record_List[i].size);
1406 (void) fprintf(STDERR, " the actual number #%ld of parameters is not compatible with declaration\n", j);
1407 continue;
1408 }
1409 }
1410 return;
1411}
1412
1413
1414void syntax_segment_value(void) { /* 'drop' segment */
1415 long nseg;
1416 char *str = (char*) NULL;
1417 char tok[STRLENGTH] = {'\0'};
1418
1419 for (nseg = 0L; nseg < Num_Segments; nseg++) {
1420 if (DROP_SEGMENT_TYPE != Segment_List[nseg].type) {
1421 continue;
1422 }
1423 str = Segment_List[nseg].value;
1424 for (;;) {
1425 str = get_token(str, tok, false);
1426 if (0 == strcmp(tok, "when")) {
1427 print_error_location("drop", Segment_List[nseg].mline, Segment_List[nseg].mfile);
1428 (void) fprintf(STDERR, " keyword 'when' is not allowed in a drop statement\n");
1429 }
1430 if (ISEMPTY(tok)) {
1431 break;
1432 }
1433 }
1434 str = Segment_List[nseg].value;
1435 C_syntax_checker(str, Segment_List[nseg].mline, Segment_List[nseg].mfile);
1436 }
1437 return;
1438}
1439
1440
1442 char *str = (char*) NULL;
1443 char tok[STRLENGTH] = {'\0'};
1444
1445 str = Terminate_List.condition;
1446 for (;;) {
1447 str = get_token(str, tok, true);
1448 if (0 == strcmp(tok, "when")) {
1449 print_error_location("terminate", Terminate_List.mline, Terminate_List.mfile);
1450 (void) fprintf(STDERR, " keyword 'when' is not allowed in a terminate statement\n");
1451 }
1452 if (ISEMPTY(tok)) {
1453 break;
1454 }
1455 }
1456 str = Terminate_List.condition;
1458 return;
1459}
1460
1461
1462void syntax_updates(void) {
1463 long out;
1464 long m, v;
1465 char *str = (char*) NULL;
1466 char tok[STRLENGTH] = {'\0'};
1467 unsigned long *ml = (unsigned long*) NULL;
1468 unsigned long *mf = (unsigned long*) NULL;
1469
1470 for (out = 0L; out < Num_Updates; out++) {
1471 str = Update_List[out].value;
1472 ml = Update_List[out].mline;
1473 mf = Update_List[out].mfile;
1474 v = var_id(Update_List[out].name);
1475 if (UNDEFINED != v) {
1476 if (0 == strcmp(Var_List[v].value, "void")) {
1477 print_error_location("update", ml, mf);
1478 (void) fprintf(STDERR, " the variable <%s> has been defined as (void) and cannot be updated\n", Update_List[out].name);
1479 }
1480 }
1481 C_syntax_checker(str, ml, mf);
1482 str = Update_List[out].value;
1483 for (;;) {
1484 str = get_token(str, tok, true);
1485 if (ISEMPTY(tok)) {
1486 break;
1487 }
1488 m = record_id(tok);
1489 if (UNDEFINED != m) {
1490 print_error_location("update", ml, mf);
1491 (void) fprintf(STDERR, " array of pointers, here <%s>, cannot be used", Record_List[m].name);
1492 (void) fprintf(STDERR, " in the update of variable <%s>\n", Update_List[out].name);
1493 }
1494 m = array_id(tok);
1495 if (UNDEFINED != m) {
1496 print_error_location("update", ml, mf);
1497 (void) fprintf(STDERR, " arrays, here <%s>, cannot be used", Array_List[m].name);
1498 (void) fprintf(STDERR, " in the update of variable <%s>\n", Update_List[out].name);
1499 }
1500 }
1501 }
1502 return;
1503}
1504
1505
1507 long out;
1508 long typ;
1509 long m;
1510 char *str = (char*) NULL;
1511 char tok[STRLENGTH] = {'\0'};
1512 unsigned long *ml = (unsigned long*) NULL;
1513 unsigned long *mf = (unsigned long*) NULL;
1514 for (out = 0L; out < Num_Vars; out++) {
1515 typ = Var_List[out].type;
1516 if ((DIGITAL_DATA_TYPE != typ) && (ANALOG_DATA_TYPE != typ)) {
1517 continue;
1518 }
1519 str = Var_List[out].value;
1520 ml = Var_List[out].mline;
1521 mf = Var_List[out].mfile;
1522 if ((DIGITAL_DATA_TYPE == typ) || (ANALOG_DATA_TYPE == typ)) {
1523 if ((!Var_List[out].external) && (is_a_string(str))) {
1524 if (DIGITAL_DATA_TYPE == typ) {
1525 print_error_location("ivar", ml, mf);
1526 }
1527 if (ANALOG_DATA_TYPE == typ) {
1528 print_error_location("dvar", ml, mf);
1529 }
1530 (void) fprintf(STDERR, " definition of the variable cannot be a string <%s>\n", str);
1531 }
1532 }
1533 C_syntax_checker(str, ml, mf);
1534 str = Var_List[out].value;
1535 for (;;) {
1536 str = get_token(str, tok, true);
1537 if (ISEMPTY(tok)) {
1538 break;
1539 }
1540 m = record_id(tok);
1541 if (UNDEFINED != m) {
1542 print_error_location("var", ml, mf);
1543 (void) fprintf(STDERR, " array of pointers <%s> cannot be used", Record_List[m].name);
1544 (void) fprintf(STDERR, " in the definition of variable <%s>\n", Var_List[out].name1);
1545 }
1546
1547 }
1548 }
1549 return;
1550}
1551
1552
1553/* ****************************************************************************************************************************** */
1554
1555/* 'check_syntax' verifies the nature of a parameter (NODE, VARIABLE, NUMBER). */
1556/* - a parameter could be required to be a node, a var or a number */
1557/* - sign could be forbidden */
1558/* DONTCARE means that no test on this parameter has to be made. */
1559/* Print error message and returns 1 if an error has been detected, returns 0 otherwise. */
1560
1561long check_syntax(long to_be, long no_sign, const char *sgn, char *tok, long id, const char *txt) {
1562 int not_to_be;
1563 int test;
1564 unsigned long *ml = (unsigned long*) NULL;
1565 unsigned long *mf = (unsigned long*) NULL;
1566 char *tg = (char*) NULL;
1567 int nflag, vflag;
1568
1569 ml = Node_List[id].mline;
1570 mf = Node_List[id].mfile;
1571 tg = Node_List[id].tag;
1572 nflag = false;
1573 vflag = false;
1574 test = false;
1575 not_to_be = (int) (((0L == to_be)) & 15L) ? 1L : 0L;
1576 if (ISEMPTY(tok) && ((0 == is_node_flagged(id)))) {
1577 print_error_location(tg, ml, mf);
1578 (void) fprintf(STDERR, " %s is missing\n", txt);
1579 flag_node(id);
1580 return 1L;
1581 }
1582 if ((0 != (not_to_be & NODE)) && (UNDEFINED != node_id(tok)) && ((0 == is_node_flagged(id)))) {
1583 print_error_location(tg, ml, mf);
1584 (void) fprintf(STDERR, " %s <%s> cannot be a node\n", txt, tok);
1585 flag_node(id);
1586 return 1;
1587 }
1588 if ((0 != (not_to_be & VARIABLE)) && (UNDEFINED != var_id(tok)) && ((0 == is_node_flagged(id)))) {
1589 print_error_location(tg, ml, mf);
1590 (void) fprintf(STDERR, " %s <%s> cannot be a variable\n", txt, tok);
1591 flag_node(id);
1592 return 1L;
1593 }
1594 if ((0 != (not_to_be & NUMBER)) && ((ANALOG_DATA_TYPE == constant_type(tok))
1595 || (HEX_DATA_TYPE == constant_type(tok)) || (DIGITAL_DATA_TYPE == constant_type(tok))) && ((0 == is_node_flagged(id)))) {
1596 print_error_location(tg, ml, mf);
1597 (void) fprintf(STDERR, " %s <%s> cannot be a constant number\n", txt, tok);
1598 flag_node(id);
1599 return 1L;
1600 }
1601 if (((0 == strcmp(sgn, "-")) || (0 == strcmp(sgn, "+"))) && (NOSIGN == no_sign) && (0 == is_node_flagged(id))) {
1602 print_error_location(tg, ml, mf);
1603 (void) fprintf(STDERR, " %s <%s> cannot be signed\n", txt, tok);
1604 flag_node(id);
1605 return 1L;
1606 }
1607 if ((0 != (DONTCARE != to_be)) && (UNDEFINED != array_id(tok)) && ((0 == is_node_flagged(id)))) {
1608 print_error_location(tg, ml, mf);
1609 (void) fprintf(STDERR, " %s <%s> is invalid as it is declared as array\n", txt, tok);
1610 flag_node(id);
1611 return 1L;
1612 }
1613 if ((0 != (DONTCARE != to_be)) && (UNDEFINED != op_id(tok)) && ((0 == is_node_flagged(id)))) {
1614 print_error_location(tg, ml, mf);
1615 (void) fprintf(STDERR, " %s <%s> is invalid as it is declared as opcode\n", txt, tok);
1616 flag_node(id);
1617 return 1L;
1618 }
1619 if ((0 != (to_be & NODE)) && (UNDEFINED != node_id(tok))) {
1620 test = true;
1621 }
1622 if ((0 != (to_be & VARIABLE)) && (UNDEFINED != var_id(tok))) {
1623 test = true;
1624 }
1625 if ((0 != (to_be & NUMBER)) && ((ANALOG_DATA_TYPE == constant_type(tok))
1626 || (HEX_DATA_TYPE == constant_type(tok)) || (DIGITAL_DATA_TYPE == constant_type(tok)))) {
1627 test = true;
1628 }
1629 if ((0 != (to_be & STRING)) && (STRING_DATA_TYPE == constant_type(tok))) {
1630 test = true;
1631 }
1632 if ((!test) && (0 != (DONTCARE != to_be)) && ((0 == is_node_flagged(id)))) {
1633 nflag = false;
1634 vflag = false;
1635 print_error_location(tg, ml, mf);
1636 (void) fprintf(STDERR, " %s <%s> must be", txt, tok);
1637 if (0 != (to_be & NODE)) {
1638 (void) fprintf(STDERR, " a node");
1639 nflag = true;
1640 }
1641 if (0 != (to_be & VARIABLE)) {
1642 if (0 != (to_be & NODE)) {
1643 (void) fprintf(STDERR, " or");
1644 }
1645 (void) fprintf(STDERR, " a variable");
1646 vflag = true;
1647 }
1648 if (0 != (to_be & NUMBER)) {
1649 if ((0 != (to_be & NODE)) || (0 != (to_be & VARIABLE))) {
1650 (void) fprintf(STDERR, " or");
1651 }
1652 (void) fprintf(STDERR, " a constant number");
1653 }
1654 if (0 != (to_be & STRING)) {
1655 if ((0 != (to_be & NODE)) || (0 != (to_be & VARIABLE)) || (0 != (to_be & NUMBER))) {
1656 (void) fprintf(STDERR, " or");
1657 }
1658 (void) fprintf(STDERR, " a string");
1659 }
1660 (void) fprintf(STDERR, "\n");
1661 if (nflag) {
1662 process_node_error(tok);
1663 }
1664 if (vflag) {
1666 }
1667 flag_node(id);
1668 return 1L;
1669 }
1670 return 0L;
1671}
1672
1673
1674void authorize_option(long num, long id) {
1675 long i;
1676 char *tg = (char*) NULL;
1677 char *str = (char*) NULL;
1678 char tok[STRLENGTH] = {'\0'};
1679 char sgn[3] = {'\0'};
1680 unsigned long *ml = (unsigned long*) NULL;
1681 unsigned long *mf = (unsigned long*) NULL;
1682 if (-1L == num) { /* no check */
1683 return;
1684 }
1685 ml = Node_List[id].mline;
1686 mf = Node_List[id].mfile;
1687 tg = Node_List[id].tag;
1688 str = Node_List[id].option;
1689 i = 0L;
1690 for (;;) {
1691 str = get_sign_and_token(str, sgn, tok);
1692 if (ISEMPTY(tok)) {
1693 break;
1694 }
1695 i++;
1696 }
1697 if ((0L != i) && (0L == num) && (0 == is_node_flagged(id))) {
1698 print_error_location(tg, ml, mf);
1699 (void) fprintf(STDERR, " no qualifier is expected for this node,\n");
1700 (void) fprintf(STDERR, " current qualifier list is ");
1701 str = Node_List[id].option;
1702 for (;;) {
1703 str = get_sign_and_token(str, sgn, tok);
1704 if (ISEMPTY(tok)) {
1705 break;
1706 }
1707 (void) fprintf(STDERR, "(%s) ", tok);
1708 }
1709 (void) fprintf(STDERR, "\n");
1710 flag_node(id);
1711 }
1712 if ((i > num) && (0 == is_node_flagged(id))) {
1713 print_error_location(tg, ml, mf);
1714 if (1L == num) {
1715 (void) fprintf(STDERR, " up to %ld qualifier is expected for this node,\n", num);
1716 } else {
1717 (void) fprintf(STDERR, " up to %ld qualifiers are expected for this node,\n", num);
1718 }
1719 (void) fprintf(STDERR, " current qualifier list is ");
1720 str = Node_List[id].option;
1721 for (;;) {
1722 str = get_sign_and_token(str, sgn, tok);
1723 if (ISEMPTY(tok)) {
1724 break;
1725 }
1726 (void) fprintf(STDERR, "(%s) ", tok);
1727 }
1728 (void) fprintf(STDERR, "\n");
1729 flag_node(id);
1730 }
1731 return;
1732}
1733
1734
1735/* Print error message and returns 1 if an error has been detected, returns 0 otherwise. */
1736
1737long something_else(const char *tok, long id) {
1738 char *tg = (char*) NULL;
1739 unsigned long *ml = (unsigned long*) NULL;
1740 unsigned long *mf = (unsigned long*) NULL;
1741 ml = Node_List[id].mline;
1742 mf = Node_List[id].mfile;
1743 tg = Node_List[id].tag;
1744 if (ISNOTEMPTY(tok) && (0 == is_node_flagged(id))) {
1745 print_error_location(tg, ml, mf);
1746 (void) fprintf(STDERR, " unexpected text appears at the end of node definition: <%s>\n", tok);
1747 flag_node(id);
1748 return 1L;
1749 }
1750 return 0L;
1751}
1752
1753
1754/* Check that parenthesis, curly and rectangular brackets are balanced and that single quotes and double quotes are paired. */
1755/* Triangular brackets are NOT checked... (as comparisons symbols interfere: in '>=', '<=', '>', '<', they are not balanced) */
1756/* Check that unary ANSI-C operators ++, --, += ... are not present (forbidden in the NAPA syntax). */
1757
1758void sanity_check(char *s, const unsigned long *mlin, const unsigned long *mfil) { /* check quotes, brackets */
1759 char *t = (char*) NULL;
1760 long dq = 0L; /* 0: outside string */
1761 long c0 = 0L; /* counter of ''' */
1762 long c1 = 0L; /* counter of '"' */
1763 long c2 = 0L; /* counter of '(' and ')' */
1764 long c3 = 0L; /* counter of '[' and ']' */
1765 long c4 = 0L; /* counter of '{' and '}' */
1766 t = s;
1767 while ((isspace((int) *t)) && ('\0' != *t)) { /* take first non blank char */
1768 t++;
1769 }
1770 if ('#' == *t) { /* clear comment line */
1771 *s = '\0';
1772 return;
1773 }
1774 t = s; /* start at 1st non blank char */
1775 while ('\0' != *t) {
1776 if ('"' == *t) { /* inside or outside string? */
1777 dq = (1L == dq) ? 0L : 1L; /* toggle, 0/1: outside/inside double quote comment */
1778 }
1779 if ((t > s) && ('/' == *t) && ('/' == *(t-1)) && (0L == dq)) {
1780 break; /* no verification after '//' */
1781 }
1782 if (((t > s) && ('+' == *(t-1)) && ('+' == *t)) || ((t > s) && ('-' == *(t-1)) && ('-' == *t))) { /* ++, -- */
1783 if (0L == dq) { /* error if outside a string */
1784 print_error_location( "syntax limitation", mlin, mfil);
1785 (void) fprintf(STDERR, " Sorry!To avoid side effects, ANSI-C operator %c%c\n", *(t-1), *t);
1786 (void) fprintf(STDERR, " cannot be used explicitely in the NAPA netlist description\n");
1788 }
1789 }
1790 if (((t > s) && ('+' == *(t-1)) && ('=' == *t)) || ((t > s) && ('-' == *(t-1)) && ('=' == *t)) /* +=, -= */
1791 || ((t > s) && ('*' == *(t-1)) && ('=' == *t)) || ((t > s) && ('/' == *(t-1)) && ('=' == *t)) /* *=, &= */
1792 || ((t > s) && ('%' == *(t-1)) && ('=' == *t)) || ((t > s) && ('&' == *(t-1)) && ('=' == *t)) /* %=, &= */
1793 || ((t > s) && ('|' == *(t-1)) && ('=' == *t)) || ((t > s) && ('^' == *(t-1)) && ('=' == *t))) { /* |=, ^= */
1794 if (0L == dq) { /* error if outside a string */
1795 print_error_location( "syntax limitation", mlin, mfil);
1796 (void) fprintf(STDERR, " Sorry!To avoid side effects, ANSI-C assignation %c%c\n", *(t-1), *t);
1797 (void) fprintf(STDERR, " cannot be used explicitely in the NAPA netlist description\n");
1799 }
1800 }
1801 if (('\'' == *t) && (0 == dq)) { /* do not count quotes inside double quote comment */
1802 c0++;
1803 } else if ('"' == *t) {
1804 c1++;
1805 } else {
1806 if ((0L == (c0 % 2L)) && (0L == (c1 % 2L))) { /* no verification inside '...' and "..." */
1807 switch (*t) {
1808 case '(':
1809 c2++;
1810 break;
1811 case ')':
1812 c2--;
1813 if (0L > c2) {
1814 print_error_location( "syntax", mlin, mfil);
1815 (void) fprintf(STDERR, " unmatched closing parenthesis in <%s> ?\n", s);
1816 (void) fprintf(STDERR, " %*s^\n", (int) ABS(t-s), " ");
1818 }
1819 break;
1820 case '[':
1821 c3++;
1822 break;
1823 case ']':
1824 c3--;
1825 if (0L > c3) {
1826 print_error_location( "syntax", mlin, mfil);
1827 (void) fprintf(STDERR, " unmatched closing bracket in <%s> ?\n", s);
1828 (void) fprintf(STDERR, " %*s^\n", (int) ABS(t-s), " ");
1830 }
1831 break;
1832 case '{':
1833 c4++;
1834 break;
1835 case '}':
1836 c4--;
1837 if (0L > c4) {
1838 print_error_location( "syntax", mlin, mfil);
1839 (void) fprintf(STDERR, " unmatched closing curly bracket in <%s> ?\n", s);
1841 }
1842 break;
1843 default:
1844 break;
1845 }
1846 }
1847 }
1848 t++;
1849 }
1850 if (0L != (c0 % 2L)) {
1851 print_error_location( "syntax", mlin, mfil);
1852 (void) fprintf(STDERR, " unmatched single quote in C expression <%s> ?\n", s);
1854 }
1855 if (0L != (c1 % 2L)) {
1856 print_error_location( "syntax", mlin, mfil);
1857 (void) fprintf(STDERR, " unmatched double quote in C expression <%s> ?\n", s);
1859 }
1860 if (0L < c2) {
1861 print_error_location( "syntax", mlin, mfil);
1862 (void) fprintf(STDERR, " missing closing parenthesis in C expression <%s> ?\n", s);
1864 }
1865 if (0L > c2) {
1866 print_error_location( "syntax", mlin, mfil);
1867 (void) fprintf(STDERR, " unmatched opening parenthesis in C expression <%s> ?\n", s);
1869 }
1870 if (0L < c3) {
1871 print_error_location( "syntax", mlin, mfil);
1872 (void) fprintf(STDERR, " missing closing rectangular bracket in C expression <%s> ?\n", s);
1874 }
1875 if (0L > c3) {
1876 print_error_location( "syntax", mlin, mfil);
1877 (void) fprintf(STDERR, " unmatched opening rectangular bracket in C expression <%s> ?\n", s);
1879 }
1880 if (0L < c4) {
1881 print_error_location( "syntax", mlin, mfil);
1882 (void) fprintf(STDERR, " missing closing curly bracket in C expression <%s> ?\n", s);
1884 }
1885 if (0L > c4) {
1886 print_error_location( "syntax", mlin, mfil);
1887 (void) fprintf(STDERR, " unmatched curly bracket in C expression <%s> ?\n", s);
1889 }
1890 return;
1891}
1892
1893
1894/* Check C syntax (parenthesis, brackets, single and double quotes, and assignations in a wrong places */
1895
1896void C_syntax_checker(char *str, const unsigned long *mlin, const unsigned long *mfil) {
1897 static int flag = false;
1898 char* s = (char*) NULL;
1899 sanity_check(str, mlin, mfil);
1900 s = str;
1901 while ('\0' != *(s+1)) {
1902 if ('=' == *(s+1)) { /* a character '=' is detected */
1903 if (('=' == *s) || ('!' == *s) || ('>' == *s) || ('<' == *s)) { /* '==', '!=', '>=' or '<=' OK! */
1904 s++;
1905 continue;
1906 } else {
1907 if ('=' == *(s+2)) { /* '==' OK! */
1908 s++;
1909 continue;
1910 } else if (('>' == *(s+2)) || ('<' == *(s+2)) || ('!' == *(s+2))) { /* '=!', '=>' or '=<' mispelled */
1911 print_error_location("syntax", mlin, mfil);
1912 (void) fprintf(STDERR, " no assignation is expected in expression ' %s '\n", str);
1913 if (flag) {
1914 flag = true;
1915 break; /* parsing of instruction may continue */
1916 } else {
1918 }
1919 } else { /* single '=' assignation is forbidden */
1920 print_error_location("syntax", mlin, mfil);
1921 (void) fprintf(STDERR, " no assignation is expected in expression ' %s '\n", str);
1922 if (flag) {
1923 flag = true;
1924 break; /* parsing of instruction may continue */
1925 } else {
1927 }
1928 }
1929 }
1930 }
1931 s++;
1932 }
1933 return;
1934}
1935
1936
1937/* ****************************************************************************************************************************** */
1938/* end of file */
int verify_rshift(void)
Definition fc.c:1400
void print_location(const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1510
void print_warning_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1484
void print_error_location(const char *type, const unsigned long *mlin, const unsigned long *mfil)
Definition fc.c:1476
long constant_type(char *identifier)
Definition id.c:1130
long get_type(char *identifier)
Definition id.c:1190
long update_id(const char *identifier, long num)
Definition id.c:807
void flag_node(long num)
Definition id.c:99
long array_id(const char *identifier)
Definition id.c:635
long op_id(const char *identifier)
Definition id.c:774
long node_id(const char *identifier)
Definition id.c:718
long var_id(const char *identifier)
Definition id.c:855
int is_node_flagged(long num)
Definition id.c:105
long record_id(const char *identifier)
Definition id.c:796
void process_array_error(const char *tok1)
Definition mp.c:441
void process_record_error(const char *tok1)
Definition mp.c:403
void process_node_error(const char *tok1)
Definition mp.c:259
void process_variable_error(const char *tok1)
Definition mp.c:331
#define DELAY2_KIND
Definition napa.h:255
#define DROP_SEGMENT_TYPE
Definition napa.h:353
#define MUX_KIND
Definition napa.h:288
#define MAXDEPTH
Definition napa.h:212
EXTERN VAR_TYPE Var_List[2047L]
Definition napa.h:970
#define STRING
Definition napa.h:368
EXTERN int Error_Flag
Definition napa.h:853
#define EQUAL_KIND
Definition napa.h:262
EXTERN RECORD_TYPE Record_List[127L]
Definition napa.h:965
#define ITOD_KIND
Definition napa.h:278
#define MOD_KIND
Definition napa.h:286
EXTERN long Num_Vars
Definition napa.h:836
#define RIP_KIND
Definition napa.h:302
EXTERN ARRAY_TYPE Array_List[63L]
Definition napa.h:950
#define MULLER_KIND
Definition napa.h:287
#define WSUM_KIND
Definition napa.h:323
#define TRACK_KIND
Definition napa.h:318
#define MACHINE
Definition napa.h:91
#define UNKNOWN_TYPE
Definition napa.h:332
#define UNDEFINED
Definition napa.h:331
EXTERN long Num_Records
Definition napa.h:828
#define RSHIFT2_KIND
Definition napa.h:307
EXTERN long Num_Updates
Definition napa.h:834
#define AND_KIND
Definition napa.h:229
#define ROM2_KIND
Definition napa.h:304
#define TRIANGLE_KIND
Definition napa.h:319
#define STDERR
Definition napa.h:105
EXTERN int Ts_Flag
Definition napa.h:884
EXTERN NODE_TYPE Node_List[4095L]
Definition napa.h:962
#define LATCH_KIND
Definition napa.h:281
#define DIFFERENTIATOR_KIND
Definition napa.h:257
#define NOSIGN
Definition napa.h:369
#define RSHIFT1_KIND
Definition napa.h:306
#define LSHIFT_KIND
Definition napa.h:282
#define INV_KIND
Definition napa.h:276
#define BWNAND_KIND
Definition napa.h:236
#define DTOI_KIND
Definition napa.h:259
#define FZNOR_KIND
Definition napa.h:267
#define OSC_KIND
Definition napa.h:294
#define CONST_KIND
Definition napa.h:246
#define DELAY3_KIND
Definition napa.h:256
EXTERN int Fs_Flag
Definition napa.h:856
#define CLOCK_KIND
Definition napa.h:244
#define NOR_KIND
Definition napa.h:291
#define ANALOG_DATA_TYPE
Definition napa.h:338
EXTERN SAMPLING_TYPE Sampling_List
Definition napa.h:978
#define ADC_KIND
Definition napa.h:226
#define COPY_KIND
Definition napa.h:247
#define OFFSET_KIND
Definition napa.h:292
#define OR_KIND
Definition napa.h:293
#define CLIP_KIND
Definition napa.h:243
EXTERN char * Record_Cell_File_Table[511L]
Definition napa.h:940
#define DONTCARE
Definition napa.h:364
#define RELAY_KIND
Definition napa.h:301
EXTERN DIRECTIVE_TYPE Directive_List[255L]
Definition napa.h:955
#define SQUARE_KIND
Definition napa.h:312
#define MIN_KIND
Definition napa.h:285
#define UADC_KIND
Definition napa.h:321
#define IUSER_KIND
Definition napa.h:280
#define NAND_KIND
Definition napa.h:289
EXTERN int Cmdline_Flag
Definition napa.h:846
#define AVERAGE_KIND
Definition napa.h:230
#define PROD_KIND
Definition napa.h:296
#define DUSER_KIND
Definition napa.h:261
#define TEST_KIND
Definition napa.h:316
EXTERN long Num_Nodes
Definition napa.h:824
#define DELAY1_KIND
Definition napa.h:254
#define GAIN_KIND
Definition napa.h:271
#define ITOB_KIND
Definition napa.h:277
#define BUF_KIND
Definition napa.h:233
#define HOLD_KIND
Definition napa.h:273
EXTERN int Ts_Ext_Flag
Definition napa.h:885
#define XOR_KIND
Definition napa.h:325
#define RAM_KIND
Definition napa.h:298
#define SIN_KIND
Definition napa.h:310
#define YES
Definition napa.h:407
#define TOGGLE_KIND
Definition napa.h:317
#define VARIABLE
Definition napa.h:366
EXTERN long Num_Directives
Definition napa.h:812
#define XNOR_KIND
Definition napa.h:324
#define BWXNOR_KIND
Definition napa.h:239
#define DALGEBRA_KIND
Definition napa.h:251
#define RECT_KIND
Definition napa.h:300
#define MERGE_KIND
Definition napa.h:284
#define ROM_KIND
Definition napa.h:303
#define FZBUF_KIND
Definition napa.h:264
#define DC_KIND
Definition napa.h:252
#define SIGN_KIND
Definition napa.h:309
#define NO
Definition napa.h:406
#define ABS(x)
Definition napa.h:374
EXTERN long Num_FileCells
Definition napa.h:814
#define NODE
Definition napa.h:365
#define FZXNOR_KIND
Definition napa.h:269
#define IALGEBRA_KIND
Definition napa.h:274
#define ALU_KIND
Definition napa.h:228
#define SUM_KIND
Definition napa.h:315
#define BWXOR_KIND
Definition napa.h:240
#define BTOI_KIND
Definition napa.h:232
#define FZNAND_KIND
Definition napa.h:266
EXTERN long Num_Segments
Definition napa.h:831
#define ISNOTEMPTY(s)
Definition napa.h:395
#define ITOOL_KIND
Definition napa.h:279
#define DTOOL_KIND
Definition napa.h:260
#define RAM2_KIND
Definition napa.h:299
#define SUB_KIND
Definition napa.h:314
#define DIV_KIND
Definition napa.h:258
#define FZOR_KIND
Definition napa.h:268
EXTERN int Fs_Ext_Flag
Definition napa.h:857
EXTERN CMDLINE_TYPE Cmdline_List[63L]
Definition napa.h:951
#define BWOR_KIND
Definition napa.h:238
#define FZXOR_KIND
Definition napa.h:270
#define POLY_KIND
Definition napa.h:295
#define RSHIFT_KIND
Definition napa.h:305
EXTERN long Num_Cmdlines
Definition napa.h:804
#define NUMBER
Definition napa.h:367
#define UDAC_KIND
Definition napa.h:322
#define ZERO_KIND
Definition napa.h:326
#define ISNOTEQUAL(x, y)
Definition napa.h:380
#define INTEGRATOR_KIND
Definition napa.h:275
#define MAX_KIND
Definition napa.h:283
EXTERN int Terminate_Flag
Definition napa.h:880
EXTERN TERMINATE_TYPE Terminate_List
Definition napa.h:980
EXTERN SEGMENT_TYPE Segment_List[127L]
Definition napa.h:966
#define STRLENGTH
Definition napa.h:217
#define BWNOR_KIND
Definition napa.h:237
#define COMP_KIND
Definition napa.h:245
#define ISEMPTY(s)
Definition napa.h:394
#define STRING_DATA_TYPE
Definition napa.h:339
#define BSHIFT_KIND
Definition napa.h:231
#define DELAY_KIND
Definition napa.h:253
#define FZINV_KIND
Definition napa.h:265
#define ALGEBRA_KIND
Definition napa.h:227
#define HEX_DATA_TYPE
Definition napa.h:340
#define BWINV_KIND
Definition napa.h:235
#define FZAND_KIND
Definition napa.h:263
#define QUANT_KIND
Definition napa.h:297
#define STEP_KIND
Definition napa.h:313
#define UNKNOWN_KIND
Definition napa.h:224
#define CHG_KIND
Definition napa.h:242
#define BWAND_KIND
Definition napa.h:234
#define DAC_KIND
Definition napa.h:250
#define TRIG_KIND
Definition napa.h:320
#define COS_KIND
Definition napa.h:248
#define NOISE_KIND
Definition napa.h:290
EXTERN int Loop_Flag
Definition napa.h:866
#define DIGITAL_DATA_TYPE
Definition napa.h:337
EXTERN UPDATE_TYPE Update_List[2047L]
Definition napa.h:968
EXTERN int Periodic_Flag
Definition napa.h:873
void print_error_banner_and_exit(void)
Definition pr.c:5482
char * upper_to_lower(char *s)
Definition tk.c:1775
char * get_token(char *str, char *tok, long keep_quotes)
Definition tk.c:1210
int is_a_string(char *str)
Definition tk.c:1369
int is_an_identifier(const char *tok)
Definition tk.c:1327
void strip_quotes(char *str)
Definition tk.c:1619
void replace_dollar(char *tok)
Definition tk.c:1713
char * get_token_between_braces(char *str, char *brc, char *tok)
Definition tk.c:1110
char * get_sign_and_token(char *str, char *sgn, char *tok)
Definition tk.c:1188
void syntax_command_line(void)
Definition sx.c:45
void authorize_option(long num, long id)
Definition sx.c:1674
void syntax_updates(void)
Definition sx.c:1462
void syntax_fs(void)
Definition sx.c:138
void syntax_directives(void)
Definition sx.c:113
void syntax_variables(void)
Definition sx.c:1506
void sanity_check(char *s, const unsigned long *mlin, const unsigned long *mfil)
Definition sx.c:1758
void syntax_records(void)
Definition sx.c:1362
long check_syntax(long to_be, long no_sign, const char *sgn, char *tok, long id, const char *txt)
Definition sx.c:1561
void syntax_nodes(void)
Definition sx.c:159
void syntax_terminate(void)
Definition sx.c:1441
long something_else(const char *tok, long id)
Definition sx.c:1737
void syntax_segment_value(void)
Definition sx.c:1414
void C_syntax_checker(char *str, const unsigned long *mlin, const unsigned long *mfil)
Definition sx.c:1896