Ruby
Number of characters: 103
N='( *-?[\d.]+ *)'
def e x
x.sub!(/\(#{N}\)|#{N}([^.\d])#{N}/){$1or(e$2).send$3,e($4)}?e(x):x.to_f
end
This is a non-recursive version of The Wicked Flea's solution. Parenthesized sub-expressions are evaluated bottom-up instead of top-down.
Edit: Converting the 'while' to a conditional + tail recursion has saved a few characters, so it is no longer non-recursive (though the recursion is not semantically necessary.)
Edit: Borrowing Daniel Martin's idea of merging the regexps saves another 11 characters!
Edit: That recursion is even more useful than I first thought! x.to_f can be rewritten as e(x), if x happens to contain a single number.
Edit: Using 'or' instead of '||' allows a pair of parentheses to be dropped.
Long version:
# Decimal number, as a capturing group, for substitution
# in the main regexp below.
N='( *-?[\d.]+ *)'
# The evaluation function
def e(x)
matched = x.sub!(/\(#{N}\)|#{N}([^\d.])#{N}/) do
# Group 1 is a numeric literal in parentheses. If this is present then
# just return it.
if $1
$1
# Otherwise, $3 is an operator symbol and $2 and $4 are the operands
else
# Recursively call e to parse the operands (we already know from the
# regexp that they are numeric literals, and this is slightly shorter
# than using :to_f)
e($2).send($3, e($4))
# We could have converted $3 to a symbol ($3.to_s) or converted the
# result back to string form, but both are done automatically anyway
end
end
if matched then
# We did one reduction. Now recurse back and look for more.
e(x)
else
# If the string doesn't look like a non-trivial expression, assume it is a
# string representation of a real number and attempt to parse it
x.to_f
end
end