### # sample calculator # input ::= ws expr ws eoi; expr ::= ws powterm expr_arg1 [{ws '^' ws powterm expr_arg2}]; powterm ::= ws factor powterm_arg1 [{ws ('*' powterm_mul | '/' powterm_div) ws factor powterm_arg2}]; factor ::= ws term factor_arg1 [{ws ('+' factor_add | '-' factor_sub) ws term factor_arg2 }]; term ::= '(' ws expr ws ')' term_paren | '-' ws expr term_minus | number term_number; number ::= number_start {dgt} ['.' {dgt}] [('e'|'E') ['-'] {dgt}] number_end; dgt ::= '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'; ws ::= [{' '|'\t'|'\n'|'\r'}]; %% #include #include #include #include extern double expr_value; int debug = 1; /* program entry */ int main(int argc,char* argv[]) { int i; if (argc == 1) { printf("Usage: %s EXPRESSION...\n",argv[0]); return 1; } for (i = 1; i < argc; i++) { char not_used[10]; int retval; retval = __BNF_str_io_parser(argv[i],not_used, input); if (retval == 0) printf("%s = %f\n",argv[i],expr_value); else printf("%s = syntax error\n",argv[i]); } return 0; } /* * parser functions */ /* number */ char* number_start_pos; double number_value; number_start() { number_start_pos = __BNF_input; return 0; } number_end() { char tmp[64]; strncpy(tmp, number_start_pos, __BNF_input - number_start_pos); tmp[__BNF_input - number_start_pos] = '\0'; number_value = atof(tmp); if (debug) printf("Got number `%s' = %f\n",tmp,number_value); return 0; } /* term */ double term_value; term_paren() { term_value = expr_value; if (debug) printf("term: got paren: term_value = %f\n",term_value); return 0; } term_minus() { term_value = -expr_value; if (debug) printf("term: got unary minus: term_value = %f\n",term_value); return 0; } term_number() { term_value = number_value; if (debug) printf("term: got number: term_value = %f\n",term_value); return 0; } /* factor */ int factor_opmode; /* 1 = add, 2 = sub */ double factor_value; factor_arg1() { factor_value = term_value; if (debug) printf("factor: got first num: factor_value = %f\n",factor_value); return 0; } factor_add() { factor_opmode=1; return 0; } factor_sub() { factor_opmode=2; return 0; } factor_arg2() { switch(factor_opmode) { case 1: factor_value += term_value; break; case 2: factor_value -= term_value; break; } if (debug) printf("factor: got second num: factor_value = %f\n",factor_value); return 0; } /* powterm */ int powterm_opmode; /* 1 = mul, 2 = div */ double powterm_value; powterm_arg1() { powterm_value = factor_value; if (debug) printf("powterm: got first num: powterm_value = %f\n",powterm_value); return 0; } powterm_mul() { powterm_opmode = 1; return 0; } powterm_div() { powterm_opmode = 2; return 0; } powterm_arg2() { switch(powterm_opmode) { case 1: powterm_value *= factor_value; break; case 2: powterm_value /= factor_value; break; } if (debug) printf("powterm: got second num: powterm_value = %f\n",powterm_value); return 0; } /* expr */ double expr_value = -1; expr_arg1() { expr_value = powterm_value; if (debug) printf("expr: got first num: expr_value = %f\n",expr_value); return 0; } expr_arg2() { // expr_value = pow(expr_value, powterm_value); if (debug) printf("expr: got second num: expr_value = %f\n",expr_value); return 0; }