File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaLexerDef.flex
Revision 1.21: download - view: text, annotated - select for diffs
Thu Sep 12 15:54:06 2002 UTC (21 years, 8 months ago) by albertel
Branches: MAIN
CVS tags: version_2_9_X, version_2_9_99_0, version_2_9_1, version_2_9_0, version_2_8_X, version_2_8_99_1, version_2_8_99_0, version_2_8_2, version_2_8_1, version_2_8_0, version_2_7_X, version_2_7_99_1, version_2_7_99_0, version_2_7_1, version_2_7_0, version_2_6_X, version_2_6_99_1, version_2_6_99_0, version_2_6_3, version_2_6_2, version_2_6_1, version_2_6_0, version_2_5_X, version_2_5_99_1, version_2_5_99_0, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_12_X, version_2_11_X, version_2_11_4_uiuc, version_2_11_4_msu, version_2_11_4, version_2_11_3_uiuc, version_2_11_3_msu, version_2_11_3, version_2_11_2_uiuc, version_2_11_2_msu, version_2_11_2_educog, version_2_11_2, version_2_11_1, version_2_11_0_RC3, version_2_11_0_RC2, version_2_11_0_RC1, version_2_11_0, version_2_10_X, version_2_10_1, version_2_10_0_RC2, version_2_10_0_RC1, version_2_10_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, version_0_6_2, version_0_6, loncapaMITrelate_1, language_hyphenation_merge, language_hyphenation, conference_2003, bz6209-base, bz6209, bz5969, bz2851, PRINT_INCOMPLETE_base, PRINT_INCOMPLETE, HEAD, GCI_3, GCI_2, GCI_1, BZ5971-printing-apage, BZ5434-fox, BZ4492-merge, BZ4492-feature_horizontal_radioresponse, BZ4492-feature_Support_horizontal_radioresponse, BZ4492-Support_horizontal_radioresponse
- From Mark Lucas,
 Fixes a few things with /DIS in scripts, eval with fml,
braces around variables.

    1: /* The LearningOnline Network with CAPA
    2:  * CAPA lexer dfinition, heavily modified to become a LON-CAPA convertor 
    3:  * $Id: capaLexerDef.flex,v 1.21 2002/09/12 15:54:06 albertel Exp $
    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: 
   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;
  152: int           sccount;		           /* Semi-colon count for MAP and RMAP  */
  153: int           HINTflag=0;
  154: int           EXPflag=0;
  155: int           EVALflag=0;
  156: int           compound_answer=0;
  157: int           essay_answer=0;
  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;
  174: static        int dosend=1;
  175: static        int firstparam=1;
  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; \
  250: yyin = Input_stream[Input_idx]; LIDBUG_PR1("<<yy_input() startup>>\n"); \
  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();
  372: 
  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 
  395: %x  S_STRING    S_ANSCONTINUE     S_TRUE_FALSE_STMT      S_WHILE_SKIP
  396: %x  S_NEXT_LINE S_VERB   S_ECHO S_STRINGINANS
  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>{
  415: {EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); 
  416: 			      send("# %s\n",&yytext[2]);
  417:                              }
  418: [^\n]*{EndLine}      {
  419:                        send("\n"); BEGIN S_TEXT;
  420:                      }
  421: }
  422: 
  423: 
  424: <S_TEXT>{
  425: ^{Spaces}"/LET" |
  426: 	   ^{Spaces}"/BEG"                  { LLDBUG_PRL1("[LET]"); Pcount = 0; BEGIN S_LET; start_mode(MODE_SCRIPT,NULL);
  427: }
  428: ^{Spaces}"/VERB"                 { 
  429:                                    LLDBUG_PRL1("[VERBATIM]");
  430:                                    BEGIN S_VERB; 
  431: 				   start_mode(MODE_OUTTEXT,NULL);
  432: 				   send("<PRE>\n");
  433:                                  }
  434: ^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
  435:                                /*    start_mode(MODE_HINT, "");*/
  436:                                    if (!HINTflag) {
  437:                                      start_streams(HINT_DEST,1);
  438:                                      HINTflag=-1;
  439:                                    }
  440:                                    change_destination(HINT_DEST);
  441:                                    send("\t",NULL);
  442: 				   BEGIN S_HINT; 
  443:                                  }
  444: ^{Spaces}"/EXP"{Alpha}*{Spaces}  { 
  445:                                    if (!EXPflag) {
  446:                                      start_streams(EXP_DEST,1);
  447:                                      EXPflag=-1;
  448:                                    }
  449:                                    change_destination(EXP_DEST);
  450:                                    send("\t",NULL);
  451:                                    LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf;  BEGIN S_EXPLAIN; }
  452: ^{Spaces}"/IMP"{Alpha}*{Space}+  { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; end_mode(); }
  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: 				    }
  462: 				    End_of_input = 1; BEGIN S_IGNORE; 
  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); }
  476: ^{Spaces}"/ANS"               { LLDBUG_PRL2("[ANS(%s)]",yytext); 
  477:                                 Pcount = 0; 
  478:                                 BEGIN S_ANSWER; 
  479:                                 end_mode();
  480: 				start_mode(MODE_ANSWER,NULL);
  481:                                 send("<numericalresponse answer=\""); 
  482: 				dosend=1;
  483: 				firstparam=1;
  484:                                 compound_answer=0;
  485:                                 essay_answer=0;
  486:                               }
  487: ^{Spaces}"/SUBJECTIVE"        { LLDBUG_PRL1("[SUBJECTIVE ANSWER]"); 
  488:                                 Pcount = 0; 
  489:                                 BEGIN S_ANSWER;
  490:                                 end_mode();
  491: 				start_mode(MODE_ANSWER,NULL);
  492:                                 send("<essayresponse");
  493: 				dosend=1; 
  494: 				firstparam=1;                            
  495:                                 compound_answer=0;
  496:                                 essay_answer=-1;
  497:                               }
  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("); }
  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();
  517:                                 BEGIN S_TEXT;
  518:                               }
  519: "/WHILE"                      |
  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();
  537:                               }
  538: ^{Spaces}"/IF"                { int i;
  539: 				IFcount++;
  540:                                 LLDBUG_PRL2("[IF <IFcount=%d>]",IFcount);
  541: 				BEGIN S_TRUE_FALSE_STMT;
  542: 				if ( IFcount == 1) {
  543:  				  start_streams(DEFAULT_DEST, 2);
  544:                                   change_destination(DEFAULT_DEST);
  545: 				  watch_mode[current_dest][1]=1;
  546: 				}
  547: 				end_mode_stream(DEFAULT_DEST, 0);
  548: 				start_mode_stream(DEFAULT_DEST,1,MODE_SCRIPT,NULL);
  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);
  557: 				end_mode_stream(DEFAULT_DEST,0);
  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--;
  566: 				end_mode_stream(DEFAULT_DEST,0);
  567: 				for(i=0;i<IFcount;i++) {send("\t",NULL);}
  568: 				send_stream(0,"</block>");
  569: 				send_stream(1,"}");
  570: 				if (IFcount == 0) {
  571: 				  if (watch_mode[current_dest][1]) {
  572: 				    end_streams(DEFAULT_DEST,1);
  573:  				  } else {
  574: 				    end_streams(DEFAULT_DEST,0);
  575: 				  }
  576:                                   change_destination(DEFAULT_DEST);
  577: 				}
  578: 				delete_cache();
  579: 				LLDBUG_PRL2("[ENDIF <IFcount=%d>]\n",IFcount); 
  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 */
  583: 				start_mode(MODE_OUTTEXT,NULL);
  584:                                 LLDBUG_PR1("[DIS<]");
  585:                                 init_funcstack();
  586:                                 Pcount = 0; BEGIN S_VARIABLE; 
  587: 				send("<display>");
  588: 				start_delayed();
  589:                               }
  590: {EndLine}                     { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */ 
  591:                                 send("\n"); }
  592: [\\]{Space}*{EndLine}         { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }                       
  593: ^{Spaces}"//"[^\n]*$		      { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
  594:                                         start_mode(MODE_SCRIPT,NULL); 
  595:                                         send("# %s\n",&yytext[2]);
  596: 					BEGIN S_COMMENT;
  597:                                       }
  598: 
  599: [^/\n\\]+$  |
  600: [/]         | 
  601: [\\]                          {  start_mode(MODE_OUTTEXT,NULL);
  602:                                 LLDBUG_PR2("[TEXT_LINE<%s>]",yytext);
  603: 				send(yytext);
  604: 			      }
  605: ([^/\n])+[/] |
  606: ([^/\n])+[\\]                 { /* matches anything until a '/' or a '\' */
  607:                                 start_mode(MODE_OUTTEXT,NULL);
  608:                                 LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext);
  609:                                 
  610:                                 yyless(yyleng-1); /* push back the last char */
  611:                                 BEGIN S_TEXT;
  612: 				send(yytext);
  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,
  631: 					"at End-of-File, a /END is needed.\n");
  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);
  715: 				  send(aptr);
  716:                                 }
  717: [/]                            { send("/"); }
  718: [\\]                           { send("\\"); }
  719: [\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ send("\n\t");}
  720: [^/\n\\]+$                     {char  *aptr = yytext;
  721:                                 send(aptr);
  722:                                }
  723: }
  724: <S_HINT>{
  725: {EndLine}                     {  LLDBUG_PR1("[CR hint]");
  726:                                  send("\n"); 
  727:                                  change_destination(DEFAULT_DEST);
  728:                                  BEGIN S_TEXT;
  729:                               }
  730: }
  731: <S_EXPLAIN>{
  732: {EndLine}                     {  LLDBUG_PR1("[CR explain]");
  733:                                  send("\n"); 
  734:                                  change_destination(DEFAULT_DEST);
  735:                                  BEGIN S_TEXT;
  736:                               }
  737: }
  738: 
  739: <S_HINTEXLAINX>{
  740: {Alpha}{AlphaNum}*            {send("${%s}",yytext);}
  741: {Space}+                      { }
  742: [)]                           {  yy_pop_state(); }
  743: }
  744: 
  745: <S_IMPORT>{
  746: {FileName}{Space}*             {
  747:                                  char *endquote;
  748:                                  end_mode();
  749: 				 start_mode(MODE_IMPORT,NULL);
  750: 				 /* Get rid of leading and trailing quotes */
  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:                                  }
  758: 				 end_mode();
  759: 				 BEGIN S_SKIP;
  760:                                }
  761: {Identifier}{Space}*           { end_mode();
  762: 				 start_mode(MODE_IMPORT,NULL);
  763: 				 send("${%s}",yytext);
  764: 				 end_mode();
  765:                                  BEGIN S_SKIP;
  766: 			       }
  767: }
  768: 
  769: <S_ANSWER>{
  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: 
  778: [Oo][Nn]                     |
  779: [Yy][Ee][Ss]                 { LLDBUG_PR1("[ON]"); send("on");}
  780: [Oo][Ff][Ff]                 |
  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);
  788:                        if (dosend==2) add_delayed("%%%s",yytext);
  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);
  795: 			       if (!EVALflag) {
  796:                                if (dosend==1) send("%s",yytext);
  797:                                if (dosend==2) add_delayed("%s",yytext);
  798:                              }
  799:                              }
  800: ">"                          { LLDBUG_PR2("[symbol(%s)]",yytext);
  801: 			       if (!EVALflag) {
  802:                                if (dosend==1) send("%s",yytext);
  803:                                if (dosend==2) add_delayed("%s",yytext);
  804:                                } else {
  805: 				 EVALflag = 0;
  806: 			       }
  807:                              }
  808: 
  809: [Pp][Cc][Rr]                 |
  810: [Hh][Gg][Rr]                 { if (firstparam) {
  811: 				firstparam=0; 
  812: 			       } else {
  813: 				add_delayed("\" />\n\t");
  814: 			       }
  815:                                add_delayed("<responseparam name=\"hgr\" type=\"on|off\" default=\""); 
  816:                                dosend=2;
  817:                              }
  818: [Tt][Oo][Ll]                 { LLDBUG_PR2("[tol(%s)]",yytext);
  819:                                if (firstparam) {
  820: 				 firstparam=0; 
  821: 			       } else {
  822: 				 add_delayed("\" />\n\t");
  823: 			       }
  824: 			       add_delayed("<responseparam name=\"tol\" type=\"tolerance\" description=\"Numerical Tolerance\" default=\""); 
  825:                                dosend=2;
  826:                              }
  827: [Ss][Ii][Gg]                 { 
  828:                                LLDBUG_PR2("[SIG(%s)]",yytext); 
  829:                                if (firstparam) {
  830: 				 firstparam=0; 
  831: 			       } else {
  832: 				 add_delayed("\" />\n\t");
  833: 			       }
  834: 			       add_delayed("<responseparam name=\"sig\" type=\"int_range,0-12\" description=\"Significant Figures\" default=\""); 
  835:                                dosend=2;
  836:                              }
  837: 
  838: [Ss][Tt][Rr]                 { LLDBUG_PR1("[STR]"); send("\" type=\""); dosend=1; }
  839: [Ee][Vv][Aa][Ll]             |
  840: [Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee] { LLDBUG_PR1("[EVAL]");send("\" eval=\""); EVALflag=1; dosend=1;}
  841: [Uu][Nn][Ii][Tt]             |
  842: [Uu][Nn][Ii][Tt][Ss]         { LLDBUG_PR1("[UNIT]"); send("\" unit=\""); dosend=1;}
  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; }
  853: [Tt][Rr][Yy]                 |
  854: [Tt][Rr][Ii][Ee][Ss]         { LLDBUG_PR1("[TRY]"); dosend=0; }
  855: [Ww][Gg][Tt]                 { LLDBUG_PR1("[WGT]"); dosend=0; }
  856: 
  857: [\)]                         { LLDBUG_PR1("[)]"); Pcount--; 
  858:                                if(Pcount==0) {
  859:                                    BEGIN S_ANSCONTINUE; 
  860:                                }
  861:                                if (essay_answer) {
  862:                                  send(">\n\t");
  863:                                } else {
  864:                                send("\">\n\t");
  865:                                }
  866: 			       dosend=1;
  867: 			       flush_delayed();
  868: 			       if (firstparam!=1) send("\" />\n");
  869:                                if (essay_answer) {
  870: 			         send("  <textfield>Enter your answer here.</textfield>\n");
  871:                                } else {
  872: 			       send("\t<textline />\n");
  873:                                }
  874:                          /* Fill in Hints */ 
  875: 			       if ( !is_dest_empty(HINT_DEST) ) {
  876: 			         send("\t<hintgroup>\n\t<hintpart on=\"default\">\n\t<startouttext />");
  877:                                  end_streams(HINT_DEST,0);
  878:                                  HINTflag=0;
  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");
  885: 			       }
  886: 
  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); 
  899:                                }
  900:                              }
  901: }
  902: 
  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); 
  908:                                }
  909: 
  910: {Alpha}{AlphaNum}*{Space}*[(]  { if (dosend==1) send("&%s",yytext);
  911:                                  if (dosend==2) add_delayed("&%s",yytext);
  912: 				 Pcount++;
  913:                                }
  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); 
  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}*    |
  927: "\."{Number}+             {  LLDBUG_PR2("[REAL<%s>]",yytext);
  928: 			     if(dosend==1) send("%s",yytext);
  929: 			     if(dosend==2) add_delayed("%s",yytext);
  930: 			  }
  931: 
  932: {Number}+                 {  LLDBUG_PR2("[INT<%s>]",yytext);
  933:                              if (dosend==1) send("%s",yytext);
  934:                              if (dosend==2) add_delayed("%s",yytext);
  935: 			  }
  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: 			  }
  944: {Space}+                  { /* LLDBUG_PR1("[SP ignored]");  Ignore Spaces */ }
  945: }
  946: 
  947: <S_VARIABLE,S_TRUE_FALSE_STMT,S_MAP,S_LET>{
  948: [\"]                      { LLDBUG_PR1("[TF,V,LET,MAP str\" ]"); 
  949:                             Current_char_p = String_buf; 
  950: 			    send("'");
  951:                             yy_push_state(S_STRING);
  952:                           }
  953: }
  954: 
  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>{
  963: [\(]                      { LLDBUG_PR1("[let if ans map (]"); 
  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>{
  973: [\(]                      { LLDBUG_PR1("[let (]"); 
  974:                             Pcount++; 
  975: 			    send(yytext);
  976:                           }
  977: }
  978: 
  979: <S_VARIABLE>[:]{Number}+[EeFf]   { 
  980:                              end_delayed();
  981:                              send("&format(");
  982:                              flush_delayed();
  983:                              send(",'%s')",yytext+1);
  984:                            }
  985: <S_ANSWER>[:]{Number}+[EeFf]   { 
  986:                              if (dosend) send("\" format=\"%s",yytext+1);
  987:                            }
  988: 
  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: 
 1017: <S_VARIABLE>{
 1018: "+"		    { send(".");}
 1019: }
 1020: 
 1021: <S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
 1022: "=="                { LLDBUG_PR1("[==]"); send(" eq ");  }
 1023: "!="                { LLDBUG_PR1("[!=]"); send(" ne ");  }
 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:                     }
 1035: [%]                 {send("%%");}
 1036: {Operator}          { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); }
 1037: }
 1038: 
 1039: 
 1040: 
 1041: <S_VARIABLE>{
 1042: [\)]                     { LLDBUG_PR1("[)]"); 
 1043:                            Pcount--; 
 1044:                            if(Pcount == 0) {
 1045: 			      send("</display>");
 1046:                               BEGIN S_TEXT; 
 1047:                               flush_delayed();
 1048:                            } else {
 1049:                               send(yytext); 
 1050:                            }
 1051:                          }
 1052: [\\]{Space}*{EndLine}    { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ }                       
 1053: {EndLine}                { LLDBUG_PR1("[EoL within /dis()]\n"); }
 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>{
 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;
 1069: 			   } else {
 1070:                                 send_stream(0,")");
 1071:                                 send_stream(1,")");
 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]; 
 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>{
 1088: [\\][\\]            { /*char  *aptr = yytext;
 1089: 			while( *aptr )   *Current_char_p++ = *aptr++;*/
 1090:                       send(yytext);
 1091:                     }
 1092: [\\][\"]            { /**Current_char_p++ = '"';*/ send("\\\"");  }
 1093: [\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
 1094: [\"]                { /* end of a string constant --   */
 1095:                       send("'");
 1096: 		      yy_pop_state();
 1097: 		    }
 1098: [%]                 { /*Escape percent signs so that vasprintf doesn't choke */
 1099:                       send("%%");
 1100:                     }
 1101: [\']                { /* Escape single quotes so that perl doesn't choke */
 1102:                       send("\\\'");
 1103:                     }
 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:                     }
 1111: .                   { /*char  *aptr = yytext;
 1112: 			while( *aptr )   *Current_char_p++ = *aptr++;*/
 1113:                       send(yytext);
 1114:                     }
 1115: }
 1116: 
 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: 
 1145: <S_LET>[\)]                  { LLDBUG_PR1("[) in LET]"); Pcount--;send(yytext); }
 1146: 
 1147: <S_SKIP>{
 1148: [^\n]+$                      {       }
 1149: {EndLine}                    { BEGIN S_TEXT; }
 1150: }
 1151: 
 1152: <S_ECHO>{
 1153: [^\n]+$                      { send(yytext); }
 1154: {EndLine}                    { send(yytext); BEGIN S_TEXT; }
 1155: }
 1156: 
 1157: <S_LET,S_ANSWER,S_MAP>{
 1158: [\\]{Space}*{EndLine}        { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ }
 1159: {EndLine}                    { LLDBUG_PR1("[EoL END let ans map]\n"); 
 1160:                                if(Pcount == 0) BEGIN S_TEXT; 
 1161:                                send(";%s",yytext); 
 1162:                              }
 1163: }
 1164: 
 1165: <S_ANSCONTINUE>{
 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 */ }
 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"); 
 1233: 		      BEGIN S_TEXT;
 1234: 		      puts("\n</PRE>\n");
 1235: 		      end_mode();
 1236: 		    }
 1237: .*|{EndLine}         { send(yytext); }
 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:   }
 1847:   end_mode();
 1848:   return (0);
 1849: #endif /*AVOIDYYINPUT*/
 1850: }
 1851: /* ------------ */
 1852: 
 1853: 
 1854: /* =========================================================== */

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