source: git/old_modgen/modgen/scanner.l @ 2bf04b

spielwiese
Last change on this file since 2bf04b was 2bf04b, checked in by Hans Schoenemann <hannes@…>, 8 years ago
format
  • Property mode set to 100644
File size: 18.8 KB
Line 
1%{
2/****************************************
3*  Computer Algebra System SINGULAR     *
4****************************************/
5#include <stdio.h>
6#include <string.h>
7#include <stdlib.h>
8#include <ctype.h>
9
10#include "modgen.h"
11#include "stype.h"
12#include "mod_grammar.h"
13
14#define DEBUG 3
15
16#  define YYLP_ERR_NONE    0
17#  define YYLP_DEF_BR2     1
18#  define YYLP_BODY_BR2    2
19#  define YYLP_BODY_BR3    3
20#  define YYLP_BODY_TMBR2  4
21#  define YYLP_BODY_TMBR3  5
22#  define YYLP_EX_BR2      6
23#  define YYLP_EX_BR3      7
24#  define YYLP_BAD_CHAR    8
25#  define YYLP_MISSQUOT    9
26#  define YYLP_MISS_BR1   10
27#  define YYLP_MISS_BR2   11
28#  define YYLP_MISS_BR3   12
29
30  extern int iseof;
31
32  int offset = 0;
33  int yylineno = 1;
34  int do_return = 0;
35
36  int state_level = -1;
37  int state_max = 0;
38  char *yylp_buffer_start;
39
40  extern int sectnum;
41  static int oldsectnum = 1;
42  extern moddef module_def;
43  extern procdef procedure_decl;
44
45  char *sectname[] = { "sect -0", "section 1",
46                       "Singular", "procedures", "C-part"
47  };
48
49  struct _states {
50    char name[32];
51    int state;
52  } * old_states = NULL;
53/*  int *old_states = NULL;*/
54
55  int current_pos(int i);
56  int read_string(char **buffer, long *start, long end);
57  int libread(FILE* f, char* buf, int max_size);
58  void add_action(char *new_text);
59
60  void push_state(int state, int new_state, char *name);
61  void switch_state(int state, int new_state, char *name);
62  void pop_state();
63  int return_sect_token(int passed, int old_sect, int new_sect);
64  extern int init_modgen(moddef *module_def, char *filename);
65
66static char * dupyytext()
67{
68  if (yyleng>0) yytext[yyleng-1] = '\0';
69  return strdup((char *)yytext);
70}
71
72#   undef YY_DECL
73#   define YY_DECL int yylex(YYSTYPE* lvalp)
74
75#   undef YY_INPUT
76#   define YY_INPUT(buf,result,max_size) \
77          if ( ((result = libread( (yyin), (char *) buf, max_size )) < 0 ) \
78                  && ferror( yyin ) ) \
79                YY_FATAL_ERROR( "read in flex scanner failed" );
80
81#   undef yywrap
82  extern "C"
83  {
84  int yywrap();
85  }
86
87#define ACTION_ECHO add_action( yytext )
88
89%}
90
91digit          [0-9]
92letter         [@a-zA-Z\']
93name           ({letter}({letter}*{digit}*_*)*|_)
94fname          ({letter}({letter}*{digit}*_*.)*|_)
95letters        ({letter}|{digit}|[_./#%^*:,])
96string         ({letters}*)
97comment        [\/][\/]
98dolar          [$]
99symbols        [~!@#$%^&*()_+-={}\\\|\[\];:,<.>/\?\' \n\~\`\r]
100aletters       ({letter}|{digit}|{symbols}|{dolar}|{escquote})
101strings        ({aletters}*)
102quote          [\"]
103escquote       (\\\")
104taborspace     [ \t]
105tos            ({taborspace}*)
106eq             (=|{tos}+=|=+{tos}|{tos}+=+{tos})
107tnl            ([ \t\n]*)
108col            (;|{tos}+;)
109eqnl           ([ \t\n]*+=[ \t\n]*)
110begincode      (%+\{)
111endcode        (\n+%+[}]+\n)
112
113WS             [[:blank:]]+
114NL             \r?\n
115WSNL           ([ \t\n\r]+)
116EQ             (([{WS}]+=[{WS}]+)|=)
117
118NAME           ([[:alpha:]_][[:alnum:]_-]*)
119FILENAME       ([[:alpha:]_][[:alnum:]_-]*\.(c|cc|h))
120NUMBER         ({digit}*)
121BOOL           (([Yy][Ee][Ss])|([Nn][Oo])|[01])
122
123/* %start START */
124
125%x preamble
126%x MODINITIAL
127%x PROCCMDBLOCK
128%x CODEBLOCK
129%x CODEBLOCK2
130%x module
131%x COMMENT
132%x COMMENTB
133%x STRING
134%x SECT2
135%x SECT3
136%x SECT4
137%x PROCDECL
138%x EXAMPLE
139%x ANYLINE
140
141%x pdef
142%x procopt
143%x procdef
144%x ctext
145%x cstring
146
147%%
148       static int brace1 = 0;  /* { } */
149       static int brace2 = 0;  /* ( ) */
150       static int brace3 = 0;  /* [ ] */
151       static int quote  = 0;  /* " */
152
153<COMMENT,COMMENTB,STRING,INITIAL><<EOF>>   {
154          printf( "EOF encountered inside an action\n");
155          printf("ERRRRROOOOORRR\n");
156                 }
157
158<INITIAL,SECT2,SECT3,SECT4>{
159        ^"%Singular".* {
160                  int passed = (oldsectnum == sectnum) ? 0 : 1;
161                  int old_sect = sectnum;
162
163                  oldsectnum = sectnum;
164                  sectnum = 2;
165                  if(!passed) yyless(0);
166                  else push_state(YYSTATE, SECT2, "SECT2");
167                  return(return_sect_token(passed, old_sect, sectnum));
168                }
169        "%Singular".* {
170                  int passed = (oldsectnum == sectnum) ? 0 : 1;
171                  int old_sect = sectnum;
172
173                  oldsectnum = sectnum;
174                  sectnum = 2;
175                  if(!passed) yyless(0);
176                  else push_state(YYSTATE, SECT2, "SECT2");
177                  return(return_sect_token(passed, old_sect, sectnum));
178                }
179        ^"%procedures".* {
180                  int passed = (oldsectnum == sectnum) ? 0 : 1;
181                  int old_sect = sectnum;
182
183                  oldsectnum = sectnum;
184                  sectnum = 3;
185                  if(!passed) yyless(0);
186                  else push_state(YYSTATE, SECT3, "SECT3");
187                  return(return_sect_token(passed, old_sect, sectnum));
188                }
189        "%procedures".* {
190                  int passed = (oldsectnum == sectnum) ? 0 : 1;
191                  int old_sect = sectnum;
192
193                  oldsectnum = sectnum;
194                  sectnum = 3;
195                  if(!passed) yyless(0);
196                  else push_state(YYSTATE, SECT3, "SECT3");
197                  return(return_sect_token(passed, old_sect, sectnum));
198                }
199        ^"%C".* {
200                  int passed = (oldsectnum == sectnum) ? 0 : 1;
201                  int old_sect = sectnum;
202
203                  oldsectnum = sectnum;
204                  sectnum = 4;
205                  if(!passed) yyless(0);
206                  else push_state(YYSTATE, SECT4, "SECT4");
207                  return(return_sect_token(passed, old_sect, sectnum));
208                }
209        "%C".* {
210                  int passed = (oldsectnum == sectnum) ? 0 : 1;
211                  int old_sect = sectnum;
212
213                  oldsectnum = sectnum;
214                  sectnum = 4;
215                  if(!passed) yyless(0);
216                  else push_state(YYSTATE, SECT4, "SECT4-2");
217                  return(return_sect_token(passed, old_sect, sectnum));
218                }
219              }
220
221
222<INITIAL>{
223        ^{WS}      push_state(YYSTATE, CODEBLOCK, "CODEBLOCK");
224        ^"/*"      push_state(YYSTATE, COMMENT, "COMMENT"); yymore();
225        "//".*{NL} ++yylineno; ACTION_ECHO;
226        {BOOL}  { if(yyleng == 1) sscanf(yytext, "%d", &lvalp->i);
227                  else {
228                    if(strcasecmp(yytext, "yes")==0) lvalp->i = 1;
229                    else lvalp->i = 0;
230                  }
231                  return BOOLTOK; }
232        ^"%{".*{NL} {
233                yylineno++;
234                push_state(YYSTATE, CODEBLOCK, "CODEBLOCK");
235                fprintf(module_def.fmtfp, "#line %d \"%s\"\n",
236                                          yylineno, module_def.filename);
237                }
238        ^"%modinitial".*{NL} {
239                yylineno++;
240                push_state(YYSTATE, MODINITIAL, "MODINITIAL");
241                fprintf(module_def.fmtfp, "#line %d \"%s\"\n",
242                                                 yylineno, module_def.filename);
243                }
244        {WS}            /* discard */
245        {NL}    { yylineno++; }
246
247        {eq}    { return '='; }
248        ";"     { return ';'; }
249        ","     { return ','; }
250
251        "\""    { do_return++;
252                  lvalp->sv.lineno = yylineno;
253                  push_state(YYSTATE, STRING, "string");
254                }
255
256        ^{NAME} {
257                  lvalp->name = strdup(yytext);
258                  return NAME;
259                }
260        {FILENAME} {
261                  lvalp->name = strdup(yytext);
262                  return FILENAME;
263                }
264           }
265
266<CODEBLOCK>{
267            ^"%}".*{NL} {
268                   char * s, *t;
269
270                   yylineno++;
271                   pop_state();
272                   s = t = lvalp->name = dupyytext();
273                   while (*yytext)
274                   {
275                     if (*yytext == '\\') yytext++;
276                     *s++ = *yytext++;
277                   }
278                   if(s-t>2 && *(s-1)=='}' && *(s-2)=='%') *(s-2)='\0';
279                   return MCCODETOK;
280                 }
281         {NL}    { yylineno++; yymore(); }
282         .       { yymore(); }
283       }
284<MODINITIAL>{
285           ^"%endinitial".*{NL} {
286                   yylineno++;
287                   pop_state();
288                 }
289           .*{NL}  { yylineno++;
290                   lvalp->name = yytext;
291                   return CODEPART; }
292       }
293<STRING>{
294          {NL}    { yylineno++; yymore(); }
295          [^\"]   { yymore(); }
296          "\\\\"  { yymore(); }
297          "\\\""  { yymore(); }
298          ("\"")  {
299                    char * s, *t;
300                    pop_state();
301                    if(do_return) {
302                      s = t = lvalp->sv.string = dupyytext();
303                      while (*yytext)
304                      {
305                        if (*yytext == '\\') yytext++;
306                        *s++ = *yytext++;
307                      }
308                      *s++ = *yytext++;
309                      do_return = 0;
310                      return MSTRINGTOK;
311                    } else {
312                      do_return = 0;
313                      yymore();
314                    }
315                  }
316        }
317
318<COMMENT>{
319        "*/"            ACTION_ECHO; pop_state(); yymore();
320        "*"           yymore();
321        {NL}          { yylineno++; yymore(); }
322        .             { yymore(); }
323          }
324
325<SECT2>{
326        {NL}    { yylineno++; }
327        {WS}    /* ignore */
328        ;       /* ignore */
329        "/*"      push_state(YYSTATE, COMMENT, "COMMENT"); yymore();
330        "//".*{NL}  ++yylineno; ACTION_ECHO;
331        proc+{WS} {
332                  brace1 = 0; /* { */
333                  brace2 = 0; /* ( */
334                  brace3 = 0; /* [ */
335                  push_state(YYSTATE, PROCDECL, "PROCDECL");
336                  return PROCDECLTOK;
337                }
338        example {
339#if DEBUG > 1
340                  printf(">>>EXAMPLE\n");
341#endif
342                  brace1 = 0; /* { */
343                  brace2 = 0; /* ( */
344                  brace3 = 0; /* [ */
345                    push_state(YYSTATE, EXAMPLE, "EXAMPLE");
346                        return EXAMPLETOK;
347                }
348             static  { return STATICTOK; }
349        .       { printf("SG(%d) <<<'%s' ", yylineno, yytext); }
350       }
351
352<SECT3>{
353        {NL}    { yylineno++; }
354        {WS}    /* ignore */
355        ;       /* ignore */
356        "/*"      push_state(YYSTATE, COMMENT, "COMMENT"); yymore();
357        "//".*{NL}  ++yylineno; ACTION_ECHO;
358        example {
359#if DEBUG > 1
360                  printf(">>>EXAMPLE\n");
361#endif
362                  brace1 = 0; /* { */
363                  brace2 = 0; /* ( */
364                  brace3 = 0; /* [ */
365                  push_state(YYSTATE, EXAMPLE, "EXAMPLE");
366                  return EXAMPLETOK;
367                }
368        static  { return STATICTOK; }
369        {NAME}  {
370                   int i,tok;
371#if DEBUG > 1
372                   printf("(%d) VAR: %s\n", yylineno, yytext);
373#endif
374                   i = IsCmd(yytext, tok);
375#if DEBUG > 1
376                   printf("Res=%d, %d => %s\n", i, tok,
377                          i ? "VARTYPETOK" : "NAME");
378#endif
379                   if(i) {
380                     lvalp->tp.name = strdup(yytext);
381                     lvalp->tp.typ = tok;
382                     push_state(YYSTATE, PROCDECL, "PROCDECL");
383                     return VARTYPETOK;
384                   }
385                   else {
386                     //do_return++;
387                     lvalp->name = strdup(yytext);
388                     push_state(YYSTATE, PROCDECL, "PROCDECL");
389                     return NAME;
390                   }
391                 }
392        .       { printf("PR(%d) <<<'%s' ", yylineno, yytext); }
393       }
394
395<EXAMPLE>{
396        {NL}    { yylineno++; }
397        {WS}    /* ignore */
398        "{"     { brace1++;
399                  switch_state(YYSTATE, CODEBLOCK2, "CODEBLOCK2");
400                  return '{';
401                }
402        .       { printf("ERROR <<<'%s' ", yytext); }
403}
404
405<SECT4>{
406        {NL}    { yylineno++; }
407        .*(\n?) { lvalp->name = yytext;
408                  return CODEPART; }
409
410        <<EOF>>  { sectnum = 0;
411                   iseof=1;
412                   lvalp->name = yytext;
413                   return SECT4END;
414                   /* yyterminate(); */
415                 }
416       }
417
418<PROCDECL>{
419         "{"     { brace1++;
420                   switch_state(YYSTATE, CODEBLOCK2, "CODEBLOCK2");
421                   return '{';
422                 }
423         "/*"       push_state(YYSTATE, COMMENT, "COMMENT");yymore();
424         "//".*{NL}  ++yylineno; ACTION_ECHO;
425         "\""    { do_return++;
426                   lvalp->sv.lineno = yylineno;
427                   push_state(YYSTATE, STRING, "string");
428                 }
429         {BOOL}  { if(yyleng == 1) sscanf(yytext, "%d", &lvalp->i);
430                   else {
431                     if(strcasecmp(yytext, "yes")==0) lvalp->i = 1;
432                     else lvalp->i = 0;
433                   }
434                   return BOOLTOK; }
435         {NUMBER} { sscanf(yytext, "%d", &lvalp->i); return NUMTOK; }
436         {NAME}  {
437                   int i,tok;
438#if DEBUG > 1
439                   printf("(%d) VAR: %s\n", yylineno, yytext);
440#endif
441                   i = IsCmd(yytext, tok);
442#if DEBUG > 1
443                   printf("Res=%d, %d => %s\n", i, tok,
444                          i ? "VARTYPETOK" : "NAME");
445#endif
446                   if(i) {
447                     lvalp->tp.name = strdup(yytext);
448                     lvalp->tp.typ = tok;
449                     return VARTYPETOK;
450                   }
451                   else {
452                     //do_return++;
453                     lvalp->name = strdup(yytext);
454                     return NAME;
455                   }
456                 }
457         {NL}    { yylineno++; }
458         "("     { return '('; }
459         ")"     { return ')'; }
460         ","     { return ','; }
461         "#"     { return '#'; }
462         "="     { return '='; }
463         ";"     { return ';'; }
464         .       { }
465
466       }
467
468<COMMENTB>{
469        "*/"          { ACTION_ECHO;
470                        pop_state();
471                        lvalp->name = yytext;
472                        return CMTPART;
473                        yymore();
474                      }
475        "*"           yymore();
476        {NL}          { yylineno++; yymore(); }
477        .             { yymore(); }
478          }
479
480<CODEBLOCK2>{
481         "/*"      push_state(YYSTATE, COMMENT, "COMMENT"); yymore();
482         "//".*{NL} { yylineno++; lvalp->name = yytext; return CODEPART; }
483         "\""    {
484                   lvalp->sv.lineno = yylineno;
485                   push_state(YYSTATE, STRING, "string"); yymore();}
486         "{"     { brace1++; yymore();}
487         "}"     { brace1--;
488                   if(brace1<=0) {
489                     char * s, *t;
490
491                     pop_state();
492#if 0
493                     s = t = lvalp->name = dupyytext();
494                     while (*yytext)
495                     {
496                       if (*yytext == '\\') yytext++;
497                       *s++ = *yytext++;
498                     }
499                     if(s-t>2 && *(s-1)=='}' && *(s-2)=='%') *(s-2)='\0';
500#else
501                     lvalp->name = yytext;
502#endif
503#if DEBUG > 1
504                     printf("2 BRACE DOWN=%d\n", brace1);
505#endif
506                     return MCODETOK;
507                   } else {
508                     yymore();
509                   }
510                 }
511         {NL}    { yylineno++; lvalp->name = yytext; return CODEPART; }
512         "%" { push_state(YYSTATE, PROCCMDBLOCK, "PROCCMDBLOCK");
513               procedure_decl.flags.start_of_code = 1;
514               return '%'; }
515         " " { yymore(); }
516         .   { yymore(); procedure_decl.flags.start_of_code = 1; }
517
518       }
519
520<PROCCMDBLOCK>{
521       {col}  { pop_state(); return ';'; }
522        "("   { return '('; }
523        ")"   { return ')'; }
524        ","   { return ','; }
525       {WS}   /* ignore */
526       {NAME} { lvalp->name = strdup(yytext); return NAME; }
527       {NL}   { yylineno++; }
528       "::"   { return MCOLONCOLON; }
529       "="    { switch_state(YYSTATE, ANYLINE, "ANYLINE"); return MEQUAL; }
530       .      { printf("PCB: '%s'\n", yytext); }
531       }
532
533<ANYLINE>{
534       {col}  { lvalp->name = yytext;
535                pop_state();
536                return ANYTOK; }
537       {NL}   { yylineno++; }
538       .       { yymore(); }
539}
540
541%%
542/*
543        [^*\n]+         ++yylineno; yymore(); /*ACTION_ECHO;* /
544        [^*\n]*{NL}     ++yylineno; yymore(); /*ACTION_ECHO;* /
545         .*(\n?) { yylineno++; lvalp->name = yytext; return CODEPART; }
546*/
547
548extern "C" {
549  int yywrap() {
550    return 1;
551  }
552}
553
554int libread(FILE* f, char* buf, int max_size)
555{ int rc;
556
557  offset = ftell(f);
558  rc  = fread( buf, 1, max_size, f );
559#if YYLPDEBUG >2
560  printf("fread: %d of %d\n", rc, max_size);
561#endif
562  yylp_buffer_start = buf;
563  return rc;
564}
565
566void switch_state(int state, int new_state, char *name)
567{
568#if DEBUG > 2
569  printf("====>SWITCH to new state %d/%d l=%d, [%s] at %d\n",
570         state, new_state, state_level, name, yylineno);
571#endif
572  strncpy(old_states[state_level].name, name,
573          sizeof(old_states[state_level].name));
574  BEGIN(new_state);
575}
576
577void push_state(int state, int new_state, char *name)
578{
579  state_level++;
580#if DEBUG > 2
581  printf("====>PUSH to new state %d/%d l=%d, [%s] at %d\n",
582         state, new_state, state_level, name, yylineno);
583#endif
584  if(state_level>=state_max) {
585    state_max++;
586    if(old_states == NULL)
587      old_states = (struct _states *)malloc(sizeof(struct _states));
588    else {
589      old_states = (struct _states *)realloc(old_states,
590                                             state_max*sizeof(struct _states));
591    }
592  }
593  old_states[state_level].state = state;
594  strncpy(old_states[state_level].name, name,
595          sizeof(old_states[state_level].name));
596  BEGIN(new_state);
597}
598
599void pop_state()
600{
601#if DEBUG > 2
602  printf("====>Back to old state %d, l=%d [%s] at %d\n",
603         old_states[state_level].state,
604         state_level,
605         (state_level>0) ? old_states[state_level-1].name : "INITIAL",
606         yylineno);
607#endif
608  if(state_level<0) return;
609  BEGIN(old_states[state_level].state);
610  state_level--;
611  if(state_level<0) state_level = -1;
612}
613
614int return_sect_token(
615  int passed,
616  int old_sect,
617  int new_sect
618  )
619{
620  if(passed) {
621#if DEBUG
622    printf("Go to section '%s' (%d)\n", sectname[new_sect], new_sect);
623#endif
624    switch(new_sect) {
625        case 2: return SECT2START;
626        case 3: return SECT3START;
627        case 4: return SECT4START;
628        default: return SECTEND;
629    }
630  } else {
631#if DEBUG
632    printf("End of section '%s' (%d)\n", sectname[old_sect], old_sect);
633#endif
634    switch(old_sect) {
635        case 2: return SECT2END;
636        case 3: return SECT3END;
637        case 4: return SECT4END;
638        default: return SECTEND;
639    }
640  }
641}
642
643void add_action(char *new_text)
644{
645  return;
646  switch(sectnum) {
647    case 1:
648      printf("1>%s<#\n", new_text);
649      break;
650    case 2:
651      printf("2>%s<#\n", new_text);
652      break;
653    case 3:
654      printf("3>%s<#\n", new_text);
655      break;
656    case 4:
657      printf("4>%s<#\n", new_text);
658      break;
659  }
660}
Note: See TracBrowser for help on using the repository browser.