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