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

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

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