File:  [LON-CAPA] / capa / capa51 / pProj / capaLexerDef.flex
Revision 1.14: download - view: text, annotated - select for diffs
Wed Jul 11 19:23:43 2007 UTC (16 years, 11 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, bz6209-base, bz6209, HEAD, GCI_3, GCI_2, GCI_1, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- support flex 2.5.33
   - use the %option mechanism to turn on the stack option
   - YY_FLUSH_BUFFER no longer available after the second %% so expand the
     macro out

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

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