--- loncom/homework/CAPA-converter/capaLexerDef.flex 2000/10/25 20:26:57 1.5 +++ loncom/homework/CAPA-converter/capaLexerDef.flex 2002/09/12 15:54:06 1.21 @@ -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.21 2002/09/12 15:54:06 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,11 +146,15 @@ 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; +int EVALflag=0; +int compound_answer=0; +int essay_answer=0; #ifdef USE_DYNAMIC_SYMBOLS Symbol *SymbList_p; @@ -216,7 +247,7 @@ void newyy_input (char *buf,int *result, } \ Input_idx = 0; \ first_run=0; \ - yyin = Input_stream[Input_idx]; LIDBUG_PR1("<>\n"); \ +yyin = Input_stream[Input_idx]; LIDBUG_PR1("<>\n"); \ } \ out_of_char = 0; \ if ( Lexi_buf[Input_idx] == NULL ) { \ @@ -361,7 +392,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 @@ -382,7 +413,7 @@ EndLine ([\r][\n]|[\n]) { {EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); - send("# %s",&yytext[2]); + send("# %s\n",&yytext[2]); } [^\n]*{EndLine} { send("\n"); BEGIN S_TEXT; @@ -401,11 +432,22 @@ EndLine ([\r][\n]|[\n]) send("
\n");
                                  }
 ^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
-                                   start_mode(MODE_BLOCK,
-					      "condition=\"&hinton\"");
+                               /*    start_mode(MODE_HINT, "");*/
+                                   if (!HINTflag) {
+                                     start_streams(HINT_DEST,1);
+                                     HINTflag=-1;
+                                   }
+                                   change_destination(HINT_DEST);
+                                   send("\t",NULL);
 				   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);
+                                   send("\t",NULL);
                                    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]");  
@@ -436,75 +478,115 @@ EndLine    ([\r][\n]|[\n])
                                 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}"/MAP"               { LLDBUG_PRL1("[MAP]");  Pcount = 0; sccount = 0; BEGIN S_MAP; start_mode(MODE_SCRIPT,NULL);send("&map("); }
+^{Spaces}"/RMAP"              { LLDBUG_PRL1("[RMAP]"); Pcount = 0; sccount = 0; BEGIN S_MAP; start_mode(MODE_SCRIPT,NULL);send("&rmap("); }
+^{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); }
 "/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 */
+				start_mode(MODE_OUTTEXT,NULL);
                                 LLDBUG_PR1("[DIS<]");
                                 init_funcstack();
                                 Pcount = 0; BEGIN S_VARIABLE; 
+				send("");
 				start_delayed();
                               }
-"/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"); }
 [\\]{Space}*{EndLine}         { LLDBUG_PR2("[\\EoL continue](%s)",yytext); /* continuation on next line */ }                       
@@ -629,78 +711,59 @@ 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);
                                 }
 [/]                            { send("/"); }
 [\\]                           { send("\\"); }
-[\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ }
+[\\]{Space}*[\n]               { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ send("\n\t");}
 [^/\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;
                               }
 }
 
 {
-{Alpha}{AlphaNum}*            { char   *aptr;
-                                char    tmp_str[QUARTER_K],warn_msg[ONE_K];
-                                int     ii, len;
-                                Symbol *tmp_p;
-                                
-                                /*tmp_p = find_identifier(yytext);*/
-                                switch(tmp_p->s_type) {
-                                  case IDENTIFIER:
-                                        sprintf(warn_msg,"var %s not defined.\n", yytext);
-                                        capa_msg(MESSAGE_ERROR,warn_msg);
-                                       break;
-                                  case I_VAR:
-                                  case I_CONSTANT: 
-                                         sprintf(tmp_str,"%ld",tmp_p->s_int);
-                                         len = strlen(tmp_str);
-                                         for(ii=0;ii< len;ii++) {
-                                           *Current_char_p++ = tmp_str[ii];
-                                         }
-                                       break;
-                                  case R_VAR:
-                                  case R_CONSTANT: 
-                                         sprintf(tmp_str,"%g",tmp_p->s_real);
-                                         len = strlen(tmp_str);
-                                         for(ii=0;ii< len;ii++) {
-                                           *Current_char_p++ = tmp_str[ii];
-                                         }
-                                       break;
-                                  case S_VAR:
-                                  case S_CONSTANT: 
-                                         len = strlen(tmp_p->s_str);
-                                         aptr = tmp_p->s_str;
-                                         for(ii=0;ii< len;ii++) {
-                                           *Current_char_p++ = *aptr++;
-                                         }
-                                       break;
-                                }
-				printf("FIXME!Hint: %s\n",yytext);
-                              }
+{Alpha}{AlphaNum}*            {send("${%s}",yytext);}
 {Space}+                      { }
 [)]                           {  yy_pop_state(); }
 }
 
 {
-{FileName}{Space}*             { end_mode();send("/res/capa/%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;
+			       }
 }
 
 {
@@ -722,43 +785,61 @@ 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);
                           if (dosend==2) add_delayed("%s",yytext);
                         }
 "<"                          { LLDBUG_PR2("[symbol(%s)]",yytext);
+			       if (!EVALflag) {
                                if (dosend==1) send("%s",yytext);
                                if (dosend==2) add_delayed("%s",yytext);
                              }
+                             }
 ">"                          { LLDBUG_PR2("[symbol(%s)]",yytext);
+			       if (!EVALflag) {
                                if (dosend==1) send("%s",yytext);
                                if (dosend==2) add_delayed("%s",yytext);
+                               } else {
+				 EVALflag = 0;
+			       }
                              }
 
 [Pp][Cc][Rr]                 |
-[Hh][Gg][Rr]                 { if (firstparam) firstparam=0; else add_delayed("\">\n\t");
-                               add_delayed("\n\t");
+			       }
+                               add_delayed("\n\t");
-			       add_delayed("\n\t");
+			       }
+			       add_delayed("\n\t");
-			       add_delayed("\n\t");
+			       }
+			       add_delayed("\n\t");
+                               } else {
                                send("\">\n\t");
+                               }
 			       dosend=1;
 			       flush_delayed();
-			       if (!firstparam) send("\">");
-			       send("\n\t\n\n");
+			       if (firstparam!=1) send("\" />\n");
+                               if (essay_answer) {
+			         send("  Enter your answer here.\n");
+                               } else {
+			       send("\t\n");
+                               }
+                         /* Fill in Hints */ 
+			       if ( !is_dest_empty(HINT_DEST) ) {
+			         send("\t\n\t\n\t");
+                                 end_streams(HINT_DEST,0);
+                                 HINTflag=0;
+                                 send("\t\n\t\n\t\n");
+			       }
+                               if (essay_answer) {
+			         send("\n");
+                               } else {
+			         send("\n");
+			       }
+
+                             }
+}
+
+{
+{Alpha}{AlphaNum}*             { LLDBUG_PR2("[ID<%s>]",yytext);
+                                 LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); 
+                                 if(Pcount <= 1) {
+                                   if (dosend==1) send("${%s}",yytext); 
+                                   if (dosend==2) add_delayed("${%s}",yytext); 
+                                 } else {
+                                   if (dosend==1) send("$%s",yytext); 
+                                   if (dosend==2) add_delayed("$%s",yytext); 
+                               }
                              }
 }
 
@@ -796,22 +911,11 @@ 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;
-                                   
-                                   yyless(yyleng-1); /* <-- push back char '[' */
-                                   RETURN(ARRAY_ID);
+{Alpha}{AlphaNum}*{Space}*[\[]  {
+                                   LLDBUG_PR2("[ARRAY<%s>]",yytext);
+                                   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}+    |
@@ -829,15 +933,21 @@ 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 */ }
 }
 
 {
 [\"]                      { LLDBUG_PR1("[TF,V,LET,MAP str\" ]"); 
                             Current_char_p = String_buf; 
-			    send("\"");
+			    send("'");
                             yy_push_state(S_STRING);
                           }
 }
@@ -850,7 +960,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);
@@ -860,7 +970,7 @@ EndLine    ([\r][\n]|[\n])
 }
 
 {
-[\(]                      { LLDBUG_PR1("[dis let ans map (]"); 
+[\(]                      { LLDBUG_PR1("[let (]"); 
                             Pcount++; 
 			    send(yytext);
                           }
@@ -870,15 +980,47 @@ EndLine    ([\r][\n]|[\n])
                              end_delayed();
                              send("&format(");
                              flush_delayed();
-                             send(",\"%s\")",yytext+1);
+                             send(",'%s')",yytext+1);
                            }
 [:]{Number}+[EeFf]   { 
                              if (dosend) send("\" format=\"%s",yytext+1);
                            }
 
+{
+[;]   { 
+        if (sccount==0) {
+          send(",[\\");
+          sccount++;
+        } else if (sccount==1) {
+          send("],[");
+          sccount++;
+        }
+       }
+[,]     {
+        if (sccount==1) {
+          send(",\\");
+        } else {
+          send(",");
+        }
+      }
+[\)]  {
+        LLDBUG_PR1("[) in MAP]"); Pcount--; 
+        if(Pcount==0) {
+          BEGIN S_SKIP; 
+        }
+        /* you might need a ; in the string below */
+        send("]%c;\n",yytext[0]);
+        sccount=0;
+      }
+}
+
+{
+"+"		    { send(".");}
+}
+
 {
-"=="                { LLDBUG_PR1("[==]"); send(yytext);  }
-"!="                { LLDBUG_PR1("[!=]"); send(yytext);  }
+"=="                { LLDBUG_PR1("[==]"); send(" eq ");  }
+"!="                { LLDBUG_PR1("[!=]"); send(" ne ");  }
 ">"                 { LLDBUG_PR1("[>]");  send(yytext);  }
 ">="                { LLDBUG_PR1("[>=]"); send(yytext);  }
 "<"                 { LLDBUG_PR1("[<]");  send(yytext);  }
@@ -890,6 +1032,7 @@ EndLine    ([\r][\n]|[\n])
 			 BEGIN S_ECHO;
                       }
                     }
+[%]                 {send("%%");}
 {Operator}          { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); }
 }
 
@@ -899,6 +1042,7 @@ EndLine    ([\r][\n]|[\n])
 [\)]                     { LLDBUG_PR1("[)]"); 
                            Pcount--; 
                            if(Pcount == 0) {
+			      send("");
                               BEGIN S_TEXT; 
                               flush_delayed();
                            } else {
@@ -914,10 +1058,27 @@ 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;
+			   } else {
+                                send_stream(0,")");
+                                send_stream(1,")");
+			   }
+			 }
+[\\]{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);
                     }
@@ -931,9 +1092,15 @@ EndLine    ([\r][\n]|[\n])
 [\\][\"]            { /**Current_char_p++ = '"';*/ send("\\\"");  }
 [\\]{Space}*[\n]    { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ }                       
 [\"]                { /* end of a string constant --   */
-                      send("\"");
+                      send("'");
 		      yy_pop_state();
 		    }
+[%]                 { /*Escape percent signs so that vasprintf doesn't choke */
+                      send("%%");
+                    }
+[\']                { /* Escape single quotes so that perl doesn't choke */
+                      send("\\\'");
+                    }
 {EndLine}           { /* check for termination of string constant */
                       char warn_msg[WARN_MSG_LENGTH];
                       
@@ -995,56 +1162,48 @@ EndLine    ([\r][\n]|[\n])
                              }
 }
 
-{
-[;,]                         { LLDBUG_PR2("[%c]",yytext[0]); send("%c",yytext[0]);  }
-[\)]                         { LLDBUG_PR1("[) in MAP]"); Pcount--; 
-                               if(Pcount==0) {
-                                   BEGIN S_SKIP; 
-                               }
-                               send("%c",yytext[0]); 
-                             }
-}
-
 {
-{Space}+                 { /* ignore white spaces */ }
-[\\]{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); }
-"/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;
-                            }
+{Spaces}{EndLine}{Spaces}"/AND"  { LLDBUG_PR1("[AND]");
+                                   compound_answer=-1;
+                                   /* implicit in LON-CAPA */ }
+{Spaces}{EndLine}{Spaces}"/OR"   { LLDBUG_PR1("[OR]"); 
+                                   compound_answer=-1;
+				   /*RETURN(ANS_OR); */ }
+{Spaces}{EndLine}{Spaces}"/ANS" { LLDBUG_PRL2("[ANS(%s)]",yytext); 
+                                Pcount = 0; 
+                                BEGIN S_ANSWER; 
+                                end_mode();
+                                if (!compound_answer) {
+			          if ( !is_dest_empty(EXP_DEST) ) {
+			            send("\n\t\n");
+                                    end_streams(EXP_DEST,0);
+                                    EXPflag=0;
+                                    send("\t\n\n");
+                                    }
+                                  send("\n\n"); 
+                                }
+				start_mode(MODE_ANSWER,NULL);
+                                send("]"); 
+			   if ( !is_dest_empty(EXP_DEST) ) {
+			     send("\n\t\n");
+                             end_streams(EXP_DEST,0);
+                             EXPflag=0;
+                             send("\t\n\n");
+                           }
+                           send("\n\n"); 
+                           BEGIN S_TEXT; 
                          }
-{EndLine}                { LLDBUG_PRL1("[SkipIF a CR]\n");       }
-[^\n]*$                  { LLDBUG_PRL2("[SkipIF anything ]",IFcount);   }
+{Spaces}		{ /* Do nothing */ }
 }
+
 {
 ([.]*){EndLine}          { /* this ignores everything until it hits an EoL */
                            LLDBUG_PRL2("[ skip \'%s\' until EoL]\n",yytext); 
@@ -1081,8 +1240,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; }