source: git/modules/modgen/grammar.y @ 73d7b5

spielwiese
Last change on this file since 73d7b5 was 73d7b5, checked in by Kai Krüger <krueger@…>, 24 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@4321 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 20.3 KB
Line 
1/*
2 * $Id: grammar.y,v 1.14 2000-05-12 12:24:43 krueger Exp $
3 */
4
5%{
6
7#include <stdio.h>
8#include <stddef.h>
9#include <stdlib.h>
10#include <stdarg.h>
11#include <string.h>
12#include <limits.h>
13
14#include <mod2.h>
15#include <tok.h>
16
17#include "modgen.h"
18#include "stype.h"
19
20int sectnum = 1;
21int iseof = 0;
22extern moddef module_def;
23extern int yylineno;
24extern int do_create_makefile;
25extern char *sectname[];
26 
27extern int init_modgen(moddef *module_def, char *filename);
28extern int write_intro(moddefv module);
29extern void write_mod_init(moddefv module, FILE *fp);
30extern void enter_id(FILE *fp, char *name, char *value,
31                     int lineno, char *file);
32 
33procdef procedure_decl;
34
35 
36void yyerror(char * fmt)
37  {
38    if(!iseof) printf("%s at line %d\n", fmt, yylineno);
39  }
40
41%}
42
43/* %expect 22 */
44%pure_parser
45
46%token MCOLONCOLON
47%token MEQUAL
48
49/* special symbols */
50%token <i> MMODULE_CMD
51%token <i> MVERSION_CMD
52%token <i> MINFO_CMD
53%token <i> MINFOFILE_CMD
54%token <i> MHELP_CMD
55%token <i> MHELPFILE_CMD
56%token <i> MCXXSRC_CMD
57%token <i> MPROC_CMD
58
59%token SECTEND
60/* SECT2: Singular procedure declaration */
61%token SECT2START
62%token SECT2END
63/* SECT3: procedure declaration */
64%token SECT3START
65%token SECT3END
66/* SECT4: C/C++ text */
67%token SECT4START
68%token SECT4END
69
70/*%token PROCEND*/
71%token PROCDECLTOK
72%token EXAMPLETOK
73%token STATICTOK
74
75/* BISON Declarations */
76
77%token VARNAMETOK
78/*%token MSTRINGTOK */
79%token <sv>   MSTRINGTOK
80%token <name> NAME
81%token <name> FILENAME
82%token <name> MCCODETOK
83%token <name> MCODETOK
84%token <name> CODEPART
85%token <name> CMTPART
86%token <name> PROCCMD
87%token <name> ANYTOK
88%token  <tp> VARTYPETOK
89%token <i>    NUMTOK
90%token <i>    BOOLTOK
91
92%type <i>    '='
93%type <name> identifier
94
95%nonassoc '='
96%%
97goal: part1 sect3 sect3end sect4
98      {
99          if(trace)printf("Finish modules 1\n");
100          return 0;
101      }
102      | part1 sect3full sect4
103      {
104          if(trace)printf("Finish modules 2\n");
105          return 0;
106      }
107      | part1 sect2full sect3full sect4
108      {
109          if(trace)printf("Finish modules 3\n");
110          return 0;
111      }
112      | part1 sect3full sect2full sect4
113      {
114          if(trace)printf("Finish modules 4\n");
115          return 0;
116      }
117;
118
119part1: initmod sect1 sect1end
120        {
121          if(do_create_makefile)mod_create_makefile(&module_def);
122          if(write_intro(&module_def)) {
123            return(myyyerror("Error while creating files\n"));
124          }
125        }
126        | sect1 sect1end
127        {
128          write_mod_init(&module_def, module_def.fmtfp);
129          if(do_create_makefile)mod_create_makefile(&module_def);
130          if(write_intro(&module_def)) {
131            return(myyyerror("Error while creating files\n"));
132          }
133        }
134        | sect1end
135        {
136          write_mod_init(&module_def, module_def.fmtfp);
137          if(do_create_makefile)mod_create_makefile(&module_def);
138          if(write_intro(&module_def)) {
139            return(myyyerror("Error while creating files\n"));
140          }
141        };
142
143initmod:
144        MCCODETOK
145        {
146          fprintf(module_def.fmtfp, "%s", $1);
147          fprintf(module_def.fmtfp, "#line %d \"%s\"\n",
148                                          yylineno, module_def.filename);
149          free($1);
150          write_mod_init(&module_def, module_def.fmtfp);
151        }
152
153sect1: expr ';'
154       | sect1 expr ';'
155;
156
157       
158sect1end: SECTEND
159        {
160          memset(&procedure_decl, 0, sizeof(procdef));
161          if(debug>2)printf("End of section 1 (new=%d)\n", sectnum);
162        }
163        ;
164
165expr:   NAME '=' MSTRINGTOK
166        {
167          var_token vt;
168          int rc = 0;
169          void (*write_cmd)(moddefv module, var_token type = VAR_NONE,
170                            idtyp t, void *arg1 = NULL, void *arg2 = NULL);
171         
172          switch(sectnum) {
173              case 1: /* pass 1: */
174                if( (vt=checkvar($1, VAR_STRING, &write_cmd)) ) {
175                  if(write_cmd!=0)
176                    write_cmd(&module_def, vt, STRING_CMD, $1, $3.string);
177                  if(vt==VAR_VERSION)
178                    make_version($3.string, &module_def);
179                }
180                else {
181                  rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n",
182                            yylineno, $1, sectnum);
183                }
184                break;
185              case 3: /* pass 3: procedure declaration */
186                if( (vt=checkvar($1, VAR_STRING, &write_cmd)) ) {
187                  proc_set_var(&procedure_decl, VAR_STRING, vt, $1, $3.string);
188                }
189                else {
190                  rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n",
191                            yylineno, $1, sectnum);
192                }
193                break;
194              default: break;
195               
196          }
197          free($1);
198          free($3.string);
199          if(rc)return(rc);
200        }
201        | NAME '=' FILENAME
202        { var_token vt;
203          void (*write_cmd)(moddefv module, var_token type = VAR_NONE,
204                            idtyp t, void *arg1 = NULL, void *arg2 = NULL);
205          switch(sectnum) {
206              case 1: /* pass 1: */
207                Add2files(&module_def, $3);
208                break;
209              case 3: /* pass 3: procedure declaration */
210                if( (vt=checkvar($1, VAR_FILE, &write_cmd)) ) {
211                  proc_set_var(&procedure_decl, VAR_FILE, vt, $1, $3);
212                }
213                break;
214              default: break;
215               
216          }
217          free($1);
218          free($3);
219        }
220        | NAME '=' files
221        { var_token vt;
222          void (*write_cmd)(moddefv module, var_token type = VAR_NONE,
223                            idtyp t, void *arg1 = NULL, void *arg2 = NULL);
224          switch(sectnum) {
225              case 1: /* pass 1: */
226                break;
227              case 3: /* pass 3: procedure declaration */
228                if( (vt=checkvar($1, VAR_FILES, &write_cmd)) ) {
229                  proc_set_var(&procedure_decl, VAR_FILES, vt, $1, &$3);
230                }
231                break;
232              default: break;
233               
234          }
235          free($1);
236          //free($3);
237        }
238        | NAME '=' NUMTOK
239        { var_token vt;
240          void (*write_cmd)(moddefv module, var_token type = VAR_NONE,
241                            idtyp t, void *arg1 = NULL, void *arg2 = NULL);
242          switch(sectnum) {
243              case 1: /* pass 1: */
244                break;
245              case 3: /* pass 3: procedure declaration */
246                if( (vt=checkvar($1, VAR_NUM, &write_cmd)) ) {
247                  proc_set_var(&procedure_decl, VAR_NUM, vt, $1, &$3);
248                }
249                break;
250              default: break;
251               
252          }
253          free($1);
254        }
255        | NAME '=' BOOLTOK
256        {
257          var_token vt;
258          int rc = 0;
259          void (*write_cmd)(moddefv module, var_token type = VAR_NONE,
260                            idtyp t, void *arg1 = NULL, void *arg2 = NULL);
261          switch(sectnum) {
262              case 1: /* pass 1: */
263                if( (vt=checkvar($1, VAR_BOOL, &write_cmd)) ) {
264                  proc_set_default_var(VAR_BOOL, vt, $1, &$3);
265                }
266                else {
267                  rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n",
268                            yylineno, $1, sectnum);
269                }
270                break;
271              case 3: /* pass 3: procedure declaration */
272                if( (vt=checkvar($1, VAR_BOOL, &write_cmd)) ) {
273                  proc_set_var(&procedure_decl, VAR_BOOL, vt, $1, &$3);
274                }
275                else {
276                  rc=myyyerror("Line %d: Unknown variable '%s' in section %d\n",
277                            yylineno, $1, sectnum);
278                }
279                break;
280              default: break;
281               
282          }
283          free($1);
284          if(rc)return(rc);
285        }
286;
287
288files:  FILENAME ',' FILENAME
289        {
290          if(debug>2)printf(">>>>>>>>files '%s' , '%s'\n", $1, $3);
291          Add2files(&module_def, $1);
292          Add2files(&module_def, $3);
293          free($1);
294          free($3);
295        }
296;
297
298sect2full: SECT2START sect2 sect2end;
299
300sect2: procdefsg
301       | sect2 procdefsg
302       ;
303
304sect2end: SECT2END
305{
306          if(debug>2)printf("End of section 'Singular' 2 (%d)\n",
307                            sectnum);
308};
309
310
311sect3full: SECT3START sect3 sect3end;
312
313sect3:  procdef
314        | sect3 procdef
315        ;
316
317sect3end: SECT3END
318        {
319          write_finish_functions(&module_def, &procedure_decl);
320          if(debug>2)printf("End of section 'procedures' 3 (%d)\n",
321                            sectnum);
322        }
323        ;
324
325/*
326 */
327procdefsg: procdeclsg proccode
328        {
329          if(debug>2)printf("SG-PROCDEF:\n");
330        }
331        | procdecl proccode procdeclexample
332        {
333          if(debug>2)printf("SG-PROCDEF mit example:\n");
334          fflush(module_def.fmtfp);
335        }
336;
337
338procdeclsg: procdeclsg2 '{'
339        {
340          setup_proc(&module_def, &procedure_decl);
341        }
342        | procdeclsg2 procdeclhelp '{'
343        {
344          setup_proc(&module_def, &procedure_decl);
345        }
346        ;
347
348procdeclsg2: procdecl1 '(' sgtypelist ')'
349         {
350           write_singular_parameter(&module_def, yylineno, "list", "#");
351           procedure_decl.lineno_other = yylineno;
352         }
353        | procdecl1
354         {
355           write_singular_parameter(&module_def, yylineno, "list", "#");
356           procedure_decl.lineno_other = yylineno;
357         }
358        | procdecl1 '(' ')'
359         {
360           write_singular_parameter(&module_def, yylineno, "list", "#");
361           procedure_decl.lineno_other = yylineno;
362         }
363        ;
364
365procdecl1: PROCDECLTOK NAME
366        {
367          init_proc(&procedure_decl, $2, NULL, yylineno, LANG_SINGULAR);
368          free($2);
369          if(write_singular_procedures(&module_def, &procedure_decl))
370            return(myyyerror("Error while creating bin-file\n"));
371        }
372        | STATICTOK PROCDECLTOK NAME
373        {
374          init_proc(&procedure_decl, $3, NULL, yylineno, LANG_SINGULAR);
375          procedure_decl.is_static = TRUE;
376          free($3);
377          if(write_singular_procedures(&module_def, &procedure_decl))
378            return(myyyerror("Error while creating bin-file\n"));
379        };
380
381procdef: procdecl proccode
382        {
383          if(debug>2)printf("PROCDEF:\n");
384        }
385        | procdecl proccode procdeclexample
386        {
387          if(debug>2)printf("PROCDEF mit example:\n");
388          fflush(module_def.fmtfp);
389        }
390        ;
391
392procdecl: procdecl2 '{'
393        {
394          setup_proc(&module_def, &procedure_decl);
395        }
396        | procdecl2 procdeclhelp '{'
397        {
398          setup_proc(&module_def, &procedure_decl);
399        }
400        ;
401
402procdecl2: funcdecl1
403        | funcdecl1 '(' ')'
404        | funcdecl1 '(' typelist ')';
405
406funcdecl1: VARTYPETOK NAME
407        {
408          if(debug>2)printf("funcdecl1-2\n");
409          init_proc(&procedure_decl, $2, &$1, yylineno);
410          free($2);
411        }
412        | STATICTOK VARTYPETOK NAME
413        {
414          if(debug>2)printf("funcdecl1-4\n");
415          init_proc(&procedure_decl, $3, &$2, yylineno);
416          free($3);
417          procedure_decl.is_static = TRUE;
418        };
419
420 
421procdeclhelp: MSTRINGTOK
422        {
423          procedure_decl.help_string = $1.string;
424          procedure_decl.lineno_other = $1.lineno;
425          if(debug>2)printf("\t\thelp at %d\n", yylineno);
426          write_help(&module_def, &procedure_decl);
427        }
428        ;
429
430proccode: proccodeline MCODETOK
431          {
432            write_function_errorhandling(&module_def, &procedure_decl);
433          };
434
435
436proccodeline: CODEPART
437        {
438          printf(">>>>(%d) %s<<<<\n", procedure_decl.flags.start_of_code, $1);
439          write_codeline(&module_def, &procedure_decl, $1, yylineno-1);
440        }
441        | proccodeline CODEPART
442        {
443          printf(">>>>(%d) %s<<<<\n", procedure_decl.flags.start_of_code, $2);
444          write_codeline(&module_def, &procedure_decl, $2);
445        }
446        | proccodeline CMTPART
447        {
448          printf(">>>>(%d) %s<<<<\n", procedure_decl.flags.start_of_code, $2);
449          write_codeline(&module_def, &procedure_decl, $2);
450        }
451        | proccodeline proccmd
452        {
453        };
454
455procdeclexample: examplestart '{' examplecodeline MCODETOK
456        {
457          write_example(&module_def, &procedure_decl);
458        }
459        ;
460
461examplestart: EXAMPLETOK
462        {
463          if(procedure_decl.procname == NULL) {
464            return(myyyerror("example without proc-declaration at line %d\n",
465                     yylineno));
466          }
467          if(debug>2)printf("Example at %d\n", yylineno);
468          procedure_decl.lineno_other = yylineno;
469        };
470 
471examplecodeline: CODEPART
472        {
473          int len = strlen($1);
474          procedure_decl.example_len = len;
475          procedure_decl.example_string = (char *)malloc(len+1);
476          memset(procedure_decl.example_string, 0, len+1);
477          memcpy(procedure_decl.example_string, $1, len);
478        }
479        | examplecodeline CODEPART
480        {
481          long len = strlen($2);
482          long newlen = procedure_decl.example_len + len;
483         
484          procedure_decl.example_string =
485            (char *)realloc((void *)procedure_decl.example_string, newlen+1);
486          memset(procedure_decl.example_string+procedure_decl.example_len,
487                 0, len+1);
488          memcpy(procedure_decl.example_string+procedure_decl.example_len,
489                 $2, len);
490          procedure_decl.example_len = newlen;
491          //strncat(procedure_decl.example_string, $2, strlen($2));
492          //procedure_decl.example_string[procedure_decl.example_len] = '\0';
493        };
494
495proccmd: '%' NAME ';'
496        { cmd_token vt;
497          void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL);
498         
499          switch(vt=checkcmd($2, &write_cmd, CMDT_SINGLE, 0)) {
500              case CMD_NONE:
501                return(myyyerror("Line %d: Unknown command '%s' in section %d\n",
502                          yylineno, $2, sectnum));
503                break;
504              case CMD_BADSYNTAX:
505                return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n",
506                          yylineno, $2, sectnum));
507                break;
508
509              case CMD_DECL:
510              case CMD_CHECK:
511                procedure_decl.flags.auto_header = 0;
512              case CMD_NODECL:
513                write_cmd(&module_def, &procedure_decl);
514                break;
515
516              default:
517                write_function_header(&module_def, &procedure_decl);
518                write_cmd(&module_def, &procedure_decl);
519          }
520          free($2);
521        }
522        | '%' NAME '(' ')' ';'
523        {
524          cmd_token vt;
525          void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL);
526         
527          switch(vt=checkcmd($2, &write_cmd, CMDT_0, 1)) {
528              case CMD_NONE:
529                return(myyyerror("Line %d: Unknown command '%s' in section %d\n",
530                          yylineno, $2, sectnum));
531                break;
532              case CMD_BADSYNTAX:
533                return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n",
534                          yylineno, $2, sectnum));
535                break;
536              default:
537                write_function_header(&module_def, &procedure_decl);
538              case CMD_DECL:
539              case CMD_CHECK:
540                write_cmd(&module_def, &procedure_decl);
541          }
542          free($2);
543        }
544        | '%' NAME '(' NAME ')' ';'
545        {
546          cmd_token vt;
547          void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL);
548         
549          switch(vt=checkcmd($2, &write_cmd, CMDT_ANY, 1)) {
550              case CMD_NONE:
551                return(myyyerror("Line %d: Unknown command '%s' in section %d\n",
552                          yylineno, $2, sectnum));
553                break;
554              case CMD_BADSYNTAX:
555                return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n",
556                          yylineno, $2, sectnum));
557                break;
558              default:
559                write_function_header(&module_def, &procedure_decl);
560              case CMD_DECL:
561              case CMD_CHECK:
562                write_cmd(&module_def, &procedure_decl, $4);
563          }
564          free($2); free($4);
565        }
566        | '%' NAME '(' identifier '(' arglist ')' ')' ';'
567        {
568          cmd_token vt;
569          void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL);
570         
571          switch(vt=checkcmd($2, &write_cmd, CMDT_ANY, 1)) {
572              case CMD_NONE:
573                return(myyyerror("Line %d: Unknown command '%s' in section %d\n",
574                          yylineno, $2, sectnum));
575                break;
576              case CMD_BADSYNTAX:
577                return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n",
578                          yylineno, $2, sectnum));
579                break;
580              default:
581                write_function_header(&module_def, &procedure_decl);
582              case CMD_DECL:
583              case CMD_CHECK:
584                write_cmd(&module_def, &procedure_decl, $4);
585          }
586          free($2);
587        }
588        | '%' NAME MEQUAL ANYTOK
589        {
590          cmd_token vt;
591          void (*write_cmd)(moddefv module, procdefv pi, void *arg = NULL);
592         
593          switch(vt=checkcmd($2, &write_cmd, CMDT_EQ, 0)) {
594              case CMD_NONE:
595                return(myyyerror("Line %d: Unknown command '%s' in section %d\n",
596                          yylineno, $2, sectnum));
597                break;
598              case CMD_BADSYNTAX:
599                return(myyyerror("Line %d: bad syntax of command '%s' in section %d\n",
600                          yylineno, $2, sectnum));
601                break;
602              default:
603                write_function_header(&module_def, &procedure_decl);
604              case CMD_DECL:
605              case CMD_CHECK:
606                write_cmd(&module_def, &procedure_decl, $4);
607          }
608          free($2);
609        };
610
611identifier: NAME
612        {
613          if(debug>2)printf("### ID ### Name %s\n", $1);
614          $$ = $1;
615        }
616        | identifier MCOLONCOLON NAME
617        {
618          int len = strlen($$) + strlen($3) + 2;
619          if(debug>2)printf("### ID ### Name %s\n", $3);
620          $$ = (char *)realloc($$, len);
621          strcat($$, "::");
622          strcat($$, $3);
623        };
624
625arglist: NAME
626        {
627          if(debug>2)printf("### ARGS %s\n", $1);
628        }
629        | arglist ',' NAME
630        {
631          if(debug>2)printf("### ARGS %s\n", $3);
632        };
633       
634sgtypelist: VARTYPETOK NAME
635        {
636          if(debug>2)printf("\tsgtypelist %s %s\n", $1.name, $2);
637          write_singular_parameter(&module_def, yylineno, $1.name, $2);
638          free($1.name);
639          free($2);
640        }
641        | VARTYPETOK '#'
642        {
643          if(debug>2)printf("\tsgtypelist %s %s\n", $1.name, $2);
644          write_singular_parameter(&module_def, yylineno, $1.name, "#");
645          free($1.name);
646        }
647        | sgtypelist ',' VARTYPETOK NAME
648        {
649          if(debug>2)printf("\tsgtypelist next  %s %s\n", $3.name, $4);
650          write_singular_parameter(&module_def, yylineno, $3.name, $4);
651          free($3.name);
652          free($4);
653        }
654        | sgtypelist ',' VARTYPETOK '#'
655        {
656          if(debug>2)printf("\tsgtypelist next  %s %s\n", $3.name, $4);
657          write_singular_parameter(&module_def, yylineno, $3.name, "#");
658          free($3.name);
659        }
660        ;
661
662typelist: VARTYPETOK
663        {
664          AddParam(&procedure_decl, &$1);
665          free($1.name);
666        }
667        | VARTYPETOK NAME
668        {
669          if(check_reseverd($2))
670            return(myyyerror("Line %d: variablename '%s' is reserved\n",
671                            yylineno, $2));
672          AddParam(&procedure_decl, &$1, $2);
673          free($1.name); free($2);
674        }
675        | typelist ',' VARTYPETOK
676        {
677          AddParam(&procedure_decl, &$3);
678          free($3.name);
679        }
680        | typelist ',' VARTYPETOK NAME
681        {
682          if(check_reseverd($4))
683            return(myyyerror("Line %d: variablename '%s' is reserved\n",
684                            yylineno, $4));
685          AddParam(&procedure_decl, &$3, $4);
686          free($3.name); free($4);
687        }
688        ;
689
690sect4:  SECT4START codeline SECT4END
691        {
692          fprintf(module_def.modfp, "%s", $2);
693        };
694
695codeline: CODEPART
696        {
697          fprintf(module_def.modfp, "#line %d \"%s\"\n",
698                                          yylineno, module_def.filename);
699        }
700        | codeline CODEPART
701        {
702        }
703        ;
704
705
706%%
707
Note: See TracBrowser for help on using the repository browser.