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