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