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 + -
显示快捷键?