Annotation of capa/capa51/pProj/capaLexerDef.flex, revision 1.11

1.9       albertel    1: /* main CAPA lexer
                      2:    Copyright (C) 1992-2000 Michigan State University
                      3: 
                      4:    The CAPA system is free software; you can redistribute it and/or
1.11    ! albertel    5:    modify it under the terms of the GNU General Public License as
1.9       albertel    6:    published by the Free Software Foundation; either version 2 of the
                      7:    License, or (at your option) any later version.
                      8: 
                      9:    The CAPA system is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1.11    ! albertel   12:    General Public License for more details.
1.9       albertel   13: 
1.11    ! albertel   14:    You should have received a copy of the GNU General Public
1.9       albertel   15:    License along with the CAPA system; see the file COPYING.  If not,
                     16:    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
1.10      albertel   17:    Boston, MA 02111-1307, USA.
                     18: 
                     19:    As a special exception, you have permission to link this program
                     20:    with the TtH/TtM library and distribute executables, as long as you
                     21:    follow the requirements of the GNU GPL in regard to all of the
                     22:    software in the executable aside from TtH/TtM.
                     23: */
1.9       albertel   24: 
1.1       albertel   25: /*------------------------------------------------------------------------*/
                     26: /*         capaLexerDef.flex   created by Isaac Tsai Jul 15 1996          */
                     27: /*                             added /END(variable)                       */
                     28: /*                             added /HIN  .... /DIS(variable) ...        */
                     29: /*                             Jan 15 1998  /{KeyWord}{KeyWord}{KeyWord}  */
                     30: /*                               replaced by /DIS                         */
                     31: /*   catch "No /END() statement found"                                    */
                     32: /*   catch "/DIS(")" and "/DIS(""")" errors "                             */
                     33: /*   catch "/LET var = "                                                  */
                     34: /*   add a new token EoL to indicate '\n' '\r''\n' and '\r'               */
                     35: /*   This file is based on flex 2.5.3, flex 2.3 apparantly cannot take it :-( */
                     36: /*   DONE /RMAP() function July 14, 1998 */
                     37: /*   DONE /AND /OR answer formats  July 20, 1998 */
                     38: /*   DONE /IF ()  /ENDIF   July 26, 1998 */
                     39: /*   DONE /WHILE ()  /ENDWHILE August 10 1998 */
                     40: /*   DONE /VERB /ENDVERB    Feb 20 1998  */
                     41: /*------------------------------------------------------------------------*/
                     42: /**************************************************************************/
                     43: 
                     44: %{
                     45: 
                     46: #include <stdio.h>
                     47: #include <stdlib.h>       /* strtod(), strtol() */
                     48: #include <string.h>
                     49: #ifdef NeXT
                     50: #include <sys/file.h>
                     51: #else 
                     52: #include <unistd.h>       /* access() */
                     53: #endif
                     54: 
1.8       albertel   55: #define YYSTYPE Symbol*
1.1       albertel   56: #include "capaCommon.h"   /* capa_access() */
                     57: #include "capaParser.h"   /* _symbol structure def */
1.8       albertel   58: #include "capaToken.h"    /* from YACC -d capaGrammarDef.y */
1.1       albertel   59: #include "lex_debug.h"    /* defined RETURN(xxx) macro */
                     60: 
                     61: 
                     62: 
                     63: /* ============================================== begin of code */
                     64: 
                     65: #define LEX_BUFLEN  (8*1024)     /* lexical buffer size (for each opened file) */
                     66: 
                     67: #ifdef  YYLMAX 
                     68: #undef  YYLMAX
                     69: #define YYLMAX   8192
                     70: #endif
                     71: 
                     72: void yyfatalerror(char*msg);
                     73: #define YY_FATAL_ERROR yyfatalerror
                     74: 
                     75: #ifdef   LEX_DBUG
                     76: #define  LLDBUG_PRL1(xx)        { printf("Line %d ",Current_line[Input_idx]); printf(xx); fflush(stdout); }
                     77: #define  LLDBUG_PRL2(xx,yy)     { printf("Line %d ",Current_line[Input_idx]); printf(xx,yy); fflush(stdout); }
                     78: #define  LLDBUG_PR1(xx)         { printf(xx); fflush(stdout); }
                     79: #define  LLDBUG_PR2(xx,yy)      { printf(xx,yy); fflush(stdout); }
                     80: #define  LLDBUG_PR3(xx,yy,zz)   { printf(xx,yy,zz); fflush(stdout); }
                     81: #else
                     82: #define  LLDBUG_PRL1(xx)        { }
                     83: #define  LLDBUG_PRL2(xx,yy)     { }
                     84: #define  LLDBUG_PR1(xx)         { }
                     85: #define  LLDBUG_PR2(xx,yy)      { }
                     86: #define  LLDBUG_PR3(xx,yy,zz)   { }
                     87: #endif
                     88: 
                     89: #ifdef   LEX_INPUT_DBUG
                     90: #define  LIDBUG_PR1(xx)         { printf(xx); fflush(stdout); }
                     91: #define  LIDBUG_PR2(xx,yy)      { printf(xx,yy); fflush(stdout); }
                     92: #define  LIDBUG_PR3(xx,yy,zz)   { printf(xx,yy,zz); fflush(stdout); }
                     93: #else
                     94: #define  LIDBUG_PR1(xx)         { }
                     95: #define  LIDBUG_PR2(xx,yy)      { }
                     96: #define  LIDBUG_PR3(xx,yy,zz)   { }
                     97: #endif
                     98: 
                     99: #ifdef   USE_DYNAMIC_SYMBOLS
                    100: #define  USE_DYNAMIC_LEXBUFS 
                    101: #endif
                    102: 
                    103: Symbol       *yylval;       /* global pointer to symbol */
                    104: 
                    105: FILE         *(Input_stream[MAX_OPENED_FILE]);             /* <-- perhaps we can use linked list */
                    106: char          Opened_filename[MAX_OPENED_FILE][QUARTER_K]; /* <-- perhaps we can use linked list */
                    107: int           Input_idx;
                    108: int           Lexi_pos[MAX_OPENED_FILE];   /* Current position in the line */
                    109: 
                    110: #ifdef  USE_DYNAMIC_LEXBUFS
                    111: char         *(Lexi_buf[MAX_OPENED_FILE]);          /* Line Buffer for current file  */
                    112: 
                    113: #else 
                    114: char          Lexi_buf[MAX_OPENED_FILE][LEX_BUFLEN+4];          /* Line Buffer for current file  */
                    115: 
                    116: #endif  /* USE_DYNAMIC_LEXBUFS */
                    117: 
                    118: char          String_buf[LEX_BUFLEN];              /* Constant String buffer <-- perhaps we can use char pointer  */
                    119: char         *Dynamic_buf;
                    120: int           Dynamic_buf_max;
                    121: int           Dynamic_buf_cur;
                    122: 
                    123: 
                    124: static   int  End_of_input;
                    125: static   int  Pcount, Bcount; /* static means only available in this file */
                    126: /* --------------------------------------------------------------------------- */
                    127: /* GLOBAL VARIABLES                                                            */
                    128: /* --------------------------------------------------------------------------- */
                    129: int           Lexi_line;                   /* Current source file line number, counting from beginning */
                    130: extern int    Current_line[MAX_OPENED_FILE];
                    131: 
                    132: int           Func_idx;
                    133: Symbol        FuncStack[MAX_FUNC_NEST];    /* <-- perhaps we can use linked list */
                    134: 
                    135: int           Array_idx;
                    136: Symbol       *ArraySymbList_p;
                    137: Symbol       *ArraySymbLast_p;
                    138: Symbol       *FmlSymbList_p;
                    139: Symbol       *FmlSymbLast_p;
                    140: int           FmlSymb_cnt;
                    141: int           Symb_count;
                    142: 
                    143: int           IFstatus[MAX_FUNC_NEST];     /* <-- perhaps we can use linked list */
                    144: int           IFcurrent[MAX_FUNC_NEST];    /* <-- perhaps we can use linked list */
                    145: int           IFcount;
                    146: WhileLoop_t   WhileStack[MAX_FUNC_NEST];   /* <-- perhaps we can use linked list */
                    147: int           While_idx, Wcount;
                    148: 
                    149: #ifdef  USE_DYNAMIC_SYMBOLS
                    150: Symbol       *SymbList_p;
                    151: Symbol       *SymbLast_p;
                    152: #else
                    153: Symbol        SymbArray[MAX_SYMB_COUNT];
                    154: #endif /* USE_DYNAMIC_SYMBOLS */
                    155: 
                    156: 
                    157: char         *Current_char_p;                      /* Collect string constant */
                    158: extern        char              *EndText_p;
                    159: extern        char              *StartText_p;
                    160: extern        Problem_t         *LexiProblem_p;
                    161: extern        Problem_t         *LastProblem_p;
                    162: int           first_run=1;
                    163: int           Stop_Parser;
                    164: #define  FLEX
                    165: 
                    166: #define  YY_STACK_USED   1  /* for yy_push_state(), yy_pop_state() */
                    167: 
                    168: #ifdef   FLEX
                    169: 
                    170: int      capaL_unput();
                    171: int      capaL_input();
                    172: 
                    173: 
                    174: /* YY_INPUT() 
                    175:    Controls scanner input.  By default, YY_INPUT reads from the
                    176:    file-pointer yyin.  Its action is to place up to max_size
                    177:    characters in the character array buf and return in the
                    178:    integer variable result either the number of characters read
                    179:    or the constant YY_NULL to indicate EOF.  
                    180:    max_size is defined to be num_to_read = 8192 in liby
                    181:    Following is a sample 
                    182:    redefinition of YY_INPUT, in the definitions section of
                    183:    the input file:
                    184:    
                    185:    %{
                    186:    #undef YY_INPUT
                    187:    #define YY_INPUT(buf,result,max_size)\
                    188:    {\
                    189:        int c = getchar();\
                    190:        result = (c == EOF) ? YY_NULL : (buf[0] = c, 1);\
                    191:    }
                    192:    %}
                    193:  
                    194: */
                    195: 
                    196: /* fgets() reads the input stream until 
                    197:    n-1 bytes have been read  OR
                    198:    a newline character is read and transferred to string  OR
                    199:    an EOF (End-of-File) condition is encountered
                    200:    
                    201:    The string is then terminated with a NULL character.  
                    202:   
                    203:   ii = fseek(FILE *stream,0L,SEEK_END) ;
                    204:   if(ii!=0) { error }
                    205:   leng = ftell(FILE *stream) + 1 ;
                    206:   fseek(FILE *stream,0L,SEEK_SET) ;
                    207:   Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*leng,1);
                    208:   
                    209: */
                    210: 
                    211: 
                    212: #ifdef AVOIDYYINPUT
                    213: #define MAX_INCLUDE_DEPTH 10
                    214: YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
                    215: int include_stack_ptr = 0;
                    216: #else
                    217: #ifdef USE_DYNAMIC_LEXBUFS
                    218: #define NEWYYINPUT
                    219: #endif
                    220: 
                    221: #ifdef  NEWYYINPUT
                    222: void newyy_input (char *buf,int *result,int max_size);
                    223: #define YY_INPUT(buf,result,max_size) newyy_input(buf,&result,max_size)
                    224: 
                    225: #else
                    226: #ifdef  USE_DYNAMIC_LEXBUFS
                    227: 
                    228: #define  YY_INPUT(buf,result,max_size) \
                    229:   { int ii, leng, out_of_char; \
                    230:     if (!Lexi_line) { /* was startup */ \
                    231:        for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
                    232:          Lexi_buf[ii] = NULL; \
                    233:          Lexi_pos[ii] = 0; \
                    234:          Current_line[ii] = 0; \
                    235:        } \
                    236:        Input_idx = 0; \
                    237:        first_run=0; \
                    238:        yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
                    239:     } \
                    240:     out_of_char = 0; \
                    241:     if ( Lexi_buf[Input_idx] == NULL ) { \
                    242:       Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1; \
                    243:     } else { \
                    244:       if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
                    245:         out_of_char=1; \
                    246:       } \
                    247:     } \
                    248:     if( out_of_char ) { \
                    249:       if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
                    250:         LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
                    251:         if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
                    252:           LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
                    253:           fclose(Input_stream[Input_idx]); \
                    254:           capa_mfree((char *)Lexi_buf[Input_idx]); \
                    255:           Lexi_buf[Input_idx] = NULL; \
                    256:           Input_idx--; \
                    257:           yyin = Input_stream[Input_idx]; \
                    258:           /* (Lexi_pos[Input_idx])++; */ \
                    259:           buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
                    260:           result = 1; \
                    261:         } else { \
                    262:           result = YY_NULL; /* End of File */ \
                    263:         } \
                    264:       } else { /* successfully read in one line */ \
                    265:         if (Lexi_buf[Input_idx]==NULL) puts("Whatup?");\
                    266:         leng = strlen(Lexi_buf[Input_idx]); \
                    267:         LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx);  \
                    268:         Lexi_pos[Input_idx] = 0; \
                    269:         Lexi_line++; \
                    270:         Current_line[Input_idx]++; \
                    271:         (Lexi_pos[Input_idx])++; \
                    272:         buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  \
                    273:         /* need to take care of return continuation conditions */ \
                    274:         /*  so, we return to one-char-at-a-time approach */ \
                    275:         /* for(ii=0;ii<leng;ii++) { */ \
                    276:         /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ \
                    277:         /* } */ \
                    278:         /* buf[ii] = '\0'; */ \
                    279:         /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
                    280:         result = 1; \
                    281:       } \
                    282:     } else { \
                    283:       /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ \
                    284:       (Lexi_pos[Input_idx])++; \
                    285:       buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
                    286:       result = 1; \
                    287:     } \
                    288:     if (Stop_Parser==1) { \
                    289:       result = YY_NULL; \
                    290:     } \
                    291:   }
                    292:   
                    293: #else 
                    294: 
                    295: #define  YY_INPUT(buf,result,max_size) \
                    296:   { int ii, leng; \
                    297:     if (!Lexi_line) { /* was startup */ \
                    298:        for(ii=0;ii < MAX_OPENED_FILE;ii++) { \
                    299:          Lexi_buf[ii][0]=0; \
                    300:          Lexi_pos[ii] = 0; \
                    301:          Current_line[ii] = 0; \
                    302:        } \
                    303:        Input_idx = 0; \
                    304:        first_run=0; \
                    305:        yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
                    306:     } \
                    307:     if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \
                    308:       if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \
                    309:         LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
                    310:         if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
                    311:           LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); \
                    312:           fclose(Input_stream[Input_idx]); \
                    313:           Input_idx--; \
                    314:           yyin = Input_stream[Input_idx]; \
                    315:           /* (Lexi_pos[Input_idx])++; */ \
                    316:           buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
                    317:           result = 1; \
                    318:         } else { \
                    319:           result = YY_NULL; /* End of File */ \
                    320:         } \
                    321:       } else { /* successfully read in one line */ \
                    322:         leng = strlen(Lexi_buf[Input_idx]); \
                    323:         LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",leng,Input_idx);  \
                    324:         Lexi_pos[Input_idx] = 0; \
                    325:         Lexi_line++; \
                    326:         Current_line[Input_idx]++; \
                    327:         (Lexi_pos[Input_idx])++; \
                    328:         buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  \
                    329:         /* need to take care of return continuation conditions */ \
                    330:         /*  so, we return to one-char-at-a-time approach */ \
                    331:         /* for(ii=0;ii<leng;ii++) { */ \
                    332:         /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ \
                    333:         /* } */ \
                    334:         /* buf[ii] = '\0'; */ \
                    335:         /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
                    336:         result = 1; \
                    337:       } \
                    338:     } else { \
                    339:       /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ \
                    340:       (Lexi_pos[Input_idx])++; \
                    341:       buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \
                    342:       result = 1; \
                    343:     } \
                    344:     if (Stop_Parser==1) { \
                    345:       result = YY_NULL; \
                    346:     } \
                    347:   }
                    348: #endif  /* USE_DYNAMIC_LEXBUFS */
                    349: #endif /*NEWYYINPUT*/
                    350: #endif /*AVOIDYYINPUT*/
                    351: 
                    352: #else
                    353: 
                    354: #undef  input
                    355: #undef  unput
                    356: 
                    357: #endif
                    358: 
                    359: int capa_eof();
                    360: %}
                    361: 
                    362: Alpha      [a-zA-Z_]
                    363: KeyChar    [A-Z]
                    364: AlphaNum   [a-zA-Z_0-9]
                    365: Number     [0-9]
                    366: HexNumber  [0-9a-fA-F]
                    367: Space      [ \t]
                    368: Spaces     ({Space}*)
                    369: FileName   (\"[^"\n]*\")
                    370: Qchar      ([0-9a-zA-Z \t!?\._,:;'"`~@#$%\^&\+\-\*=|\[\]{}()])
                    371: Operator   ([=\+\-\*/%<>!&|,])
                    372: Identifier ([a-zA-Z_][a-zA-Z_0-9]*)
                    373: EndLine    ([\r][\n]|[\n])
                    374: 
                    375: %a 10500
                    376: %o 15000
                    377: %k 10000
                    378: %p 10000
                    379: %n 1000
1.6       albertel  380: %x  S_COMMENT   S_HINT S_HINTEXLAINX  S_IMPORT S_EXPLAIN S_ENDX    S_UNIT   S_IGNORE  
                    381: %x  S_SKIP      S_VARIABLE S_LET  S_DEFINE     S_TEXT    S_MAP     S_FIGURE S_ANSWER 
                    382: %x  S_STRING    S_ANSCONTINUE     S_TRUE_FALSE_STMT      S_IF_SKIP S_WHILE_SKIP
                    383: %x  S_NEXT_LINE S_RANDOMORDER     S_VERB
1.1       albertel  384: %array
                    385: 
                    386: 
                    387: 
                    388: %%
                    389: 
                    390: <S_IGNORE>{
                    391: {EndLine}                       BEGIN S_IGNORE;
                    392: [^\n]*$                         BEGIN S_IGNORE;
                    393: <<EOF>>                        {
                    394:                                   capa_eof();
                    395: #ifndef AVOIDYYINPUT
                    396: 				  yyterminate();
                    397: #endif
                    398:                                }
                    399: }
                    400: 
                    401: <S_COMMENT>[^\n]*{EndLine}      BEGIN S_TEXT;
                    402: 
                    403: <S_TEXT>{
                    404: ^{Spaces}"/LET" |
                    405: ^{Spaces}"/BEG"                  { LLDBUG_PRL1("[LET]"); Pcount = 0; init_funcstack(); BEGIN S_LET; RETURN(CAPA_LET); }
                    406: ^{Spaces}"/VERB"                 { 
                    407:                                    LLDBUG_PRL1("[VERBATIM]");
1.2       albertel  408: 				   Dynamic_buf = (char *)capa_malloc(sizeof(char),10);
                    409: 				   Dynamic_buf_max = 10;
1.1       albertel  410: 				   Dynamic_buf_cur = 0;
                    411: 				   Dynamic_buf[0] = '\0';
                    412:                                    BEGIN S_VERB; 
                    413:                                  }
                    414: ^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); Current_char_p = String_buf;  BEGIN S_HINT; }
                    415: ^{Spaces}"/EXP"{Alpha}*{Spaces}  { LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf;  BEGIN S_EXPLAIN; }
                    416: ^{Spaces}"/IMP"{Alpha}*{Space}+  { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; }
                    417: ^{Spaces}"/END"                  { LLDBUG_PRL1("[END]");  
                    418:                                     if ( (LexiProblem_p !=NULL) && 
                    419: 					 (LexiProblem_p->question != NULL) && 
                    420: 					 (LexiProblem_p->ans_type == 0)) {
                    421: 				      EndText_p=strsave(LexiProblem_p->question);
                    422: 				      free_problems(LexiProblem_p);
                    423: 				      LexiProblem_p=NULL;
                    424: 				    } else {
                    425: 				      EndText_p=NULL;
                    426: 				    }
                    427: 				    End_of_input = 1; BEGIN S_IGNORE;RETURN(CAPA_END); 
                    428:                                   }
                    429: ^{Spaces}"/START"[^\n]*          { LLDBUG_PRL1("[START]");  
                    430:                                     if (LexiProblem_p !=NULL && 
                    431: 					LexiProblem_p->question != NULL) {
                    432: 				      StartText_p=strsave(LexiProblem_p->question);
                    433: 				    } else {
                    434: 				      StartText_p=NULL;
                    435: 				    }
                    436: 				    BEGIN S_TEXT;
                    437: 				    RETURN(CAPA_START); 
                    438:                                   }
                    439:                                   
                    440: ^{Spaces}"/END"{Spaces}[\(]{Spaces}      { LLDBUG_PRL1("[END()]"); BEGIN S_ENDX; }
                    441: ^"/DEF"                       { Bcount = 0; BEGIN S_DEFINE; RETURN(CAPA_DEF); }
                    442: ^{Spaces}"/ANS"               { LLDBUG_PRL2("[ANS(%s)]",yytext); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_ANS); }
                    443: ^{Spaces}"/SUBJECTIVE"        { LLDBUG_PRL1("[SUBJECTIVE ANSWER]"); Pcount = 0; BEGIN S_ANSWER; RETURN(CAPA_SUBJ); }
                    444: ^{Spaces}"/MAP"               { LLDBUG_PRL1("[MAP]");  Pcount = 0; BEGIN S_MAP;   RETURN(CAPA_MAP); }
                    445: ^{Spaces}"/RMAP"              { LLDBUG_PRL1("[RMAP]"); Pcount = 0; BEGIN S_MAP;   RETURN(CAPA_RMAP); }
                    446: ^{Spaces}"/RQO"{Spaces}*      { LLDBUG_PRL1("[RQO]"); BEGIN S_RANDOMORDER; 
                    447:                                 RETURN(CAPA_RQO);}
                    448: ^{Spaces}"/ENDWHILE"([^\n])*          { long int  file_pos;       
                    449:                                 int   top_item, input_idx;
                    450:                                 LLDBUG_PRL2("[ENDWHILE While_idx=<%d>]\n",While_idx);
                    451:                                 
                    452:                                 top_item = While_idx - 1;
                    453:                                 if( top_item < 0 ) { /* strange things must have happened here! */
                    454:                                   
                    455:                                 } else {
                    456:                                   input_idx = WhileStack[top_item].input_idx;
                    457:                                   file_pos = WhileStack[top_item].pos_idx;
                    458:                                   Current_line[input_idx] = WhileStack[top_item].line_idx;
                    459:                                   Lexi_pos[input_idx] = 0;
                    460:                                   fseek(Input_stream[input_idx],file_pos,SEEK_SET);
                    461:                                   fgets(Lexi_buf[input_idx],LEX_BUFLEN-1,Input_stream[input_idx]);
                    462:                                   While_idx--;
                    463:                                 }
                    464:                                 BEGIN S_TEXT;
                    465:                               }
                    466: "/WHILE"                      |
                    467: ^{Spaces}"/WHILE"             { long int file_pos;
                    468:                                 int      leng;
                    469:                                 LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",While_idx);
                    470:                                 leng = strlen(Lexi_buf[Input_idx]);  /* length of current line */
                    471:                                 /* <-- because we use fgets() to read input, 
                    472:                                        thus ftell() will give the starting position of next line */
                    473:                                 WhileStack[While_idx].input_idx = Input_idx;
                    474:                                 file_pos = ftell(Input_stream[Input_idx]);
                    475:                                 file_pos -= leng;  /* calibrate the current line length */
                    476:                                 WhileStack[While_idx].pos_idx = file_pos;  /* begin of current line */
                    477:                                 WhileStack[While_idx].line_idx = Current_line[Input_idx];
                    478:                                 While_idx++;  /* advance the stack pointer */
                    479:                                 
                    480:                                 BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_WHILE); 
                    481:                                 
                    482:                               }
                    483: ^{Spaces}"/IF"                { IFcount++; IFcurrent[IFcount] = RUN_IF_PORTION;
                    484:                                 LLDBUG_PRL2("[IF <IFcount=%d>]",IFcount);  BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_IF); }
                    485: ^{Spaces}"/ELSE"([^\n])*        { LLDBUG_PRL2("[ELSE <IFcount=%d>]\n",IFcount); 
                    486:                                 IFcurrent[IFcount] = RUN_ELSE_PORTION;
                    487:                                 if( IFstatus[IFcount] == IF_TRUE ) {
                    488:                                   LLDBUG_PRL1("[ELSE begin Skip]\n");
                    489:                                   BEGIN S_IF_SKIP;
                    490:                                 }
                    491:                               }
                    492: ^{Spaces}"/ENDIF"([^\n])*    { IFcount--; LLDBUG_PRL2("[ENDIF <IFcount=%d>]\n",IFcount); 
                    493:                               }
                    494: "/AND"                        { LLDBUG_PRL1("[AND]"); BEGIN S_ANSCONTINUE; RETURN(ANS_AND); }
                    495: "/DIS"                        { /* since S_VARIABLE treat {Space} as null, so here we do not match ( */
                    496:                                 /* so that between /DIS and ( can have as many {Space} as we want */
                    497:                                 LLDBUG_PR1("[DIS<]");
                    498:                                 init_funcstack();
                    499:                                 Pcount = 0; BEGIN S_VARIABLE; 
                    500:                                 RETURN(CAPA_VAR); 
                    501:                               }
                    502: "/OR"                         { LLDBUG_PRL1("[OR]"); BEGIN S_ANSCONTINUE;  RETURN(ANS_OR); }
                    503: {EndLine}                     { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */ 
                    504:                                 RETURN(EoL); }
                    505: [\\]{Space}*{EndLine}         { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }                       
                    506: ^{Spaces}"//"[^\n]*$		      { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);    BEGIN S_COMMENT; }
                    507: [^/\n\\]+$  |
                    508: [/]         | 
                    509: [\\]                          {  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    510:                                 yylval->s_str = strsave(yytext);
                    511:                                 LLDBUG_PR2("[TEXT_LINE<%s>]",yytext);
                    512: 			        RETURN(TEXT_LINE); 
                    513: 			      }
                    514: ([^/\n])+[/] |
                    515: ([^/\n])+[\\]                 { /* matches anything until a '/' or a '\' */
                    516:                                 LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext);
                    517:                                 
                    518:                                 yyless(yyleng-1); /* push back the last char */
                    519:                                 yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    520:                                 yylval->s_str = strsave(yytext);
                    521:                                 
                    522:                                 BEGIN S_TEXT;
                    523:                                 RETURN(TEXT_LINE); 
                    524:                               }
                    525: <<EOF>>                       { 
                    526: #ifdef AVOIDYYINPUT
                    527:                                 char    warn_msg[ONE_K];
                    528: 
                    529:                                 if ( (--include_stack_ptr < 0) || Stop_Parser) {
                    530: 				  if (Stop_Parser) {
                    531:                                     if ( LexiProblem_p!=NULL &&
                    532: 					 LexiProblem_p->question != NULL)
                    533: 				      EndText_p=strsave(LexiProblem_p->question);
                    534: 				    while (include_stack_ptr >= 0) {
                    535: 				      yy_delete_buffer( YY_CURRENT_BUFFER );
                    536: 				      yy_switch_to_buffer(
                    537: 						 include_stack[include_stack_ptr]);
                    538: 				      --include_stack_ptr;
                    539: 				    }
                    540: 				  } else {
                    541: 				    sprintf(warn_msg,
                    542: 					    "at End-of-File, a /END is needed.\n");
                    543: 				    capa_msg(MESSAGE_ERROR,warn_msg);
                    544: 				  }
                    545: 				  free_problems(LexiProblem_p);
                    546: 				  LexiProblem_p=NULL;
                    547: 				  yyterminate();
                    548: 				} else {
                    549: 				  yy_delete_buffer( YY_CURRENT_BUFFER );
                    550: 				  yy_switch_to_buffer(include_stack[include_stack_ptr]);
                    551: 				}
                    552: #else                              
                    553: 				char    warn_msg[ONE_K];
                    554:                                 if (!Stop_Parser) { 
                    555: 				 sprintf(warn_msg,"at End-of-File, a /END is needed.\n");
                    556: 				 capa_msg(MESSAGE_ERROR,warn_msg);
                    557: 				} else {
                    558: 				  if (LexiProblem_p != NULL &&
                    559: 				      LexiProblem_p->question != NULL)
                    560: 				    EndText_p=strsave(LexiProblem_p->question);
                    561: 				}
                    562:                                 capa_eof(); 
                    563: 				yyterminate();
                    564: #endif
                    565:                               }
                    566: }
                    567: 
                    568: 
                    569: <S_ENDX>{
                    570: {Alpha}{AlphaNum}*    { /* DONE: add codes to handle /END() */
                    571: 				char *question_end=NULL;
                    572: 				End_of_input = 1;
                    573: 				if (EndText_p!=NULL) capa_mfree((char*)EndText_p);
                    574: 				if ((LexiProblem_p!=NULL) &&
                    575: 				    (LexiProblem_p->question != NULL) &&
                    576: 				    (LexiProblem_p->ans_type == 0)) {
                    577: 				  question_end=strsave(LexiProblem_p->question);
                    578: 				}
                    579:                                 if( yyleng > 0 ) {
                    580:                                   
                    581:                                   LLDBUG_PRL2("[END()<%s>]\n",yytext);
                    582:                                   yylval = find_identifier(yytext);
                    583:                                 
                    584:                                   switch(yylval->s_type) {
                    585:                                     case IDENTIFIER:
                    586:                                     case I_VAR: case I_CONSTANT:
                    587:                                     case R_VAR: case R_CONSTANT:
                    588:                                          break;
                    589:                                     case S_VAR: case S_CONSTANT:
                    590:                                          EndText_p = strsave(yylval->s_str);
                    591: 					 if (question_end) {
                    592: 					   int leng; char *new_end;
                    593: 					   leng = strlen(EndText_p) + 
                    594: 					     strlen(question_end) + 1;
                    595: 					   new_end = capa_malloc(sizeof(char), leng);
                    596: 					   strcat(new_end, question_end);
                    597: 					   strcat(new_end, EndText_p);  
                    598: 					   capa_mfree(EndText_p);  
                    599: 					   capa_mfree(question_end);  
                    600: 					   EndText_p=new_end;
                    601: 					 }
                    602:                                          break;
                    603:                                     default: break;
                    604:                                   }
                    605:                                 }
                    606:                                 BEGIN S_IGNORE;   RETURN(CAPA_END);
                    607:                               }
                    608: {Space}*                      { /* ignore spaces */ }
                    609: [\)]                          { /* a right paren */ 
                    610:                                 if ( (LexiProblem_p != NULL) &&
                    611: 				     (LexiProblem_p->question != NULL) && 
                    612: 				     (LexiProblem_p->ans_type == 0)) {
                    613: 				  EndText_p=strsave(LexiProblem_p->question);
                    614: 				} else {
                    615: 				  EndText_p=NULL;
                    616: 				}
                    617:                                 BEGIN S_IGNORE;   
                    618: 				RETURN(CAPA_END);  
                    619:                               }
                    620: }
                    621: 
                    622: <S_HINT,S_EXPLAIN>{
                    623: [/][Dd][Ii][Ss]{Space}*[\(]{Space}*  {  yy_push_state(S_HINTEXLAINX); }
                    624: [^/\n]+[/\\]                    { char  *aptr = yytext;
                    625:                                   int    ii;
                    626:                                 
                    627:                                   yyless(yyleng-1);
                    628:                                   for(ii=0;ii<yyleng;ii++) {
                    629:                                   *Current_char_p++ = *aptr++;
                    630:                                 }
                    631:                                 
                    632:                               }
                    633: [/]                            { *Current_char_p++ = '/'; }
                    634: [\\]                           { *Current_char_p++ = '\\'; }
                    635: [\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ }
                    636: [^/\n\\]+$                      { char  *aptr = yytext;
                    637:                                 int    ii;
                    638:                                 for(ii=0;ii<yyleng;ii++) {
                    639:                                   *Current_char_p++ = *aptr++;
                    640:                                 }
                    641:                               }
                    642: }
                    643: <S_HINT>{
                    644: {EndLine}                     {  LLDBUG_PR1("[CR hint]");
                    645:                                  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    646: 		                *Current_char_p++ = '\n'; *Current_char_p = '\0';
                    647: 	                         yylval->s_str = strsave(String_buf);
                    648:                                  BEGIN S_TEXT; RETURN(HINT_LINE); 
                    649:                               }
                    650: }
                    651: <S_EXPLAIN>{
                    652: {EndLine}                     {  LLDBUG_PR1("[CR explain]");
                    653:                                  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    654: 		                *Current_char_p++ = '\n'; *Current_char_p = '\0';
                    655: 	                         yylval->s_str = strsave(String_buf);
                    656:                                  BEGIN S_TEXT; RETURN(EXPLAIN_LINE); 
                    657:                               }
                    658: }
                    659: 
                    660: <S_HINTEXLAINX>{
                    661: {Alpha}{AlphaNum}*            { char   *aptr;
                    662:                                 char    tmp_str[QUARTER_K],warn_msg[ONE_K];
                    663:                                 int     ii, len;
                    664:                                 Symbol *tmp_p;
                    665:                                 
                    666:                                 tmp_p = find_identifier(yytext);
                    667:                                 switch(tmp_p->s_type) {
                    668:                                   case IDENTIFIER:
                    669:                                         sprintf(warn_msg,"var %s not defined.\n", yytext);
                    670:                                         capa_msg(MESSAGE_ERROR,warn_msg);
                    671:                                        break;
                    672:                                   case I_VAR:
                    673:                                   case I_CONSTANT: 
                    674:                                          sprintf(tmp_str,"%ld",tmp_p->s_int);
                    675:                                          len = strlen(tmp_str);
                    676:                                          for(ii=0;ii< len;ii++) {
                    677:                                            *Current_char_p++ = tmp_str[ii];
                    678:                                          }
                    679:                                        break;
                    680:                                   case R_VAR:
                    681:                                   case R_CONSTANT: 
                    682:                                          sprintf(tmp_str,"%g",tmp_p->s_real);
                    683:                                          len = strlen(tmp_str);
                    684:                                          for(ii=0;ii< len;ii++) {
                    685:                                            *Current_char_p++ = tmp_str[ii];
                    686:                                          }
                    687:                                        break;
                    688:                                   case S_VAR:
                    689:                                   case S_CONSTANT: 
                    690:                                          len = strlen(tmp_p->s_str);
                    691:                                          aptr = tmp_p->s_str;
                    692:                                          for(ii=0;ii< len;ii++) {
                    693:                                            *Current_char_p++ = *aptr++;
                    694:                                          }
                    695:                                        break;
                    696:                                 }
                    697:                               }
                    698: {Space}+                      { }
                    699: [)]                           {  yy_pop_state(); }
                    700: }
                    701: 
                    702: <S_IMPORT>{
                    703: {FileName}{Space}*             { parse_filename(yytext);    BEGIN S_SKIP; }
                    704: {Identifier}{Space}*           { parse_import_id(yytext);   BEGIN S_SKIP; }
                    705: }
                    706: 
                    707: <S_ANSWER>{
                    708: [Pp][Ll][Uu][Ss]             { LLDBUG_PR1("[PLUS]");  RETURN(ANS_PLUS); }
                    709: [Mm][Ii][Nn][Uu][Ss]         { LLDBUG_PR1("[MINUS]"); RETURN(ANS_MINUS); }
                    710: [Cc][Ss]                     { LLDBUG_PR1("[CS]");    RETURN(ANS_CS); }
                    711: [Cc][Ii]                     { LLDBUG_PR1("[CI]");    RETURN(ANS_CI); }
                    712: [Mm][Cc]                     { LLDBUG_PR1("[MC]");    RETURN(ANS_MC); }
                    713: [Oo][Nn]                     |
                    714: [Yy][Ee][Ss]                 { LLDBUG_PR1("[ON]");    RETURN(ANS_ON); }
                    715: [Oo][Ff][Ff]                 |
                    716: [Nn][Oo]                     { LLDBUG_PR1("[OFF]");   RETURN(ANS_OFF); }
                    717: [Ff][Mm][Ll]                 { LLDBUG_PR1("[FORMULA]");   RETURN(ANS_FORMULA); }
                    718: [Ff][Mm][Tt]                 { LLDBUG_PR1("[FMT]");   RETURN(ANS_FMT); }
                    719: [Uu][Nn][Ff][Mm][Tt]         { LLDBUG_PR1("[UNFMT]"); RETURN(ANS_UNFMT); }
                    720: [,:%=@#-]                  { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
                    721: "<"                          { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
                    722: ">"                          { LLDBUG_PR2("[symbol(%s)]",yytext); return(yytext[0]); }
                    723: [Ss][Ii][Gg]                 { LLDBUG_PR2("[SIG(%s)]",yytext);  RETURN(ANS_SIG); }
                    724: [Tt][Oo][Ll]                 { LLDBUG_PR2("[tol(%s)]",yytext);  RETURN(ANS_TOLERANCE); }
                    725: [Ss][Tt][Rr]                 { LLDBUG_PR1("[STR]");   RETURN(ANS_COMPARE); }
                    726: [Ww][Gg][Tt]                 { LLDBUG_PR1("[WGT]");   RETURN(ANS_WEIGHT); }
                    727: [Pp][Cc][Rr]                 |
                    728: [Hh][Gg][Rr]                 { RETURN(ANS_PCREDIT); }
                    729: [Pp][Aa][Tt][Hh]             { RETURN(ANS_PATH); }
                    730: [Cc][Aa][Ll][Cc]             { RETURN(ANS_CALC); }
                    731: [Tt][Rr][Yy]                 |
                    732: [Tt][Rr][Ii][Ee][Ss]         { LLDBUG_PR1("[TRY]");     RETURN(ANS_TRY); }
                    733: [Uu][Nn][Ii][Tt]             |
                    734: [Uu][Nn][Ii][Tt][Ss]         { LLDBUG_PR1("[UNIT]");    RETURN(ANS_UNIT); }
                    735: [Bb][Rr]                     { LLDBUG_PR1("[SHOW_BR]"); RETURN(ANS_SHOW_BR);  }
1.7       albertel  736: [Vv][Ee][Rr][Bb][Aa][Tt][Ii][Mm] { LLDBUG_PR1("[VERBATIM]"); RETURN(ANS_VERBATIM); }
1.1       albertel  737: [Aa][Nn][Ss][Bb][Oo][Xx]     { LLDBUG_PR1("[SHOW_ANS_BOX]"); RETURN(ANS_BOX_SHOW);  }
                    738: [Hh][Ii][Nn][Tt]             { LLDBUG_PR1("[HINT]");    RETURN(ANS_HINT); }
                    739: [Ee][Xx][Pp][Ll][Aa][Ii][Nn] { LLDBUG_PR1("[EXPLAIN]"); RETURN(ANS_EXPLAIN); }
                    740: [Ee][Xx][Tt][Ee][Rr][Nn][Aa][Ll]  { LLDBUG_PR1("[EXTERNAL]"); RETURN(ANS_EXTERNAL); }
                    741: [Ee][Vv][Aa][Ll]             |
                    742: [Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee]             { LLDBUG_PR1("[EVAL]"); RETURN(ANS_EVAL); }
                    743: [\)]                         { LLDBUG_PR1("[)]"); Pcount--; 
                    744:                                if(Pcount==0) {
                    745:                                    BEGIN S_ANSCONTINUE; 
                    746:                                }
                    747:                                return(yytext[0]); 
                    748:                              }
                    749: }
                    750: 
                    751: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_ANSWER,S_MAP>{
                    752: {Alpha}{AlphaNum}*             { LLDBUG_PR2("[ID<%s>]",yytext);LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); 
                    753:                                  yylval = find_identifier(yytext); RETURN(IDENTIFIER); 
                    754:                                }
                    755: 
                    756: {Alpha}{AlphaNum}*{Space}*[(]  { char aline[MAX_FUNC_NAME];
                    757:                                  int  i;          
                    758:                                    for(i=0;i < (yyleng-1); i++) {
                    759:                                      if( yytext[i] == ' ' || yytext[i] == '\t' || 
                    760:                                          yytext[i] == 0   || yytext[i] == '(' )    break;
                    761:                                      aline[i] = yytext[i];
                    762:                                    }
                    763:                                    aline[i] = 0;
                    764:                                    LLDBUG_PR3("[FUNCT<%s:%d>]",aline,Func_idx);
                    765:                             (FuncStack[Func_idx]).s_type = FUNCTION_ID;
                    766: 			    (FuncStack[Func_idx]).s_name = strsave(aline); /* free it in parser() */
                    767: 				   Func_idx++;
                    768: 				   yyless(yyleng-1); /* <-- push back '(' char  */
                    769: 				   RETURN(FUNCTION_ID); 
                    770:                                }
                    771: {Alpha}{AlphaNum}*{Space}*[\[]  {  char aline[MAX_FUNC_NAME];
                    772:                                    int  i;   
                    773:                                    for(i=0;i < (yyleng-1); i++) {
                    774:                                      if( yytext[i] == ' ' || yytext[i] == '\t' || 
                    775:                                          yytext[i] == 0   || yytext[i] == '[' )    break;
                    776:                                      aline[i] = yytext[i];
                    777:                                    }
                    778:                                    aline[i] = 0;
                    779:                                    LLDBUG_PR2("[ARRAY<%s>]",aline);
                    780:                                    
                    781:                                    yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
                    782:                                    yylval->s_name = strsave(aline); /* free it in parser() */
                    783:                                    yylval->s_type = ARRAY_ID;
                    784:                                    
                    785:                                    yyless(yyleng-1); /* <-- push back char '[' */
                    786:                                    RETURN(ARRAY_ID);
                    787:                                }
                    788: {Number}*"\."{Number}*[Ee]"+"{Number}+ |
                    789: {Number}*"\."{Number}*[Ee]{Number}+    |
                    790: {Number}*"\."{Number}*[Ee]"-"{Number}+ |
                    791: {Number}+[Ee]"+"{Number}+ |
                    792: {Number}+[Ee]{Number}+    |
                    793: {Number}+[Ee]"-"{Number}+ |
                    794: {Number}+"\."{Number}*    |
                    795: "\."{Number}+             {  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
                    796:                              yylval->s_real = strtod(yytext, (char **) 0);
                    797:                              yylval->s_type = R_CONSTANT;
                    798:                              LLDBUG_PR2("[REAL<%s>]",yytext);
                    799:                              RETURN(R_CONSTANT);
                    800: 			  }
                    801: 
                    802: {Number}+                 {  yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */
                    803:                              yylval->s_int = strtol(yytext, (char **) 0, 0);
                    804:                              yylval->s_type= I_CONSTANT;
                    805:                              LLDBUG_PR2("[INT<%s>]",yytext);
                    806:                              RETURN(I_CONSTANT);
                    807: 			  }
                    808: [\(]                      { LLDBUG_PR1("[dis let ans map (]"); Pcount++; return(yytext[0]); }
                    809: [\[]                      { LLDBUG_PR1("[dis let ans map '[']");         return(yytext[0]); }
                    810: [\]]                      { LLDBUG_PR1("[dis let ans map ']']");         return(yytext[0]); }
                    811: {Space}+                  { /* LLDBUG_PR1("[SP ignored]");  Ignore Spaces */ }
                    812: [\"]                      { LLDBUG_PR1("[TF,V,LET,ANS,MAP str\" ]"); 
                    813:                             Current_char_p = String_buf; 
                    814:                             yy_push_state(S_STRING); 
                    815:                           }
                    816: }
                    817: 
1.3       albertel  818: <S_VARIABLE,S_ANSWER>[:]{Number}+[EeFf]   { char  num[ONE_TWO_EIGHT], fmt[SMALL_LINE_BUFFER];
1.1       albertel  819:                              int   i;
                    820:                              LLDBUG_PR2("[FORMAT<%s>]",yytext);
                    821:                              for(i=0;i<yyleng-2;i++) {
                    822:                                num[i] = yytext[i+1];
                    823:                              }
                    824:                              num[yyleng-2] = 0; /* terminate the numerical string */
                    825:                              yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    826:                              i = strtol(num, (char **) 0, 0);
                    827:                              yylval->s_type=FORMAT;
                    828:                              switch( yytext[yyleng-1] ) {
                    829:                                case 'e': sprintf(fmt,"%%.%de", i);
                    830:                                          yylval->s_distype = E_FORMAT; break;
                    831:                                case 'E': sprintf(fmt,"%%.%dE", i);
                    832:                                          yylval->s_distype = E_FORMAT; break;
                    833:                                case 'f': 
                    834:                                case 'F': sprintf(fmt,"%%.%df", i);
                    835:                                          yylval->s_distype = F_FORMAT; break;
                    836:                              }
                    837:                              yylval->s_str = strsave(fmt);
                    838:                              RETURN(FORMAT);
                    839:                            }
                    840: 
                    841: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
                    842: "=="                { LLDBUG_PR1("[==]"); RETURN(EQ_op);  }
                    843: "!="                { LLDBUG_PR1("[!=]"); RETURN(NE_op);  }
                    844: ">"                 { LLDBUG_PR1("[>]");  RETURN(GT_op);  }
                    845: ">="                { LLDBUG_PR1("[>=]"); RETURN(GE_op);  }
                    846: "<"                 { LLDBUG_PR1("[<]");  RETURN(LT_op);  }
                    847: "<="                { LLDBUG_PR1("[<=]"); RETURN(LE_op);  }
                    848: "&&"                { LLDBUG_PR1("[&&]"); RETURN(AND_op); }
                    849: "||"                { LLDBUG_PR1("[||]"); RETURN(OR_op);  }
                    850: "//"                { if(Pcount==0) BEGIN S_SKIP;         }
                    851: {Operator}          { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); return(yytext[0]); }
                    852: }
                    853: 
                    854: 
                    855: <S_RANDOMORDER>{
                    856: {Number}+ {
                    857:              yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); 
                    858: 	     yylval->s_int = strtol(yytext, (char **) 0, 0);
                    859: 	     yylval->s_type= I_CONSTANT;
                    860: 	     LLDBUG_PR2("[INT<%s>]",yytext);
                    861: 	     RETURN(I_CONSTANT);
                    862:           }
                    863: [+~,\-!]   { LLDBUG_PR2("[randqo(%s)]",yytext); return(yytext[0]); }
                    864: {EndLine} { LLDBUG_PR1("[EoLRQO]"); BEGIN S_TEXT; RETURN(EoL);}
                    865: }
                    866: 
                    867: <S_VARIABLE>{
                    868: [\)]                     { LLDBUG_PR1("[)]"); Pcount--; if(Pcount == 0)  BEGIN S_TEXT; return(yytext[0]); }
                    869: [\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ }                       
                    870: {EndLine}                { LLDBUG_PR1("[EoL within /dis()]\n"); RETURN(EoL); }
                    871: .                   { char warn_msg[WARN_MSG_LENGTH]; 
                    872:                       sprintf(warn_msg,"When use a VARIABLE, an unexpected char [%c] is encountered.\n",yytext[0]);
                    873:                       capa_msg(MESSAGE_ERROR,warn_msg);
                    874:                     }
                    875: }
                    876: 
                    877: <S_TRUE_FALSE_STMT>{
1.6       albertel  878: [\)]                     { LLDBUG_PRL1("[) in TRUE_FALSE]"); Pcount--; if(Pcount == 0)  BEGIN S_NEXT_LINE; return(yytext[0]); }
1.1       albertel  879: [\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ }                       
                    880: {EndLine}                { LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL); }
                    881: .                   { char warn_msg[WARN_MSG_LENGTH]; 
                    882:                       sprintf(warn_msg,"In /IF(), an unexpected char [%c] is encountered.\n",yytext[0]);
                    883:                       capa_msg(MESSAGE_ERROR,warn_msg);
                    884:                     }
                    885: }
                    886: 
                    887: <S_STRING>{
                    888: [\\][\\]            { char  *aptr = yytext;
                    889:                       while( *aptr )   *Current_char_p++ = *aptr++;
                    890:                     }
                    891: [\\][\"]            { *Current_char_p++ = '"';  }
                    892: [\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
                    893: [\"]                { /* end of a string constant --   */
                    894:                       yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                    895: 		      *Current_char_p = '\0';
                    896: 	              yylval->s_str = strsave(String_buf);  /* ****   */
                    897: 		      yylval->s_type = S_CONSTANT;
                    898: 		      /* printf("STRING:%s\n", String_buf); */
                    899: 		      LLDBUG_PR2("[%s\"END str]",String_buf);
                    900: 		      yy_pop_state();
                    901: 		      RETURN(S_CONSTANT); }
                    902: {EndLine}           { /* check for termination of string constant */
                    903:                       char warn_msg[WARN_MSG_LENGTH];
                    904:                       
                    905:                       *Current_char_p = '\0';
                    906:                       sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf);
                    907:                       capa_msg(MESSAGE_ERROR,warn_msg);
                    908:                       yy_pop_state();
                    909:                     }
                    910: .                   { char  *aptr = yytext;
                    911:                       while( *aptr )   *Current_char_p++ = *aptr++;
                    912:                     }
                    913: }
                    914: 
                    915: <S_LET>[\)]                  { LLDBUG_PR1("[) in LET]"); Pcount--; return(yytext[0]); }
                    916: 
                    917: <S_SKIP>{
                    918: [^\n]+$                      {       }
                    919: {EndLine}                    { BEGIN S_TEXT; RETURN(EoL);  }
                    920: }
                    921: 
                    922: <S_LET,S_ANSWER,S_MAP>{
                    923: [\\]{Space}*{EndLine}        { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ }
                    924: {EndLine}                    { LLDBUG_PR1("[EoL END let ans map]\n"); if(Pcount == 0) BEGIN S_TEXT; RETURN(EoL); }
                    925: }
                    926: 
                    927: <S_MAP>{
                    928: [;,]                         { LLDBUG_PR2("[%c]",yytext[0]); return(yytext[0]);  }
                    929: [\)]                         { LLDBUG_PR1("[) in MAP]"); Pcount--; 
                    930:                                if(Pcount==0) {
                    931:                                    BEGIN S_SKIP; 
                    932:                                }
                    933:                                return(yytext[0]); 
                    934:                              }
                    935: }
                    936: 
                    937: <S_ANSCONTINUE>{
                    938: {Space}+                 { /* ignore white spaces */ }
                    939: [\\]{Space}*{EndLine}    { /* continuation */ }
                    940: {EndLine}                { /* end of answer and/or other answers */ LLDBUG_PR1("[complete an answer<EoL>]"); 
                    941:                            BEGIN S_TEXT; }
                    942: "/AND"                   { LLDBUG_PR1("[AND]"); RETURN(ANS_AND); }
                    943: "/OR"                    { LLDBUG_PR1("[OR]");  RETURN(ANS_OR);  }
                    944: }
                    945: 
                    946: <S_IF_SKIP>{
                    947: ^{Spaces}"/IF"[^\n]*{EndLine}    { IFcount++; LLDBUG_PRL2("[Skip IF <IFcount=%d>]\n",IFcount); 
                    948:                                    IFstatus[IFcount] = IF_DONT_CARE;
                    949:                                  }
                    950: ^{Spaces}"/ELSE"[^\n]*{EndLine}  {  LLDBUG_PRL2("[Skip ELSE <IFcount=%d>]",IFcount);
                    951:                             IFcurrent[IFcount]=RUN_ELSE_PORTION; 
                    952:                             if( IFstatus[IFcount] == IF_FALSE ) {
                    953:                                LLDBUG_PRL1("[ELSE begin TEXT CR]\n");
                    954:                                BEGIN S_TEXT;
                    955:                             } 
                    956:                             if( IFstatus[IFcount] == IF_TRUE ) {
                    957:                                LLDBUG_PRL1("[ELSE THIS SHOULD NEVER HAPPEN.]\n");
                    958:                             }
                    959:                          }
                    960: ^{Spaces}"/ENDIF"[^\n]*{EndLine} { IFcount--; LLDBUG_PRL2("[Skip ENDIF <IFcount=%d>]\n",IFcount);
                    961:                             if( IFcount == 0 ) {
                    962:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
                    963:                                BEGIN S_TEXT;
                    964:                             }
                    965:                             if( (IFcurrent[IFcount] == RUN_IF_PORTION )&&(IFstatus[IFcount] == IF_TRUE)) {
                    966:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
                    967:                                BEGIN S_TEXT;
                    968:                             }
                    969:                             if( (IFcurrent[IFcount] == RUN_ELSE_PORTION )&&(IFstatus[IFcount] == IF_FALSE)) {
                    970:                                LLDBUG_PRL1("[ENDIF begin TEXT CR]\n");
                    971:                                BEGIN S_TEXT;
                    972:                             }
                    973:                          }
                    974: {EndLine}                { LLDBUG_PRL1("[SkipIF a CR]\n");       }
                    975: [^\n]*$                  { LLDBUG_PRL2("[SkipIF anything <IFcount=%d>]",IFcount);   }
                    976: }
                    977: <S_NEXT_LINE>{
1.6       albertel  978: ([.]*){EndLine}          { /* this ignores everything until it hits an EoL */
                    979:                            LLDBUG_PRL2("[<S_NEXT_LINE> skip \'%s\' until EoL]\n",yytext); 
                    980:                            BEGIN S_TEXT;
                    981:                          }
1.1       albertel  982: }
                    983: 
                    984: <S_WHILE_SKIP>{
                    985: ^{Spaces}"/WHILE"[^\n]*{EndLine}        { Wcount++;
                    986:                                           LLDBUG_PRL2("[SkipWHILE /WHILE <Wcount=%d>]\n",Wcount);   
                    987:                                         }
                    988: ^{Spaces}"/ENDWHILE"[^\n]*{EndLine}     { 
                    989:                                           if(Wcount==0) {
                    990:                                              LLDBUG_PRL2("[SkipWHILE->/ENDWHILE <Wcount=%d>]\n",Wcount);
                    991:                                              BEGIN S_TEXT;
                    992:                                           } else {
                    993:                                              Wcount--;
                    994:                                              LLDBUG_PRL2("[SkipWHILE /ENDWHILE <Wcount=%d>]\n",Wcount);
                    995:                                           }
                    996:                                         }
                    997: {EndLine}                { LLDBUG_PRL1("[SkipWHILE a CR]\n");       }                         
                    998: [^\n]*$                  { LLDBUG_PRL2("[SkipWHILE anything <Wcount=%d>]",Wcount);   }
                    999: }
                   1000: 
                   1001: <S_VERB>{
                   1002: ^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n"); 
                   1003:                       yylval = (Symbol *) capa_malloc(1, sizeof(Symbol));
                   1004: 		      yylval->s_str = strsave(Dynamic_buf);  /* ****   */
                   1005: 		      yylval->s_type = S_CONSTANT;  
                   1006: 		      capa_mfree(Dynamic_buf);
                   1007: 		      Dynamic_buf_cur=-1;
                   1008: 		      Dynamic_buf_max=0;
                   1009: 		      BEGIN S_TEXT;   RETURN(VERBATIM);   
                   1010: 		    }
                   1011: .*|{EndLine}         { append_dynamic_buf(yytext); }
                   1012: }
                   1013: 
                   1014: %%
                   1015: 
                   1016: /* ========================================================================================== */
                   1017: extern void
                   1018: begin_if_skip() { BEGIN S_IF_SKIP; }
                   1019: 
                   1020: extern void
                   1021: begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; }
                   1022: 
                   1023: extern void
                   1024: begin_next_line()  { BEGIN S_NEXT_LINE; }
                   1025: 
                   1026: extern void
                   1027: begin_var() { BEGIN S_VARIABLE; }
                   1028: 
                   1029: extern void
                   1030: begin_let() { BEGIN S_LET; }
                   1031: 
                   1032: extern void
                   1033: begin_def() { BEGIN S_DEFINE; }
                   1034: 
                   1035: extern void
                   1036: begin_ans() { BEGIN S_ANSWER; }
                   1037: 
                   1038: extern void
                   1039: begin_map() { BEGIN S_MAP; }
                   1040: 
                   1041: extern void
                   1042: begin_ignore() { BEGIN S_IGNORE; }
                   1043: 
                   1044: extern void
                   1045: begin_text() { BEGIN S_TEXT; }
                   1046: 
                   1047: extern void
                   1048: begin_question() { LLDBUG_PR1("[<S_TEXT>]"); 
                   1049:                    IFcount = 0; While_idx=0; /* initialize some stacks */
                   1050:                    End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
                   1051: 
                   1052: extern void
                   1053: end_problemset() { End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; }
                   1054: 
                   1055: 
                   1056: /* ========================================================================================== */
                   1057: 
                   1058: #define  NUM_KEY   2
                   1059: int
                   1060: match_keyword(key) char *key;
                   1061: {
                   1062:   char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
                   1063:   int    i;
                   1064:   
                   1065:   for(i=0;i < NUM_KEY; i++) {
                   1066:      if( !strncmp(keyword[i], key, 4) ) {
                   1067:         return (1);
                   1068:      }
                   1069:   }
                   1070:   return (0);
                   1071: }
                   1072: 
                   1073: int
                   1074: match_functionid(key) char *key;
                   1075: {
                   1076:   char  *keyword[NUM_KEY] = {"/DIS", "/DIR" };
                   1077:   int    i;
                   1078:   
                   1079:   for(i=0;i < NUM_KEY; i++) {
                   1080:      if( !strncmp(keyword[i], key, 4) ) {
                   1081:         return (1);
                   1082:      }
                   1083:   }
                   1084:   return (0);
                   1085: }
                   1086: /* -------------------------------------------------------------------------- */
                   1087: /* -------------------------------------------------------------------------- */
                   1088: 
                   1089: void  init_funcstack() 
                   1090: {  
                   1091:  int ii;
                   1092:  for(ii=0;ii<Func_idx;ii++) {
                   1093:    capa_mfree(FuncStack[ii].s_name);
                   1094:  }
                   1095:  Func_idx = 0;  
                   1096: }
                   1097: 
                   1098: 
                   1099: /* -------------------------------------------------------------------------- */
                   1100: /* GET THE NEXT CHARACTER OF THE SOURCE FILE                                  */
                   1101: /* -------------------------------------------------------------------------- */
                   1102: 
                   1103: #ifdef  FLEX
                   1104: int   capaL_input()
                   1105: #else
                   1106: int                        /* RETURNS: next character */
                   1107: input()                    /* ARGUMENTS: (none)       */
                   1108: #endif
                   1109: 
                   1110: {                          /* LOCAL VARIABLES:        */
                   1111:   static  int startup=1;  /*    First call flag      */
                   1112:   
                   1113:   LLDBUG_PRL1("<<capaL_input() is called>>\n");
                   1114:   if (!Lexi_line) { /* was startup */
                   1115:        for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) {
                   1116:          /* for(ii=0;ii<LEX_BUFLEN;ii++) {
                   1117:            Lexi_buf[Input_idx][ii]=0;
                   1118:          }
                   1119:          */
                   1120:          Lexi_buf[Input_idx][0]=0;
                   1121:          Lexi_pos[Input_idx] = 0;
                   1122:        }
                   1123:        Input_idx = 0;
                   1124:        startup=0;
                   1125:        yyin = Input_stream[Input_idx];
                   1126:   }
                   1127:   if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
                   1128:     if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
                   1129:       /* EOF? */
                   1130:       /* no use in flex
                   1131:          printf("capaL_input()EOF %s\n",Opened_filename[Input_idx+1]); fflush(stdout); */
                   1132:       return (0);
                   1133:     }
                   1134:     Lexi_pos[Input_idx] = 0;
                   1135:     Lexi_line++;
                   1136:     printf("input()(%d)\n",Lexi_line);
                   1137:   }
                   1138:   (Lexi_pos[Input_idx])++;
                   1139:   return ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1] );
                   1140: }
                   1141:  
                   1142: /******************************************************************************/
                   1143: /* PUSH BACK ONE CHARACTER OF THE INPUT                                       */
                   1144: /******************************************************************************/
                   1145: 
                   1146: int                /* RETURNS: nothing     */
                   1147: capaL_unput(ch)          /* ARGUMENTS:           */
                   1148: register int ch;   /*    Character to push */
                   1149: {
                   1150:    if (ch)   (Lexi_pos[Input_idx])--;
                   1151:  
                   1152:    /* unput() stream cannot be re-defined */
                   1153:    /* unput(ch); inconsistency between YY_INPUT() and internal matched yytext */
                   1154:    return (0);
                   1155: 
                   1156: }
                   1157: 
                   1158: 
                   1159: /******************************************************/
                   1160: 
                   1161: #ifndef DMALLOC
                   1162: 
                   1163: char *       
                   1164: strsave(char *s) 
                   1165: {            
                   1166:    char *p;  
1.4       albertel 1167:    if (s==NULL) {return s;}
1.1       albertel 1168:    p=capa_malloc(strlen(s)+1,1);
                   1169:    strcpy(p,s);
                   1170:    return (p);
                   1171: }
                   1172: 
                   1173: #endif
                   1174: 
                   1175: /* =========================================================================== */
                   1176: 
                   1177: #ifndef DMALLOC
                   1178: char *
                   1179: capa_malloc(unsigned num,unsigned sz)
                   1180: {
                   1181:   char *p;
                   1182:   p = calloc(num, sz);
                   1183:   bzero(p, num*sz);  /* added Jan 21 1998 */
                   1184:   return (p);
                   1185: }
                   1186: 
                   1187: #endif
                   1188: 
                   1189: #ifndef DMALLOC
                   1190: void
                   1191: capa_mfree(p) char *p;
                   1192: {
                   1193:   free(p);
                   1194: }
                   1195: #endif
                   1196: 
                   1197: void
                   1198: capa_msg(int type, char *p) 
                   1199: { int  idx, i, j;
                   1200:   int  len;
                   1201:   char warn_msg[WARN_MSG_LENGTH];
                   1202:   char tmp_line[ONE_TWO_EIGHT];
                   1203:   char  *tmp_str;
                   1204:   
                   1205:   strcpy(warn_msg,"File: ");
                   1206:   idx=6;
                   1207:   for(i=0;i<=Input_idx;i++) {
                   1208:     len=strlen(Opened_filename[i]);
                   1209:     for(j=0;j<len;j++) {
                   1210:       warn_msg[idx++] = Opened_filename[i][j];
                   1211:     }
                   1212:     if(i < Input_idx) {
                   1213:       warn_msg[idx++]='-';
                   1214:       warn_msg[idx++]='>';
                   1215:     }
                   1216:     warn_msg[idx]=0;
                   1217:   }
                   1218:   switch (type) {
                   1219:     case MESSAGE_ERROR:
                   1220:            sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
                   1221:            len=strlen(tmp_line);
                   1222:            for(j=0;j<len;j++) {
                   1223:               warn_msg[idx++] = tmp_line[j];
                   1224:            }
                   1225:            warn_msg[idx]=0;
                   1226:            append_error(warn_msg); append_error(p);
1.5       albertel 1227: 	   break;
1.1       albertel 1228:     case MESSAGE_WARN:
                   1229:     default:
                   1230:            sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);
                   1231:            len=strlen(tmp_line);
                   1232:            for(j=0;j<len;j++) {
                   1233:              warn_msg[idx++] = tmp_line[j];
                   1234:            }
                   1235:            warn_msg[idx]=0;
                   1236:            j = strlen(warn_msg);
                   1237:            len = strlen(p);
                   1238:            tmp_str = (char *)capa_malloc(len+j+1,1);
                   1239:            for(i=0;i<j;i++) {
                   1240:              tmp_str[i]=warn_msg[i];
                   1241:            } 
                   1242:            for(i=j;i<j+len;i++) {
                   1243:              tmp_str[i] = p[i-j];
                   1244:            }
                   1245:            append_warn(type,tmp_str);
                   1246:            capa_mfree(tmp_str);
                   1247:            break;
                   1248:   }
                   1249: }
                   1250: 
                   1251: /* ======================================================================== */
                   1252: void
                   1253: capa_warn_header(int type)
                   1254: {
                   1255:   int  idx, i, j;
                   1256:   int  len;
                   1257:   char warn_msg[WARN_MSG_LENGTH];
                   1258:   char tmp_line[ONE_TWO_EIGHT];
                   1259:   
                   1260:   strcpy(warn_msg,"File: ");
                   1261:   idx=6;
                   1262:   for(i=0;i<=Input_idx;i++) {
                   1263:     len=strlen(Opened_filename[i]);
                   1264:     for(j=0;j<len;j++) {
                   1265:       warn_msg[idx++] = Opened_filename[i][j];
                   1266:     }
                   1267:     if(i < Input_idx) {
                   1268:       warn_msg[idx++]='-';
                   1269:       warn_msg[idx++]='>';
                   1270:     }
                   1271:     warn_msg[idx]=0;
                   1272:   }
                   1273:   switch (type) {
                   1274:     case MESSAGE_ERROR:
                   1275:       sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
                   1276:       
                   1277:       break;
                   1278:     case MESSAGE_WARN:
                   1279:       sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);break;
                   1280:     default:
                   1281:     sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);break;
                   1282:   }
                   1283:   len=strlen(tmp_line);
                   1284:   for(j=0;j<len;j++) {
                   1285:     warn_msg[idx++] = tmp_line[j];
                   1286:   }
                   1287:   warn_msg[idx]=0;
                   1288:   append_error(warn_msg);
                   1289: }
                   1290: 
                   1291: /* --------------------------------------------------------------------------- */
                   1292: #ifdef AVOIDYYINPUT
                   1293: 
                   1294: void change_file(char *fname)
                   1295: {
                   1296:   char warn_msg[WARN_MSG_LENGTH];
                   1297:   if( capa_access(fname, (F_OK | R_OK)) == -1 ) {
                   1298:     sprintf(warn_msg,"/IMP \"%s\", import file does not exist or is not readable.\n",
                   1299: 	    fname);
                   1300:     capa_msg(MESSAGE_ERROR,warn_msg);
                   1301:     return;
                   1302:   } 
                   1303:   
                   1304:   if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
                   1305:     sprintf(warn_msg,"Includes nested too deeply" );
                   1306:     capa_msg(MESSAGE_ERROR,warn_msg);
                   1307:     return;
                   1308:   }
                   1309: 
                   1310:   include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER;
                   1311:   yyin = fopen( fname, "r" );
                   1312:   yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) );
                   1313: }
                   1314: 
                   1315: void
                   1316: parse_filename(char *line)
                   1317: {
                   1318:   char *start, fname[MAX_BUFFER_SIZE],  warn_msg[WARN_MSG_LENGTH];
                   1319:   int ii,len;
                   1320: 
                   1321:   start = index(line, '\"'); /*** hpux complained */
                   1322:   if( start == NULL ) {
                   1323:     sprintf(warn_msg,"/IMP was not given a filename.\n");
                   1324:     capa_msg(MESSAGE_ERROR,warn_msg);
                   1325:     return;
                   1326:   }
                   1327:   start++; len = strlen(start) - 1;
                   1328:   ii = 0;
                   1329:   while( start[ii] != '\"' ) fname[ii++] = start[ii];
                   1330:   fname[ii] = 0;
                   1331:   LLDBUG_PR2("[parse_filename<%s>]\n",fname);
                   1332:   
                   1333:   change_file(fname);
                   1334: }
                   1335: 
                   1336: void
                   1337: parse_import_id(char *line)
                   1338: {
                   1339:   char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
                   1340:   int     ii, dup_open;
                   1341:   Symbol *symb_p;
                   1342:   int     no_error = 0;
                   1343:   
                   1344:   ii = 0;
                   1345:   while( line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t' ) 
                   1346:     fname[ii++] = line[ii]; 
                   1347:   fname[ii] = 0;
                   1348: 
                   1349:   LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
                   1350:   symb_p = find_identifier(fname);
                   1351:   
                   1352:   switch (symb_p->s_type) {
                   1353:    case IDENTIFIER:
                   1354:      sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
                   1355:      capa_msg(MESSAGE_ERROR,warn_msg);
                   1356:      break;
                   1357:    case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
                   1358:      sprintf(warn_msg,"var cannot be a number.\n");
                   1359:      capa_msg(MESSAGE_ERROR,warn_msg);
                   1360:      break;
                   1361:    case S_VAR:  case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str);
                   1362:      no_error = 1;
                   1363:      break;
                   1364:   }
                   1365:   if( no_error ) change_file(fname);
                   1366: }
                   1367: 
                   1368: #else
                   1369: void
                   1370: parse_filename(char *line)
                   1371: {
                   1372:   char  *start, fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
                   1373:   int    ii, len, dup_open;
                   1374:   
                   1375:   /* printf("IMPORT %s\n", line); */
                   1376:   
                   1377:   start = index(line, '\"'); /*** hpux complained */
                   1378:   if( start != NULL ) {
                   1379:     start++; len = strlen(start) - 1;
                   1380:     ii = 0;
                   1381:     while( start[ii] != '\"' ) {
                   1382:       fname[ii] = start[ii]; ii++;
                   1383:     }
                   1384:     fname[ii] = 0;
                   1385:     LLDBUG_PR2("[parse_filename<%s>]\n",fname);
                   1386:     if(Input_idx < (MAX_OPENED_FILE -1)) {
                   1387:       dup_open = 0;
                   1388:       /* -- no need to check duplicated opening a file 
                   1389:       for(ii=0;ii<Input_idx;ii++) {
                   1390:         if(strcmp(Opened_filename[ii],fname)==0) {
                   1391:           dup_open =1;
                   1392:         }
                   1393:       }
                   1394:       */
                   1395:       if( !dup_open ) {
                   1396:         if( capa_access(fname, (F_OK | R_OK)) == -1 ) {
                   1397:           sprintf(warn_msg,"/IMP \"%s\", import file does not exist or is not readable.\n",fname);
                   1398:           capa_msg(MESSAGE_ERROR,warn_msg);
                   1399:         } else {
                   1400:           Input_idx++;
                   1401:           Input_stream[Input_idx]=fopen(fname,"r");
                   1402:           sprintf(Opened_filename[Input_idx], "%s",fname);
                   1403:           Current_line[Input_idx] = 0;
                   1404:         }
                   1405:       } else {
                   1406:         /*
                   1407:           sprintf(warn_msg,"/IMP \"%s\", import file has already been imported.\n",fname);
                   1408:           capa_msg(MESSAGE_WARN,warn_msg);
                   1409:         */
                   1410:         if( capa_access(fname, (F_OK | R_OK)) == -1 ) {
                   1411:           sprintf(warn_msg,"/IMP \"%s\", import file does not exist or is not readable.\n",fname);
                   1412:           capa_msg(MESSAGE_ERROR,warn_msg);
                   1413:         } else {
                   1414:           Input_idx++;
                   1415:           Input_stream[Input_idx]=fopen(fname,"r");
                   1416:           sprintf(Opened_filename[Input_idx], "%s",fname);
                   1417:           Current_line[Input_idx] = 0;
                   1418:         }
                   1419:       }
                   1420:     } else {
                   1421:       sprintf(warn_msg,"/IMP more the %d levels deep ignoring further imports.\n",MAX_OPENED_FILE-1);
                   1422:       capa_msg(MESSAGE_WARN,warn_msg);
                   1423:     }
                   1424:   } else {
                   1425:     sprintf(warn_msg,"%s, is not a valid file name.\n",line);
                   1426:     capa_msg(MESSAGE_ERROR,warn_msg);
                   1427:   }
                   1428:   
                   1429: }
                   1430: 
                   1431: void
                   1432: parse_import_id(char *line)
                   1433: {
                   1434:   char    fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH];
                   1435:   int     ii, dup_open;
                   1436:   Symbol *symb_p;
                   1437:   int     no_error = 0;
                   1438:   
                   1439:     ii = 0;
                   1440:     while (line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t') {
                   1441:       fname[ii] = line[ii]; ii++;
                   1442:     }
                   1443:     fname[ii] = 0;
                   1444:     LLDBUG_PR2("[parse_import_id<%s>]\n",fname);
                   1445:     symb_p = find_identifier(fname);
                   1446:     
                   1447:     switch (symb_p->s_type) {
                   1448:       case IDENTIFIER:
                   1449: 	sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname);
                   1450: 	capa_msg(MESSAGE_ERROR,warn_msg);
                   1451: 	break;
                   1452:       case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT:
                   1453: 	sprintf(warn_msg,"var cannot be a number.\n");
                   1454: 	capa_msg(MESSAGE_ERROR,warn_msg);
                   1455: 	break;
                   1456:       case S_VAR:
                   1457:       case S_CONSTANT:
                   1458: 	sprintf(fname,"%s",symb_p->s_str);
                   1459: 	no_error = 1;
                   1460: 	break;
                   1461:     }
                   1462:     if( no_error ) {
                   1463:       if(Input_idx < (MAX_OPENED_FILE -1) ) {
                   1464:           dup_open = 0;
                   1465:           /* no need to check duplicated opening a file 
                   1466:           for(ii=0;ii<Input_idx;ii++) {
                   1467:             if(strcmp(Opened_filename[ii],fname)==0)  dup_open =1; 
                   1468:           }
                   1469:           */
                   1470:           if( !dup_open ) {
                   1471:             if( capa_access(fname, (F_OK | R_OK)) == -1 ) {
                   1472:               sprintf(warn_msg,"/IMP \"%s\", import file does not exist or is not readable.\n", fname);
                   1473:               capa_msg(MESSAGE_ERROR,warn_msg);
                   1474:             } else {
                   1475:               Input_idx++;
                   1476:               Input_stream[Input_idx]=fopen(fname,"r");
                   1477:               sprintf(Opened_filename[Input_idx], "%s",fname);
                   1478:               Current_line[Input_idx] = 0;
                   1479:             }
                   1480:           } else {
                   1481:             /*  NO warning on duplicated open a file
                   1482:             sprintf(warn_msg,"/IMP \"%s\", file has already been imported.\n", fname);
                   1483:             capa_msg(MESSAGE_WARN,warn_msg);
                   1484:             */
                   1485:             if( capa_access(fname, (F_OK | R_OK)) == -1 ) {
                   1486:               sprintf(warn_msg,"/IMP \"%s\", import file does not exist or is not readable.\n", fname);
                   1487:               capa_msg(MESSAGE_ERROR,warn_msg);
                   1488:             } else {
                   1489:               Input_idx++;
                   1490:               Input_stream[Input_idx]=fopen(fname,"r");
                   1491:               sprintf(Opened_filename[Input_idx], "%s",fname);
                   1492:               Current_line[Input_idx] = 0;
                   1493:             }
                   1494: 
                   1495:           }
                   1496:         } else {
                   1497:           sprintf(warn_msg,"/IMP , too many files has been imported. The maximum is %d files.\n",
                   1498:               MAX_OPENED_FILE-1);
                   1499:           capa_msg(MESSAGE_WARN,warn_msg);
                   1500:         }
                   1501:       }
                   1502: }
                   1503: #endif /*AVOIDYYINPUT*/
                   1504: 
                   1505: void append_dynamic_buf(new_str) char *new_str;
                   1506: {
                   1507:   int ii,len;
                   1508:   
                   1509:   if(new_str==NULL) return;
                   1510:   len=strlen(new_str);
                   1511: #ifdef LEX_DBUG
                   1512:   printf("before: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
                   1513: 	 len,Dynamic_buf_cur,Dynamic_buf_max);
                   1514: #endif /* LEX_DBUG */    
                   1515:   if (Dynamic_buf_cur+len+1>Dynamic_buf_max) {
                   1516:     char *temp_text;
                   1517:     Dynamic_buf_max=(Dynamic_buf_cur+len)*2;
                   1518:     temp_text=(char*)capa_malloc(sizeof(char),Dynamic_buf_max);
                   1519:     strncpy(temp_text,Dynamic_buf,Dynamic_buf_max);
                   1520:     free(Dynamic_buf);
                   1521:     Dynamic_buf=temp_text;
                   1522:   }
                   1523:   for(ii=0;ii<len;ii++) {
                   1524:     Dynamic_buf[Dynamic_buf_cur+ii]=new_str[ii];
                   1525:   }
                   1526:   Dynamic_buf_cur += len;
                   1527:   Dynamic_buf[Dynamic_buf_cur+1]='\0';
                   1528: #ifdef LEX_DBUG
                   1529:   printf("after: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
                   1530: 	 len,Dynamic_buf_cur,Dynamic_buf_max);
1.2       albertel 1531:   printf("Dyn_buf %s; added %s\n",Dynamic_buf,new_str);
1.1       albertel 1532: #endif /* LEX_DBUG */    
                   1533: }
                   1534: 
                   1535: char* parser_status()
                   1536: {
                   1537:   char *buf,small[SMALL_LINE_BUFFER];
                   1538:   int i,j,totlen=0,len,idx=0;
                   1539:   
                   1540:   for(i=0;i<=Input_idx;i++) totlen+=strlen(Opened_filename[i])+6;
                   1541:   buf=capa_malloc(sizeof(char),totlen);
                   1542:   for(i=0;i<=Input_idx;i++) {
                   1543:     len=strlen(Opened_filename[i]);
                   1544:     for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
                   1545:     buf[idx++] = ':';
                   1546:     sprintf(small,"%d",Current_line[i]);
                   1547:     len=strlen(small);
                   1548:     for(j=0;j<len;j++) buf[idx++] = small[j];
                   1549:     buf[idx++]=' ';
                   1550:     buf[idx]='\0';
                   1551:   }
                   1552:   return buf;
                   1553: }
                   1554: 
                   1555: void yyfatalerror(char*msg)
                   1556: {
                   1557:   char    warn_msg[WARN_MSG_LENGTH];
1.6       albertel 1558:   sprintf(warn_msg,"Invalid character[\'%s\']\n",yytext);
1.1       albertel 1559:   capa_msg(MESSAGE_ERROR,warn_msg);
1.6       albertel 1560:   capa_msg(MESSAGE_ERROR,msg);
1.1       albertel 1561: }
                   1562: void yyerror(char* msg)
                   1563: {
                   1564:   char    warn_msg[WARN_MSG_LENGTH];
                   1565:   sprintf(warn_msg,"%s\n",msg);
                   1566:   capa_msg(MESSAGE_ERROR,warn_msg);
                   1567: }
                   1568: 
                   1569: void newyy_input (char *buf,int *result,int max_size) 
                   1570: { int ii, leng, out_of_char; 
                   1571:  if (!Lexi_line) { /* was startup */ 
                   1572:    for(ii=0;ii < MAX_OPENED_FILE;ii++) { 
                   1573:      Lexi_buf[ii] = NULL; 
                   1574:      Lexi_pos[ii] = 0; 
                   1575:      Current_line[ii] = 0; 
                   1576:    } 
                   1577:    Input_idx = 0; 
                   1578:    first_run=0; 
                   1579:    yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); 
                   1580:  } 
                   1581:  out_of_char = 0; 
                   1582:  if ( Lexi_buf[Input_idx] == NULL ) { 
                   1583:    Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1;
                   1584:  } else { 
                   1585:    if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { 
                   1586:      /* test if the line buffer is empty or at the end */ 
                   1587:      out_of_char=1; 
                   1588:    } 
                   1589:  }
                   1590:  if( out_of_char ) { 
                   1591:    if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { 
                   1592:      /* read in one line */ 
                   1593:      LIDBUG_PR2("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); 
                   1594:      if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { 
                   1595:        LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\n",Input_idx); 
                   1596:        fclose(Input_stream[Input_idx]); 
                   1597:        capa_mfree((char *)Lexi_buf[Input_idx]); 
                   1598:        Lexi_buf[Input_idx] = NULL; 
                   1599:        Input_idx--; 
                   1600:        yyin = Input_stream[Input_idx]; 
                   1601:        /* (Lexi_pos[Input_idx])++; */ 
                   1602:        buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
                   1603:        *result = 1; 
                   1604:      } else { 
                   1605:        *result = YY_NULL; /* End of File */ 
                   1606:      } 
                   1607:    } else { /* successfully read in one line */ 
                   1608:      leng = strlen(Lexi_buf[Input_idx]); 
                   1609:      LIDBUG_PR3("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\n",
                   1610: 		leng,Input_idx);  
                   1611:      Lexi_pos[Input_idx] = 0; 
                   1612:      Lexi_line++; 
                   1613:      Current_line[Input_idx]++; 
                   1614:      (Lexi_pos[Input_idx])++; 
                   1615:      buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1];  
                   1616:      /* need to take care of return continuation conditions */ 
                   1617:      /*  so, we return to one-char-at-a-time approach */ 
                   1618:      /* for(ii=0;ii<leng;ii++) { */ 
                   1619:      /*  buf[ii] = Lexi_buf[Input_idx][ii]; */ 
                   1620:      /* } */ 
                   1621:      /* buf[ii] = '\0'; */ 
                   1622:      /* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ 
                   1623:      *result = 1; 
                   1624:    } 
                   1625:  } else { 
                   1626:    /* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\n",Input_idx);  */ 
                   1627:    (Lexi_pos[Input_idx])++; 
                   1628:    buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; 
                   1629:    *result = 1; 
                   1630:  } 
                   1631:  if (Stop_Parser==1) *result = YY_NULL;  
                   1632: }
                   1633: 
                   1634: int capa_eof()
                   1635: {
                   1636: #ifdef AVOIDYYINPUT
                   1637:   if ( --include_stack_ptr < 0 ) yyterminate();
                   1638:   else {
                   1639:     yy_delete_buffer( YY_CURRENT_BUFFER );
                   1640:     yy_switch_to_buffer(include_stack[include_stack_ptr]);
                   1641:   }
                   1642: #else
                   1643:   if(Input_idx == 0) {
                   1644:     fclose(Input_stream[Input_idx]);
                   1645:     capa_mfree((char *)Lexi_buf[Input_idx]); 
                   1646:     free_problems(LexiProblem_p);
                   1647:     LexiProblem_p=NULL;
                   1648:     /* printf("\nCAPA EOF\n"); fflush(stdout); */
                   1649:   }
                   1650:   return (0);
                   1651: #endif /*AVOIDYYINPUT*/
                   1652: }
                   1653: /* ------------ */
                   1654: 
                   1655: 
                   1656: /* =========================================================== */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>