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