bc2.c
来自「自己做的常用库和实现的数据结构。public domain.」· C语言 代码 · 共 168 行
C
168 行
#include "my.h"#define MAX_LEN 80#define sub_node_test(X) if(X->tag == PTR) { \ X->type.oprand = process_glist_link(X->type.new_head); \ X->tag = RAND; \ goto loop; \ }typedef enum { RAND, CODE, PTR } elem_type_tag;typedef union { double oprand; char opcode; struct glist_node *new_head;} type_union;typedef struct glist_node { elem_type_tag tag; type_union type; struct glist_node *next;} GLIST;void free_glist_next_node(GLIST *p){ GLIST *t = p->next; p->next = t->next; free(t);}void free_whole_glist(GLIST *p){ GLIST *t; while(p) { t = p->next; free(p); p = t; }}void process_unit(GLIST *t1, GLIST *t2, GLIST *t3){ switch(t2->type.opcode) { case '+': t1->type.oprand += t3->type.oprand; break; case '-': t1->type.oprand -= t3->type.oprand; break; case '*': t1->type.oprand *= t3->type.oprand; break; case '/': t1->type.oprand /= t3->type.oprand; break; case '%': t1->type.oprand = (int)t1->type.oprand % (int)t3->type.oprand; } free_glist_next_node(t1); free_glist_next_node(t2);}double process_glist_link(GLIST *head){ GLIST *p, *t1, *t2; double t;loop: p=head; sub_node_test(p); if((t1 = p->next) == NULL) { t = p->type.oprand; free(p); return t; } t1=t1->next; sub_node_test(t1->type.new_head); if((t2=t1->next) == NULL) process_unit(p, p->next, t1); else { t1=p->next; if( (t1->type.opcode == '+' || t1->type.opcode == '-') && (t2->type.opcode == '*' || t2->type.opcode == '/' || t2->type.opcode == '%')) { sub_node_test(t2->next->type.new_head); process_unit(t1->next, t2, t2->next); } else process_unit(p, t1, t1->next); }}void parse_input(const char *input_buf, const char *input_buf_tail, char *tmp_buf, GLIST **glp){ const char *p = input_buf, *head_tag, *tail_tag; size_t cnt, cnt2; for(;;) { if(*p == '(') { for(cnt=0,cnt2=0,tail_tag = head_tag = p; p != input_buf_tail; p++) { if(*p == '(') cnt++; else if(*p == ')' && ++cnt2 == cnt) { tail_tag = p; break; } } if(head_tag == tail_tag) goto input_format_error; *glp = (GLIST *)mem('m', sizeof(GLIST)); (*glp)->tag = PTR; parse_input(head_tag+1, tail_tag-1, tmp_buf, &((*glp)->type.new_head)); if(p++ == input_buf_tail) goto over; } else if( *p == '-' || *p == '+' ) { if(p == input_buf_tail) goto input_format_error; if(isdigit( *(p+1)) || *(p+1) == '(' || *(p+1) == '.') { *glp = (GLIST *)mem('m', sizeof(GLIST)); (*glp)->tag = RAND; (*glp)->type.oprand = 0.0; } } else if(isdigit(*p) || *p == '.') { for(head_tag = tail_tag = p; p != input_buf_tail; p++) if(! isdigit(*p) && *p != '.') { tail_tag = --p; break; } yastrcpy(tmp_buf, head_tag, tail_tag); *glp = (GLIST *)mem('m', sizeof(GLIST)); (*glp)->tag = RAND; (*glp)->type.oprand = atof(tmp_buf); if(p++ == input_buf_tail) goto over; } if(p == input_buf_tail) goto input_format_error; *glp = (GLIST *)mem('m', sizeof(GLIST)); (*glp)->tag = CODE; (*glp)->type.opcode = *p++; parse_input(p, input_buf_tail, tmp_buf, &((*glp)->next)); }input_format_error: free_whole_glist(*glp); fatal_error("Fatal: input format error");over: (*glp)->next = NULL; return;}void preprocess_input(char *input_buf, size_t nmemb, char **input_buf_tail){ int c; size_t left=0, right=0, i=0; while( (c=getchar()) != '\n' && c != EOF && i < nmemb-1) if(isdigit(c) || c=='+' || c=='-' || c=='*' || c=='/' || c=='%' || c=='(' || c== ')' || c=='.') { input_buf[i++] = c; if(c=='(') left++; else if(c==')') right++; } if(left != right) fatal_error("Fatal: input format error"); *input_buf_tail = &input_buf[i-1];}int main(void){ char input_buf[MAX_LEN+1], tmp_buf[MAX_LEN+1]; char *input_buf_tail; double result; GLIST bc_glist, *glp = &bc_glist; preprocess_input(input_buf, MAX_LEN+1, &input_buf_tail); parse_input(input_buf, input_buf_tail, tmp_buf, &glp); result = process_glist_link(glp); printf("%f\n", result); return EXIT_SUCCESS;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?