📄 mfcalc.y
字号:
{AFNCT, HashValue((unsigned char*)"binomdist"), (double(*)(double))&binomdist}, {AFNCT, HashValue((unsigned char*)"normdist"), (double(*)(double))&normdist}, {AFNCT, HashValue((unsigned char*)"norminv"), (double(*)(double))&norminv}, {AFNCT, HashValue((unsigned char*)"chidist"), (double(*)(double))&chidist}, {AFNCT, HashValue((unsigned char*)"chiinv"), (double(*)(double))&chiinv}, {SFNCT, HashValue((unsigned char*)"strlen"), (double(*)(double))&_strlen}, {SFNCT, HashValue((unsigned char*)"eval"), (double(*)(double))&eval}, {FNCT, HashValue((unsigned char*)"erf"), errf}, {FNCT, HashValue((unsigned char*)"erfc"), errfc}, {FNCT, HashValue((unsigned char*)"sign"), sign}, {FNCT, HashValue((unsigned char*)"gammaln"), gammln}, {FNCT, HashValue((unsigned char*)"factorial"), factorial}, {FNCT, HashValue((unsigned char*)"rand"), rand}, {FNCT, HashValue((unsigned char*)"srand"), srand}, {FNCT, HashValue((unsigned char*)"floor"), floor}, {FNCT, HashValue((unsigned char*)"abs"), fabs}, {FNCT, HashValue((unsigned char*)"asin"), asin}, {FNCT, HashValue((unsigned char*)"acos"), acos}, {FNCT, HashValue((unsigned char*)"atan"), atan}, {FNCT, HashValue((unsigned char*)"sinh"), sinh}, {FNCT, HashValue((unsigned char*)"cosh"), cosh}, {FNCT, HashValue((unsigned char*)"tanh"), tanh}, {FNCT, HashValue((unsigned char*)"sin"), sin}, {FNCT, HashValue((unsigned char*)"cos"), cos}, {FNCT, HashValue((unsigned char*)"atan"), atan}, {FNCT, HashValue((unsigned char*)"log10"), log10}, {FNCT, HashValue((unsigned char*)"ln"), log}, {FNCT, HashValue((unsigned char*)"log"), log}, {FNCT, HashValue((unsigned char*)"exp"), exp}, {FNCT, HashValue((unsigned char*)"sqrt"), sqrt}, {0, 0, 0}};// Store strings in a liststatic char **str_list = 0L;static int n_str = 0;static char *PushString(char *text){ if(text && text[0]) { if(str_list = (char**)realloc(str_list, sizeof(char*)*(n_str+1))) str_list[n_str] = strdup(text); return str_list[n_str++]; } return 0L;}//The symbol table: a chain of `struct symrec'static symrec *sym_table, *sym_tab_first;//Rearrange function table with previously used functions in frontvoid ArrangeFunctions(){ symrec *ptr, *ptr1, *ptr2, *next; for(ptr = sym_table, ptr1 = ptr2 = 0L; (ptr); ) { next = ptr->next; if(ptr->name) { ptr->next = ptr1; ptr1 = ptr; } else { ptr->next = ptr2; ptr2 = ptr; } ptr = next; } for(sym_table = 0L, ptr = ptr2; (ptr); ){ next = ptr->next; ptr->next = sym_table; sym_table = ptr; ptr = next; } for(ptr = ptr1; (ptr); ){ next = ptr->next; ptr->next = sym_table; sym_table = ptr; ptr = next; } sym_tab_first = sym_table; bRecent = false;}// Put arithmetic functions and predifened variables in tablevoid InitArithFuncs(DataObj *d){ int i; symrec *ptr, *next; if(d) curr_data = d; if(sym_table) { for (ptr = sym_table; ptr != (symrec *) 0;){ if(ptr) { next = ptr->next; delete (ptr); } ptr = next; } sym_table = sym_tab_first = (symrec *) 0; } for (i = 0; arith_fncts[i].h_name; i++) { ptr = putsym (arith_fncts[i].h_name, arith_fncts[i].f_type); ptr->fnctptr = (double (*)(...))arith_fncts[i].fnct; } ptr = putsym(HashValue((unsigned char*)"zdiv"), VAR); ptr->SetValue(1.0); sym_tab_first = sym_table;}static void init_table (void){ str_list = 0L; n_str = 0; push_syntax();}static void clear_table(){ int i; if(str_list) { for(i = 0; i < n_str; i++) if(str_list[i]) free(str_list[i]); free(str_list); str_list = 0L; n_str = 0; } pop_syntax();}static symrec *putsym (unsigned int h_name, int sym_type){ sym_table = new symrec(h_name, sym_type, sym_table); return sym_table;}static symrec *getsym (unsigned int h_name, char *sym_name){ symrec *ptr; if(!h_name) return 0; for (ptr = sym_table; ptr != (symrec *) 0; ptr = (symrec *)ptr->next) { if (ptr->h_name == h_name){ if(sym_name && !ptr->name) { ptr->SetName(sym_name); bRecent = true; } return ptr; } //predefined variables never end on a digit else if(ptr == sym_tab_first) { if(sym_name && isdigit(sym_name[strlen(sym_name)-1])) return 0; } } return 0;}static intpush(YYSTYPE *res, YYSTYPE *val){ if(val->a_data) { if(!(res->a_data)) { if(!(val->a_data=(double*)realloc(val->a_data, (val->a_count+2)*sizeof(double))))return 0; val->a_data[val->a_count++] = res->val; res->a_data = val->a_data; res->a_count = val->a_count; val->a_data = 0L; val->a_count = 0; val->val = res->val; return 1; } else { if(!(res->a_data=(double*)realloc(res->a_data, (val->a_count+res->a_count)*sizeof(double))))return 0; memcpy(&res->a_data[res->a_count], val->a_data, val->a_count*sizeof(double)); res->a_count += val->a_count; free(val->a_data); val->a_data = 0L; val->a_count = 0; return 1; } } if(!(res->a_data )){ if(!(res->a_data = (double*)malloc(2*sizeof(double))))return 0; res->a_data[0] = res->val; res->a_data[1] = val->val; res->a_count = 2; return 1; } else { if(!(res->a_data = (double*)realloc(res->a_data, (res->a_count+2)*sizeof(double))))return 0; res->a_data[res->a_count] = val->val; res->a_count++; return 1; } return 0;}static intrange_array(YYSTYPE * res, char *range){ AccRange *r; int row, col; anyResult ares; if(!range || !range[0] || !(r = new AccRange(range))) return 0; if(!r->GetFirst(&col, &row) || !(res->a_data = (double*)malloc(r->CountItems() * sizeof(double)))) { delete(r); return 0; } parse_level++; for(res->a_count = 0; r->GetNext(&col, &row); ) { if(curr_data->GetResult(&ares, row, col, parse_level > MAX_PARSE)) { switch(ares.type) { case ET_VALUE: res->a_data[res->a_count++] = ares.value; break; case ET_TEXT: if(ares.text && ares.text[0]) last_err_desc = "#ARGS"; break; case ET_ERROR: last_err_desc = "#ARGS"; break; } } } parse_level--; delete(r); return 1;}static YYSTYPE *proc_clause(YYSTYPE *res){ int i, n, o_pos; char *o_cmd; double *n_data; if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return res; if(!res->text) return res; if(!res->a_data && (res->a_data = (double*)malloc(sizeof(double)))) { res->a_data[0] = res->type == VAR && res->tptr ? res->tptr->GetValue() : res->val; res->a_count = 1; } else if(!res->a_data) return res; if(!(n_data = (double*)malloc(res->a_count * sizeof(double)))) return res; o_pos = buff_pos; o_cmd = buffer; for(i = n = 0; i < res->a_count; i++) { buffer = res->text; buff_pos = 0; if(!syntax_level) break; syntax_level->clval = res->a_data[i]; yyparse(); if(line_res.type == ET_VALUE && line_res.value != 0.0) n_data[n++] = res->a_data[i]; } free(res->a_data); res->a_data = n_data; res->a_count = n; free(res->text); res->text=0L; syntax_level->cl1 = syntax_level->cl2 = 0; buffer = o_cmd; buff_pos = o_pos; return res;}static void exec_clause(YYSTYPE *res){ int i, j; char *cmd; if(!(syntax_level) || !syntax_level->cl1 || syntax_level->cl2 <= syntax_level->cl1) return; if(!(cmd = (char*)malloc(syntax_level->cl2 - syntax_level->cl1 +2)))return; while(buffer[syntax_level->cl1] <= ' ' && syntax_level->cl1 < syntax_level->cl2) syntax_level->cl1++; for(j = 0, i = syntax_level->cl1; i< syntax_level->cl2; i++) { cmd[j++] = buffer[i]; } cmd[j++] = ';'; cmd[j++] = 0; res->text = cmd;}struct parse_info { char *buffer; int buff_pos; DataObj *curr_data; symrec *sym_table; YYSTYPE yylval; struct parse_info *next; char **str_list; char *last_err_desc; int n_str, yychar, yynerrs;};static parse_info *parse_stack = 0L;static void push_parser(){ parse_info *ptr; if(!sym_table) InitArithFuncs(0L); else if(!parse_level && bRecent) ArrangeFunctions(); ptr = (parse_info *) malloc(sizeof(parse_info)); ptr->buffer = buffer; ptr->buff_pos = buff_pos; ptr->curr_data = curr_data; ptr->last_err_desc = last_err_desc; ptr->sym_table = sym_table; sym_table = sym_tab_first; memcpy(&ptr->yylval, &yylval, sizeof(YYSTYPE)); ptr->next = parse_stack; ptr->str_list = str_list; str_list = 0L; ptr->n_str = n_str; n_str = 0; ptr->yychar = yychar; ptr->yynerrs = yynerrs; parse_stack = ptr; last_err_desc = 0L; parse_level++; //reenter ? push_syntax(); syntax_level->last_tok = 0;}static void pop_parser(){ parse_info *ptr; symrec *n; if(ptr = parse_stack) { while(sym_table && sym_table != sym_tab_first) { n = sym_table->next; delete(sym_table); sym_table = n; } if(sym_table) sym_table = ptr->sym_table; parse_stack = ptr->next; buffer = ptr->buffer; buff_pos = ptr->buff_pos; curr_data = ptr->curr_data; last_err_desc = ptr->last_err_desc; memcpy(&yylval, &ptr->yylval, sizeof(YYSTYPE)); str_list = ptr->str_list; n_str = ptr->n_str; yychar = ptr->yychar; yynerrs = ptr->yynerrs; free(ptr); parse_level--; } pop_syntax();}static int is_ttoken(int h_nam){ switch(h_nam) { case 101: return E; case 26992: return PI; case 28381: if(syntax_level) syntax_level->cl1 = buff_pos; return CLAUSE; case 9252: return CLVAL; case 26217: return IF; case 6033: return ELSE; } return 0;}static symrec *curr_sym;static int yylex (void){ int i, c, tok; unsigned int h_nam; char tmp_txt[80]; symrec *s; while((c = buffer[buff_pos++]) == ' ' || c == '\t'); //get first nonwhite char if(!c) return 0; //test for block statement if(c == '{') { for(i= 0; i < 79 && ((tok = buffer[buff_pos]) && (tok != '}')); buff_pos++) { tmp_txt[i++] = (char)tok; } if(buffer[buff_pos] == '}')buff_pos++; tmp_txt[i] = 0; yylval.text = PushString(tmp_txt); return yylval.type = BLOCK; } //test for '..' operator if(c == '.' && buffer[buff_pos] == '.') { buff_pos++; return yylval.type = SER; } //test for number if(c == '.' || isdigit(c)) { for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) == '.' || isdigit(c)); buff_pos++) { tmp_txt[i++] = (char)c; if(i && buffer[buff_pos+1] == 'e' && (buffer[buff_pos+2] == '-' || buffer[buff_pos+2] == '+')){ tmp_txt[i++] = buffer[++buff_pos]; tmp_txt[i++] = buffer[++buff_pos]; } if(i && buffer[buff_pos+1] == '.' && buffer[buff_pos+2] == '.') { //operator '..' buff_pos++; break; } } tmp_txt[i] = 0; sscanf(tmp_txt, "%lf", &yylval.val); return yylval.type = NUM; } //test for name or stringtoken if(isalpha(c) || c=='$') { for(buff_pos--, i = 0; i < 79 && ((c = buffer[buff_pos]) && (isalnum(c) || c == '$')); buff_pos++) { tmp_txt[i++] = (char)c; } tmp_txt[i] = 0; h_nam = HashValue((unsigned char*)tmp_txt); if(tok = is_ttoken(h_nam)) return tok; if(!(s = getsym(h_nam, tmp_txt))){ s = putsym(h_nam, VAR); s->SetName(tmp_txt); } curr_sym = yylval.tptr = s; return s->type; } //test for string if(c == '"' || c == '\'') { for(i= 0; i < 79 && ((tok = buffer[buff_pos]) && (tok != c)); buff_pos++) { tmp_txt[i++] = (char)tok; } if(buffer[buff_pos] == c)buff_pos++; tmp_txt[i] = 0; yylval.text = PushString(tmp_txt); return yylval.type = STR; } tok = 0; switch(c) { case '=': if(buffer[buff_pos] == '=') tok = EQ; break; case '!': if(buffer[buff_pos] == '=') tok = NE; break; case '>': if(buffer[buff_pos] == '=') tok = GE; else return GT; break; case '<': if(buffer[buff_pos] == '=') tok = LE; else if(buffer[buff_pos] == '>') tok = NE; else return LT; break; case '&': if(buffer[buff_pos] == '&') tok = AND; break; case '|': if(buffer[buff_pos] == '|') tok = OR; break; case ')': if(syntax_level) { if(syntax_level->cl1 && syntax_level->next) { syntax_level->next->cl1 = syntax_level->cl1; syntax_level->next->cl2 = buff_pos-1; } } pop_syntax(); break; case '(': push_syntax(); case '?': if(syntax_level) syntax_level->last_tok = c; break; case ':': if(syntax_level) { if(syntax_level->last_tok == '(') return COLR; else if(syntax_level->last_tok == '?') return COLC; } break; case ';': if(syntax_level) { if(syntax_level->last_tok == '(') return PSEP; } break; case '+': if(buffer[buff_pos] == '+') tok = INC; break; case '-': if(buffer[buff_pos] == '-') tok = DEC; break; } if(tok) { buff_pos++; return tok; } //Any other character is a token by itself return c;}bool do_xyfunc(DataObj *d, double x1, double x2, double step, char *expr, lfPOINT **pts, long *npts, char *param){ double x, y; symrec *sx, *sy; lfPOINT *new_points;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -