式を評価する1つの方法は、再帰的降下パーサを使用することです。 http://en.wikipedia.org/wiki/Recursive_descent_parser
ここBNFの形態での文法は次のとおりここ http://en.wikipedia.org/wiki/Backus-Naur_form
Expr ::= Term ('+' Term | '-' Term)*
Term ::= Factor ('*' Factor | '/' Factor)*
Factor ::= ['-'] (Number | '(' Expr ')')
Number ::= Digit+
*は、1つ以上の反復を意味+、先行する要素が0回以上繰り返される手段、角括弧はオプションを意味します。
文法は、最も高い優先度の要素が最初に一緒に集められるか、この場合は最初に評価されることを保証します。 文法の各ノードにアクセスするときに、抽象構文ツリーを構築するのではなく、現在のノードを評価して値を返します。
例コード(完璧ではないが、あなたのコードにBNFをマッピングする方法のアイデアを与える必要があります):
def parse_expr():
term = parse_term()
while 1:
if match('+'):
term = term + parse_term()
elif match('-'):
term = term - parse_term()
else: return term
def parse_term():
factor = parse_factor()
while 1:
if match('*'):
factor = factor * parse_factor()
elif match('/'):
factor = factor/parse_factor()
else: return factor
def parse_factor():
if match('-'):
negate = -1
else: negate = 1
if peek_digit():
return negate * parse_number()
if match('('):
expr = parse_expr()
if not match(')'): error...
return negate * expr
error...
def parse_number():
num = 0
while peek_digit():
num = num * 10 + read_digit()
return num
1 + 2 * 10 - 2
のあなたの例を評価する方法を表示するには:
call parse_expr stream is 1 + 2 * 10 - 2
call parse term
call parse factor
call parse number which returns 1 stream is now + 2 * 10 - 2
match '+' stream is now 2 * 10 - 2
call parse factor
call parse number which returns 2 stream is now * 10 - 2
match '*' stream is now 10 - 2
call parse number which returns 10 stream is now - 2
computes 2 * 10, return 20
compute 1 + 20 -> 21
match '-' stream is now 2
call parse factor
call parse number which returns 2 stream is empty
compute 21 - 2, return 19
return 19
評価する方法はたくさんあります。ここに1つあります:http://en.wikipedia.org/wiki/Shunting-yard_algorithm –
好きな言語は? Irony.netを使っている.Netの例があります。 http://blog.miraclespain.com/archive/2009/Oct-07.html – gjvdkamp