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