--- loncom/homework/CAPA-converter/capaLexerDef.flex 2001/11/15 21:42:42 1.9 +++ loncom/homework/CAPA-converter/capaLexerDef.flex 2002/03/20 18:15:00 1.19 @@ -1,3 +1,30 @@ +/* The LearningOnline Network with CAPA + * CAPA lexer dfinition, heavily modified to become a LON-CAPA convertor + * $Id: capaLexerDef.flex,v 1.19 2002/03/20 18:15:00 albertel Exp $ + * + * Copyright Michigan State University Board of Trustees + * + * This file is part of the LearningOnline Network with CAPA (LON-CAPA). + * + * LON-CAPA is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * LON-CAPA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with LON-CAPA; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * /home/httpd/html/adm/gpl.txt + * + * http://www.lon-capa.org/ + */ + /*------------------------------------------------------------------------*/ /* capaLexerDef.flex created by Isaac Tsai Jul 15 1996 */ /* added /END(variable) */ @@ -119,12 +146,12 @@ Symbol *FmlSymbLast_p; int FmlSymb_cnt; int Symb_count; -int IFstatus[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */ -int IFcurrent[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */ int IFcount; WhileLoop_t WhileStack[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */ int While_idx, Wcount; int sccount; /* Semi-colon count for MAP and RMAP */ +int HINTflag=0; +int EXPflag=0; #ifdef USE_DYNAMIC_SYMBOLS Symbol *SymbList_p; @@ -362,7 +389,7 @@ EndLine ([\r][\n]|[\n]) %n 1000 %x S_COMMENT S_HINT S_HINTEXLAINX S_IMPORT S_EXPLAIN S_ENDX S_UNIT S_IGNORE %x S_SKIP S_VARIABLE S_LET S_DEFINE S_TEXT S_MAP S_FIGURE S_ANSWER -%x S_STRING S_ANSCONTINUE S_TRUE_FALSE_STMT S_IF_SKIP S_WHILE_SKIP +%x S_STRING S_ANSCONTINUE S_TRUE_FALSE_STMT S_WHILE_SKIP %x S_NEXT_LINE S_VERB S_ECHO S_STRINGINANS %array @@ -402,10 +429,20 @@ EndLine ([\r][\n]|[\n]) send("
\n");
                                  }
 ^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
-                                   start_mode(MODE_HINT, "");
+                               /*    start_mode(MODE_HINT, "");*/
+                                   if (!HINTflag) {
+                                     start_streams(HINT_DEST,1);
+                                     HINTflag=-1;
+                                   }
+                                   change_destination(HINT_DEST);
 				   BEGIN S_HINT; 
                                  }
-^{Spaces}"/EXP"{Alpha}*{Spaces}  { start_mode(MODE_BLOCK,"condition=&explanation");
+^{Spaces}"/EXP"{Alpha}*{Spaces}  { 
+                                   if (!EXPflag) {
+                                     start_streams(EXP_DEST,1);
+                                     EXPflag=-1;
+                                   }
+                                   change_destination(EXP_DEST);
                                    LLDBUG_PRL1("[EXP]"); Current_char_p = String_buf;  BEGIN S_EXPLAIN; }
 ^{Spaces}"/IMP"{Alpha}*{Space}+  { LLDBUG_PRL1("[IMP]"); BEGIN S_IMPORT; end_mode(); }
 ^{Spaces}"/END"                  { LLDBUG_PRL1("[END]");  
@@ -444,59 +481,95 @@ EndLine    ([\r][\n]|[\n])
                                 Pcount = 0; 
                                 BEGIN S_ANSWER;
                                 end_mode();
+				start_mode(MODE_ANSWER,NULL);
                                 send("]\n",While_idx);
-                                
-                                top_item = While_idx - 1;
-                                if( top_item < 0 ) { /* strange things must have happened here! */
-                                  
-                                } else {
-                                  input_idx = WhileStack[top_item].input_idx;
-                                  file_pos = WhileStack[top_item].pos_idx;
-                                  Current_line[input_idx] = WhileStack[top_item].line_idx;
-                                  Lexi_pos[input_idx] = 0;
-                                  fseek(Input_stream[input_idx],file_pos,SEEK_SET);
-                                  fgets(Lexi_buf[input_idx],LEX_BUFLEN-1,Input_stream[input_idx]);
-                                  While_idx--;
-                                }
+^{Spaces}"/ENDWHILE"([^\n])*          { 
+                                int i;
+                                LLDBUG_PRL2("[ENDWHILE While_idx=<%d>]\n",IFcount);
+                                IFcount--;
+				end_mode_stream(DEFAULT_DEST,0);
+				for(i=0;i");
+				send_stream(1,"}");
+				if (IFcount == 0) {
+				  if (watch_mode[current_dest][1]) {
+				    end_streams(DEFAULT_DEST,1);
+ 				  } else {
+				    end_streams(DEFAULT_DEST,0);
+				  }
+                                  change_destination(DEFAULT_DEST);
+				}
+				delete_cache();
                                 BEGIN S_TEXT;
                               }
 "/WHILE"                      |
-^{Spaces}"/WHILE"             { long int file_pos;
-                                int      leng;
-                                LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",While_idx);
-                                leng = strlen(Lexi_buf[Input_idx]);  /* length of current line */
-                                /* <-- because we use fgets() to read input, 
-                                       thus ftell() will give the starting position of next line */
-                                WhileStack[While_idx].input_idx = Input_idx;
-                                file_pos = ftell(Input_stream[Input_idx]);
-                                file_pos -= leng;  /* calibrate the current line length */
-                                WhileStack[While_idx].pos_idx = file_pos;  /* begin of current line */
-                                WhileStack[While_idx].line_idx = Current_line[Input_idx];
-                                While_idx++;  /* advance the stack pointer */
-                                
-                                BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_WHILE); 
-                                
+^{Spaces}"/WHILE"             { 
+                                int      i;
+                                LLDBUG_PRL2("[WHILE While_idx=<%d>]\n",IFcount);
+                                IFcount++;  /* advance the stack pointer */
+                                BEGIN S_TRUE_FALSE_STMT;
+				if ( IFcount == 1) {
+ 				  start_streams(DEFAULT_DEST, 2);
+                                  change_destination(DEFAULT_DEST);
+				  watch_mode[current_dest][1]=1;
+				}
+				end_mode_stream(DEFAULT_DEST, 0);
+				start_mode_stream(DEFAULT_DEST,1,MODE_SCRIPT,NULL);
+				for(i=1;i]",IFcount);  BEGIN S_TRUE_FALSE_STMT; RETURN(CAPA_IF); }
-^{Spaces}"/ELSE"([^\n])*        { LLDBUG_PRL2("[ELSE ]\n",IFcount); 
-                                IFcurrent[IFcount] = RUN_ELSE_PORTION;
-                                if( IFstatus[IFcount] == IF_TRUE ) {
-                                  LLDBUG_PRL1("[ELSE begin Skip]\n");
-                                  BEGIN S_IF_SKIP;
-                                }
+^{Spaces}"/IF"                { int i;
+				IFcount++;
+                                LLDBUG_PRL2("[IF ]",IFcount);
+				BEGIN S_TRUE_FALSE_STMT;
+				if ( IFcount == 1) {
+ 				  start_streams(DEFAULT_DEST, 2);
+                                  change_destination(DEFAULT_DEST);
+				  watch_mode[current_dest][1]=1;
+				}
+				end_mode_stream(DEFAULT_DEST, 0);
+				start_mode_stream(DEFAULT_DEST,1,MODE_SCRIPT,NULL);
+				for(i=1;i]\n",IFcount);
+				end_mode_stream(DEFAULT_DEST,0);
+				for(i=1;i\n",
+				      cached_data[current_cache].str);
+				send_stream(1,"} else {");
                               }
-^{Spaces}"/ENDIF"([^\n])*    { IFcount--; LLDBUG_PRL2("[ENDIF ]\n",IFcount); 
+^{Spaces}"/ENDIF"([^\n])*     { int i;
+				IFcount--;
+				end_mode_stream(DEFAULT_DEST,0);
+				for(i=0;i");
+				send_stream(1,"}");
+				if (IFcount == 0) {
+				  if (watch_mode[current_dest][1]) {
+				    end_streams(DEFAULT_DEST,1);
+ 				  } else {
+				    end_streams(DEFAULT_DEST,0);
+				  }
+                                  change_destination(DEFAULT_DEST);
+				}
+				delete_cache();
+				LLDBUG_PRL2("[ENDIF ]\n",IFcount); 
                               }
-"/AND"                        { LLDBUG_PRL1("[AND]"); BEGIN S_ANSCONTINUE; RETURN(ANS_AND); }
+"/AND"                        { LLDBUG_PRL1("[AND]"); /*implict in LON-CAPA*/}
 "/DIS"                        { /* since S_VARIABLE treat {Space} as null, so here we do not match ( */
                                 /* so that between /DIS and ( can have as many {Space} as we want */
                                 LLDBUG_PR1("[DIS<]");
@@ -506,7 +579,7 @@ EndLine    ([\r][\n]|[\n])
                               }
 "/OR"                         { LLDBUG_PRL1("[OR]"); BEGIN S_ANSCONTINUE;  RETURN(ANS_OR); }
 {EndLine}                     { LLDBUG_PR1("[EoL within S_TEXT]\n"); /* end of the whole text line */ 
-                                send("\n"); }
+                                send("
\n"); } [\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ } ^{Spaces}"//"[^\n]*$ { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); start_mode(MODE_SCRIPT,NULL); @@ -629,8 +702,6 @@ EndLine ([\r][\n]|[\n]) { [/][Dd][Ii][Ss]{Space}*[\(]{Space}* { yy_push_state(S_HINTEXLAINX); } [^/\n]+[/\\] { char *aptr = yytext; - int ii; - yyless(yyleng-1); send(aptr); } @@ -638,19 +709,20 @@ EndLine ([\r][\n]|[\n]) [\\] { send("\\"); } [\\]{Space}*[\n] { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ } [^/\n\\]+$ {char *aptr = yytext; - int ii; - send(aptr); + send(aptr); } } { {EndLine} { LLDBUG_PR1("[CR hint]"); send("\n"); + change_destination(DEFAULT_DEST); BEGIN S_TEXT; } } { {EndLine} { LLDBUG_PR1("[CR explain]"); send("\n"); + change_destination(DEFAULT_DEST); BEGIN S_TEXT; } } @@ -662,8 +734,26 @@ EndLine ([\r][\n]|[\n]) } { -{FileName}{Space}* { end_mode();send("/res/ohiou/%s\n",yytext); BEGIN S_SKIP; } -{Identifier}{Space}* { end_mode();send("$%s\n",yytext); BEGIN S_SKIP; } +{FileName}{Space}* { char *endquote; + end_mode(); + start_mode(MODE_IMPORT,NULL); + /* Get rid of leading and trailing quotes */ + endquote = strrchr(yytext,'\"'); + *endquote = '\0'; + if (yytext[1] == '/') { + send("%s%s",import_prefix,&yytext[1]); + } else { + send("%s",&yytext[1]); + } + end_mode(); + BEGIN S_SKIP; + } +{Identifier}{Space}* { end_mode(); + start_mode(MODE_IMPORT,NULL); + send("$%s",yytext); + end_mode(); + BEGIN S_SKIP; + } } { @@ -685,7 +775,7 @@ EndLine ([\r][\n]|[\n]) [,=] { LLDBUG_PR2("[symbol(%s)]",yytext);} [%] { LLDBUG_PR2("[symbol(%s)]",yytext); if (dosend==1) send("%s",yytext); - if (dosend==2) add_delayed("%s",yytext); + if (dosend==2) add_delayed("%%%s",yytext); } [:@#-] { LLDBUG_PR2("[symbol(%s)]",yytext); if (dosend==1) send("%s",yytext); @@ -701,27 +791,39 @@ EndLine ([\r][\n]|[\n]) } [Pp][Cc][Rr] | -[Hh][Gg][Rr] { if (firstparam) firstparam=0; else add_delayed("\" />\n\t"); +[Hh][Gg][Rr] { if (firstparam) { + firstparam=0; + } else { + add_delayed("\" />\n\t"); + } add_delayed("\n\t"); + if (firstparam) { + firstparam=0; + } else { + add_delayed("\" />\n\t"); + } add_delayed("\n\t"); - add_delayed("\n\t"); + } + add_delayed("\n\t"); dosend=1; flush_delayed(); - if (!firstparam) send("\" />"); - send("\n\t\n\n"); + if (firstparam!=1) send("\" />\n"); + send("\t\n"); + /* Fill in Hints */ + if ( !is_dest_empty(HINT_DEST) ) { + send("\n\t\n\t"); + end_streams(HINT_DEST,0); + HINTflag=0; + send("\t\n\t\n\n"); + } + send("\n\n"); + + if ( !is_dest_empty(EXP_DEST) ) { + send("\n\t\n"); + end_streams(EXP_DEST,0); + EXPflag=0; + send("\t\n\n"); + } } } @@ -759,22 +876,12 @@ EndLine ([\r][\n]|[\n]) if (dosend==2) add_delayed("&%s",yytext); Pcount++; } -{Alpha}{AlphaNum}*{Space}*[\[] { char aline[MAX_FUNC_NAME]; - int i; - for(i=0;i < (yyleng-1); i++) { - if( yytext[i] == ' ' || yytext[i] == '\t' || - yytext[i] == 0 || yytext[i] == '[' ) break; - aline[i] = yytext[i]; - } - aline[i] = 0; - LLDBUG_PR2("[ARRAY<%s>]",aline); - - yylval = (Symbol *) capa_malloc(1, sizeof(Symbol)); /* *** */ - yylval->s_name = strsave(aline); /* free it in parser() */ - yylval->s_type = ARRAY_ID; +{Alpha}{AlphaNum}*{Space}*[\[] { + LLDBUG_PR2("[ARRAY<%s>]",yytext); - yyless(yyleng-1); /* <-- push back char '[' */ - RETURN(ARRAY_ID); + yyless(yyleng-1); /*<-- push back char '[' */ + if (dosend==1) send("$%s",yytext); + if (dosend==2) add_delayed("$%s",yytext); } {Number}*"\."{Number}*[Ee]"+"{Number}+ | {Number}*"\."{Number}*[Ee]{Number}+ | @@ -792,8 +899,14 @@ EndLine ([\r][\n]|[\n]) if (dosend==1) send("%s",yytext); if (dosend==2) add_delayed("%s",yytext); } -[\[] { LLDBUG_PR1("[dis let ans map '[']"); return(yytext[0]); } -[\]] { LLDBUG_PR1("[dis let ans map ']']"); return(yytext[0]); } +[\[] { LLDBUG_PR1("[dis let ans map '[']"); + if(dosend==1) send("%s",yytext); + if(dosend==2) add_delayed("%s",yytext); + } +[\]] { LLDBUG_PR1("[dis let ans map ']']"); + if(dosend==1) send("%s",yytext); + if(dosend==2) add_delayed("%s",yytext); + } {Space}+ { /* LLDBUG_PR1("[SP ignored]"); Ignore Spaces */ } } @@ -813,7 +926,7 @@ EndLine ([\r][\n]|[\n]) } { -[\(] { LLDBUG_PR1("[dis let ans map (]"); +[\(] { LLDBUG_PR1("[let if ans map (]"); Pcount++; if (Pcount > 1 ) { if (dosend==1) send(yytext); @@ -823,7 +936,7 @@ EndLine ([\r][\n]|[\n]) } { -[\(] { LLDBUG_PR1("[dis let ans map (]"); +[\(] { LLDBUG_PR1("[let (]"); Pcount++; send(yytext); } @@ -881,6 +994,7 @@ EndLine ([\r][\n]|[\n]) BEGIN S_ECHO; } } +[%] {send("%%");} {Operator} { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); } } @@ -905,10 +1019,24 @@ EndLine ([\r][\n]|[\n]) } { -[\)] { LLDBUG_PRL1("[) in TRUE_FALSE]"); Pcount--; if(Pcount == 0) BEGIN S_NEXT_LINE; return(yytext[0]); } -[\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ } -{EndLine} { LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL); } -. { char warn_msg[WARN_MSG_LENGTH]; +[\)] { + LLDBUG_PRL1("[) in TRUE_FALSE]"); + Pcount--; + if(Pcount == 0) { + stop_cache(); + send_stream(0,"\">\n"); + send_stream(1,") {\n"); + BEGIN S_NEXT_LINE; + } + } +[\\]{Space}*{EndLine} { + LLDBUG_PR2("[\\EoL continue in S_TRUE_FALSE_STMT](%s)",yytext); /* continuation on next line */ + } +{EndLine} { + LLDBUG_PR1("[EoL within /IF()]\n"); RETURN(EoL); + } +. { + char warn_msg[WARN_MSG_LENGTH]; sprintf(warn_msg,"In /IF(), an unexpected char [%c] is encountered.\n",yytext[0]); capa_msg(MESSAGE_ERROR,warn_msg); } @@ -925,6 +1053,9 @@ EndLine ([\r][\n]|[\n]) send("'"); yy_pop_state(); } +[%] { /*Escape percent signs so that vasprintf doesn't choke */ + send("%%"); + } {EndLine} { /* check for termination of string constant */ char warn_msg[WARN_MSG_LENGTH]; @@ -991,41 +1122,10 @@ EndLine ([\r][\n]|[\n]) [\\]{Space}*{EndLine} { /* continuation */ } {EndLine} { /* end of answer and/or other answers */ LLDBUG_PR1("[complete an answer]"); BEGIN S_TEXT; } -"/AND" { LLDBUG_PR1("[AND]"); RETURN(ANS_AND); } +"/AND" { LLDBUG_PR1("[AND]"); /* implicit in LON-CAPA */ } "/OR" { LLDBUG_PR1("[OR]"); RETURN(ANS_OR); } } -{ -^{Spaces}"/IF"[^\n]*{EndLine} { IFcount++; LLDBUG_PRL2("[Skip IF ]\n",IFcount); - IFstatus[IFcount] = IF_DONT_CARE; - } -^{Spaces}"/ELSE"[^\n]*{EndLine} { LLDBUG_PRL2("[Skip ELSE ]",IFcount); - IFcurrent[IFcount]=RUN_ELSE_PORTION; - if( IFstatus[IFcount] == IF_FALSE ) { - LLDBUG_PRL1("[ELSE begin TEXT CR]\n"); - BEGIN S_TEXT; - } - if( IFstatus[IFcount] == IF_TRUE ) { - LLDBUG_PRL1("[ELSE THIS SHOULD NEVER HAPPEN.]\n"); - } - } -^{Spaces}"/ENDIF"[^\n]*{EndLine} { IFcount--; LLDBUG_PRL2("[Skip ENDIF ]\n",IFcount); - if( IFcount == 0 ) { - LLDBUG_PRL1("[ENDIF begin TEXT CR]\n"); - BEGIN S_TEXT; - } - if( (IFcurrent[IFcount] == RUN_IF_PORTION )&&(IFstatus[IFcount] == IF_TRUE)) { - LLDBUG_PRL1("[ENDIF begin TEXT CR]\n"); - BEGIN S_TEXT; - } - if( (IFcurrent[IFcount] == RUN_ELSE_PORTION )&&(IFstatus[IFcount] == IF_FALSE)) { - LLDBUG_PRL1("[ENDIF begin TEXT CR]\n"); - BEGIN S_TEXT; - } - } -{EndLine} { LLDBUG_PRL1("[SkipIF a CR]\n"); } -[^\n]*$ { LLDBUG_PRL2("[SkipIF anything ]",IFcount); } -} { ([.]*){EndLine} { /* this ignores everything until it hits an EoL */ LLDBUG_PRL2("[ skip \'%s\' until EoL]\n",yytext); @@ -1062,8 +1162,6 @@ EndLine ([\r][\n]|[\n]) %% /* ========================================================================================== */ -extern void -begin_if_skip() { BEGIN S_IF_SKIP; } extern void begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; }