Simple 4 operations calculator ... {{{ awk # usage: print calc("5 * (1 + 2) * 5 + 7") # reads and update s[0] # return the first token function next_token(s, t) { sub(/^[[:space:]]*/,"", s[0]) if (match(s[0], /^[()]/) || match(s[0], /^[-+]?[0-9]+(\.[0-9]+)*/) || match(s[0], /^[-+*/]/)) { t = substr(s[0], RSTART, RLENGTH) s[0] = substr(s[0], RLENGTH+1) return t } else { return "" } } # read input and performs the shuting-yard algorithm # result is in postfixed # return the length of the postfixed array function s_y( input, postfixed ,len, stack, head, op, s, token, pre) { # precedence table pre["+"]=pre["-"]=1 pre["*"]=pre["/"]=2 pre["("]=0 s[0] = input while (token = next_token(s)) { if (token ~ /^[-+]?[0-9]+(\.[0-9]+)*/) { postfixed[++len] = token } else if (token ~ /[-+/*]/) { while ((head > 0) && (pre[token] <= pre[stack[head]])) { postfixed[++len] = stack[head] head-=1 } stack[++head] = token } else if (token ~ /[(]/) { stack[++head] = token } else if (token ~ /[)]/) { while ((head > 0) && (stack[head] != "(")) { postfixed[++len] = stack[head] head -= 1 } if (head == 0) { print "Syntax Error" return 0 } else { head -= 1 } } } while ((head > 0)) { postfixed[++len] = stack[head--] } return len } #eval the postfixed operation function eval(postfixed, len, stack, ptr, i) { for (i=1; i<=len; i++) { if (postfixed[i] == "-") { ptr-=1 stack[ptr] = stack[ptr] - stack[ptr+1] } else if (postfixed[i] == "+") { ptr-=1 stack[ptr] = stack[ptr] + stack[ptr+1] } else if (postfixed[i] == "*") { ptr-=1 stack[ptr] = stack[ptr] * stack[ptr+1] } else if (postfixed[i] == "/") { ptr-=1 stack[ptr] = stack[ptr] / stack[ptr+1] } else { stack[++ptr] = postfixed[i] } } return stack[ptr] } function calc(input, postfixed, len) { len = s_y(input, postfixed) return eval(postfixed,len) } BEGIN { print calc("5.4 * (1 + -2) * 5 + 7") } }}}
Summary:
This change is a minor edit.
Username: