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