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