source: git/modules/modgen/grammar.y @ 8e153e

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