/* 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) */ /* added /HIN .... /DIS(variable) ... */ /* Jan 15 1998 /{KeyWord}{KeyWord}{KeyWord} */ /* replaced by /DIS */ /* catch "No /END() statement found" */ /* catch "/DIS(")" and "/DIS(""")" errors " */ /* catch "/LET var = " */ /* add a new token EoL to indicate '\n' '\r''\n' and '\r' */ /* This file is based on flex 2.5.3, flex 2.3 apparantly cannot take it :-( */ /* DONE /RMAP() function July 14, 1998 */ /* DONE /AND /OR answer formats July 20, 1998 */ /* DONE /IF () /ENDIF July 26, 1998 */ /* DONE /WHILE () /ENDWHILE August 10 1998 */ /* DONE /VERB /ENDVERB Feb 20 1998 */ /*------------------------------------------------------------------------*/ /**************************************************************************/ %{ #include #include /* strtod(), strtol() */ #include #ifdef NeXT #include #else #include /* access() */ #endif #include "capaCommon.h" /* capa_access() */ #include "capaParser.h" /* _symbol structure def */ #include "lex_debug.h" /* defined RETURN(xxx) macro */ #ifdef YYSTYPE #undef YYSTYPE #endif #define YYSTYPE Symbol_p #include "capaToken.h" /* from YACC -d capaGrammarDef.y */ /* ============================================== begin of code */ #define LEX_BUFLEN (8*1024) /* lexical buffer size (for each opened file) */ #ifdef YYLMAX #undef YYLMAX #define YYLMAX 8192 #endif void yyfatalerror(char*msg); #define YY_FATAL_ERROR yyfatalerror #ifdef LEX_DBUG #define LLDBUG_PRL1(xx) { printf("Line %d ",Current_line[Input_idx]); printf(xx); fflush(stdout); } #define LLDBUG_PRL2(xx,yy) { printf("Line %d ",Current_line[Input_idx]); printf(xx,yy); fflush(stdout); } #define LLDBUG_PR1(xx) { printf(xx); fflush(stdout); } #define LLDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); } #define LLDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); } #else #define LLDBUG_PRL1(xx) { } #define LLDBUG_PRL2(xx,yy) { } #define LLDBUG_PR1(xx) { } #define LLDBUG_PR2(xx,yy) { } #define LLDBUG_PR3(xx,yy,zz) { } #endif #ifdef LEX_INPUT_DBUG #define LIDBUG_PR1(xx) { printf(xx); fflush(stdout); } #define LIDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); } #define LIDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); } #else #define LIDBUG_PR1(xx) { } #define LIDBUG_PR2(xx,yy) { } #define LIDBUG_PR3(xx,yy,zz) { } #endif #ifdef USE_DYNAMIC_SYMBOLS #define USE_DYNAMIC_LEXBUFS #endif Symbol *yylval; /* global pointer to symbol */ FILE *(Input_stream[MAX_OPENED_FILE]); /* <-- perhaps we can use linked list */ char Opened_filename[MAX_OPENED_FILE][QUARTER_K]; /* <-- perhaps we can use linked list */ int Input_idx; int Lexi_pos[MAX_OPENED_FILE]; /* Current position in the line */ #ifdef USE_DYNAMIC_LEXBUFS char *(Lexi_buf[MAX_OPENED_FILE]); /* Line Buffer for current file */ #else char Lexi_buf[MAX_OPENED_FILE][LEX_BUFLEN+4]; /* Line Buffer for current file */ #endif /* USE_DYNAMIC_LEXBUFS */ char String_buf[LEX_BUFLEN]; /* Constant String buffer <-- perhaps we can use char pointer */ char *Dynamic_buf; int Dynamic_buf_max; int Dynamic_buf_cur; static int End_of_input; static int Pcount, Bcount; /* static means only available in this file */ /* --------------------------------------------------------------------------- */ /* GLOBAL VARIABLES */ /* --------------------------------------------------------------------------- */ int Lexi_line; /* Current source file line number, counting from beginning */ extern int Current_line[MAX_OPENED_FILE]; int Func_idx; Symbol FuncStack[MAX_FUNC_NEST]; /* <-- perhaps we can use linked list */ int Array_idx; Symbol *ArraySymbList_p; Symbol *ArraySymbLast_p; Symbol *FmlSymbList_p; Symbol *FmlSymbLast_p; int FmlSymb_cnt; int Symb_count; 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; Symbol *SymbLast_p; #else Symbol SymbArray[MAX_SYMB_COUNT]; #endif /* USE_DYNAMIC_SYMBOLS */ char *Current_char_p; /* Collect string constant */ extern char *EndText_p; extern char *StartText_p; extern Problem_t *LexiProblem_p; extern Problem_t *LastProblem_p; int first_run=1; int Stop_Parser; static int dosend=1; static int firstparam=1; #define FLEX #define YY_STACK_USED 1 /* for yy_push_state(), yy_pop_state() */ #ifdef FLEX int capaL_unput(); int capaL_input(); /* YY_INPUT() Controls scanner input. By default, YY_INPUT reads from the file-pointer yyin. Its action is to place up to max_size characters in the character array buf and return in the integer variable result either the number of characters read or the constant YY_NULL to indicate EOF. max_size is defined to be num_to_read = 8192 in liby Following is a sample redefinition of YY_INPUT, in the definitions section of the input file: %{ #undef YY_INPUT #define YY_INPUT(buf,result,max_size)\ {\ int c = getchar();\ result = (c == EOF) ? YY_NULL : (buf[0] = c, 1);\ } %} */ /* fgets() reads the input stream until n-1 bytes have been read OR a newline character is read and transferred to string OR an EOF (End-of-File) condition is encountered The string is then terminated with a NULL character. ii = fseek(FILE *stream,0L,SEEK_END) ; if(ii!=0) { error } leng = ftell(FILE *stream) + 1 ; fseek(FILE *stream,0L,SEEK_SET) ; Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*leng,1); */ #ifdef AVOIDYYINPUT #define MAX_INCLUDE_DEPTH 10 YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH]; int include_stack_ptr = 0; #else #ifdef USE_DYNAMIC_LEXBUFS #define NEWYYINPUT #endif #ifdef NEWYYINPUT void newyy_input (char *buf,int *result,int max_size); #define YY_INPUT(buf,result,max_size) newyy_input(buf,&result,max_size) #else #ifdef USE_DYNAMIC_LEXBUFS #define YY_INPUT(buf,result,max_size) \ { int ii, leng, out_of_char; \ if (!Lexi_line) { /* was startup */ \ for(ii=0;ii < MAX_OPENED_FILE;ii++) { \ Lexi_buf[ii] = NULL; \ Lexi_pos[ii] = 0; \ Current_line[ii] = 0; \ } \ Input_idx = 0; \ first_run=0; \ yyin = Input_stream[Input_idx]; LIDBUG_PR1("<>\n"); \ } \ out_of_char = 0; \ if ( Lexi_buf[Input_idx] == NULL ) { \ Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1; \ } else { \ if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \ out_of_char=1; \ } \ } \ if( out_of_char ) { \ if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \ LIDBUG_PR2("<>\n",Input_idx); \ if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \ LIDBUG_PR2("<>\n",Input_idx); \ fclose(Input_stream[Input_idx]); \ capa_mfree((char *)Lexi_buf[Input_idx]); \ Lexi_buf[Input_idx] = NULL; \ Input_idx--; \ yyin = Input_stream[Input_idx]; \ /* (Lexi_pos[Input_idx])++; */ \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ result = 1; \ } else { \ result = YY_NULL; /* End of File */ \ } \ } else { /* successfully read in one line */ \ if (Lexi_buf[Input_idx]==NULL) puts("Whatup?");\ leng = strlen(Lexi_buf[Input_idx]); \ LIDBUG_PR3("<>\n",leng,Input_idx); \ Lexi_pos[Input_idx] = 0; \ Lexi_line++; \ Current_line[Input_idx]++; \ (Lexi_pos[Input_idx])++; \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ /* need to take care of return continuation conditions */ \ /* so, we return to one-char-at-a-time approach */ \ /* for(ii=0;ii>\n",Input_idx); */ \ (Lexi_pos[Input_idx])++; \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ result = 1; \ } \ if (Stop_Parser==1) { \ result = YY_NULL; \ } \ } #else #define YY_INPUT(buf,result,max_size) \ { int ii, leng; \ if (!Lexi_line) { /* was startup */ \ for(ii=0;ii < MAX_OPENED_FILE;ii++) { \ Lexi_buf[ii][0]=0; \ Lexi_pos[ii] = 0; \ Current_line[ii] = 0; \ } \ Input_idx = 0; \ first_run=0; \ yyin = Input_stream[Input_idx]; LIDBUG_PR1("<>\n"); \ } \ if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ \ if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ \ LIDBUG_PR2("<>\n",Input_idx); \ if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \ LIDBUG_PR2("<>\n",Input_idx); \ fclose(Input_stream[Input_idx]); \ Input_idx--; \ yyin = Input_stream[Input_idx]; \ /* (Lexi_pos[Input_idx])++; */ \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ result = 1; \ } else { \ result = YY_NULL; /* End of File */ \ } \ } else { /* successfully read in one line */ \ leng = strlen(Lexi_buf[Input_idx]); \ LIDBUG_PR3("<>\n",leng,Input_idx); \ Lexi_pos[Input_idx] = 0; \ Lexi_line++; \ Current_line[Input_idx]++; \ (Lexi_pos[Input_idx])++; \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ /* need to take care of return continuation conditions */ \ /* so, we return to one-char-at-a-time approach */ \ /* for(ii=0;ii>\n",Input_idx); */ \ (Lexi_pos[Input_idx])++; \ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; \ result = 1; \ } \ if (Stop_Parser==1) { \ result = YY_NULL; \ } \ } #endif /* USE_DYNAMIC_LEXBUFS */ #endif /*NEWYYINPUT*/ #endif /*AVOIDYYINPUT*/ #else #undef input #undef unput #endif int capa_eof(); %} Alpha [a-zA-Z_] KeyChar [A-Z] AlphaNum [a-zA-Z_0-9] Number [0-9] HexNumber [0-9a-fA-F] Space [ \t] Spaces ({Space}*) FileName (\"[^"\n]*\") Qchar ([0-9a-zA-Z \t!?\._,:;'"`~@#$%\^&\+\-\*=|\[\]{}()]) Operator ([=\+\-\*/%<>!&|,]) Identifier ([a-zA-Z_][a-zA-Z_0-9]*) EndLine ([\r][\n]|[\n]) %a 10500 %o 15000 %k 10000 %p 10000 %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_WHILE_SKIP %x S_NEXT_LINE S_VERB S_ECHO S_STRINGINANS %array %% { {EndLine} BEGIN S_IGNORE; [^\n]*$ BEGIN S_IGNORE; <> { capa_eof(); #ifndef AVOIDYYINPUT yyterminate(); #endif } } { {EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); send("# %s\n",&yytext[2]); } [^\n]*{EndLine} { send("\n"); BEGIN S_TEXT; } } { ^{Spaces}"/LET" | ^{Spaces}"/BEG" { LLDBUG_PRL1("[LET]"); Pcount = 0; BEGIN S_LET; start_mode(MODE_SCRIPT,NULL); } ^{Spaces}"/VERB" { LLDBUG_PRL1("[VERBATIM]"); BEGIN S_VERB; start_mode(MODE_OUTTEXT,NULL); send("
\n");
                                 }
^{Spaces}"/HIN"{Alpha}*{Spaces}  { LLDBUG_PRL1("[HIN]"); 
                               /*    start_mode(MODE_HINT, "");*/
                                   if (!HINTflag) {
                                     start_streams(HINT_DEST,1);
                                     HINTflag=-1;
                                   }
                                   change_destination(HINT_DEST);
				   BEGIN S_HINT; 
                                 }
^{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]");  
                                    if ( (LexiProblem_p !=NULL) && 
					 (LexiProblem_p->question != NULL) && 
					 (LexiProblem_p->ans_type == 0)) {
				      EndText_p=strsave(LexiProblem_p->question);
				      LexiProblem_p=NULL;
				    } else {
				      EndText_p=NULL;
				    }
				    End_of_input = 1; BEGIN S_IGNORE; 
                                  }
^{Spaces}"/START"[^\n]*          { LLDBUG_PRL1("[START]");  
                                    if (LexiProblem_p !=NULL && 
					LexiProblem_p->question != NULL) {
				      StartText_p=strsave(LexiProblem_p->question);
				    } else {
				      StartText_p=NULL;
				    }
				    BEGIN S_TEXT;
                                  }
                                  
^{Spaces}"/END"{Spaces}[\(]{Spaces}      { LLDBUG_PRL1("[END()]"); BEGIN S_ENDX; }
^"/DEF"                       { Bcount = 0; BEGIN S_DEFINE; RETURN(CAPA_DEF); }
^{Spaces}"/ANS"               { LLDBUG_PRL2("[ANS(%s)]",yytext); 
                                Pcount = 0; 
                                BEGIN S_ANSWER; 
                                end_mode();
				start_mode(MODE_ANSWER,NULL);
                                send("]\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"             { 
                                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;
				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])*     { 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]"); /*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<]");
                                init_funcstack();
                                Pcount = 0; BEGIN S_VARIABLE; 
				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 */ } ^{Spaces}"//"[^\n]*$ { LLDBUG_PRL2("[COMMENT<%s>]\n",yytext); start_mode(MODE_SCRIPT,NULL); send("# %s\n",&yytext[2]); BEGIN S_COMMENT; } [^/\n\\]+$ | [/] | [\\] { start_mode(MODE_OUTTEXT,NULL); LLDBUG_PR2("[TEXT_LINE<%s>]",yytext); send(yytext); } ([^/\n])+[/] | ([^/\n])+[\\] { /* matches anything until a '/' or a '\' */ start_mode(MODE_OUTTEXT,NULL); LLDBUG_PR2("[TEXT_LINE( )<%s>]",yytext); yyless(yyleng-1); /* push back the last char */ BEGIN S_TEXT; send(yytext); } <> { #ifdef AVOIDYYINPUT char warn_msg[ONE_K]; if ( (--include_stack_ptr < 0) || Stop_Parser) { if (Stop_Parser) { if ( LexiProblem_p!=NULL && LexiProblem_p->question != NULL) EndText_p=strsave(LexiProblem_p->question); while (include_stack_ptr >= 0) { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer( include_stack[include_stack_ptr]); --include_stack_ptr; } } else { sprintf(warn_msg, "at End-of-File, a /END is needed.\n"); capa_msg(MESSAGE_ERROR,warn_msg); } free_problems(LexiProblem_p); LexiProblem_p=NULL; yyterminate(); } else { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer(include_stack[include_stack_ptr]); } #else char warn_msg[ONE_K]; if (!Stop_Parser) { sprintf(warn_msg,"at End-of-File, a /END is needed.\n"); capa_msg(MESSAGE_ERROR,warn_msg); } else { if (LexiProblem_p != NULL && LexiProblem_p->question != NULL) EndText_p=strsave(LexiProblem_p->question); } capa_eof(); yyterminate(); #endif } } { {Alpha}{AlphaNum}* { /* DONE: add codes to handle /END() */ char *question_end=NULL; End_of_input = 1; if (EndText_p!=NULL) capa_mfree((char*)EndText_p); if ((LexiProblem_p!=NULL) && (LexiProblem_p->question != NULL) && (LexiProblem_p->ans_type == 0)) { question_end=strsave(LexiProblem_p->question); } if( yyleng > 0 ) { LLDBUG_PRL2("[END()<%s>]\n",yytext); /*yylval = find_identifier(yytext);*/ switch(yylval->s_type) { case IDENTIFIER: case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT: break; case S_VAR: case S_CONSTANT: EndText_p = strsave(yylval->s_str); if (question_end) { int leng; char *new_end; leng = strlen(EndText_p) + strlen(question_end) + 1; new_end = capa_malloc(sizeof(char), leng); strcat(new_end, question_end); strcat(new_end, EndText_p); capa_mfree(EndText_p); capa_mfree(question_end); EndText_p=new_end; } break; default: break; } } BEGIN S_IGNORE; RETURN(CAPA_END); } {Space}* { /* ignore spaces */ } [\)] { /* a right paren */ if ( (LexiProblem_p != NULL) && (LexiProblem_p->question != NULL) && (LexiProblem_p->ans_type == 0)) { EndText_p=strsave(LexiProblem_p->question); } else { EndText_p=NULL; } BEGIN S_IGNORE; RETURN(CAPA_END); } } { [/][Dd][Ii][Ss]{Space}*[\(]{Space}* { yy_push_state(S_HINTEXLAINX); } [^/\n]+[/\\] { char *aptr = yytext; yyless(yyleng-1); send(aptr); } [/] { send("/"); } [\\] { send("\\"); } [\\]{Space}*[\n] { LLDBUG_PR1("[\\CR hint explain continue]"); /* Hint and explain continuation */ } [^/\n\\]+$ {char *aptr = yytext; 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}* {send("${%s}",yytext);} {Space}+ { } [)] { yy_pop_state(); } } { {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; } } { [Pp][Ll][Uu][Ss] { LLDBUG_PR1("[PLUS]"); add_delayed("+");} [Mm][Ii][Nn][Uu][Ss] { LLDBUG_PR1("[MINUS]"); add_delayed("-");} [Cc][Ss] { LLDBUG_PR1("[CS]"); send("cs");} [Cc][Ii] { LLDBUG_PR1("[CI]"); send("ci");} [Mm][Cc] { LLDBUG_PR1("[MC]"); send("mc");} [Ff][Mm][Ll] { LLDBUG_PR1("[FORMULA]"); send("fml"); } [Oo][Nn] | [Yy][Ee][Ss] { LLDBUG_PR1("[ON]"); send("on");} [Oo][Ff][Ff] | [Nn][Oo] { LLDBUG_PR1("[OFF]"); send("off");} [Ff][Mm][Tt] { LLDBUG_PR1("[FMT]"); } [Uu][Nn][Ff][Mm][Tt] { LLDBUG_PR1("[UNFMT]"); } [,=] { LLDBUG_PR2("[symbol(%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 (dosend==1) send("%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 (dosend==1) send("%s",yytext); if (dosend==2) add_delayed("%s",yytext); } [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"); dosend=1; flush_delayed(); 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"); } } } { {Alpha}{AlphaNum}* { LLDBUG_PR2("[ID<%s>]",yytext); LLDBUG_PR2("[SYMB CNT=<%d>]", Symb_count); if (dosend==1) send("$%s",yytext); if (dosend==2) add_delayed("$%s",yytext); } {Alpha}{AlphaNum}*{Space}*[(] { if (dosend==1) send("&%s",yytext); if (dosend==2) add_delayed("&%s",yytext); Pcount++; } {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}+ | {Number}*"\."{Number}*[Ee]"-"{Number}+ | {Number}+[Ee]"+"{Number}+ | {Number}+[Ee]{Number}+ | {Number}+[Ee]"-"{Number}+ | {Number}+"\."{Number}* | "\."{Number}+ { LLDBUG_PR2("[REAL<%s>]",yytext); if(dosend==1) send("%s",yytext); if(dosend==2) add_delayed("%s",yytext); } {Number}+ { LLDBUG_PR2("[INT<%s>]",yytext); 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); } [\]] { 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("'"); yy_push_state(S_STRING); } } { [\"] { LLDBUG_PR1("[ANS str\" ]"); Current_char_p = String_buf; yy_push_state(S_STRINGINANS); } } { [\(] { LLDBUG_PR1("[let if ans map (]"); Pcount++; if (Pcount > 1 ) { if (dosend==1) send(yytext); if (dosend==2) add_delayed(yytext); } } } { [\(] { LLDBUG_PR1("[let (]"); Pcount++; send(yytext); } } [:]{Number}+[EeFf] { end_delayed(); send("&format("); flush_delayed(); 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; } } { "==" { LLDBUG_PR1("[==]"); send(yytext); } "!=" { LLDBUG_PR1("[!=]"); send(yytext); } ">" { LLDBUG_PR1("[>]"); send(yytext); } ">=" { LLDBUG_PR1("[>=]"); send(yytext); } "<" { LLDBUG_PR1("[<]"); send(yytext); } "<=" { LLDBUG_PR1("[<=]"); send(yytext); } "&&" { LLDBUG_PR1("[&&]"); send(yytext); } "||" { LLDBUG_PR1("[||]"); send(yytext); } "//" { if(Pcount==0) { send("; #"); BEGIN S_ECHO; } } [%] {send("%%");} {Operator} { LLDBUG_PR2("[Op(%c) in VAR,TF_STMT,LET]",yytext[0]); send(yytext); } } { [\)] { LLDBUG_PR1("[)]"); Pcount--; if(Pcount == 0) { BEGIN S_TEXT; flush_delayed(); } else { send(yytext); } } [\\]{Space}*{EndLine} { LLDBUG_PR2("[\\EoL continue in S_VARIABLE (DIS?)](%s)",yytext); /* continuation on next line */ } {EndLine} { LLDBUG_PR1("[EoL within /dis()]\n"); } . { char warn_msg[WARN_MSG_LENGTH]; sprintf(warn_msg,"When use a VARIABLE, an unexpected char [%c] is encountered.\n",yytext[0]); capa_msg(MESSAGE_ERROR,warn_msg); } } { [\)] { 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); } } { [\\][\\] { /*char *aptr = yytext; while( *aptr ) *Current_char_p++ = *aptr++;*/ send(yytext); } [\\][\"] { /**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("'"); 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]; sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf); capa_msg(MESSAGE_ERROR,warn_msg); yy_pop_state(); } . { /*char *aptr = yytext; while( *aptr ) *Current_char_p++ = *aptr++;*/ send(yytext); } } { [\\][\\] { /*char *aptr = yytext; while( *aptr ) *Current_char_p++ = *aptr++;*/ if (dosend==1) send("%s",yytext); if (dosend==2) add_delayed("%s",yytext); } [\\][\"] { /**Current_char_p++ = '"';*/ if (dosend==1) send("%s",yytext); if (dosend==2) add_delayed("%s",yytext); } [\\]{Space}*[\n] { LLDBUG_PR2("[\\CR continue in S_STRING](%s)",yytext); /* continuation on next line */ } [\"] { /* end of a string constant -- */ yy_pop_state(); } {EndLine} { /* check for termination of string constant */ char warn_msg[WARN_MSG_LENGTH]; sprintf(warn_msg,"STRING not terminated properly, an EoL encountered in the middle.\n%s\n",String_buf); capa_msg(MESSAGE_ERROR,warn_msg); yy_pop_state(); } . { /*char *aptr = yytext; while( *aptr ) *Current_char_p++ = *aptr++;*/ if (dosend==1) send("%s",yytext); if (dosend==2) add_delayed("%s",yytext); } } [\)] { LLDBUG_PR1("[) in LET]"); Pcount--;send(yytext); } { [^\n]+$ { } {EndLine} { BEGIN S_TEXT; } } { [^\n]+$ { send(yytext); } {EndLine} { send(yytext); BEGIN S_TEXT; } } { [\\]{Space}*{EndLine} { LLDBUG_PR1("[\\EoL let ans map]"); /* continuation */ } {EndLine} { LLDBUG_PR1("[EoL END let ans map]\n"); if(Pcount == 0) BEGIN S_TEXT; send(";%s",yytext); } } { {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]"); /* implicit in LON-CAPA */ } "/OR" { LLDBUG_PR1("[OR]"); RETURN(ANS_OR); } } { ([.]*){EndLine} { /* this ignores everything until it hits an EoL */ LLDBUG_PRL2("[ skip \'%s\' until EoL]\n",yytext); BEGIN S_TEXT; } } { ^{Spaces}"/WHILE"[^\n]*{EndLine} { Wcount++; LLDBUG_PRL2("[SkipWHILE /WHILE ]\n",Wcount); } ^{Spaces}"/ENDWHILE"[^\n]*{EndLine} { if(Wcount==0) { LLDBUG_PRL2("[SkipWHILE->/ENDWHILE ]\n",Wcount); BEGIN S_TEXT; } else { Wcount--; LLDBUG_PRL2("[SkipWHILE /ENDWHILE ]\n",Wcount); } } {EndLine} { LLDBUG_PRL1("[SkipWHILE a CR]\n"); } [^\n]*$ { LLDBUG_PRL2("[SkipWHILE anything ]",Wcount); } } { ^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n"); BEGIN S_TEXT; puts("\n
\n"); end_mode(); } .*|{EndLine} { send(yytext); } } %% /* ========================================================================================== */ extern void begin_while_skip() { Wcount=0; While_idx--; /* while is FALSE, pop it out from stack */ BEGIN S_WHILE_SKIP; } extern void begin_next_line() { BEGIN S_NEXT_LINE; } extern void begin_var() { BEGIN S_VARIABLE; } extern void begin_let() { BEGIN S_LET; } extern void begin_def() { BEGIN S_DEFINE; } extern void begin_ans() { BEGIN S_ANSWER; } extern void begin_map() { BEGIN S_MAP; } extern void begin_ignore() { BEGIN S_IGNORE; } extern void begin_text() { BEGIN S_TEXT; } extern void begin_question() { LLDBUG_PR1("[]"); IFcount = 0; While_idx=0; /* initialize some stacks */ End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; } extern void end_problemset() { End_of_input = 0; YY_FLUSH_BUFFER; BEGIN S_TEXT; } /* ========================================================================================== */ #define NUM_KEY 2 int match_keyword(key) char *key; { char *keyword[NUM_KEY] = {"/DIS", "/DIR" }; int i; for(i=0;i < NUM_KEY; i++) { if( !strncmp(keyword[i], key, 4) ) { return (1); } } return (0); } int match_functionid(key) char *key; { char *keyword[NUM_KEY] = {"/DIS", "/DIR" }; int i; for(i=0;i < NUM_KEY; i++) { if( !strncmp(keyword[i], key, 4) ) { return (1); } } return (0); } /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ void init_funcstack() { int ii; for(ii=0;ii>\n"); if (!Lexi_line) { /* was startup */ for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) { /* for(ii=0;ii= MAX_INCLUDE_DEPTH ) { sprintf(warn_msg,"Includes nested too deeply" ); capa_msg(MESSAGE_ERROR,warn_msg); return; } include_stack[include_stack_ptr++] = YY_CURRENT_BUFFER; yyin = fopen( fname, "r" ); yy_switch_to_buffer( yy_create_buffer( yyin, YY_BUF_SIZE ) ); } void parse_filename(char *line) { char *start, fname[MAX_BUFFER_SIZE], warn_msg[WARN_MSG_LENGTH]; int ii,len; start = index(line, '\"'); /*** hpux complained */ if( start == NULL ) { sprintf(warn_msg,"/IMP was not given a filename.\n"); capa_msg(MESSAGE_ERROR,warn_msg); return; } start++; len = strlen(start) - 1; ii = 0; while( start[ii] != '\"' ) fname[ii++] = start[ii]; fname[ii] = 0; LLDBUG_PR2("[parse_filename<%s>]\n",fname); change_file(fname); } void parse_import_id(char *line) { char fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH]; int ii, dup_open; Symbol *symb_p; int no_error = 0; ii = 0; while( line[ii] != '\0' && line[ii] != ' ' && line[ii] != '\n' && line[ii] != '\t' ) fname[ii++] = line[ii]; fname[ii] = 0; LLDBUG_PR2("[parse_import_id<%s>]\n",fname); /*symb_p = find_identifier(fname);*/ switch (symb_p->s_type) { case IDENTIFIER: sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname); capa_msg(MESSAGE_ERROR,warn_msg); break; case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT: sprintf(warn_msg,"var cannot be a number.\n"); capa_msg(MESSAGE_ERROR,warn_msg); break; case S_VAR: case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str); no_error = 1; break; } if( no_error ) change_file(fname); } #else void parse_filename(char *line) { char *start, fname[QUARTER_K], warn_msg[WARN_MSG_LENGTH]; int ii, len, dup_open; /* printf("IMPORT %s\n", line); */ start = index(line, '\"'); /*** hpux complained */ if( start != NULL ) { start++; len = strlen(start) - 1; ii = 0; while( start[ii] != '\"' ) { fname[ii] = start[ii]; ii++; } fname[ii] = 0; LLDBUG_PR2("[parse_filename<%s>]\n",fname); if(Input_idx < (MAX_OPENED_FILE -1)) { dup_open = 0; /* -- no need to check duplicated opening a file for(ii=0;ii]\n",fname); /*symb_p = find_identifier(fname);*/ switch (symb_p->s_type) { case IDENTIFIER: sprintf(warn_msg,"/IMP %s, var is not defined.\n", fname); capa_msg(MESSAGE_ERROR,warn_msg); break; case I_VAR: case I_CONSTANT: case R_VAR: case R_CONSTANT: sprintf(warn_msg,"var cannot be a number.\n"); capa_msg(MESSAGE_ERROR,warn_msg); break; case S_VAR: case S_CONSTANT: sprintf(fname,"%s",symb_p->s_str); no_error = 1; break; } if( no_error ) { if(Input_idx < (MAX_OPENED_FILE -1) ) { dup_open = 0; /* no need to check duplicated opening a file for(ii=0;iiDynamic_buf_max) { char *temp_text; Dynamic_buf_max=(Dynamic_buf_cur+len)*2; temp_text=(char*)capa_malloc(sizeof(char),Dynamic_buf_max); strncpy(temp_text,Dynamic_buf,Dynamic_buf_max); free(Dynamic_buf); Dynamic_buf=temp_text; } for(ii=0;ii>\n"); } out_of_char = 0; if ( Lexi_buf[Input_idx] == NULL ) { Lexi_buf[Input_idx] = (char *)capa_malloc(sizeof(char)*LEX_BUFLEN+1,1); out_of_char=1; } else { if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) { /* test if the line buffer is empty or at the end */ out_of_char=1; } } if( out_of_char ) { if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) { /* read in one line */ LIDBUG_PR2("<>\n",Input_idx); if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { LIDBUG_PR2("<>\n",Input_idx); fclose(Input_stream[Input_idx]); capa_mfree((char *)Lexi_buf[Input_idx]); Lexi_buf[Input_idx] = NULL; Input_idx--; yyin = Input_stream[Input_idx]; /* (Lexi_pos[Input_idx])++; */ buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; *result = 1; } else { *result = YY_NULL; /* End of File */ } } else { /* successfully read in one line */ leng = strlen(Lexi_buf[Input_idx]); LIDBUG_PR3("<>\n", leng,Input_idx); Lexi_pos[Input_idx] = 0; Lexi_line++; Current_line[Input_idx]++; (Lexi_pos[Input_idx])++; buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; /* need to take care of return continuation conditions */ /* so, we return to one-char-at-a-time approach */ /* for(ii=0;ii>\n",Input_idx); */ (Lexi_pos[Input_idx])++; buf[0] = Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1]; *result = 1; } if (Stop_Parser==1) *result = YY_NULL; } int capa_eof() { #ifdef AVOIDYYINPUT if ( --include_stack_ptr < 0 ) yyterminate(); else { yy_delete_buffer( YY_CURRENT_BUFFER ); yy_switch_to_buffer(include_stack[include_stack_ptr]); } #else if(Input_idx == 0) { fclose(Input_stream[Input_idx]); capa_mfree((char *)Lexi_buf[Input_idx]); /*free_problems(LexiProblem_p);*/ LexiProblem_p=NULL; /* printf("\nCAPA EOF\n"); fflush(stdout); */ } end_mode(); return (0); #endif /*AVOIDYYINPUT*/ } /* ------------ */ /* =========================================================== */