/** * This is the main function for parsing/code generation. * * @param input_file the raw token file to read from (all numbers and spaces) */ int pl0_parse(FILE *input_file, int a_flag) { token_type token = nulsym; int error_code = 0; token = get_token(input_file); error_code = block(input_file, &token); if(!error_code) { if(token != periodsym) { error_code = 9; } else { // return 0; in main() error_code = emit(OPR, 0, OPR_RET); if(error_code) return error_code; } } if(!error_code && a_flag) { printf("%s\n\n", get_parse_error(error_code)); print_code(stdout); print_code_pretty(stdout); printf("\n"); } return error_code; }
amort_sched_ptr amort_opt( amort_sched_ptr amortsched, void *parse_env) { char buffer[200], *errp; unsigned long ii; unsigned prec = amortsched->prec; var_store value; numeric_ptr nval; struct tm *times_E, *times_I; /* print amortization options */ times_E = (struct tm *)calloc(1, sizeof(struct tm)); ii = amortsched->Eff_Date_jdn; times_E->tm_mday = amortsched->day_E; times_E->tm_mon = amortsched->month_E - 1; times_E->tm_year = amortsched->year_E - 1900; times_E->tm_wday = (ii + 1) % 7; times_E->tm_yday = amortsched->yday_E; times_I = (struct tm *)calloc(1, sizeof(struct tm)); ii = amortsched->Init_Date_jdn; times_I->tm_mday = amortsched->day_I; times_I->tm_mon = amortsched->month_I - 1; times_I->tm_year = amortsched->year_I - 1900; times_I->tm_wday = (ii + 1) % 7; times_I->tm_yday = amortsched->yday_I; printf("\n******************************"); qof_strftime(buffer, (size_t)50, "%c", times_E); printf("\nEffective Date: %s\n", buffer); qof_strftime(buffer, (size_t)50, "%c", times_I); printf("Initial Payment Date: %s\n", buffer); free(times_E); free(times_I); printf("The Original Present Value (pv) is: %.*f\n", (int)prec, amortsched->pv); printf("The Original Periodic Payment (pmt) is: %.*f\n", (int)prec, amortsched->pmt); printf("The Original Future Value (fv) is: %.*f\n", (int)prec, amortsched->fv); printf("The Delayed Present Value (pve) is: %.*f\n", (int)prec, amortsched->pve); printf("The New Periodic Payment (pmt) for pve is: %.*f\n\n", (int)prec, amortsched->new_pmt); printf("The amortization options are:\n"); printf("1 -- Amortize with Original Amount and Constant Payment to Principal: %.*f\n", (int) prec, amortsched->cpmt1); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_1); printf("2 -- Amortize with Delayed Amount and Constant Payment to Principal: %.*f\n", (int)prec, amortsched->cpmt2); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_2); printf("3 -- Amortize with Original Transaction Values\n"); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_3); printf("4 -- Amortize with Delayed Amount, Original Periodic Payment\n"); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_4); printf("5 -- Amortize with Delayed Amount, New Periodic Payment\n"); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_5); if ( amortsched->new_n ) { printf("6 -- Amortize with Original Amount, Original Periodic Payment,\n"); printf(" new number of total payments (n): %u\n", amortsched->new_n); printf(" and final payment: %.*f\n", (int)prec, amortsched->final_pmt_opt_6); } /* endif */ printf("Enter choice 1, 2, 3, 4, 5 or 6: "); fgets(buffer, 190, stdin); amortsched->option = buffer[0] - '0'; printf("Amortization Schedule:\n"); printf("y -- Yearly Summary\n"); printf("p -- Periodic Payment\n"); if ( amortsched->option < 3 ) { printf("Enter Choice y or p: "); } else { printf("f -- Fixed Advanced Payment\n"); printf("a -- Variable Advanced Payment\n"); printf("Enter Choice y, p, f or a: "); } /* endif */ fgets(buffer, 190, stdin); amortsched->summary = buffer[0]; if ( amortsched->summary == 'f' ) { if ( amortsched->fixed_pmt != 0.0 ) { printf("Current Fixed Prepayment: %.*f\nChange Fixed Prepayment? (y/n): ", (int)prec, amortsched->fixed_pmt); fgets(buffer, 190, stdin); } else { buffer[0] = 'y'; } /* endif */ if ( buffer[0] == 'y' ) { printf("Enter Fixed Prepayment Amount: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched->fixed_pmt = (double)(nval->value.int_value); break; case DBL_TYPE: amortsched->fixed_pmt = nval->value.dbl_value; break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ } /* endif */ } /* endif */ return amortsched; } /* amort_opt */
int main(int argc, char **argv, char **env) { char buffer[200], *errp; size_t sbuf; size_t retcnt; var_store value; var_store_ptr value_list; numeric_ptr nval; unsigned compute, jj, yrE, monthE, dayE, yrI, monthI, dayI; struct tm *times_E, *times_I; void *parse_env; amort_sched amortsched; financial_info fininfo; /* check dynamic storage allocation */ /* mtrace(); */ set_default(&fininfo); set_fin_vars(); parse_env = init_parser(predefined_fin_vars, '.', ',', trans_numeric, numeric_ops, negate_numeric, free_numeric); npp = fininfo.npp; ir = fininfo.ir; pv = fininfo.pv; pmt = fininfo.pmt; fv = fininfo.fv; CF = fininfo.CF; PF = fininfo.PF; disc = fininfo.disc; bep = fininfo.bep; fininfo.prec = prec; printf("Single Letter Commands:\na -- amortization schedule\nc -- compute financial variable\nd -- delete variable\ns -- output financial variable status\nq -- quit\nv -- list defined variables\n"); for (;;) { printf("<>"); retcnt = strlen(fgets(buffer, 190, stdin)); if ( (retcnt == 2) && (strchr(sl_commands, buffer[0]) != NULL) ) { if ( buffer[0] == 'q' ) break; amortsched.prec = fininfo.prec; switch ( buffer[0] ) { case 'a': if ( amortsched.Eff_Date_jdn && amortsched.Init_Date_jdn ) { printf("Current Effective year: %u\nCurrent Effective month: %u\nCurrent Effective day: %u\nCurrent Initial year: %u\nCurrent Initial month: %u\nCurrent Initial day %u\n", amortsched.year_E, amortsched.month_E, amortsched.day_E, amortsched.year_I, amortsched.month_I, amortsched.day_I); printf("Change dates ? (y/n) "); fgets(buffer, 190, stdin); } else { buffer[0] = 'y'; } /* endif */ if ( buffer[0] == 'y' ) { printf("Enter Effective Date - year: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.year_E = nval->value.int_value; break; case DBL_TYPE: amortsched.year_E = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ printf("Enter Effective Date - month: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.month_E = nval->value.int_value; break; case DBL_TYPE: amortsched.month_E = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ printf("Enter Effective Date - day: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.day_E = nval->value.int_value; break; case DBL_TYPE: amortsched.day_E = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ printf("Enter Initial Payment Date - year: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.year_I = nval->value.int_value; break; case DBL_TYPE: amortsched.year_I = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ printf("Enter Initial Payment Date - month: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.month_I = nval->value.int_value; break; case DBL_TYPE: amortsched.month_I = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ printf("Enter Initial Payment Date - day: "); fgets(buffer, 190, stdin); if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: amortsched.day_I = nval->value.int_value; break; case DBL_TYPE: amortsched.day_I = (unsigned)(nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ } /* endif */ amortsched.n = npp; amortsched.nint = ir; amortsched.pv = pv; amortsched.pmt = pmt; amortsched.fv = fv; amortsched.CF = CF; amortsched.PF = PF; amortsched.disc = disc; amortsched.bep = bep; Amortization_init(&amortsched); amort_opt(&amortsched, parse_env); (void)Amortization_Schedule(&amortsched); prt_amortization_schedule(&amortsched, stdout); Amortization_free(&amortsched); break; case 'c': printf("Compute:\nn - 1\ni - 2\npv - 3\npmt - 4\nfv - 5\n1, 2, 3, 4 or 5: "); retcnt = strlen(fgets(buffer, 190, stdin)); compute = buffer[0] - '0'; switch ( compute-- ) { case 0: /* all values specified nothing to compute */ break; case 1: /* compute number of periods, npp */ printf("Computing numbor of periods\n"); npp = fi_calc_num_payments(&fininfo); printf("Number of Periods: %u\n", npp); nval = (numeric_ptr)(predefined_fin_vars[compute].value); nval->value.int_value = npp; break; case 2: /* compute interest, ir */ printf("Computing interest rate\n"); ir = fi_calc_interest(&fininfo); printf("Nominal Interest Rate: %.*f\n", prec, ir); nval = (numeric_ptr)(predefined_fin_vars[compute].value); nval->value.dbl_value = ir; break; case 3: /* compute present value, pv */ printf("Computing Present Value\n"); pv = fi_calc_present_value(&fininfo); printf("Present Value: %.*f\n", prec, pv); nval = (numeric_ptr)(predefined_fin_vars[compute].value); nval->value.dbl_value = pv; break; case 4: /* compute periodic payment, pmt */ printf("Computing periodic payment\n"); pmt = fi_calc_payment(&fininfo); printf("Periodic Payment: %.*f\n", prec, pmt); nval = (numeric_ptr)(predefined_fin_vars[compute].value); nval->value.dbl_value = pmt; break; case 5: /* compute future value, fv */ printf("Computing Future Value\n"); fv = fi_calc_future_value(&fininfo); printf("Future Value: %.*f\n", prec, fv); nval = (numeric_ptr)(predefined_fin_vars[compute].value); nval->value.dbl_value = fv; break; default: /* whoops */ break; } /* endswitch */ break; case 'd': printf("Enter name of variable to delete: "); retcnt = strlen(fgets(buffer, 190, stdin)); buffer[retcnt - 1] = EOS; if ( !delete_var(buffer, parse_env) ) { printf("Unable to delete specified variable\n"); } /* endif */ break; case 's': prt_status(&fininfo, stdout); break; case 'v': for ( value_list = parser_get_vars(parse_env) ; value_list ; value_list = value_list->next_var ) { printf("%s: ", value_list->variable_name); nval = (numeric_ptr)(value_list->value); switch ( nval->type ) { case INT_TYPE: printf("%i\n", nval->value.int_value); break; case DBL_TYPE: printf("%.*f\n", prec, nval->value.dbl_value); break; } /* endswitch */ } /* endfor */ break; } /* endswitch */ } else if ( retcnt > 1 ) { buffer[retcnt - 1] = EOS; if ( (errp = parse_string(&value, buffer, parse_env)) == NULL ) { if ( value.variable_name ) printf("Variable: %s\n", value.variable_name); nval = (numeric_ptr)(value.value); switch ( nval->type ) { case INT_TYPE: printf("Evaluated Value: %i\n", nval->value.int_value); break; case DBL_TYPE: printf("Evaluated Value: %.*f\n", prec, nval->value.dbl_value); break; } /* endswitch */ if ( !value.variable_name ) free_numeric(value.value); chk_vars(predefined_fin_vars, fin_vars, fin_type, PREDEFINED_FIN_VARS); fininfo.npp = npp; fininfo.ir = ir; fininfo.pv = pv; fininfo.pmt = pmt; fininfo.fv = fv; fininfo.CF = CF; fininfo.PF = PF; fininfo.disc = disc; fininfo.bep = bep; } else { parse_error(get_parse_error(parse_env), buffer, errp); } /* endif */ } /* endif */ } /* endfor */ exit_parser(parse_env); unset_fin_vars(); } /* main */
int main(int argc, char **argv) { FILE *input_file = NULL; int l_flag = 0, a_flag = 0, v_flag = 0; // output flags if(argc > 1) { int i; for(i = 1; i < argc; i++) { // last arg must be the input_file if((i+1) == argc) { input_file = fopen(argv[i], "r"); if(!input_file) { printf("File %s not found.\n", argv[1]); exit(EXIT_FAILURE); } } else { if(argv[i][0] == '-') { int j; for(j = 1; j < strlen(argv[i]); j++) { if(argv[i][j] == 'l') l_flag = 1; else if(argv[i][j] == 'a') a_flag = 1; else if(argv[i][j] == 'v') v_flag = 1; else { printf("Unknown option: %s\n", argv[i]); exit(EXIT_FAILURE); } } } } } } else { printf("Usage: pl0-compiler [-l] [-a] [-v] /path/to/input_file\n"); exit(EXIT_FAILURE); } FILE *lexeme_file = tmpfile(); pl0_lex(input_file, lexeme_file, l_flag); fclose(input_file); rewind(lexeme_file); int error_code = pl0_parse(lexeme_file, a_flag); fclose(lexeme_file); if(error_code == 0) { FILE *code_file = tmpfile(); print_code(code_file); rewind(code_file); if(v_flag) { printf("Running in PM/0\n"); printf("===============\n\n"); } error_code = pm0(code_file, v_flag); if(v_flag) { printf("\n===============\n\n"); } if(!error_code) { if(v_flag) { printf("Finished without error.\n"); } } else { printf("Error number %d.\n", error_code); } fclose(code_file); } else { printf("Error number %d, %s\n", error_code, get_parse_error(error_code)); } return EXIT_SUCCESS; }
gboolean gnc_exp_parser_parse_separate_vars (const char * expression, gnc_numeric *value_p, char **error_loc_p, GHashTable *varHash ) { parser_env_ptr pe; var_store_ptr vars; struct lconv *lc; var_store result; char * error_loc; ParserNum *pnum; if (expression == NULL) return FALSE; if (!parser_inited) gnc_exp_parser_real_init ( (varHash == NULL) ); result.variable_name = NULL; result.value = NULL; result.next_var = NULL; vars = make_predefined_variables (); if ( varHash != NULL ) { g_hash_table_foreach( varHash, make_predefined_vars_from_external_helper, &vars); } lc = gnc_localeconv (); pe = init_parser (vars, lc->mon_decimal_point, lc->mon_thousands_sep, trans_numeric, numeric_ops, negate_numeric, g_free, func_op); error_loc = parse_string (&result, expression, pe); pnum = result.value; if (error_loc == NULL) { if (gnc_numeric_check (pnum->value)) { if (error_loc_p != NULL) *error_loc_p = (char *) expression; last_error = NUMERIC_ERROR; } else { if (pnum) { if (value_p) *value_p = gnc_numeric_reduce (pnum->value); if (!result.variable_name) g_free (pnum); } if (error_loc_p != NULL) *error_loc_p = NULL; last_error = PARSER_NO_ERROR; } } else { if (error_loc_p != NULL) *error_loc_p = error_loc; last_error = get_parse_error (pe); } if ( varHash != NULL ) { var_store_ptr newVars; gpointer maybeKey, maybeValue; gnc_numeric *numericValue; newVars = parser_get_vars( pe ); for ( ; newVars ; newVars = newVars->next_var ) { pnum = newVars->value; if ( g_hash_table_lookup_extended( varHash, newVars->variable_name, &maybeKey, &maybeValue ) ) { g_hash_table_remove( varHash, maybeKey ); g_free( maybeKey ); g_free( maybeValue ); } numericValue = g_new0( gnc_numeric, 1 ); *numericValue = ((ParserNum*)newVars->value)->value; // WTF? // numericValue = NULL; g_hash_table_insert( varHash, g_strdup(newVars->variable_name), numericValue ); } } else { update_variables (vars); } free_predefined_variables (vars); exit_parser (pe); return last_error == PARSER_NO_ERROR; }