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