Một cách để thực hiện đánh giá biểu thức là bằng trình phân tích cú pháp gốc đệ quy. http://en.wikipedia.org/wiki/Recursive_descent_parser
Dưới đây là một ví dụ ngữ pháp ở dạng BNF: http://en.wikipedia.org/wiki/Backus-Naur_form
Expr ::= Term ('+' Term | '-' Term)*
Term ::= Factor ('*' Factor | '/' Factor)*
Factor ::= ['-'] (Number | '(' Expr ')')
Number ::= Digit+
đây * có nghĩa là các yếu tố trước được lặp lại không hay nhiều lần, + có nghĩa là một hoặc nhiều lặp đi lặp lại, dấu ngoặc vuông có nghĩa là không bắt buộc.
Ngữ pháp đảm bảo rằng các yếu tố ưu tiên cao nhất được thu thập cùng nhau trước tiên hoặc trong trường hợp này, được đánh giá trước tiên. Khi bạn truy cập từng nút trong ngữ pháp, thay vì xây dựng một cây cú pháp trừu tượng, bạn đánh giá nút hiện tại và trả về giá trị.
Ví dụ mã (không hoàn hảo nhưng sẽ cho bạn một ý tưởng về làm thế nào để lập bản đồ BNF để code):
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
Để hiển thị như thế nào ví dụ của bạn của 1 + 2 * 10 - 2
sẽ đánh giá:
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
Có nhiều cách để đánh giá nó. Đây là một: http://en.wikipedia.org/wiki/Shunting-yard_algorithm –
Bất kỳ ngôn ngữ nào bạn thích? Dưới đây là một ví dụ trong. Net sử dụng Irony.net. http://blog.miraclespain.com/archive/2009/Oct-07.html – gjvdkamp