Annotation of loncom/homework/CAPA-converter/capaLexerDef.flex, revision 1.21

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

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