File:
[LON-CAPA] /
loncom /
homework /
CAPA-converter /
capaLexerDef.flex
Revision
1.21:
download - view:
text,
annotated -
select for diffs
Thu Sep 12 15:54:06 2002 UTC (22 years, 3 months ago) by
albertel
Branches:
MAIN
CVS tags:
version_2_9_X,
version_2_9_99_0,
version_2_9_1,
version_2_9_0,
version_2_8_X,
version_2_8_99_1,
version_2_8_99_0,
version_2_8_2,
version_2_8_1,
version_2_8_0,
version_2_7_X,
version_2_7_99_1,
version_2_7_99_0,
version_2_7_1,
version_2_7_0,
version_2_6_X,
version_2_6_99_1,
version_2_6_99_0,
version_2_6_3,
version_2_6_2,
version_2_6_1,
version_2_6_0,
version_2_5_X,
version_2_5_99_1,
version_2_5_99_0,
version_2_5_2,
version_2_5_1,
version_2_5_0,
version_2_4_X,
version_2_4_99_0,
version_2_4_2,
version_2_4_1,
version_2_4_0,
version_2_3_X,
version_2_3_99_0,
version_2_3_2,
version_2_3_1,
version_2_3_0,
version_2_2_X,
version_2_2_99_1,
version_2_2_99_0,
version_2_2_2,
version_2_2_1,
version_2_2_0,
version_2_1_X,
version_2_1_99_3,
version_2_1_99_2,
version_2_1_99_1,
version_2_1_99_0,
version_2_1_3,
version_2_1_2,
version_2_1_1,
version_2_1_0,
version_2_12_X,
version_2_11_X,
version_2_11_5_msu,
version_2_11_5,
version_2_11_4_uiuc,
version_2_11_4_msu,
version_2_11_4,
version_2_11_3_uiuc,
version_2_11_3_msu,
version_2_11_3,
version_2_11_2_uiuc,
version_2_11_2_msu,
version_2_11_2_educog,
version_2_11_2,
version_2_11_1,
version_2_11_0_RC3,
version_2_11_0_RC2,
version_2_11_0_RC1,
version_2_11_0,
version_2_10_X,
version_2_10_1,
version_2_10_0_RC2,
version_2_10_0_RC1,
version_2_10_0,
version_2_0_X,
version_2_0_99_1,
version_2_0_2,
version_2_0_1,
version_2_0_0,
version_1_99_3,
version_1_99_2,
version_1_99_1_tmcc,
version_1_99_1,
version_1_99_0_tmcc,
version_1_99_0,
version_1_3_X,
version_1_3_3,
version_1_3_2,
version_1_3_1,
version_1_3_0,
version_1_2_X,
version_1_2_99_1,
version_1_2_99_0,
version_1_2_1,
version_1_2_0,
version_1_1_X,
version_1_1_99_5,
version_1_1_99_4,
version_1_1_99_3,
version_1_1_99_2,
version_1_1_99_1,
version_1_1_99_0,
version_1_1_3,
version_1_1_2,
version_1_1_1,
version_1_1_0,
version_1_0_99_3,
version_1_0_99_2,
version_1_0_99_1,
version_1_0_99,
version_1_0_3,
version_1_0_2,
version_1_0_1,
version_1_0_0,
version_0_99_5,
version_0_99_4,
version_0_99_3,
version_0_99_2,
version_0_99_1,
version_0_99_0,
version_0_6_2,
version_0_6,
loncapaMITrelate_1,
language_hyphenation_merge,
language_hyphenation,
conference_2003,
bz6209-base,
bz6209,
bz5969,
bz2851,
PRINT_INCOMPLETE_base,
PRINT_INCOMPLETE,
HEAD,
GCI_3,
GCI_2,
GCI_1,
BZ5971-printing-apage,
BZ5434-fox,
BZ4492-merge,
BZ4492-feature_horizontal_radioresponse,
BZ4492-feature_Support_horizontal_radioresponse,
BZ4492-Support_horizontal_radioresponse
- From Mark Lucas,
Fixes a few things with /DIS in scripts, eval with fml,
braces around variables.
/* 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) */
/* 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 <stdio.h>
#include <stdlib.h> /* strtod(), strtol() */
#include <string.h>
#ifdef NeXT
#include <sys/file.h>
#else
#include <unistd.h> /* 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;
int EVALflag=0;
int compound_answer=0;
int essay_answer=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("<<yy_input() startup>>\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("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\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("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\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<leng;ii++) { */ \
/* buf[ii] = Lexi_buf[Input_idx][ii]; */ \
/* } */ \
/* buf[ii] = '\0'; */ \
/* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
result = 1; \
} \
} else { \
/* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\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("<<yy_input() startup>>\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("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx); \
if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) { \
LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\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("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\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<leng;ii++) { */ \
/* buf[ii] = Lexi_buf[Input_idx][ii]; */ \
/* } */ \
/* buf[ii] = '\0'; */ \
/* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */ \
result = 1; \
} \
} else { \
/* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\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
%%
<S_IGNORE>{
{EndLine} BEGIN S_IGNORE;
[^\n]*$ BEGIN S_IGNORE;
<<EOF>> {
capa_eof();
#ifndef AVOIDYYINPUT
yyterminate();
#endif
}
}
<S_COMMENT>{
{EndLine}{Spaces}"//"[^\n]*$ {LLDBUG_PRL2("[COMMENT<%s>]\n",yytext);
send("# %s\n",&yytext[2]);
}
[^\n]*{EndLine} {
send("\n"); BEGIN S_TEXT;
}
}
<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("<PRE>\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);
send("\t",NULL);
BEGIN S_HINT;
}
^{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]");
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("<numericalresponse answer=\"");
dosend=1;
firstparam=1;
compound_answer=0;
essay_answer=0;
}
^{Spaces}"/SUBJECTIVE" { LLDBUG_PRL1("[SUBJECTIVE ANSWER]");
Pcount = 0;
BEGIN S_ANSWER;
end_mode();
start_mode(MODE_ANSWER,NULL);
send("<essayresponse");
dosend=1;
firstparam=1;
compound_answer=0;
essay_answer=-1;
}
^{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<IFcount;i++) {send("\t",NULL);}
send_stream(0,"</while>");
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;i++) {send("\t",NULL);}
send_stream(0,"<while condition=\"",NULL);
send_stream(1,"while (",NULL);
new_cache();
start_cache();
}
^{Spaces}"/IF" { int i;
IFcount++;
LLDBUG_PRL2("[IF <IFcount=%d>]",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<IFcount;i++) {send("\t",NULL);}
send_stream(0,"<block condition=\"",NULL);
send_stream(1,"if (",NULL);
new_cache();
start_cache();
}
^{Spaces}"/ELSE"([^\n])* { int i;
LLDBUG_PRL2("[ELSE <IFcount=%d>]\n",IFcount);
end_mode_stream(DEFAULT_DEST,0);
for(i=1;i<IFcount;i++) {send("\t",NULL);}
send_stream(0,
"</block>\n<block condition=\"!(%s)\">",
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<IFcount;i++) {send("\t",NULL);}
send_stream(0,"</block>");
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 <IFcount=%d>]\n",IFcount);
}
"/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("<display>");
start_delayed();
}
{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);
}
<<EOF>> {
#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
}
}
<S_ENDX>{
{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);
}
}
<S_HINT,S_EXPLAIN>{
[/][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 */ send("\n\t");}
[^/\n\\]+$ {char *aptr = yytext;
send(aptr);
}
}
<S_HINT>{
{EndLine} { LLDBUG_PR1("[CR hint]");
send("\n");
change_destination(DEFAULT_DEST);
BEGIN S_TEXT;
}
}
<S_EXPLAIN>{
{EndLine} { LLDBUG_PR1("[CR explain]");
send("\n");
change_destination(DEFAULT_DEST);
BEGIN S_TEXT;
}
}
<S_HINTEXLAINX>{
{Alpha}{AlphaNum}* {send("${%s}",yytext);}
{Space}+ { }
[)] { yy_pop_state(); }
}
<S_IMPORT>{
{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;
}
}
<S_ANSWER>{
[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 (!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("<responseparam name=\"hgr\" type=\"on|off\" default=\"");
dosend=2;
}
[Tt][Oo][Ll] { LLDBUG_PR2("[tol(%s)]",yytext);
if (firstparam) {
firstparam=0;
} else {
add_delayed("\" />\n\t");
}
add_delayed("<responseparam name=\"tol\" type=\"tolerance\" description=\"Numerical Tolerance\" default=\"");
dosend=2;
}
[Ss][Ii][Gg] {
LLDBUG_PR2("[SIG(%s)]",yytext);
if (firstparam) {
firstparam=0;
} else {
add_delayed("\" />\n\t");
}
add_delayed("<responseparam name=\"sig\" type=\"int_range,0-12\" description=\"Significant Figures\" default=\"");
dosend=2;
}
[Ss][Tt][Rr] { LLDBUG_PR1("[STR]"); send("\" type=\""); dosend=1; }
[Ee][Vv][Aa][Ll] |
[Ee][Vv][Aa][Ll][Uu][Aa][Tt][Ee] { LLDBUG_PR1("[EVAL]");send("\" eval=\""); EVALflag=1; dosend=1;}
[Uu][Nn][Ii][Tt] |
[Uu][Nn][Ii][Tt][Ss] { LLDBUG_PR1("[UNIT]"); send("\" unit=\""); dosend=1;}
[Ee][Xx][Tt][Ee][Rr][Nn][Aa][Ll] { LLDBUG_PR1("[EXTERNAL]"); dosend=0; }
[Aa][Nn][Ss][Bb][Oo][Xx] { LLDBUG_PR1("[SHOW_ANS_BOX]"); dosend=0; }
[Vv][Ee][Rr][Bb][Aa][Tt][Ii][Mm] { LLDBUG_PR1("[VERBATIM]"); dosend=0; }
[Bb][Rr] { LLDBUG_PR1("[SHOW_BR]"); dosend=0; }
[Pp][Aa][Tt][Hh] { send("\" path=\""); dosend=0; }
[Cc][Aa][Ll][Cc] { send("\" calc=\""); dosend=0; }
[Ee][Xx][Pp][Ll][Aa][Ii][Nn] { LLDBUG_PR1("[EXPLAIN]"); dosend=0; }
[Hh][Ii][Nn][Tt] { LLDBUG_PR1("[HINT]"); dosend=0; }
[Tt][Rr][Yy] |
[Tt][Rr][Ii][Ee][Ss] { LLDBUG_PR1("[TRY]"); dosend=0; }
[Ww][Gg][Tt] { LLDBUG_PR1("[WGT]"); dosend=0; }
[\)] { LLDBUG_PR1("[)]"); Pcount--;
if(Pcount==0) {
BEGIN S_ANSCONTINUE;
}
if (essay_answer) {
send(">\n\t");
} else {
send("\">\n\t");
}
dosend=1;
flush_delayed();
if (firstparam!=1) send("\" />\n");
if (essay_answer) {
send(" <textfield>Enter your answer here.</textfield>\n");
} else {
send("\t<textline />\n");
}
/* Fill in Hints */
if ( !is_dest_empty(HINT_DEST) ) {
send("\t<hintgroup>\n\t<hintpart on=\"default\">\n\t<startouttext />");
end_streams(HINT_DEST,0);
HINTflag=0;
send("\t<endouttext />\n\t</hintpart>\n\t</hintgroup>\n");
}
if (essay_answer) {
send("</essayresponse>\n");
} else {
send("</numericalresponse>\n");
}
}
}
<S_VARIABLE>{
{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);
}
}
}
<S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP,S_ANSWER>{
{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 */ }
}
<S_VARIABLE,S_TRUE_FALSE_STMT,S_MAP,S_LET>{
[\"] { LLDBUG_PR1("[TF,V,LET,MAP str\" ]");
Current_char_p = String_buf;
send("'");
yy_push_state(S_STRING);
}
}
<S_ANSWER>{
[\"] { LLDBUG_PR1("[ANS str\" ]");
Current_char_p = String_buf;
yy_push_state(S_STRINGINANS);
}
}
<S_VARIABLE,S_TRUE_FALSE_STMT,S_MAP,S_ANSWER>{
[\(] { LLDBUG_PR1("[let if ans map (]");
Pcount++;
if (Pcount > 1 ) {
if (dosend==1) send(yytext);
if (dosend==2) add_delayed(yytext);
}
}
}
<S_LET>{
[\(] { LLDBUG_PR1("[let (]");
Pcount++;
send(yytext);
}
}
<S_VARIABLE>[:]{Number}+[EeFf] {
end_delayed();
send("&format(");
flush_delayed();
send(",'%s')",yytext+1);
}
<S_ANSWER>[:]{Number}+[EeFf] {
if (dosend) send("\" format=\"%s",yytext+1);
}
<S_MAP>{
[;] {
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;
}
}
<S_VARIABLE>{
"+" { send(".");}
}
<S_VARIABLE,S_TRUE_FALSE_STMT,S_LET,S_MAP>{
"==" { LLDBUG_PR1("[==]"); send(" eq "); }
"!=" { LLDBUG_PR1("[!=]"); send(" ne "); }
">" { 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); }
}
<S_VARIABLE>{
[\)] { LLDBUG_PR1("[)]");
Pcount--;
if(Pcount == 0) {
send("</display>");
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);
}
}
<S_TRUE_FALSE_STMT>{
[\)] {
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);
}
}
<S_STRING>{
[\\][\\] { /*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("%%");
}
[\'] { /* Escape single quotes so that perl 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);
}
}
<S_STRINGINANS>{
[\\][\\] { /*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);
}
}
<S_LET>[\)] { LLDBUG_PR1("[) in LET]"); Pcount--;send(yytext); }
<S_SKIP>{
[^\n]+$ { }
{EndLine} { BEGIN S_TEXT; }
}
<S_ECHO>{
[^\n]+$ { send(yytext); }
{EndLine} { send(yytext); BEGIN S_TEXT; }
}
<S_LET,S_ANSWER,S_MAP>{
[\\]{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);
}
}
<S_ANSCONTINUE>{
{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("<postanswerdate>\n\t<startouttext />\n");
end_streams(EXP_DEST,0);
EXPflag=0;
send("\t<endouttext />\n</postanswerdate>\n");
}
send("</part>\n<part>\n");
}
start_mode(MODE_ANSWER,NULL);
send("<numericalresponse answer=\"");
dosend=1;
firstparam=1;
compound_answer=0;
essay_answer=0;
}
{Spaces}{EndLine} {
/* end of answer and/or other answers */
LLDBUG_PR1("[complete an answer<EoL>]");
if ( !is_dest_empty(EXP_DEST) ) {
send("<postanswerdate>\n\t<startouttext />\n");
end_streams(EXP_DEST,0);
EXPflag=0;
send("\t<endouttext />\n</postanswerdate>\n");
}
send("</part>\n<part>\n");
BEGIN S_TEXT;
}
{Spaces} { /* Do nothing */ }
}
<S_NEXT_LINE>{
([.]*){EndLine} { /* this ignores everything until it hits an EoL */
LLDBUG_PRL2("[<S_NEXT_LINE> skip \'%s\' until EoL]\n",yytext);
BEGIN S_TEXT;
}
}
<S_WHILE_SKIP>{
^{Spaces}"/WHILE"[^\n]*{EndLine} { Wcount++;
LLDBUG_PRL2("[SkipWHILE /WHILE <Wcount=%d>]\n",Wcount);
}
^{Spaces}"/ENDWHILE"[^\n]*{EndLine} {
if(Wcount==0) {
LLDBUG_PRL2("[SkipWHILE->/ENDWHILE <Wcount=%d>]\n",Wcount);
BEGIN S_TEXT;
} else {
Wcount--;
LLDBUG_PRL2("[SkipWHILE /ENDWHILE <Wcount=%d>]\n",Wcount);
}
}
{EndLine} { LLDBUG_PRL1("[SkipWHILE a CR]\n"); }
[^\n]*$ { LLDBUG_PRL2("[SkipWHILE anything <Wcount=%d>]",Wcount); }
}
<S_VERB>{
^{Spaces}"/ENDVERB" { LLDBUG_PRL1("[END VERB]\n");
BEGIN S_TEXT;
puts("\n</PRE>\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("[<S_TEXT>]");
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<Func_idx;ii++) {
capa_mfree(FuncStack[ii].s_name);
}
Func_idx = 0;
}
/* -------------------------------------------------------------------------- */
/* GET THE NEXT CHARACTER OF THE SOURCE FILE */
/* -------------------------------------------------------------------------- */
#ifdef FLEX
int capaL_input()
#else
int /* RETURNS: next character */
input() /* ARGUMENTS: (none) */
#endif
{ /* LOCAL VARIABLES: */
static int startup=1; /* First call flag */
LLDBUG_PRL1("<<capaL_input() is called>>\n");
if (!Lexi_line) { /* was startup */
for(Input_idx=0;Input_idx < MAX_OPENED_FILE;Input_idx++) {
/* for(ii=0;ii<LEX_BUFLEN;ii++) {
Lexi_buf[Input_idx][ii]=0;
}
*/
Lexi_buf[Input_idx][0]=0;
Lexi_pos[Input_idx] = 0;
}
Input_idx = 0;
startup=0;
yyin = Input_stream[Input_idx];
}
if (!Lexi_buf[Input_idx][Lexi_pos[Input_idx]]) {
if (fgets(Lexi_buf[Input_idx],LEX_BUFLEN-1,Input_stream[Input_idx])==NULL) {
/* EOF? */
/* no use in flex
printf("capaL_input()EOF %s\n",Opened_filename[Input_idx+1]); fflush(stdout); */
return (0);
}
Lexi_pos[Input_idx] = 0;
Lexi_line++;
printf("input()(%d)\n",Lexi_line);
}
(Lexi_pos[Input_idx])++;
return ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]-1] );
}
/******************************************************************************/
/* PUSH BACK ONE CHARACTER OF THE INPUT */
/******************************************************************************/
int /* RETURNS: nothing */
capaL_unput(ch) /* ARGUMENTS: */
register int ch; /* Character to push */
{
if (ch) (Lexi_pos[Input_idx])--;
/* unput() stream cannot be re-defined */
/* unput(ch); inconsistency between YY_INPUT() and internal matched yytext */
return (0);
}
/******************************************************/
#ifndef DMALLOC
char *
strsave(char *s)
{
char *p;
if (s==NULL) {return s;}
p=capa_malloc(strlen(s)+1,1);
strcpy(p,s);
return (p);
}
#endif
/* =========================================================================== */
#ifndef DMALLOC
char *
capa_malloc(unsigned num,unsigned sz)
{
char *p;
p = calloc(num, sz);
bzero(p, num*sz); /* added Jan 21 1998 */
return (p);
}
#endif
#ifndef DMALLOC
void
capa_mfree(p) char *p;
{
free(p);
}
#endif
void
capa_msg(int type, char *p)
{ int idx, i, j;
int len;
char warn_msg[WARN_MSG_LENGTH];
char tmp_line[ONE_TWO_EIGHT];
char *tmp_str;
strcpy(warn_msg,"File: ");
idx=6;
for(i=0;i<=Input_idx;i++) {
len=strlen(Opened_filename[i]);
for(j=0;j<len;j++) {
warn_msg[idx++] = Opened_filename[i][j];
}
if(i < Input_idx) {
warn_msg[idx++]='-';
warn_msg[idx++]='>';
}
warn_msg[idx]=0;
}
switch (type) {
case MESSAGE_ERROR:
sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
len=strlen(tmp_line);
for(j=0;j<len;j++) {
warn_msg[idx++] = tmp_line[j];
}
warn_msg[idx]=0;
append_error(warn_msg); append_error(p);
break;
case MESSAGE_WARN:
default:
sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);
len=strlen(tmp_line);
for(j=0;j<len;j++) {
warn_msg[idx++] = tmp_line[j];
}
warn_msg[idx]=0;
j = strlen(warn_msg);
len = strlen(p);
tmp_str = (char *)capa_malloc(len+j+1,1);
for(i=0;i<j;i++) {
tmp_str[i]=warn_msg[i];
}
for(i=j;i<j+len;i++) {
tmp_str[i] = p[i-j];
}
append_warn(type,tmp_str);
capa_mfree(tmp_str);
break;
}
}
/* ======================================================================== */
void
capa_warn_header(int type)
{
int idx, i, j;
int len;
char warn_msg[WARN_MSG_LENGTH];
char tmp_line[ONE_TWO_EIGHT];
strcpy(warn_msg,"File: ");
idx=6;
for(i=0;i<=Input_idx;i++) {
len=strlen(Opened_filename[i]);
for(j=0;j<len;j++) {
warn_msg[idx++] = Opened_filename[i][j];
}
if(i < Input_idx) {
warn_msg[idx++]='-';
warn_msg[idx++]='>';
}
warn_msg[idx]=0;
}
switch (type) {
case MESSAGE_ERROR:
sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);
break;
case MESSAGE_WARN:
sprintf(tmp_line,", Line %d: WARNING:", Current_line[Input_idx]);break;
default:
sprintf(tmp_line,", Line %d: ERROR:", Current_line[Input_idx]);break;
}
len=strlen(tmp_line);
for(j=0;j<len;j++) {
warn_msg[idx++] = tmp_line[j];
}
warn_msg[idx]=0;
append_error(warn_msg);
}
/* --------------------------------------------------------------------------- */
#ifdef AVOIDYYINPUT
void change_file(char *fname)
{
char warn_msg[WARN_MSG_LENGTH];
if ( include_stack_ptr >= 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<Input_idx;ii++) {
if(strcmp(Opened_filename[ii],fname)==0) {
dup_open =1;
}
}
*/
if( !dup_open ) {
Input_idx++;
Input_stream[Input_idx]=fopen(fname,"r");
sprintf(Opened_filename[Input_idx], "%s",fname);
Current_line[Input_idx] = 0;
} else {
/*
sprintf(warn_msg,"/IMP \"%s\", import file has already been imported.\n",fname);
capa_msg(MESSAGE_WARN,warn_msg);
*/
Input_idx++;
Input_stream[Input_idx]=fopen(fname,"r");
sprintf(Opened_filename[Input_idx], "%s",fname);
Current_line[Input_idx] = 0;
}
} else {
sprintf(warn_msg,"/IMP more the %d levels deep ignoring further imports.\n",MAX_OPENED_FILE-1);
capa_msg(MESSAGE_WARN,warn_msg);
}
} else {
sprintf(warn_msg,"%s, is not a valid file name.\n",line);
capa_msg(MESSAGE_ERROR,warn_msg);
}
}
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]; 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 ) {
if(Input_idx < (MAX_OPENED_FILE -1) ) {
dup_open = 0;
/* no need to check duplicated opening a file
for(ii=0;ii<Input_idx;ii++) {
if(strcmp(Opened_filename[ii],fname)==0) dup_open =1;
}
*/
if( !dup_open ) {
Input_idx++;
Input_stream[Input_idx]=fopen(fname,"r");
sprintf(Opened_filename[Input_idx], "%s",fname);
Current_line[Input_idx] = 0;
} else {
/* NO warning on duplicated open a file
sprintf(warn_msg,"/IMP \"%s\", file has already been imported.\n", fname);
capa_msg(MESSAGE_WARN,warn_msg);
*/
Input_idx++;
Input_stream[Input_idx]=fopen(fname,"r");
sprintf(Opened_filename[Input_idx], "%s",fname);
Current_line[Input_idx] = 0;
}
} else {
sprintf(warn_msg,"/IMP , too many files has been imported. The maximum is %d files.\n",
MAX_OPENED_FILE-1);
capa_msg(MESSAGE_WARN,warn_msg);
}
}
}
#endif /*AVOIDYYINPUT*/
void append_dynamic_buf(new_str) char *new_str;
{
int ii,len;
if(new_str==NULL) return;
len=strlen(new_str);
#ifdef LEX_DBUG
printf("before: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
len,Dynamic_buf_cur,Dynamic_buf_max);
#endif /* LEX_DBUG */
if (Dynamic_buf_cur+len+1>Dynamic_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<len;ii++) {
Dynamic_buf[Dynamic_buf_cur+ii]=new_str[ii];
}
Dynamic_buf_cur += len;
Dynamic_buf[Dynamic_buf_cur+1]='\0';
#ifdef LEX_DBUG
printf("after: len %d; Dynamic_buf_cur %d; Dynamic_buf_max %d\n",
len,Dynamic_buf_cur,Dynamic_buf_max);
printf("Dyn_buf %s; added %s\n",Dynamic_buf,new_str);
#endif /* LEX_DBUG */
}
char* parser_status()
{
char *buf,small[SMALL_LINE_BUFFER];
int i,j,totlen=0,len,idx=0;
for(i=0;i<=Input_idx;i++) totlen+=strlen(Opened_filename[i])+6;
buf=capa_malloc(sizeof(char),totlen);
for(i=0;i<=Input_idx;i++) {
len=strlen(Opened_filename[i]);
for(j=0;j<len;j++) buf[idx++] = Opened_filename[i][j];
buf[idx++] = ':';
sprintf(small,"%d",Current_line[i]);
len=strlen(small);
for(j=0;j<len;j++) buf[idx++] = small[j];
buf[idx++]=' ';
buf[idx]='\0';
}
return buf;
}
void yyfatalerror(char*msg)
{
char warn_msg[WARN_MSG_LENGTH];
sprintf(warn_msg,"Invalid character[\'%s\']\n",yytext);
capa_msg(MESSAGE_ERROR,warn_msg);
capa_msg(MESSAGE_ERROR,msg);
}
void yyerror(char* msg)
{
char warn_msg[WARN_MSG_LENGTH];
sprintf(warn_msg,"%s\n",msg);
capa_msg(MESSAGE_ERROR,warn_msg);
}
void newyy_input (char *buf,int *result,int 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("<<yy_input() startup>>\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("<<yy_input() fgets() returns NULL, input index=%d>>\n",Input_idx);
if( (Input_idx > 0) && ( Lexi_buf[Input_idx][Lexi_pos[Input_idx]] == '\0') ) {
LIDBUG_PR2("<<yy_input() close an input stream, input index=%d>>\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("<<yy_input() read into buffer a line(leng=%d), input index=%d>>\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<leng;ii++) { */
/* buf[ii] = Lexi_buf[Input_idx][ii]; */
/* } */
/* buf[ii] = '\0'; */
/* printf("YY_INPUT()(Lexi_line=%d,max size=%d)(%c)",Lexi_line,max_size,buf[0]); */
*result = 1;
}
} else {
/* LIDBUG_PR2("<<yy_input() increase Lexi_pos, input index=%d>>\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*/
}
/* ------------ */
/* =========================================================== */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>