[Home]
HomePage RecentChanges Frequently Asked Questions

SimpleCalc

Simple 4 operations calculator ...

# 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")
}

Edit this page View other revisions Administration
Last edited 2015年09月10日 06:14 UTC by pgas (diff)

Powered by sdf Creative Commons License <pierre.gaston+awk@gmail.com>

Awk Wiki by #awk is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.

AltStyle によって変換されたページ (->オリジナル) /