File:  [LON-CAPA] / loncom / homework / CAPA-converter / capaLexerDef.flex
Revision 1.14: download - view: text, annotated - select for diffs
Tue Dec 4 15:17:57 2001 UTC (22 years, 7 months ago) by albertel
Branches: MAIN
CVS tags: HEAD
- GPL headers

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

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