mình không có ý định phát triển nó thành 1 cái máy tính hoàn chỉnh, mà chỉ muốn thử bộ tính toán thôi, vì mục đích của mình là cho phép một chương trình lưu công thức trong DB, sau đó load lên cả data và công thức lên rồi tính toanns kkết quả, ví như bài toán thông kê chẳng hạn, đương nhiên không ai muốn sau này nếu thay đổi công thức thì phải thay đổi cả một chương trình tính toán, mà chỉ muốn thay công thức dạng text đã lưu trong DB thôi
Trở lại vấn đề là mình làm như thế nào
thứ quan trọng đáng kể nhất mình cần viết là:
Code:
Package expcalc;
Helpers
digit = ['0' .. '9'];
letter = [['a' .. 'z']+['A' .. 'Z']];
cr = 13;
lf = 10;
tab = 9;
ws = ' ';
Tokens
t_open = '(';
t_close = ')';
t_dot = '.';
t_comma = ',';
t_plus = '+';
t_pos = 'pos';
t_minus = '-';
t_neg = 'neg';
t_mul = '*';
t_div = '/';
t_power = '^';
t_exp = 'exp';
t_fact = '!';
t_log = 'log';
t_ln = 'ln';
t_lg = 'lg';
t_sin = 'sin';
t_cos = 'cos';
t_tan = 'tan';
t_cotan = 'cotan';
t_asin = 'asin';
t_acos = 'acos';
t_atan = 'atan';
t_acotan = 'acotan';
t_sqrt = 'sqrt';
t_sqr = 'sqr';
t_cub = 'cub';
t_cubrt = 'cubrt';
t_pi = 'PI';
t_e = 'E';
t_var = ('v' | 'V') (digit)* ;
t_num = digit+ (('E' | 'e') ('+' | '-')? digit+ | '.' digit+ (('E' | 'e') ('+' | '-')? digit+)?);
t_digits = digit+;
t_delim = (tab | ws | cr | lf)+ ;
Ignored Tokens
t_delim;
Productions
exp = operand;
operand = operand1;
operand1 = {operand2} operand2 |
{plus} operand1 t_plus operand2 |
{minus} operand1 t_minus operand2;
operand2 = {operand3} operand3 |
{neg} t_minus operand2 |
{pos} t_plus operand2;
operand3 = {operand4} operand4 |
{mul} operand3 t_mul operand4 |
{div} operand3 t_div operand4;
operand4 = {operand5} operand5 |
{power} operand4 t_power operand5;
operand5 = {operand6} operand6 |
{sin} t_sin t_open operand t_close |
{cos} t_cos t_open operand t_close |
{tan} t_tan t_open operand t_close |
{cotan} t_cotan t_open operand t_close |
{asin} t_asin t_open operand t_close |
{acos} t_acos t_open operand t_close |
{atan} t_atan t_open operand t_close |
{acotan} t_acotan t_open operand t_close |
{sqr} t_sqr t_open operand t_close |
{sqrt} t_sqrt t_open operand t_close |
{cub} t_cub t_open operand t_close |
{cubrt} t_cubrt t_open operand t_close |
{exp} t_exp t_open operand t_close |
{log} t_log t_open operand t_comma operand1 t_close |
{lg} t_lg t_open operand t_close |
{ln} t_ln t_open operand t_close;
operand6 = {operand7} operand7 |
{fact} operand7 t_fact;
operand7 = {term} term |
{bracket} t_open operand t_close;
term = {int} t_digits |
{num} t_num |
{var} t_var |
{pi} t_pi |
{e} t_e;
Đây là file đặc tả cú pháp biểu thức cho sablecc, sau khi có file này, gọi sablecc, thực chất là 1 tool, sẽ sinh ra toàn bộ code java cần thiết bao gồm: phân tích từ vựng, phân tích cú pháp, tạo cây cú pháp, việc duy nhất còn lại là viết phần sinh ra mã đích, cụ thể trong bài này là sinh ra biểu thức hậu tố và tính toán
với sablecc: sinh ra java
với antlr: sinh ra C++ hoặc java (tùy chọn)
với lex/yacc: sinh ra C thuần khiết
Toàn bộ project mình đặt ở đây, trong đó có file .bat để gọi sablecc (sablecc chỉ cần 1 file là sablecc.jar, có thể download ở nhiều chỗ), yêu cầu bạn có JRE, sau khi buid muốn chạy được thì thêm đường dẫn JRE\bin vào biến môi trường path. Project có sử dụng cả C++ và java, nên cũng tốt cho cả những bạn muốn tìm hiểu cách liên lạc C++ và java
http://j.1asphost.com/goldsoft2/download/code/expcalc.zip.2