Annotation of loncom/homework/CAPA-converter/capaGrammarDef.y, revision 1.1
1.1 ! albertel 1: /* ========================================================================== */
! 2: /* capaGrammarDef.y created by Isaac Tsai */
! 3: /* 1998, 1999 copyrighted by Isaac Tsai */
! 4: /* no longer there is a length constrain on string concatenation July 13 1998 */
! 5: /* /RMAP() function */
! 6: /* TODO: new mechanism to collect answer informations */
! 7: /*****************************************************************************/
! 8: /*****************************************************************************/
! 9: /*****************************************************************************/
! 10: %{
! 11: #include <stdio.h>
! 12: #include <ctype.h>
! 13: #include <string.h>
! 14: #include <math.h>
! 15: #include "capaParser.h" /* _symbol structure def */
! 16: #include "capaCommon.h"
! 17: #include "capaFunction.h"
! 18: #include "capaRQO.h"
! 19: #ifdef __hpux
! 20: #include <stdlib.h>
! 21: #include <alloca.h>
! 22: #endif
! 23:
! 24: #ifdef YACC_DBUG
! 25: #define YYDBUG_PR1(xx) { printf(xx); fflush(stdout); }
! 26: #define YYDBUG_PR2(xx,yy) { printf(xx,yy); fflush(stdout); }
! 27: #define YYDBUG_PR3(xx,yy,zz) { printf(xx,yy,zz); fflush(stdout); }
! 28: #define YYDBUG_PR4(xx,yy,zz,aa) { printf(xx,yy,zz,aa); fflush(stdout); }
! 29: #define YYDBUG_SYM(xx) { switch((xx)->s_type) { \
! 30: case IDENTIFIER: \
! 31: printf("ID(%s)\n",(xx)->s_name); break; \
! 32: case I_VAR: case I_CONSTANT: \
! 33: printf("INT(%d)\n",(xx)->s_int); break; \
! 34: case R_VAR: case R_CONSTANT: \
! 35: printf("REAL(%.16g)\n",(xx)->s_real); break; \
! 36: case S_VAR: case S_CONSTANT: \
! 37: printf("STR(%s)\n",(xx)->s_str); break; \
! 38: } }
! 39: #else /* YACC_DBUG */
! 40: #define YYDBUG_PR1(xx) { }
! 41: #define YYDBUG_PR2(xx,yy) { }
! 42: #define YYDBUG_PR3(xx,yy,zz) { }
! 43: #define YYDBUG_PR4(xx,yy,zz,aa) { }
! 44: #define YYDBUG_SYM(xx) { }
! 45: #endif /* YACC_DBUG */
! 46:
! 47: int yylex();
! 48: void yyerror(char*);
! 49: void free_calc_expr(Symbol*);
! 50: void assign_pts (Symbol *, Symbol *, Symbol *);
! 51: /******************************************************************************/
! 52: /* GLOBAL VARIABLES */
! 53: /******************************************************************************/
! 54: int Lexi_qnum;
! 55:
! 56: extern int Lexi_line;
! 57: extern int Lexi_pos[MAX_OPENED_FILE];
! 58: extern char Opened_filename[MAX_OPENED_FILE][QUARTER_K];
! 59: extern int Input_idx;
! 60: int Current_line[MAX_OPENED_FILE];
! 61: extern int Func_idx;
! 62: extern Symbol FuncStack[MAX_FUNC_NEST];
! 63: extern int IFstatus[MAX_FUNC_NEST];
! 64: extern int IFcount;
! 65: /*extern int gUnitError;*/
! 66:
! 67: int Parsemode_f; /* Parser mode flag */
! 68:
! 69: Problem_t *FirstProblem_p; /* First problem */
! 70: Problem_t *LastProblem_p; /* Last problem */
! 71: Problem_t *LexiProblem_p; /* Current problem */
! 72: char *EndText_p;
! 73: char *StartText_p;
! 74: char *ErrorMsg_p;
! 75: int ErrorMsg_count;
! 76: WarnMsg_t *WarnMsg_p;
! 77: int WarnMsg_count;
! 78: int Answer_infospec;
! 79: void (*Status_Func)();
! 80: AnswerInfo_t CurrAnsInfo;
! 81:
! 82: RandQO_t *QuestionOrder;
! 83: PointsList_t *CurrPtsList;
! 84: PointsList_t *LastPtsList;
! 85:
! 86:
! 87:
! 88:
! 89: #ifdef YYSTYPE
! 90: #undef YYSTYPE
! 91: #endif
! 92: #define YYSTYPE Symbol_p
! 93:
! 94:
! 95: #define ADD_op 1
! 96: #define SUB_op 2
! 97: #define MUL_op 3
! 98: #define DIV_op 4
! 99: #define IDIV_op 5
! 100: #define NOT_DEFINED_op 9
! 101:
! 102: /*#define yyerror printf*/
! 103:
! 104: %}
! 105: %token NEW_ID
! 106: %token I_CONSTANT R_CONSTANT S_CONSTANT
! 107: %token I_VAR R_VAR S_VAR
! 108:
! 109: %token IDENTIFIER FUNCTION_ID ARRAY_ID
! 110: %token HINT_LINE EXPLAIN_LINE TEXT_LINE IMPORT_LINE
! 111: %token CAPA_LET CAPA_DEF CAPA_DIS CAPA_END CAPA_VAR
! 112: %token CAPA_ESC CAPA_MAP CAPA_FIG CAPA_ANS CAPA_RMAP
! 113: %token CAPA_IF CAPA_ELSE CAPA_ENDIF CAPA_SUBJ CAPA_WHILE
! 114: %token CAPA_ENDWHILE CAPA_START
! 115: %token ANS_AND ANS_BOX_SHOW ANS_CALC ANS_CI ANS_COMPARE ANS_CS
! 116: %token ANS_EVAL ANS_EXPLAIN ANS_EXTERNAL ANS_FMT
! 117: %token ANS_FORMULA ANS_HINT ANS_MC ANS_MINUS
! 118: %token ANS_OFF ANS_ON ANS_OR ANS_ORDERED
! 119: %token ANS_PATH ANS_PCREDIT ANS_PLUS ANS_RANGE
! 120: %token ANS_SHOW_BR ANS_SIG ANS_TOLERANCE ANS_TRY ANS_TYPE
! 121: %token ANS_UNFMT ANS_UNIT ANS_VERBATIM ANS_WEIGHT
! 122: %token VAR_RANGE VERBATIM
! 123: %token SLASH FORMAT
! 124: %token EQ_op NE_op GT_op GE_op LT_op LE_op AND_op OR_op EoL
! 125:
! 126: %start prob_set
! 127:
! 128: %%
! 129:
! 130: prob_set : startQ questions CAPA_END { YYDBUG_PR1(" prob_set := startQ questions END\n\n"); }
! 131: ;
! 132:
! 133: questions : a_line { YYDBUG_PR1(" questions <= a_line");
! 134: if (Status_Func != NULL) Status_Func();
! 135: }
! 136: | questions a_line { YYDBUG_PR1(" questions <= questions a_line");
! 137: if (Status_Func != NULL) Status_Func();
! 138: }
! 139: ;
! 140:
! 141: startL : CAPA_LET { YYDBUG_PR1("\n begin_let::"); }
! 142: ;
! 143:
! 144: startV : CAPA_VAR { YYDBUG_PR1(" begin_var"); }
! 145: ;
! 146:
! 147: startA : CAPA_ANS { YYDBUG_PR1("\n START ANSWER(/ANS)::\n");
! 148: init_answerinfo();
! 149: }
! 150: ;
! 151:
! 152: startSA : CAPA_SUBJ { YYDBUG_PR1("\n START SUBJECT ANSWER(/SUBJECTIVE)::\n");
! 153: init_answerinfo();
! 154: }
! 155: ;
! 156:
! 157: startM : CAPA_MAP { YYDBUG_PR1("\n begin_map::"); }
! 158: ;
! 159:
! 160: startR : CAPA_RMAP { YYDBUG_PR1("\n begin_rmap::"); }
! 161: ;
! 162:
! 163: ans_and_op : ANS_AND { add_answer_cnt(ANS_AND); YYDBUG_PR1("(AND ,new an answer info)"); }
! 164: ;
! 165:
! 166: ans_or_op : ANS_OR { add_answer_cnt(ANS_OR); YYDBUG_PR1("(OR ,new an answer info)"); }
! 167: ;
! 168:
! 169: a_line : startL statement EoL { YYDBUG_PR1(" a_line <= startL statement CR\n"); }
! 170: | CAPA_END { YYDBUG_PR1(" a_line <= END\n\n"); }
! 171: | CAPA_START { YYDBUG_PR1(" aline <= CAPA_START\n");
! 172: start_question_over();
! 173: }
! 174: | HINT_LINE { append_hint($1->s_str);
! 175: YYDBUG_PR2(" a_line <= Hint_line(%s)\n",$1->s_str);
! 176: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 177: }
! 178: | EXPLAIN_LINE { append_explain($1->s_str);
! 179: YYDBUG_PR2(" a_line <= Explain_line(%s)\n",$1->s_str);
! 180: capa_mfree($1->s_str); capa_mfree((char*)$1);
! 181: }
! 182: | IMPORT_LINE EoL { YYDBUG_PR1(" a_line <= import_line CR\n"); }
! 183: | q_text EoL { YYDBUG_PR1(" a_line <= Qtext CR\n"); append_text("\n"); }
! 184: | answer_expr { YYDBUG_PR1(" a_line <= answer_expr (init a new prob) CR\n");
! 185: init_new_prob(); }
! 186: | if_expr { YYDBUG_PR1(" a_line <= if_expr\n"); }
! 187: | while_expr { YYDBUG_PR1(" a_line <= while_expr\n"); }
! 188: | map_expr EoL { YYDBUG_PR1(" a_line <= map_expr CR\n"); }
! 189: | EoL { YYDBUG_PR1(" a_line <= (CR)\n"); }
! 190: | VERBATIM { YYDBUG_PR1(" a_line <= (VERBATIM)\n");
! 191: switch(Parsemode_f) {
! 192: case TeX_MODE: append_text("\\begin{verbatim}");
! 193: break;
! 194: case HTML_MODE: append_text("<PRE>");
! 195: break;
! 196: }
! 197: append_text($1->s_str);
! 198: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 199: switch(Parsemode_f) {
! 200: case TeX_MODE: append_text("\\end{verbatim}\n");
! 201: break;
! 202: case HTML_MODE: append_text("</PRE>\n");
! 203: break;
! 204: }
! 205: }
! 206: | error EoL { char warn_msg[WARN_MSG_LENGTH];
! 207: YYDBUG_PR1(" a_line := ERROR(CR)\n");
! 208: sprintf(warn_msg," Question %d: Syntax error.\n", Lexi_qnum+1);
! 209: capa_msg(MESSAGE_ERROR,warn_msg);
! 210: begin_text();
! 211: }
! 212:
! 213: ;
! 214:
! 215: statement : IDENTIFIER '=' calc_expr
! 216: { char warn_msg[WARN_MSG_LENGTH];
! 217:
! 218: if ( $1 != $3 ) { /* /LET a = a */
! 219: switch($1->s_type) {
! 220: case IDENTIFIER:
! 221: case I_VAR: case I_CONSTANT:
! 222: case R_VAR: case R_CONSTANT: break;
! 223: case S_VAR: case S_CONSTANT:
! 224: capa_mfree($1->s_str); $1->s_str = NULL; break;
! 225: default: break;
! 226: }
! 227: switch($3->s_type) {
! 228: case IDENTIFIER:
! 229: sprintf(warn_msg,"var \"%s\" not defined before use.\n",$3->s_name);
! 230: capa_msg(MESSAGE_ERROR,warn_msg);
! 231: break;
! 232: case I_VAR: case I_CONSTANT:
! 233: $1->s_type = I_VAR;
! 234: $1->s_int = $3->s_int;
! 235: break;
! 236: case R_VAR: case R_CONSTANT:
! 237: $1->s_type = R_VAR;
! 238: $1->s_real = $3->s_real;
! 239: break;
! 240: case S_VAR: case S_CONSTANT:
! 241: $1->s_type = S_VAR;
! 242: $1->s_str = strsave($3->s_str);
! 243: break;
! 244: }
! 245: YYDBUG_PR1(" statement <= ID = calc_expr:: "); YYDBUG_SYM($3);
! 246: free_calc_expr($3);
! 247: }
! 248: }
! 249: | ARRAY_ID '[' calc_expr ']' '=' calc_expr
! 250: { Symbol *s_p;
! 251: char warn_msg[WARN_MSG_LENGTH];
! 252:
! 253: s_p = get_array_symbol($1,$3,1);
! 254: switch(s_p->s_type) {
! 255: case IDENTIFIER:
! 256: case I_VAR: case I_CONSTANT:
! 257: case R_VAR: case R_CONSTANT: break;
! 258: case S_VAR: case S_CONSTANT:
! 259: capa_mfree(s_p->s_str); s_p->s_str = NULL; break;
! 260: default: break;
! 261: }
! 262: switch($6->s_type) {
! 263: case IDENTIFIER:
! 264: sprintf(warn_msg,"var \"%s\" not defined before use.\n",$6->s_name);
! 265: capa_msg(MESSAGE_ERROR,warn_msg);
! 266: break;
! 267: case I_VAR: case I_CONSTANT:
! 268: s_p->s_type = I_VAR;
! 269: s_p->s_int = $6->s_int;
! 270: break;
! 271: case R_VAR: case R_CONSTANT:
! 272: s_p->s_type = R_VAR;
! 273: s_p->s_real = $6->s_real;
! 274: break;
! 275: case S_VAR: case S_CONSTANT:
! 276: s_p->s_type = S_VAR;
! 277: s_p->s_str = strsave($6->s_str);
! 278: break;
! 279: }
! 280: free_calc_expr($6);
! 281: }
! 282: ;
! 283:
! 284:
! 285: q_text : TEXT_LINE { append_text($1->s_str);
! 286: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 287: }
! 288: | var_expr { }
! 289: | q_text var_expr { }
! 290: | q_text TEXT_LINE { append_text($2->s_str);
! 291: capa_mfree($2->s_str); capa_mfree((char *)$2);
! 292: }
! 293: ;
! 294:
! 295: if_expr : CAPA_IF '(' calc_expr ')'
! 296: { int leng=0; /* begin_next_line(); no use, can be get rid of */
! 297: YYDBUG_PR2("(IF expr <IFcount=%d>)\n",IFcount);
! 298: switch($3->s_type) {
! 299: case IDENTIFIER:
! 300: IFstatus[IFcount] = IF_FALSE;
! 301: begin_next_line();
! 302: break;
! 303: case I_CONSTANT: case I_VAR:
! 304: if(!$3->s_int) {
! 305: IFstatus[IFcount] = IF_FALSE;
! 306: begin_if_skip();
! 307: } else {
! 308: IFstatus[IFcount] = IF_TRUE;
! 309: begin_next_line();
! 310: }
! 311: break;
! 312: case R_CONSTANT: case R_VAR:
! 313: if($3->s_real == 0.0) {
! 314: IFstatus[IFcount] = IF_FALSE;
! 315: begin_if_skip();
! 316: }else{
! 317: IFstatus[IFcount] = IF_TRUE;
! 318: begin_next_line();
! 319: }
! 320: break;
! 321: case S_CONSTANT:
! 322: if ( $3->s_str) {
! 323: leng = strlen($3->s_str);
! 324: capa_mfree($3->s_str);
! 325: }
! 326: if(leng == 0) {
! 327: IFstatus[IFcount] = IF_FALSE;
! 328: begin_if_skip();
! 329: }else{
! 330: IFstatus[IFcount] = IF_TRUE;
! 331: begin_next_line();
! 332: }
! 333: break;
! 334: case S_VAR:
! 335: if ( $3->s_str) {
! 336: leng = strlen($3->s_str);
! 337: capa_mfree($3->s_str);
! 338: }
! 339: if(leng == 0) {
! 340: IFstatus[IFcount] = IF_FALSE;
! 341: begin_if_skip();
! 342: }else{
! 343: IFstatus[IFcount] = IF_TRUE;
! 344: begin_next_line();
! 345: }
! 346: break;
! 347: }
! 348: capa_mfree((char*)$3);
! 349: }
! 350: ;
! 351:
! 352: while_expr : CAPA_WHILE '(' calc_expr ')'
! 353: {
! 354: int leng;
! 355: YYDBUG_PR1("(WHILE expr)\n");
! 356: switch($3->s_type) {
! 357: case IDENTIFIER: /* undefined identifier regarded as false */
! 358: begin_while_skip();
! 359: break;
! 360: case I_CONSTANT: case I_VAR:
! 361: if(!$3->s_int) {
! 362: begin_while_skip();
! 363: } else {
! 364: begin_next_line(); /* skip to EoL and begin S_TEXT */
! 365: }
! 366: break;
! 367: case R_CONSTANT: case R_VAR:
! 368: if($3->s_real == 0.0) {
! 369: begin_while_skip();
! 370: }else{
! 371: begin_next_line(); /* skip to EoL and begin S_TEXT */
! 372: }
! 373: break;
! 374: case S_CONSTANT:
! 375: leng = strlen($3->s_str);
! 376: capa_mfree($3->s_str);
! 377: if(leng == 0) {
! 378: begin_while_skip();
! 379: }else{
! 380: begin_next_line(); /* skip to EoL and begin S_TEXT */
! 381: }
! 382: break;
! 383: case S_VAR:
! 384: leng = strlen($3->s_str);
! 385: if(leng == 0) {
! 386: begin_while_skip();
! 387: }else{
! 388: begin_next_line(); /* skip to EoL and begin S_TEXT */
! 389: }
! 390: break;
! 391: }
! 392: capa_mfree((char*)$3);
! 393: }
! 394: ;
! 395:
! 396: var_expr : startV '(' formated_ans ')'
! 397: { display_var( $3 ) ; }
! 398: ;
! 399:
! 400: answer_expr : answer_spec { finish_answer_info();
! 401: }
! 402: | answer_expr ans_and_op answer_spec
! 403: { finish_answer_info();
! 404: YYDBUG_PR1(" answer_expr <-- AND answers (copy answerinfo)\n"); }
! 405: | answer_expr ans_or_op answer_spec
! 406: { finish_answer_info();
! 407: YYDBUG_PR1(" answer_expr <-- OR answers (copy answerinfo)\n");
! 408: } | startSA '(' answer_info ')'
! 409: { YYDBUG_PR1("\n subjective answer\n");
! 410: finish_answer_info();
! 411: LexiProblem_p->ans_type = ANSWER_IS_SUBJECTIVE;
! 412: }
! 413: | startSA '(' ')'
! 414: { YYDBUG_PR1("\n subjective answer\n");
! 415: finish_answer_info();
! 416: LexiProblem_p->ans_type = ANSWER_IS_SUBJECTIVE;
! 417: }
! 418:
! 419: ;
! 420:
! 421: answer_spec : startA '(' formated_ans ')'
! 422: { assign_answer( $3 );
! 423: YYDBUG_PR1("\nASSIGN Answer\n");
! 424: }
! 425: | startA '(' formated_ans ',' answer_info ')'
! 426: { assign_answer( $3 );
! 427: YYDBUG_PR1("\nASSIGN Answers + Answer Info\n");
! 428: }
! 429: ;
! 430:
! 431: answer_info : ans_infospec
! 432: | answer_info ',' ans_infospec
! 433: ;
! 434:
! 435:
! 436: ans_infospec : ANS_TOLERANCE '=' a_number
! 437: { YYDBUG_PR1(" ans_infospec:= TOL=a_number");
! 438: assign_tolerance(TOL_ABSOLUTE,$3);
! 439: }
! 440: | ANS_TOLERANCE '=' IDENTIFIER
! 441: { assign_tolerance(TOL_ABSOLUTE,$3);
! 442: }
! 443: | ANS_TOLERANCE '=' IDENTIFIER '%'
! 444: { assign_tolerance(TOL_PERCENTAGE,$3);
! 445: }
! 446: | ANS_TOLERANCE '=' a_number '%'
! 447: { assign_tolerance(TOL_PERCENTAGE,$3);
! 448: }
! 449: | ANS_COMPARE '=' answer_comp { }
! 450: | ANS_SIG '=' answer_sig { }
! 451: | ANS_WEIGHT '=' an_integer
! 452: { assign_weight( $3 );
! 453: }
! 454: | ANS_WEIGHT '=' IDENTIFIER
! 455: { assign_weight( $3 );
! 456: }
! 457: | ANS_HINT '=' an_integer { assign_hint( $3 );
! 458: }
! 459: | ANS_HINT '=' IDENTIFIER { assign_hint( $3 );
! 460: }
! 461: | ANS_PCREDIT '=' ANS_ON { LexiProblem_p->partial_cdt = 1;
! 462: }
! 463: | ANS_PCREDIT '=' ANS_OFF { LexiProblem_p->partial_cdt = 0;
! 464: }
! 465: | ANS_SHOW_BR '=' ANS_ON { LexiProblem_p->show_br = DO_SHOW;
! 466: }
! 467: | ANS_SHOW_BR '=' ANS_OFF { LexiProblem_p->show_br = DONOT_SHOW;
! 468: }
! 469: | ANS_VERBATIM '=' ANS_ON { LexiProblem_p->verbatim = DO_VERBATIM;
! 470: }
! 471: | ANS_VERBATIM '=' ANS_OFF { LexiProblem_p->verbatim = DONOT_VERBATIM;
! 472: }
! 473: | ANS_BOX_SHOW '=' ANS_ON { LexiProblem_p->show_ans_box = DO_SHOW;
! 474: }
! 475: | ANS_BOX_SHOW '=' ANS_OFF { LexiProblem_p->show_ans_box = DONOT_SHOW;
! 476: }
! 477: | ANS_CALC '=' ANS_FMT { CurrAnsInfo.ans_calc = CALC_FORMATED;
! 478: }
! 479: | ANS_CALC '=' ANS_UNFMT { CurrAnsInfo.ans_calc = CALC_UNFORMATED;
! 480: }
! 481: | ANS_TRY '=' an_integer { assign_try_limits( $3 );
! 482: }
! 483: | ANS_TRY '=' IDENTIFIER { assign_try_limits( $3 );
! 484: }
! 485: | ANS_UNIT '=' S_CONSTANT { assign_units( $3 ); capa_mfree($3->s_str); capa_mfree((char *)$3);
! 486: }
! 487: | ANS_UNIT '=' IDENTIFIER { assign_units( $3 );
! 488: }
! 489: | ANS_EVAL '=' var_range { CurrAnsInfo.ans_pts_list = CurrPtsList;
! 490: CurrPtsList=NULL; LastPtsList = NULL;
! 491: }
! 492: ;
! 493:
! 494:
! 495: var_range : '<' S_CONSTANT '@' pt_list '>' { assign_id_list( $2 );
! 496: capa_mfree($2->s_str);
! 497: capa_mfree((char *)$2);
! 498: }
! 499: | '<' IDENTIFIER '@' pt_list '>' { assign_id_list( $2 ); }
! 500: ;
! 501:
! 502: pt_list : pt_list ',' point_coord { int idx;
! 503: idx = LastPtsList->pts_idx; idx++;
! 504: /*LastPtsList->pts_next = new_ptslist( $3 );*/
! 505: LastPtsList = LastPtsList->pts_next;
! 506: LastPtsList->pts_idx = idx;
! 507: CurrPtsList->pts_idx = idx;
! 508: if( $3->s_type == S_CONSTANT ) {
! 509: capa_mfree($3->s_str); capa_mfree((char *)$3);
! 510: }
! 511: }
! 512: | pt_list ',' pt_range { }
! 513: | point_coord { /*CurrPtsList = new_ptslist( $1 );*/
! 514: LastPtsList = CurrPtsList;
! 515: if( $1->s_type == S_CONSTANT ) {
! 516: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 517: }
! 518: }
! 519: | pt_range { }
! 520: ;
! 521:
! 522: pt_range : point_coord ':' point_coord '#' IDENTIFIER
! 523: {
! 524: assign_pts($1,$3,$5);
! 525: /*PointsList_t *pt;
! 526: if( LastPtsList != NULL ) {
! 527: LastPtsList->pts_next = gen_ptslist( $1, $3, $5 );
! 528: pt = LastPtsList->pts_next;
! 529: while( pt->pts_next != NULL ) {
! 530: pt = pt->pts_next;
! 531: }
! 532: LastPtsList = pt;
! 533: } else {
! 534: CurrPtsList = gen_ptslist( $1, $3, $5 );
! 535: LastPtsList = CurrPtsList;
! 536: }
! 537: if( $1->s_type == S_CONSTANT ) {
! 538: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 539: }
! 540: if( $3->s_type == S_CONSTANT ) {
! 541: capa_mfree($3->s_str); capa_mfree((char *)$3);
! 542: }
! 543: */
! 544: }
! 545: | point_coord ':' point_coord '#' ARRAY_ID '[' calc_expr ']'
! 546: { assign_pts($1,$3,get_array_symbol($5,$7,1)); }
! 547: | point_coord ':' point_coord '#' a_number
! 548: {
! 549: assign_pts($1,$3,$5);
! 550: /*PointsList_t *pt;
! 551:
! 552: if( LastPtsList != NULL ) {
! 553: LastPtsList->pts_next = gen_ptslist( $1, $3, $5 );
! 554: pt = LastPtsList->pts_next;
! 555: while( pt->pts_next != NULL ) {
! 556: pt = pt->pts_next;
! 557: }
! 558: LastPtsList = pt;
! 559: } else {
! 560: CurrPtsList = gen_ptslist( $1, $3, $5 );
! 561: LastPtsList = CurrPtsList;
! 562: }
! 563: if( $1->s_type == S_CONSTANT ) {
! 564: capa_mfree($1->s_str); capa_mfree((char *)$1);
! 565: }
! 566: if( $3->s_type == S_CONSTANT ) {
! 567: capa_mfree($3->s_str); capa_mfree((char *)$3);
! 568: }
! 569: if( $5->s_type == I_CONSTANT || $5->s_type == R_CONSTANT) {
! 570: capa_mfree((char *)$5);
! 571: }
! 572: */
! 573: }
! 574: ;
! 575:
! 576:
! 577: point_coord : IDENTIFIER { $$ = $1; }
! 578: | ARRAY_ID '[' calc_expr ']' { $$ = get_array_symbol($1,$3,1); }
! 579: | S_CONSTANT { $$ = $1; }
! 580: ;
! 581:
! 582:
! 583:
! 584: formated_ans : calc_expr { $1->s_distype = DEFAULT_FORMAT;
! 585: $$ = $1;
! 586: $1->s_format = NULL;
! 587: YYDBUG_PR2(" formated_ans := calc_expr (type %d)",$1->s_type);
! 588: }
! 589: | calc_expr FORMAT { $1->s_distype = $2->s_distype;
! 590: $1->s_format = strsave($2->s_str); /* **** */
! 591: capa_mfree($2->s_str); capa_mfree((char *)$2);
! 592: $$ = $1;
! 593: YYDBUG_PR1(" formated_ans <= calc_expr FORMAT");
! 594: }
! 595: ;
! 596:
! 597:
! 598:
! 599: answer_sig : an_integer { assign_sigs( $1->s_int,$1->s_int);
! 600: capa_mfree((char *)$1);
! 601: }
! 602: | an_integer ANS_PLUS an_integer
! 603: { assign_sigs($1->s_int,$1->s_int + $3->s_int);
! 604: capa_mfree((char *)$1); capa_mfree((char *)$3);
! 605: }
! 606: | an_integer ANS_MINUS an_integer
! 607: { assign_sigs($1->s_int - $3->s_int,$1->s_int);
! 608: capa_mfree((char *)$1); capa_mfree((char *)$3);
! 609: }
! 610: | an_integer ANS_PLUS an_integer ANS_MINUS an_integer
! 611: { assign_sigs($1->s_int - $5->s_int,$1->s_int + $3->s_int);
! 612: capa_mfree((char *)$1); capa_mfree((char *)$3); capa_mfree((char *)$5);
! 613: }
! 614: | an_integer ANS_MINUS an_integer ANS_PLUS an_integer
! 615: { assign_sigs($1->s_int - $3->s_int,$1->s_int + $5->s_int);
! 616: capa_mfree((char *)$1); capa_mfree((char *)$3); capa_mfree((char *)$5);
! 617: }
! 618: ;
! 619:
! 620: answer_comp : ANS_CS { CurrAnsInfo.ans_type = ANSWER_IS_STRING_CS; }
! 621: | ANS_CI { CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI; }
! 622: | ANS_MC { CurrAnsInfo.ans_type = ANSWER_IS_CHOICE; }
! 623: | ANS_FORMULA { CurrAnsInfo.ans_type = ANSWER_IS_FORMULA; }
! 624: | ANS_EXTERNAL { CurrAnsInfo.ans_type = ANSWER_IS_EXTERNAL; }
! 625: ;
! 626:
! 627:
! 628: map_expr : startM '(' basic_constr ';' var_list ';' arg_list ')'
! 629: { char key[SMALL_LINE_BUFFER];
! 630: char warn_msg[WARN_MSG_LENGTH];
! 631: int result=0;
! 632:
! 633: YYDBUG_PR1(" map_expr body executed\n");
! 634: sprintf(key,"%ld",$3->s_int);
! 635: if( $5->s_argc == $7->s_argc ) {
! 636: /*result=do_map(key, $5->s_argp, $7->s_argp, $5->s_argc, FORWARD_MAP);*/
! 637: } else {
! 638: if ($5->s_argc==1) {
! 639: Symbol *a_sp;
! 640: a_sp=build_array_list($5,$7->s_argc);
! 641: /*result=do_map(key, a_sp->s_argp, $7->s_argp, a_sp->s_argc, FORWARD_MAP);*/
! 642: /*free_arglist(a_sp->s_argp);*/
! 643: } else {
! 644: sprintf(warn_msg,"/MAP arg. counts are not matched.\n");
! 645: capa_msg(MESSAGE_ERROR,warn_msg);
! 646: }
! 647: }
! 648: if (result!=0) {
! 649: sprintf(warn_msg,
! 650: "/MAP had invalid arguments.\n");
! 651: capa_msg(MESSAGE_ERROR,warn_msg);
! 652: }
! 653: /*free_arglist($5->s_argp);*/
! 654: /*free_arglist($7->s_argp);*/
! 655: }
! 656: | startR '(' basic_constr ';' var_list ';' arg_list ')'
! 657: { char key[SMALL_LINE_BUFFER];
! 658: char warn_msg[WARN_MSG_LENGTH];
! 659: int result=0;
! 660:
! 661: YYDBUG_PR1(" rmap_expr body executed\n");
! 662: sprintf(key,"%ld",$3->s_int);
! 663: if( $5->s_argc == $7->s_argc ) {
! 664: /*result=do_map(key, $5->s_argp, $7->s_argp, $5->s_argc, REVERSE_MAP);*/
! 665:
! 666: } else {
! 667: if ($5->s_argc==1) {
! 668: Symbol *a_sp;
! 669: a_sp=build_array_list($5,$7->s_argc);
! 670: /*result=do_map(key, a_sp->s_argp, $7->s_argp, a_sp->s_argc, FORWARD_MAP);*/
! 671: /*free_arglist(a_sp->s_argp);*/
! 672: } else {
! 673: sprintf(warn_msg,"/RMAP arg. counts are not matched.\n");
! 674: capa_msg(MESSAGE_ERROR,warn_msg);
! 675: }
! 676: }
! 677: if (result!=0) {
! 678: sprintf(warn_msg,
! 679: "/MAP had invalid arguments.\n");
! 680: capa_msg(MESSAGE_ERROR,warn_msg);
! 681: }
! 682: /*free_arglist($5->s_argp);*/
! 683: /*free_arglist($7->s_argp);*/
! 684: }
! 685: ;
! 686:
! 687:
! 688:
! 689: calc_expr : calc_expr EQ_op block { $$ = symbols_op($1, $3, EQ_op); }
! 690: | calc_expr NE_op block { $$ = symbols_op($1, $3, NE_op); }
! 691: | calc_expr GE_op block { $$ = symbols_op($1, $3, GE_op); }
! 692: | calc_expr GT_op block { $$ = symbols_op($1, $3, GT_op); }
! 693: | calc_expr LE_op block { $$ = symbols_op($1, $3, LE_op); }
! 694: | calc_expr LT_op block { $$ = symbols_op($1, $3, LT_op); }
! 695: | calc_expr AND_op block { $$ = symbols_op($1, $3, AND_op); }
! 696: | calc_expr OR_op block { $$ = symbols_op($1, $3, OR_op); }
! 697: | block { $$ = $1;
! 698: YYDBUG_PR1(" calc_expr <= block "); YYDBUG_SYM($1); }
! 699: ;
! 700:
! 701: block : block '+' term { $$ = symbols_op($1, $3, ADD_op); YYDBUG_PR1("block <= block '+' term "); YYDBUG_SYM($$); }
! 702: | block '-' term { $$ = symbols_op($1, $3, SUB_op); }
! 703: | term { $$ = $1; YYDBUG_PR2(" block <= term YYSTATE(%d) ",yystate); YYDBUG_SYM($1); }
! 704: ;
! 705:
! 706: term : term '*' basic_constr { $$ = symbols_op($1, $3, MUL_op); }
! 707: | term '/' basic_constr { $$ = symbols_op($1, $3, DIV_op); }
! 708: | term '%' basic_constr { $$ = symbols_op($1, $3, IDIV_op); }
! 709: | basic_constr { $$ = $1;
! 710: YYDBUG_PR1(" term <= basic_constr "); YYDBUG_SYM($1); }
! 711: ;
! 712:
! 713: basic_constr : FUNCTION_ID '(' ')' { int tmp;
! 714:
! 715: Func_idx--;
! 716: if(Func_idx >= 0 ) {
! 717: /*tmp = match_function(FuncStack[Func_idx].s_name,0);*/
! 718: /*$$ = do_function(tmp, 0, NULL );*/
! 719: capa_mfree(FuncStack[Func_idx].s_name);
! 720: }
! 721:
! 722: }
! 723: | FUNCTION_ID '(' arg_list ')'
! 724: { int tmp;
! 725:
! 726: Func_idx--;
! 727: YYDBUG_PR4(" basic_constr <= FUNCTION<%s><argc=%d> YYSTATE(%d) ",
! 728: FuncStack[Func_idx].s_name,$3->s_argc,yystate);
! 729:
! 730: if(Func_idx >= 0 ) {
! 731: /*tmp = match_function(FuncStack[Func_idx].s_name,$3->s_argc);*/
! 732: /*$$ = do_function(tmp, $3->s_argc, $3->s_argp);*/
! 733: capa_mfree(FuncStack[Func_idx].s_name);
! 734: /*free_arglist($3->s_argp);*/
! 735: }
! 736: YYDBUG_PR1(" basic_constr <= RETURN FUNCT "); YYDBUG_SYM($$);
! 737:
! 738: }
! 739: | an_array { $$ = $1; }
! 740: | IDENTIFIER { /* do not free identifier */
! 741: $$ = $1;
! 742: }
! 743: | '-' basic_constr { $$ = $2;
! 744: switch($2->s_type) {
! 745: case I_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
! 746: $$->s_type = I_CONSTANT;
! 747: case I_CONSTANT: $$->s_int = - $2->s_int; break;
! 748: case R_VAR: $$ = (Symbol *)capa_malloc(sizeof(Symbol),1);
! 749: $$->s_type = R_CONSTANT;
! 750: case R_CONSTANT: $$->s_real = (-1.0)*($2->s_real);
! 751: break;
! 752: case S_VAR:
! 753: case S_CONSTANT: break;
! 754: default: break;
! 755: }
! 756: }
! 757: | '+' basic_constr { $$ = $2; }
! 758: | S_CONSTANT { $$ = $1; }
! 759: | a_number { $$ = $1; }
! 760: | '(' calc_expr ')' { $$ = $2; }
! 761: ;
! 762:
! 763: arg_list : arg_list ',' calc_expr { $$ = $1;
! 764: $$->s_argc++;
! 765: /*$$->s_argp = addto_arglist($1->s_argp, $3);*/
! 766: }
! 767: | calc_expr { $$ = $1;
! 768: $$->s_argc = 1;
! 769: /*$$->s_argp = new_arglist($1);*/
! 770: }
! 771: ;
! 772:
! 773:
! 774: var_list : IDENTIFIER { /* do not free identifier */
! 775: YYDBUG_PR1(" var_list <= ID");
! 776: $$ = $1;
! 777: $$->s_argc = 1;
! 778: /*$$->s_argp = new_arglist($1);*/
! 779: }
! 780: | ARRAY_ID '[' calc_expr ']'{
! 781: YYDBUG_PR1(" var_list <= ARRAYID,calc");
! 782: $$ = get_array_symbol($1,$3,1);
! 783: $$->s_argc = 1;
! 784: /*$$->s_argp = new_arglist($$);*/
! 785: }
! 786: | var_list ',' ARRAY_ID '[' calc_expr ']' {
! 787: YYDBUG_PR1(" var_list <= var_list,ARRAYID,calc");
! 788: $$ = $1;
! 789: $$->s_argc++;
! 790: /*$$->s_argp = addto_arglist($1->s_argp,
! 791: get_array_symbol($3,$5,1));*/
! 792: }
! 793: | var_list ',' IDENTIFIER { /* do not free identifier */
! 794: YYDBUG_PR1(" var_list <= var_list,ID");
! 795: $$ = $1;
! 796: $$->s_argc++;
! 797: /*$$->s_argp = addto_arglist($1->s_argp, $3);*/
! 798: }
! 799: ;
! 800:
! 801:
! 802: a_number : an_integer { $$ = $1; }
! 803: | a_real { $$ = $1; }
! 804: ;
! 805:
! 806: an_integer : I_CONSTANT { $$ = $1; }
! 807: ;
! 808:
! 809: a_real : R_CONSTANT { $$ = $1; }
! 810: ;
! 811:
! 812: an_array : ARRAY_ID '[' calc_expr ']' {
! 813: YYDBUG_PR1(" an_array <= ARRAY_ID '['calc_expr ']' ");
! 814: $$=get_array_symbol($1,$3,1);
! 815: }
! 816: ;
! 817:
! 818: startQ : { /* first matching will occur before first line of input text */
! 819: YYDBUG_PR1(" startQ := begin_question\n");
! 820: begin_question(); Answer_infospec = 0;
! 821: }
! 822: ;
! 823:
! 824:
! 825:
! 826: %%
! 827: /* ============================================================================ */
! 828: ExpNode_p
! 829: mk_node(op, left, right) int op; ExpNode_p left; ExpNode_p right;
! 830: {
! 831: ExpNode *np;
! 832:
! 833: np = (ExpNode* )malloc(sizeof(ExpNode));
! 834: np->e_type = op;
! 835: np->e_lsibp = left;
! 836: np->e_rsibp = right;
! 837: left->e_parentp = np;
! 838: right->e_parentp = np;
! 839: return (np);
! 840: }
! 841:
! 842: ExpNode_p
! 843: mk_leaf(type, valp) int type; Symbol_p valp;
! 844: {
! 845: ExpNode *np;
! 846:
! 847: np = (ExpNode*)malloc(sizeof(ExpNode));
! 848: np->e_type = IDENTIFIER;
! 849: np->e_sp = valp;
! 850: return (np);
! 851:
! 852: }
! 853:
! 854: /* ------------------------------------------------------------- */
! 855: void free_calc_expr(Symbol *expr)
! 856: {
! 857: switch(expr->s_type) {
! 858: case I_CONSTANT:
! 859: case R_CONSTANT: capa_mfree((char *)expr); break;
! 860: case S_CONSTANT: capa_mfree(expr->s_str); capa_mfree((char *)expr); break;
! 861: default: break;
! 862: }
! 863: }
! 864:
! 865: /* this is the entry point to array symbol retrieval */
! 866: /* array main name and index are used to locate the symbol */
! 867: /* name of the array is used to retrieve the array symbol */
! 868:
! 869: Symbol* get_array_symbol ( name,index,free_symbols )
! 870: Symbol *name,*index;int free_symbols;
! 871: {
! 872: Symbol *s_p, *a_p;
! 873: char *key, *tmp;
! 874: int leng, idx_len;
! 875: leng = strlen(name->s_name)+8; /* [ ] */
! 876:
! 877: switch(index->s_type) {
! 878: case I_VAR:
! 879: case I_CONSTANT: tmp = (char *)capa_malloc(64,1);
! 880: sprintf(tmp,"%ld",index->s_int);
! 881: break;
! 882: case R_VAR:
! 883: case R_CONSTANT: tmp = (char *)capa_malloc(64,1);
! 884: sprintf(tmp,"%g",index->s_real);
! 885: break;
! 886: case S_VAR:
! 887: case S_CONSTANT: idx_len = strlen(index->s_str); tmp = (char *)capa_malloc(idx_len+4,1);
! 888: sprintf(tmp,"\"%s\"",index->s_str); /* string array index is a bit different from integer one */
! 889: break;
! 890: default: break;
! 891: }
! 892: idx_len = strlen(tmp);
! 893:
! 894: key = (char *)capa_malloc(idx_len+leng,1);
! 895: sprintf(key,"%s[%s]",name->s_name,tmp);
! 896:
! 897: /*a_p = find_arrayid(name->s_name);*/ /* use the array name to search array tree */
! 898: /* did not check for error! */
! 899: /*s_p = find_array_by_index(a_p,key);*/ /* use the index portion to search along array linked list */
! 900: capa_mfree((char *)tmp); capa_mfree((char *)key);
! 901:
! 902: if (free_symbols) { /* free both the name symbol and index symbol */
! 903: if( (index->s_type == I_CONSTANT) || (index->s_type == R_CONSTANT) )
! 904: capa_mfree((char *)index);
! 905: if(index->s_type == S_CONSTANT) {
! 906: capa_mfree(index->s_str); capa_mfree((char *)index);
! 907: }
! 908: capa_mfree(name->s_name); capa_mfree((char *)name);
! 909: }
! 910: return (s_p);
! 911: }
! 912:
! 913: Symbol * build_array_list(ar_name,num_elem)
! 914: Symbol *ar_name;int num_elem;
! 915: {
! 916: int i;
! 917: Symbol *arg_list,*a_p;
! 918: char idx_str[MAX_BUFFER_SIZE];
! 919:
! 920: /*a_p = find_arrayid(ar_name->s_name);*/
! 921: i = 1;
! 922: sprintf(idx_str,"%s[%d]",ar_name->s_name,i); /* create array elements with integer index */
! 923: /*arg_list = find_array_by_index(a_p,idx_str);*/ /* will create a new element if not found */
! 924: arg_list->s_argc=1;
! 925: /*arg_list->s_argp=new_arglist(arg_list);*/
! 926:
! 927: for (i=2;i<=num_elem;i++) {
! 928: sprintf(idx_str,"%s[%d]",ar_name->s_name,i);
! 929: arg_list->s_argc++;
! 930: /*arg_list->s_argp=addto_arglist(arg_list->s_argp,find_array_by_index(a_p,idx_str));*/
! 931: }
! 932: return arg_list;
! 933: }
! 934:
! 935:
! 936:
! 937:
! 938:
! 939:
! 940:
! 941: /* ------------------------------------------------------------- */
! 942: void
! 943: append_text(str) char *str;
! 944: {
! 945: char *q;
! 946: int i;
! 947:
! 948: if (!LexiProblem_p->question) {
! 949: if (!(q = capa_malloc(strlen(str)+1,1))) printf("No room to append.");
! 950: strncpy(q,str,strlen(str)+1);
! 951: } else {
! 952: i = strlen(LexiProblem_p->question);
! 953: i += (strlen(str)+1);
! 954: q = capa_malloc(i,1); /* *** */
! 955: if (!q) printf("No room to append().");
! 956: strcat(strncpy(q,LexiProblem_p->question, strlen(LexiProblem_p->question)+1), str);
! 957: capa_mfree(LexiProblem_p->question);
! 958: }
! 959: LexiProblem_p->question=q;
! 960: }
! 961:
! 962: /******************************************************************************/
! 963: /* ADD A STRING TO THE CURRENT HINT TEXT BLOCK */
! 964: /******************************************************************************/
! 965: void /* RETURNS: nothing */
! 966: append_hint(str) /* ARGUMENTS: */
! 967: char *str; /* String to add */
! 968: { /* LOCAL VARIABLES: */
! 969: char *q; /* New string */
! 970:
! 971: if (!LexiProblem_p->hint) {
! 972: if (!(q = capa_malloc(strlen(str)+1,1)))
! 973: printf("no room");
! 974: strncpy(q,str,strlen(str)+1);
! 975: } else {
! 976: if (!(q = capa_malloc(strlen(LexiProblem_p->hint)+strlen(str)+1,1)))
! 977: printf("no room");
! 978: strcat(strncpy(q,LexiProblem_p->hint,strlen(LexiProblem_p->hint)), str);
! 979: capa_mfree(LexiProblem_p->hint);
! 980: }
! 981: LexiProblem_p->hint=q;
! 982: /* printf("APPEND HINT: %s\n", str); */
! 983: }
! 984: /******************************************************************************/
! 985: /* ADD A STRING TO THE CURRENT EXPLAIN TEXT BLOCK */
! 986: /******************************************************************************/
! 987: void /* RETURNS: nothing */
! 988: append_explain(str) /* ARGUMENTS: */
! 989: char *str; /* String to add */
! 990: { /* LOCAL VARIABLES: */
! 991: char *q; /* New string */
! 992:
! 993: if (!LexiProblem_p->explain) {
! 994: if (!(q = capa_malloc(strlen(str)+1,1)))
! 995: printf("no room");
! 996: strncpy(q,str, strlen(str)+1);
! 997: } else {
! 998: if (!(q = capa_malloc(strlen(LexiProblem_p->explain)+strlen(str)+1,1)))
! 999: printf("no room");
! 1000: strcat(strncpy(q,LexiProblem_p->explain,strlen(LexiProblem_p->explain)+1), str);
! 1001: capa_mfree(LexiProblem_p->explain);
! 1002: }
! 1003: LexiProblem_p->explain=q;
! 1004: /* printf("APPEND EXPLAIN: %s\n", str); */
! 1005: }
! 1006:
! 1007: void
! 1008: append_error(str) char *str;
! 1009: {
! 1010: char *q;
! 1011: int i;
! 1012:
! 1013: ErrorMsg_count++;
! 1014: if (!ErrorMsg_p) {
! 1015: if (!(q = capa_malloc(strlen(str)+1,1))) printf("No room in append.");
! 1016: strncpy(q,str,strlen(str)+1);
! 1017: } else {
! 1018: i = strlen(ErrorMsg_p);
! 1019: i += (strlen(str)+1);
! 1020: q = capa_malloc(i,1); /* *** */
! 1021: if (!q) printf("No room in append()");
! 1022: strcat(strncpy(q,ErrorMsg_p, strlen(ErrorMsg_p)+1), str);
! 1023: capa_mfree(ErrorMsg_p);
! 1024: }
! 1025: ErrorMsg_p=q;
! 1026: /* printf("APPEND ERROR: %s\n", str); */
! 1027: }
! 1028: void
! 1029: append_warn(type,str) int type;char *str;
! 1030: {
! 1031: WarnMsg_t *p, *t;
! 1032: char *q;
! 1033:
! 1034: WarnMsg_count++;
! 1035: if (!WarnMsg_p) {
! 1036: if (!(p = (WarnMsg_t *)capa_malloc(sizeof(WarnMsg_t),1))) printf("No room in create WarnMsg_t.");
! 1037: if (!(q = capa_malloc(strlen(str)+1,1))) printf("No room in allocating space for warn msg.");
! 1038: strncpy(q,str,strlen(str)+1);
! 1039: p->warn_next = NULL;
! 1040: p->warn_type = type;
! 1041: p->warn_str = q;
! 1042: WarnMsg_p=p;
! 1043: } else {
! 1044: for(t=WarnMsg_p;t->warn_next;t=t->warn_next) { } /* do nothing within for loop */
! 1045: if (!(p = (WarnMsg_t *)capa_malloc(sizeof(WarnMsg_t),1))) printf("No room in create WarnMsg_t.");
! 1046: if (!(q = capa_malloc(strlen(str)+1,1))) printf("No room in allocating space for warn msg.");
! 1047: strncpy(q,str,strlen(str)+1);
! 1048: p->warn_next = NULL;
! 1049: p->warn_type = type;
! 1050: p->warn_str = q;
! 1051: t->warn_next = p;
! 1052: }
! 1053: }
! 1054:
! 1055: /*****************************************************************************/
! 1056: /*********** if *b is a constant symbol, destroy (free) b ********************/
! 1057: /*********** if *a is a var symbol, create a new symbol **********************/
! 1058: /* do not free(*a) */
! 1059: /* If either a or b is invalid it propagates the error up the parse tree */
! 1060: Symbol *
! 1061: symbols_op(a, b, op) Symbol *a; Symbol *b; int op;
! 1062: {
! 1063: int type, new, leng;
! 1064: long tmp_i, tmp_j;
! 1065: double tmp_p, tmp_q;
! 1066: char a_str[QUARTER_K], *b_str=NULL, *r_strp;
! 1067: char warn_msg[ONE_K];
! 1068: Symbol *a_symp;
! 1069:
! 1070: if( a->s_type == IDENTIFIER || b->s_type == IDENTIFIER ) {
! 1071: if(a->s_type == IDENTIFIER) { /* a is IDENTIFIER */
! 1072: sprintf(warn_msg,"var \"%s\" not defined before use.\n", a->s_name);
! 1073: capa_msg(MESSAGE_ERROR,warn_msg);
! 1074: return (a);
! 1075: } else { /* b is IDENTIFIER */
! 1076: sprintf(warn_msg,"var \"%s\" not defined before use.\n",b->s_name);
! 1077: capa_msg(MESSAGE_ERROR,warn_msg);
! 1078: return (b);
! 1079: }
! 1080: } else { /* a and b are neither identifiers */
! 1081: if( (a->s_type == I_VAR) ||
! 1082: (a->s_type == R_VAR) ||
! 1083: (a->s_type == S_VAR) ) {
! 1084: a_symp = (Symbol *)capa_malloc(sizeof(Symbol),1); /* *** */
! 1085: new = 1;
! 1086: } else {
! 1087: new = 0;
! 1088: a_symp = a; /* re-use symbol *a */
! 1089: }
! 1090: if( ((a->s_type == I_CONSTANT)||(a->s_type == I_VAR)) &&
! 1091: ((b->s_type == I_CONSTANT)||(b->s_type == I_VAR)) ) { /* both a and b are integer */
! 1092: type = I_CONSTANT;
! 1093: switch( op ) {
! 1094: case ADD_op: a_symp->s_int = a->s_int + b->s_int ; break;
! 1095: case SUB_op: a_symp->s_int = a->s_int - b->s_int ; break;
! 1096: case MUL_op: a_symp->s_int = a->s_int * b->s_int ; break;
! 1097: case DIV_op: if(b->s_int != 0) {
! 1098: a_symp->s_int = a->s_int / b->s_int ;
! 1099: } else {
! 1100: sprintf(warn_msg,"division (/) by zero!\n");
! 1101: capa_msg(MESSAGE_ERROR,warn_msg);
! 1102: } break;
! 1103: case IDIV_op: if(b->s_int != 0) {
! 1104: a_symp->s_int = (a->s_int % b->s_int );
! 1105: } else {
! 1106: sprintf(warn_msg,"integer division (%%) by zero!\n");
! 1107: capa_msg(MESSAGE_ERROR,warn_msg);
! 1108: } break;
! 1109: case EQ_op: a_symp->s_int = ((a->s_int == b->s_int)? 1: 0); break;
! 1110: case NE_op: a_symp->s_int = ((a->s_int == b->s_int)? 0: 1); break;
! 1111: case GT_op: a_symp->s_int = ((a->s_int > b->s_int)? 1: 0); break;
! 1112: case GE_op: a_symp->s_int = ((a->s_int >= b->s_int)? 1: 0); break;
! 1113: case LT_op: a_symp->s_int = ((a->s_int < b->s_int)? 1: 0); break;
! 1114: case LE_op: a_symp->s_int = ((a->s_int <= b->s_int)? 1: 0); break;
! 1115: case AND_op: a_symp->s_int = ((a->s_int && b->s_int)? 1: 0); break;
! 1116: case OR_op: a_symp->s_int = ((a->s_int || b->s_int)? 1: 0); break;
! 1117: }
! 1118: } else { /* a, b neither are integers */
! 1119: if( (a->s_type == S_VAR) || (a->s_type == S_CONSTANT) ||
! 1120: (b->s_type == S_VAR) || (b->s_type == S_CONSTANT) ) { /* either a or b is a string */
! 1121: type = S_CONSTANT; /* the return type is a string */
! 1122: if( (a->s_type == S_VAR) || (a->s_type == S_CONSTANT) ) { /* a is a string */
! 1123: if (a->s_str == NULL ||
! 1124: (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL)) {
! 1125: if (a->s_str == NULL) {
! 1126: sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name);
! 1127: capa_msg(MESSAGE_ERROR,warn_msg);
! 1128: }
! 1129: if (((b->s_type == S_VAR) || (b->s_type == S_CONSTANT)) && b->s_str == NULL) {
! 1130: sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",a->s_name);
! 1131: capa_msg(MESSAGE_ERROR,warn_msg);
! 1132: }
! 1133: } else { /* a is a valid string */
! 1134: switch( b->s_type ) {
! 1135: case I_VAR:
! 1136: case I_CONSTANT:
! 1137: leng = SMALL_LINE_BUFFER; /* assuming a long integer does not exceed 128 digits*/
! 1138: b_str= capa_malloc(sizeof(char), leng);
! 1139: sprintf(b_str,"%ld", b->s_int);
! 1140: break;
! 1141: case R_VAR:
! 1142: case R_CONSTANT:
! 1143: leng = SMALL_LINE_BUFFER;/*assuming a double does not exceed128chars*/
! 1144: b_str= capa_malloc(sizeof(char), leng);
! 1145: sprintf(b_str,"%.15g", b->s_real);
! 1146: break;
! 1147: case S_VAR:
! 1148: case S_CONSTANT: /* DONE: get rid of limitations on b_str[] */
! 1149: leng = strlen( b->s_str ) + 1;
! 1150: b_str= capa_malloc(sizeof(char), leng);
! 1151: sprintf(b_str,"%s",b->s_str);
! 1152: /*if(b->s_type == S_CONSTANT) capa_mfree(b->s_str);*/
! 1153: break;
! 1154: }
! 1155: switch( op ) {
! 1156: case ADD_op:
! 1157: leng = strlen( a->s_str ) + strlen(b_str) + 1;
! 1158: r_strp = capa_malloc(sizeof(char), leng); /* **** */
! 1159: strcat(r_strp, a->s_str);
! 1160: strcat(r_strp, b_str); /* concatenate two strings together */
! 1161: if( !new ) capa_mfree(a->s_str);
! 1162: a_symp->s_str = r_strp;
! 1163: break;
! 1164: case SUB_op:
! 1165: case MUL_op:
! 1166: case DIV_op:
! 1167: case IDIV_op:
! 1168: if( !new ) capa_mfree(a->s_str);
! 1169: a_symp->s_str = strsave("<<Op NOT DEFINED>>");
! 1170: sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n");
! 1171: capa_msg(MESSAGE_ERROR,warn_msg);
! 1172: break;
! 1173: case EQ_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 1: 0);
! 1174: type = I_CONSTANT; break;
! 1175: case NE_op: a_symp->s_int = (strcmp(a->s_str, b_str) == 0? 0: 1);
! 1176: type = I_CONSTANT; break;
! 1177: case GT_op: a_symp->s_int = (strcmp(a->s_str, b_str) > 0? 1: 0);
! 1178: type = I_CONSTANT; break;
! 1179: case GE_op: a_symp->s_int = (strcmp(a->s_str, b_str) >= 0? 1: 0);
! 1180: type = I_CONSTANT; break;
! 1181: case LT_op: a_symp->s_int = (strcmp(a->s_str, b_str) < 0? 1: 0);
! 1182: type = I_CONSTANT; break;
! 1183: case LE_op: a_symp->s_int = (strcmp(a->s_str, b_str) <= 0? 1: 0);
! 1184: type = I_CONSTANT; break;
! 1185: case AND_op:
! 1186: if( (a->s_str[0] != 0) && (b_str[0] != 0)) {
! 1187: a_symp->s_int = 1;
! 1188: } else {
! 1189: a_symp->s_int = 0;
! 1190: }
! 1191: type = I_CONSTANT; break;
! 1192: case OR_op:
! 1193: if( (a->s_str[0] != 0) || (b_str[0] != 0)) {
! 1194: a_symp->s_int = 1;
! 1195: } else {
! 1196: a_symp->s_int = 0;
! 1197: }
! 1198: type = I_CONSTANT; break;
! 1199: }
! 1200: }
! 1201: if (b_str!=NULL) capa_mfree(b_str);
! 1202: } else { /* b is string and a is either integer or real */
! 1203: switch( a->s_type ) {
! 1204: case I_VAR:
! 1205: case I_CONSTANT:
! 1206: sprintf(a_str,"%ld", a->s_int); break;
! 1207: case R_VAR:
! 1208: case R_CONSTANT:
! 1209: sprintf(a_str,"%.15g", a->s_real); break;
! 1210: }
! 1211: switch( op ) {
! 1212: case ADD_op:
! 1213: leng = strlen( b->s_str ) + strlen(a_str) + 1;
! 1214: r_strp = capa_malloc(sizeof(char), leng); /* *** */
! 1215: strcat(r_strp, a_str);
! 1216: strcat(r_strp, b->s_str);
! 1217: /*if( b->s_type == S_CONSTANT ) capa_mfree(b->s_str);*/
! 1218: a_symp->s_str = r_strp; break;
! 1219: case SUB_op:
! 1220: case MUL_op:
! 1221: case DIV_op:
! 1222: case IDIV_op:
! 1223: a_symp->s_str = strsave("<<Op NOT DEFINED>>");
! 1224: sprintf(warn_msg,"integer division (%%) cannot accept string operand!\n");
! 1225: capa_msg(MESSAGE_ERROR,warn_msg);
! 1226: break;
! 1227: case EQ_op: a_symp->s_int = (strcmp(a_str, b->s_str) == 0? 1: 0);
! 1228: type = I_CONSTANT; break;
! 1229: case NE_op: a_symp->s_int = (strcmp(a_str, b->s_str) == 0? 0: 1);
! 1230: type = I_CONSTANT; break;
! 1231: case GT_op: a_symp->s_int = (strcmp(a_str, b->s_str) > 0? 1: 0);
! 1232: type = I_CONSTANT; break;
! 1233: case GE_op: a_symp->s_int = (strcmp(a_str, b->s_str) >= 0? 1: 0);
! 1234: type = I_CONSTANT; break;
! 1235: case LT_op: a_symp->s_int = (strcmp(a_str, b->s_str) < 0? 1: 0);
! 1236: type = I_CONSTANT; break;
! 1237: case LE_op: a_symp->s_int = (strcmp(a_str,b->s_str) <= 0? 1: 0);
! 1238: type = I_CONSTANT; break;
! 1239: case AND_op: if( (a_str[0] != 0) && (b->s_str[0] != 0)) {
! 1240: a_symp->s_int = 1;
! 1241: } else {
! 1242: a_symp->s_int = 0;
! 1243: }
! 1244: type = I_CONSTANT; break;
! 1245: case OR_op: if( (a_str[0] != 0) || (b_str[0] != 0)) {
! 1246: a_symp->s_int = 1;
! 1247: } else {
! 1248: a_symp->s_int = 0;
! 1249: }
! 1250: type = I_CONSTANT; break;
! 1251: }
! 1252: }
! 1253:
! 1254: } else { /* both a and b are real */
! 1255: type = R_CONSTANT;
! 1256: if( (a->s_type == R_CONSTANT)||(a->s_type == R_VAR) ) {
! 1257: tmp_p = a->s_real;
! 1258: } else {
! 1259: tmp_p = (double)a->s_int;
! 1260: }
! 1261: if( (b->s_type == R_CONSTANT)||(b->s_type == R_VAR) ) {
! 1262: tmp_q = b->s_real;
! 1263: } else {
! 1264: tmp_q = (double)b->s_int;
! 1265: }
! 1266: switch( op ) {
! 1267: case ADD_op: a_symp->s_real = tmp_p + tmp_q ; break;
! 1268: case SUB_op: a_symp->s_real = tmp_p - tmp_q ; break;
! 1269: case MUL_op: a_symp->s_real = tmp_p * tmp_q ; break;
! 1270: case DIV_op: if(tmp_q != 0.0) {
! 1271: a_symp->s_real = tmp_p / tmp_q ;
! 1272: } else {
! 1273: /* printf("FDIVISION by ZERO\n"); */
! 1274: sprintf(warn_msg,"division (/) by zero!\n");
! 1275: capa_msg(MESSAGE_ERROR,warn_msg);
! 1276: }
! 1277: break;
! 1278: case IDIV_op: if(tmp_q != 0.0 ) {
! 1279: tmp_i = (long)tmp_p;
! 1280: tmp_j = (long)tmp_q;
! 1281: a_symp->s_int = tmp_i % tmp_j;
! 1282: type = I_CONSTANT;
! 1283: } else {
! 1284: /* printf("DIVISION by ZERO\n"); */
! 1285: sprintf(warn_msg,"division (/) by zero!\n");
! 1286: capa_msg(MESSAGE_ERROR,warn_msg);
! 1287: }
! 1288: break;
! 1289: case EQ_op: type = I_CONSTANT;
! 1290: a_symp->s_int = ((tmp_p == tmp_q)? 1: 0); break;
! 1291: case NE_op: type = I_CONSTANT;
! 1292: a_symp->s_int = ((tmp_p == tmp_q)? 0: 1); break;
! 1293: case GT_op: type = I_CONSTANT;
! 1294: a_symp->s_int = ((tmp_p > tmp_q)? 1: 0); break;
! 1295: case GE_op: type = I_CONSTANT;
! 1296: a_symp->s_int = ((tmp_p >= tmp_q)? 1: 0); break;
! 1297: case LT_op: type = I_CONSTANT;
! 1298: a_symp->s_int = ((tmp_p < tmp_q)? 1: 0); break;
! 1299: case LE_op: type = I_CONSTANT;
! 1300: a_symp->s_int = ((tmp_p <= tmp_q)? 1: 0); break;
! 1301: case AND_op: type = I_CONSTANT;
! 1302: a_symp->s_int = ((tmp_p && tmp_q)? 1: 0); break;
! 1303: case OR_op: type = I_CONSTANT;
! 1304: a_symp->s_int = ((tmp_p || tmp_q)? 1: 0); break;
! 1305: }
! 1306: }
! 1307: }
! 1308: if( (b->s_type == I_CONSTANT) ||
! 1309: (b->s_type == R_CONSTANT) ) capa_mfree((char *)b); /* free symbol *b only */
! 1310: if( (b->s_type == S_CONSTANT) ) {
! 1311: capa_mfree((char *)b->s_str);
! 1312: capa_mfree((char *)b);
! 1313: }
! 1314: a_symp->s_type = type;
! 1315: return (a_symp);
! 1316: }
! 1317: }
! 1318:
! 1319: /* ------------------------------------------------------ */
! 1320: char *
! 1321: format_toTeX( real ) char *real;
! 1322: {
! 1323: int idx, length, fraclength, i_exp;
! 1324: char *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal;
! 1325: char warn_msg[WARN_MSG_LENGTH];
! 1326:
! 1327: length = strlen(real);
! 1328: if( index( real, 'e' ) == NULL ) {
! 1329: if( index( real, 'E' ) == NULL ) {
! 1330: sprintf(result,"%s", real);
! 1331: } else {
! 1332: expo_p = index(real, 'E'); /*** hpux complained */
! 1333: fraclength = length - strlen(expo_p);
! 1334: expo_p++; if(expo_p[0] == '+') expo_p++;
! 1335: sscanf(expo_p,"%d",&i_exp);
! 1336: for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
! 1337: fracS[fraclength] = 0;
! 1338: if(i_exp == 0 ) {
! 1339: sprintf(result,"$%s$", fracS);
! 1340: } else {
! 1341: sprintf(result,"$%s \\times 10^{%d}$", fracS, i_exp);
! 1342: }
! 1343: }
! 1344: } else {
! 1345: if( index( real, 'E' ) == NULL ) {
! 1346: expo_p = index(real, 'e'); /*** hpux complained */
! 1347: fraclength = length - strlen(expo_p);
! 1348: expo_p++; if(expo_p[0] == '+') expo_p++;
! 1349: sscanf(expo_p,"%d",&i_exp);
! 1350: for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
! 1351: fracS[fraclength] = 0;
! 1352: if(i_exp == 0 ) {
! 1353: sprintf(result,"$%s$", fracS);
! 1354: } else {
! 1355: sprintf(result,"$%s \\times 10^{%d}$", fracS, i_exp);
! 1356: }
! 1357: } else {
! 1358: sprintf(result,"<<Ill-formed REAL>>");
! 1359: sprintf(warn_msg,"number %s is not a valid real number!\n",real);
! 1360: capa_msg(MESSAGE_ERROR,warn_msg);
! 1361: }
! 1362: }
! 1363: areal = (char *) capa_malloc(strlen(result)+1, 1);
! 1364: strcpy(areal,result);
! 1365: return (areal);
! 1366: }
! 1367: /* ------------------------------------------------------ */
! 1368: char *
! 1369: format_toHTML( real ) char *real;
! 1370: {
! 1371: int idx, length, fraclength, i_exp;
! 1372: char *expo_p, fracS[SMALL_LINE_BUFFER], result[ONE_K], *areal;
! 1373: char warn_msg[WARN_MSG_LENGTH];
! 1374:
! 1375: length = strlen(real);
! 1376: if( index( real, 'e' ) == NULL ) {
! 1377: if( index( real, 'E' ) == NULL ) {
! 1378: sprintf(result,"%s", real);
! 1379: } else {
! 1380: expo_p = index(real, 'E'); /*** hpux complained */
! 1381: fraclength = length - strlen(expo_p);
! 1382: expo_p++; if(expo_p[0] == '+') expo_p++;
! 1383: sscanf(expo_p,"%d",&i_exp);
! 1384: for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
! 1385: fracS[fraclength] = 0;
! 1386: if(i_exp == 0 ) {
! 1387: sprintf(result,"%s", fracS);
! 1388: } else {
! 1389: sprintf(result,"%s×10<sup>%d</sup>", fracS, i_exp); /* × is code for x */
! 1390: }
! 1391: }
! 1392: } else { /* the string contains 'e' char */
! 1393: if( index( real, 'E' ) == NULL ) {
! 1394: expo_p = index(real, 'e'); /*** hpux complained */
! 1395: fraclength = length - strlen(expo_p);
! 1396: expo_p++; if(expo_p[0] == '+') expo_p++;
! 1397: sscanf(expo_p,"%d",&i_exp);
! 1398: for(idx=0;idx<fraclength;idx++) fracS[idx] = real[idx];
! 1399: fracS[fraclength] = 0;
! 1400: if(i_exp == 0 ) {
! 1401: sprintf(result,"%s", fracS);
! 1402: } else {
! 1403: sprintf(result,"%s×10<sup>%d</sup>", fracS, i_exp); /* × is code for x */
! 1404: }
! 1405: } else {
! 1406: sprintf(result,"<<Ill-formed REAL>>");
! 1407: sprintf(warn_msg,"number %s is not a valid real number!\n",real);
! 1408: capa_msg(MESSAGE_ERROR,warn_msg);
! 1409: }
! 1410: }
! 1411: areal = (char *) capa_malloc(strlen(result)+1, 1);
! 1412: strcpy(areal,result);
! 1413: return (areal);
! 1414: }
! 1415: /* -- This routine is called when a /ANS is encountered -- */
! 1416: void
! 1417: init_answerinfo()
! 1418: {
! 1419:
! 1420: CurrAnsInfo.ans_str = NULL;
! 1421: CurrAnsInfo.ans_type = 0;
! 1422: CurrAnsInfo.ans_calc = CALC_DEFAULT;
! 1423: CurrAnsInfo.ans_tol_type = TOL_ABSOLUTE;
! 1424: CurrAnsInfo.ans_tol = TOL_DEFAULT;
! 1425: CurrAnsInfo.ans_sig_ub = SIG_UB_DEFAULT;
! 1426: CurrAnsInfo.ans_sig_lb = SIG_LB_DEFAULT;
! 1427: CurrAnsInfo.ans_id_list = NULL;
! 1428: CurrAnsInfo.ans_pts_list = NULL;
! 1429: CurrAnsInfo.ans_fmt[0] = '\0';
! 1430: CurrAnsInfo.ans_unit_str[0] = '\0';
! 1431: CurrAnsInfo.ans_unit = NULL;
! 1432: CurrAnsInfo.ans_next = NULL;
! 1433: }
! 1434: /* when encountered a /DIS(variable) */
! 1435: void
! 1436: display_var( s )Symbol *s;
! 1437: {
! 1438: char *aline;
! 1439: char *tmp_p;
! 1440: char warn_msg[WARN_MSG_LENGTH];
! 1441:
! 1442:
! 1443: switch(s->s_type) {
! 1444: case IDENTIFIER:
! 1445: aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
! 1446: sprintf(aline,"VAR \"%s\" NOT DEFINED!", s->s_name);
! 1447: sprintf(warn_msg,"display var \"%s\" not defined before use.\n",s->s_name);
! 1448: capa_msg(MESSAGE_ERROR,warn_msg);
! 1449: break;
! 1450: case I_VAR: case I_CONSTANT:
! 1451: aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
! 1452: sprintf(aline, "%ld", s->s_int);
! 1453: break;
! 1454: case R_VAR: case R_CONSTANT:
! 1455: aline = (char *)capa_malloc(sizeof(char)*ONE_K,1);
! 1456: if(Parsemode_f == TeX_MODE) {
! 1457: if(s->s_distype == DEFAULT_FORMAT ) {
! 1458: sprintf(aline,"%.15g",s->s_real);
! 1459: } else {
! 1460: sprintf(aline,s->s_format,s->s_real);
! 1461: }
! 1462: tmp_p = format_toTeX(aline);
! 1463: sprintf(aline,"%s",tmp_p);
! 1464: capa_mfree( (char *)tmp_p);
! 1465:
! 1466: } else {
! 1467: if(Parsemode_f == HTML_MODE ) {
! 1468: if(s->s_distype == DEFAULT_FORMAT ) {
! 1469: sprintf(aline,"%.15g",s->s_real);
! 1470: } else {
! 1471: sprintf(aline,s->s_format,s->s_real);
! 1472: }
! 1473: tmp_p = format_toHTML(aline);
! 1474: sprintf(aline,"%s",tmp_p);
! 1475: capa_mfree( (char *)tmp_p);
! 1476: } else {
! 1477: if(s->s_distype == DEFAULT_FORMAT ) {
! 1478: sprintf(aline,"%.15g",s->s_real);
! 1479: } else {
! 1480: sprintf(aline,s->s_format,s->s_real);
! 1481: }
! 1482: }
! 1483: }
! 1484: break;
! 1485: case S_VAR: case S_CONSTANT:
! 1486: if (s->s_str == NULL) {
! 1487: sprintf(warn_msg,"variable %s has not yet been assigned a value.\n",
! 1488: s->s_name);
! 1489: capa_msg(MESSAGE_ERROR,warn_msg);
! 1490: aline=(char *)capa_malloc(9,1);
! 1491: sprintf(aline,"NO VALUE");
! 1492: } else {
! 1493: aline = (char *)capa_malloc(strlen(s->s_str)+1,1);
! 1494: sprintf(aline,"%s",s->s_str);
! 1495: }
! 1496: break;
! 1497: }
! 1498: append_text(aline);
! 1499: capa_mfree((char *)aline);
! 1500: if(s->s_format) { capa_mfree((char *)s->s_format); }
! 1501: s->s_format = NULL;
! 1502: switch(s->s_type) { /* free up spaces taken by constants */
! 1503: case I_CONSTANT:
! 1504: case R_CONSTANT: capa_mfree((char *)s); break;
! 1505: case S_CONSTANT: capa_mfree(s->s_str); capa_mfree((char *)s); break;
! 1506: default: break;
! 1507: }
! 1508:
! 1509: }
! 1510:
! 1511: /* Assign the correct answer to CurrAnsInfo first */
! 1512: void
! 1513: assign_answer( s ) Symbol *s;
! 1514: {
! 1515: char aline[QUARTER_K];
! 1516: char warn_msg[WARN_MSG_LENGTH];
! 1517:
! 1518: /*problem_default(LexiProblem_p);*/
! 1519: switch(s->s_type) {
! 1520: case IDENTIFIER:
! 1521: sprintf(warn_msg,"File %s, Line %3d: in /ANS, var %s not defined before use.\n",
! 1522: Opened_filename[Input_idx],Current_line[Input_idx],s->s_name);
! 1523: capa_msg(MESSAGE_ERROR,warn_msg);
! 1524: CurrAnsInfo.ans_str = strsave("ANSWER NOT DEFINED!");
! 1525: CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI;
! 1526: sprintf(CurrAnsInfo.ans_fmt,"%%s");
! 1527: if (CurrAnsInfo.ans_tol == 0.0) {
! 1528: sprintf(warn_msg, "File %s, Line %3d: answer has a numerical value of %ld and an implicit zero tolerance.\n",
! 1529: Opened_filename[Input_idx],Current_line[Input_idx],s->s_int);
! 1530: capa_msg(MESSAGE_WARN,warn_msg);
! 1531: }
! 1532: break;
! 1533: case I_VAR: case I_CONSTANT:
! 1534: sprintf(aline, "%ld", s->s_int);
! 1535: CurrAnsInfo.ans_str = strsave(aline);
! 1536: CurrAnsInfo.ans_type = ANSWER_IS_INTEGER;
! 1537: sprintf(CurrAnsInfo.ans_fmt,"%%ld");
! 1538: break;
! 1539: case R_VAR: case R_CONSTANT:
! 1540: if(s->s_distype == DEFAULT_FORMAT ) {
! 1541: sprintf(aline,"%.15g",s->s_real);
! 1542: sprintf(CurrAnsInfo.ans_fmt,"%%.15g");
! 1543: } else {
! 1544: sprintf(aline,"%.15g",s->s_real);
! 1545: strcpy(CurrAnsInfo.ans_fmt,s->s_format);
! 1546: }
! 1547: CurrAnsInfo.ans_str = strsave(aline);
! 1548: CurrAnsInfo.ans_type = ANSWER_IS_FLOAT;
! 1549: if( CurrAnsInfo.ans_tol == 0.0 ) {
! 1550: sprintf(warn_msg,"File %s, Line %3d: answer has a numerical value of %s and a zero tolerance.\n",
! 1551: Opened_filename[Input_idx],Current_line[Input_idx],aline);
! 1552: capa_msg(MESSAGE_WARN,warn_msg);
! 1553: }
! 1554: break;
! 1555: case S_VAR: case S_CONSTANT:
! 1556: CurrAnsInfo.ans_str = strsave(s->s_str);
! 1557: if (s->s_str!=NULL && (strlen(s->s_str)>ANSWER_STRING_LENG-1)) {
! 1558: sprintf(warn_msg,"File %s, Line %3d: answer is too long, max allowed length is %d, current answer is %d\n",
! 1559: Opened_filename[Input_idx],Current_line[Input_idx],
! 1560: ANSWER_STRING_LENG-1, strlen(s->s_str));
! 1561: capa_msg(MESSAGE_ERROR,warn_msg);
! 1562: CurrAnsInfo.ans_str[ANSWER_STRING_LENG-1]='\0';
! 1563: }
! 1564: if ( !CurrAnsInfo.ans_type ) { /* not yet specified by str= answer info */
! 1565: CurrAnsInfo.ans_type = ANSWER_IS_STRING_CI;
! 1566: }
! 1567: sprintf(CurrAnsInfo.ans_fmt,"%%s");
! 1568: break;
! 1569: }
! 1570: if(s->s_format) {
! 1571: capa_mfree((char *)s->s_format);
! 1572: }
! 1573: s->s_format = NULL;
! 1574: switch(s->s_type) {
! 1575: case I_CONSTANT:
! 1576: case R_CONSTANT: capa_mfree((char *)s); break;
! 1577: case S_CONSTANT: capa_mfree(s->s_str); capa_mfree((char *)s); break;
! 1578: default: break;
! 1579: }
! 1580:
! 1581: }
! 1582:
! 1583: /* Assign tolerance to CurrAnsInfo first */
! 1584: void
! 1585: assign_tolerance(tol_type, s) int tol_type; Symbol *s;
! 1586: {
! 1587: char warn_msg[WARN_MSG_LENGTH];
! 1588:
! 1589: CurrAnsInfo.ans_tol_type = tol_type;
! 1590: switch( s->s_type ) {
! 1591: case IDENTIFIER:
! 1592: sprintf(warn_msg,"TOL = var, \"%s\" not defined before use.\n",s->s_name);
! 1593: capa_msg(MESSAGE_ERROR,warn_msg);
! 1594: CurrAnsInfo.ans_tol = 0.0;
! 1595: break;
! 1596: case I_VAR: case I_CONSTANT:
! 1597: CurrAnsInfo.ans_tol =(double)s->s_int;
! 1598: break;
! 1599: case R_VAR: case R_CONSTANT:
! 1600: CurrAnsInfo.ans_tol = s->s_real;
! 1601: break;
! 1602: case S_VAR: case S_CONSTANT: CurrAnsInfo.ans_tol = 0.0;
! 1603: break;
! 1604: }
! 1605: free_calc_expr(s);
! 1606: }
! 1607:
! 1608: /* Problem weight is per problem based */
! 1609: void
! 1610: assign_weight( s ) Symbol *s;
! 1611: { char warn_msg[WARN_MSG_LENGTH];
! 1612: YYDBUG_PR1(" weight = identifier\n");
! 1613: switch( s->s_type ) {
! 1614: case IDENTIFIER:
! 1615: sprintf(warn_msg,"WGT = var, \"%s\" not defined before use.\n", s->s_name);
! 1616: capa_msg(MESSAGE_ERROR,warn_msg);
! 1617: LexiProblem_p->weight = WEIGHT_DEFAULT;
! 1618: break;
! 1619: case I_VAR: case I_CONSTANT:
! 1620: if( s->s_int < 0 ) {
! 1621: sprintf(warn_msg,"WGT = %ld, weight cannot be less than zero.\n", s->s_int);
! 1622: capa_msg(MESSAGE_ERROR,warn_msg);
! 1623: LexiProblem_p->weight = WEIGHT_DEFAULT;
! 1624: } else {
! 1625: LexiProblem_p->weight = s->s_int;
! 1626: }
! 1627: break;
! 1628: case R_VAR: case R_CONSTANT:
! 1629: if( s->s_real < 0.0 ) {
! 1630: sprintf(warn_msg,"WGT = %g, weight cannot be less than zero.\n", s->s_real);
! 1631: capa_msg(MESSAGE_ERROR,warn_msg);
! 1632: LexiProblem_p->weight = WEIGHT_DEFAULT;
! 1633: } else {
! 1634: LexiProblem_p->weight = (int)(s->s_real);
! 1635: }
! 1636: break;
! 1637: case S_VAR: case S_CONSTANT: LexiProblem_p->weight = WEIGHT_DEFAULT; break;
! 1638: }
! 1639: free_calc_expr(s);
! 1640: }
! 1641: /* Answer try limit is per problem based */
! 1642: void
! 1643: assign_try_limits( s ) Symbol *s;
! 1644: { char warn_msg[WARN_MSG_LENGTH];
! 1645: switch( s->s_type ) {
! 1646: case IDENTIFIER:
! 1647: sprintf(warn_msg,"TRY = var, \"%s\" not defined before use.\n",s->s_name);
! 1648: capa_msg(MESSAGE_ERROR,warn_msg);
! 1649: LexiProblem_p->tries = MAX_TRIES;
! 1650: break;
! 1651: case I_VAR: case I_CONSTANT:
! 1652: if(s->s_int <= 0) {
! 1653: sprintf(warn_msg,"TRIES = %ld, tries cannot be less than or equal to zero.\n",s->s_int);
! 1654: capa_msg(MESSAGE_ERROR,warn_msg);
! 1655: LexiProblem_p->tries = MAX_TRIES;
! 1656: } else {
! 1657: LexiProblem_p->tries = s->s_int;
! 1658: }
! 1659: break;
! 1660: case R_VAR: case R_CONSTANT:
! 1661: if(s->s_real <= 0.0) {
! 1662: sprintf(warn_msg,"TRIES = %g, tries cannot be less than or equal to zero.\n",s->s_real);
! 1663: capa_msg(MESSAGE_ERROR,warn_msg);
! 1664: LexiProblem_p->tries = MAX_TRIES;
! 1665: } else {
! 1666: LexiProblem_p->tries = (int)(s->s_real);
! 1667: }
! 1668: break;
! 1669: case S_VAR: case S_CONSTANT: LexiProblem_p->tries = MAX_TRIES; break;
! 1670: }
! 1671: free_calc_expr(s);
! 1672: }
! 1673: /* Answer hint is per problem based */
! 1674: void
! 1675: assign_hint( s ) Symbol *s;
! 1676: { char warn_msg[WARN_MSG_LENGTH];
! 1677:
! 1678: switch( s->s_type ) {
! 1679: case IDENTIFIER:
! 1680: sprintf(warn_msg,"HINT = var, \"%s\" not defined before use.\n", s->s_name);
! 1681: capa_msg(MESSAGE_ERROR,warn_msg);
! 1682: LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
! 1683: break;
! 1684: case I_VAR: case I_CONSTANT:
! 1685: if( s->s_int < 0 ) {
! 1686: sprintf(warn_msg,"HINT = %ld, show hint cannot be less than zero.\n", s->s_int);
! 1687: capa_msg(MESSAGE_ERROR,warn_msg);
! 1688: LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
! 1689: } else {
! 1690: LexiProblem_p->show_hint = s->s_int;
! 1691: }
! 1692: break;
! 1693: case R_VAR: case R_CONSTANT:
! 1694: if( s->s_real < 0.0 ) {
! 1695: sprintf(warn_msg,"HINT = %g, show hint cannot be less than zero.\n", s->s_real);
! 1696: capa_msg(MESSAGE_ERROR,warn_msg);
! 1697: LexiProblem_p->show_hint = SHOW_HINT_DEFAULT;
! 1698: } else {
! 1699: LexiProblem_p->weight = (int)(s->s_real);
! 1700: }
! 1701: break;
! 1702: case S_VAR: case S_CONSTANT: LexiProblem_p->show_hint = SHOW_HINT_DEFAULT; break;
! 1703: }
! 1704: free_calc_expr(s);
! 1705: }
! 1706:
! 1707: /* Assign answer units string to CurrAnsInfo first */
! 1708: void
! 1709: assign_units( s ) Symbol *s;
! 1710: {
! 1711: char symb_str[ONE_TWO_EIGHT];
! 1712: char warn_msg[WARN_MSG_LENGTH];
! 1713:
! 1714: switch( s->s_type ) {
! 1715: case IDENTIFIER:
! 1716: sprintf(warn_msg,"UNIT = var, \"%s\" not defined before use.\n", s->s_name);
! 1717: capa_msg(MESSAGE_ERROR,warn_msg);
! 1718: break;
! 1719: case I_VAR: case I_CONSTANT:
! 1720: sprintf(warn_msg,"UNIT = %ld, unit cannot be a number.\n", s->s_int);
! 1721: capa_msg(MESSAGE_ERROR,warn_msg);
! 1722: break;
! 1723: case R_VAR: case R_CONSTANT:
! 1724: sprintf(warn_msg,"UNIT = %g, unit cannot be a number.\n", s->s_real);
! 1725: capa_msg(MESSAGE_ERROR,warn_msg);
! 1726: break;
! 1727: case S_VAR: case S_CONSTANT:
! 1728: strcpy(symb_str,s->s_str);
! 1729: strcpy(CurrAnsInfo.ans_unit_str,symb_str);
! 1730: /*CurrAnsInfo.ans_unit = u_parse_unit(symb_str);*/
! 1731: /*if (gUnitError) {
! 1732: sprintf(warn_msg,"Error in unit specified: %s\n",symb_str);
! 1733: capa_msg(MESSAGE_ERROR,warn_msg);
! 1734: }*/
! 1735: break;
! 1736: }
! 1737: }
! 1738: void
! 1739: assign_sigs( lb, ub ) int lb; int ub;
! 1740: {
! 1741: CurrAnsInfo.ans_sig_lb = lb;
! 1742: CurrAnsInfo.ans_sig_ub = ub;
! 1743: }
! 1744:
! 1745: void
! 1746: assign_id_list( s ) Symbol *s;
! 1747: {
! 1748: char warn_msg[WARN_MSG_LENGTH];
! 1749:
! 1750: switch( s->s_type ) {
! 1751: case IDENTIFIER:
! 1752: sprintf(warn_msg,"Eval = < ID @ Pts >, \"%s\" not defined before use.\n", s->s_name);
! 1753: capa_msg(MESSAGE_ERROR,warn_msg);
! 1754: break;
! 1755: case I_VAR: case I_CONSTANT:
! 1756: sprintf(warn_msg,"Eval = < %ld @ Pts >, ID cannot be a number.\n", s->s_int);
! 1757: capa_msg(MESSAGE_ERROR,warn_msg);
! 1758: break;
! 1759: case R_VAR: case R_CONSTANT:
! 1760: sprintf(warn_msg,"Eval = < %.16g @ Pts >, ID cannot be a number.\n", s->s_real);
! 1761: capa_msg(MESSAGE_ERROR,warn_msg);
! 1762: break;
! 1763: case S_VAR: case S_CONSTANT:
! 1764: CurrAnsInfo.ans_id_list = strsave(s->s_str);
! 1765: break;
! 1766: }
! 1767: }
! 1768:
! 1769: /* void assign_pts ( Symbol* coord1, Symbol* coord2, Symbol* num) { */
! 1770: void assign_pts (coord1, coord2, num)Symbol *coord1;Symbol *coord2;Symbol *num;
! 1771: {
! 1772: PointsList_t *pt;
! 1773: if( LastPtsList != NULL ) {
! 1774: /*LastPtsList->pts_next = gen_ptslist( coord1, coord2, num );*/
! 1775: pt = LastPtsList->pts_next;
! 1776: while( pt->pts_next != NULL ) {
! 1777: pt = pt->pts_next;
! 1778: }
! 1779: LastPtsList = pt;
! 1780: } else {
! 1781: /*CurrPtsList = gen_ptslist( coord1, coord2, num );*/
! 1782: LastPtsList = CurrPtsList;
! 1783: }
! 1784: if(coord1->s_type == S_CONSTANT) {
! 1785: capa_mfree(coord1->s_str); capa_mfree((char *)coord1);
! 1786: }
! 1787: if(coord2->s_type == S_CONSTANT) {
! 1788: capa_mfree(coord2->s_str); capa_mfree((char *)coord2);
! 1789: }
! 1790: if(num->s_type == I_CONSTANT || num->s_type == R_CONSTANT) {
! 1791: capa_mfree((char *)num);
! 1792: }
! 1793: }
! 1794:
! 1795: /* =========================================================================== */
! 1796:
! 1797:
! 1798:
! 1799:
! 1800:
! 1801:
! 1802: /* =========================================================================== */
! 1803:
! 1804: void start_question_over()
! 1805: {
! 1806: /*free_problems(LexiProblem_p);*/
! 1807: LexiProblem_p = (Problem_t *) capa_malloc(sizeof(Problem_t),1);
! 1808: /*problem_default(LexiProblem_p);*/
! 1809: begin_question();
! 1810: }
! 1811:
! 1812: void
! 1813: init_new_prob()
! 1814: {
! 1815: if (LastProblem_p) {
! 1816: LastProblem_p->next = LexiProblem_p;
! 1817: } else {
! 1818: FirstProblem_p = LexiProblem_p;
! 1819: }
! 1820: LastProblem_p = LexiProblem_p;
! 1821: Lexi_qnum++;
! 1822: LexiProblem_p = (Problem_t *) capa_malloc(sizeof(Problem_t),1); /* *** */
! 1823: /*problem_default(LexiProblem_p);*/
! 1824: }
! 1825: void
! 1826: add_answer_cnt(op)int op;
! 1827: {
! 1828: LexiProblem_p->ans_cnt++;
! 1829: if(LexiProblem_p->ans_op == 0) { /* the very first /AND or /OR */
! 1830: LexiProblem_p->ans_op = op;
! 1831: } else {
! 1832: if( LexiProblem_p->ans_op != op ) { char warn_msg[WARN_MSG_LENGTH];
! 1833: sprintf(warn_msg,"When specifying multiple answers, either /AND or /OR can be used, but not both.\n");
! 1834: capa_msg(MESSAGE_ERROR,warn_msg);
! 1835: }
! 1836: }
! 1837: }
! 1838:
! 1839: /* -- called when forming answer_expr */
! 1840: void
! 1841: finish_answer_info()
! 1842: {
! 1843: AnswerInfo_t *ai;
! 1844:
! 1845: if( LexiProblem_p->ans_cnt == 1 ) { /* Only one answer is defined */
! 1846: LexiProblem_p->answer = CurrAnsInfo.ans_str;
! 1847: LexiProblem_p->ans_type = CurrAnsInfo.ans_type;
! 1848: LexiProblem_p->calc = CurrAnsInfo.ans_calc;
! 1849: LexiProblem_p->tol_type = CurrAnsInfo.ans_tol_type;
! 1850: LexiProblem_p->tolerance = CurrAnsInfo.ans_tol;
! 1851: LexiProblem_p->sig_ubound= CurrAnsInfo.ans_sig_ub;
! 1852: LexiProblem_p->sig_lbound= CurrAnsInfo.ans_sig_lb;
! 1853: LexiProblem_p->id_list = CurrAnsInfo.ans_id_list;
! 1854: LexiProblem_p->pts_list = CurrAnsInfo.ans_pts_list;
! 1855: strcpy(LexiProblem_p->ans_fmt,CurrAnsInfo.ans_fmt);
! 1856: strcpy(LexiProblem_p->unit_str,CurrAnsInfo.ans_unit_str);
! 1857: LexiProblem_p->ans_unit = CurrAnsInfo.ans_unit;
! 1858: } else {
! 1859: ai = (AnswerInfo_t *)capa_malloc(sizeof(AnswerInfo_t),1);
! 1860: ai->ans_str = CurrAnsInfo.ans_str;
! 1861: ai->ans_type = CurrAnsInfo.ans_type;
! 1862: ai->ans_calc = CurrAnsInfo.ans_calc;
! 1863: ai->ans_tol_type = CurrAnsInfo.ans_tol_type;
! 1864: ai->ans_tol = CurrAnsInfo.ans_tol;
! 1865: ai->ans_sig_ub = CurrAnsInfo.ans_sig_ub;
! 1866: ai->ans_sig_lb = CurrAnsInfo.ans_sig_lb;
! 1867: ai->ans_id_list = CurrAnsInfo.ans_id_list;
! 1868: ai->ans_pts_list = CurrAnsInfo.ans_pts_list;
! 1869: strcpy(ai->ans_fmt,CurrAnsInfo.ans_fmt);
! 1870: strcpy(ai->ans_unit_str,CurrAnsInfo.ans_unit_str);
! 1871: ai->ans_unit = CurrAnsInfo.ans_unit;
! 1872: ai->ans_next = NULL;
! 1873: if(LexiProblem_p->ans_cnt == 2) {
! 1874: LexiProblem_p->ans_list = ai;
! 1875: } else {
! 1876: (LexiProblem_p->ans_list_last)->ans_next = ai;
! 1877: }
! 1878: LexiProblem_p->ans_list_last = ai;
! 1879: }
! 1880:
! 1881: }
! 1882:
! 1883: /* === End of capaGrammarDef.y ============================================= */
! 1884:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>