![]() |
China DOS Union-- Unite DOS · Advance DOS · Grow DOS --Union site: www.cn-dos.net Forum site: www.cn-dos.net/forum |
| Guest | Log in | Register | Members | Search | China DOS Union |
|
中国DOS联盟论坛 The time now is 2026-09-14 13:21 |
47,812 topics / 349,917 posts / today 0 new / 48,268 members |
| DOS批处理 & 脚本技术(批处理室) » A batch script that can calculate simple expressions |
| Printable Version 13,099 / 22 |
| Floor1 brglng | Posted 2005-08-15 15:53 |
| 银牌会员 Posts 466 Credits 1,200 From 上海 | |
|
I've compiled an interesting batch script for NT-based systems like 2K/XP, which can calculate simple expressions. It's just an entry-level one, so I'm posting it here.
@echo off The latest version of this batch script can be downloaded from the "DIY" directory on my E drive. [ Last edited by namejm on 2007-2-3 at 09:49 PM ] |
|
| Floor2 venchia | Posted 2005-08-15 18:02 |
| 初级用户 Posts 11 Credits 125 | |
|
Not bad, collected
|
|
| Floor3 merlin | Posted 2005-08-15 19:00 |
| 初级用户 Posts 18 Credits 143 | |
|
Why not write one for Win9x/me/DOS!
|
|
| Floor4 Michael | Posted 2005-08-15 19:44 |
| 钻石会员 Posts 3,041 Credits 10,056 | |
|
Maybe only 2k/xp has ready-made expression evaluation statements.
|
|
| Floor5 brglng | Posted 2005-08-16 09:41 |
| 银牌会员 Posts 466 Credits 1,200 From 上海 | |
Originally posted by Michael at 2005-8-15 07:44 PM: Well, that's right. In fact, to really achieve better expression calculation, you can just use those command-line calculators. Their usage is very convenient. The /a parameter of the set command in NT also has many limitations, and the function is not strong. For example, it does not support floating-point numbers, does not support complex mathematical functions (such as sin, cos), etc. So, this batch processing is actually not very practical, and can only be used for learning. I think this batch processing has a good comprehensive application of new command switches and syntax for 2K/XP. [ Last edited by brglng on 2005-8-16 at 10:18 ] |
|
| Floor6 Michael | Posted 2005-08-16 21:36 |
| 钻石会员 Posts 3,041 Credits 10,056 | |
|
I was really startled at first. I thought the expression calculation was also done by batch processing.
Writing a similar program in C++ still needs so many lines: #include<iostream> #include<string> #include<map> #include<cctype> #include<sstream> using namespace std; namespace Parser { double prim(bool); double term(bool); double expr(bool); } namespace Lexer { enum Token_value { NAME, NUMBER, END, PLUS='+', MINUS='-', MUL='*', DIV='/', PRINT=';', ASSIGN='=', LP='(', RP=')' }; Token_value curr_tok; double number_value; string string_value; map<string,double>table; Token_value get_token(); } namespace Driver { int no_of_errors; istream* input; void skip(); void sta(); } namespace Error { struct Syntax_error { const char* p; Syntax_error(const char* q) {p=q;} }; struct Zero_divide{}; } using namespace Driver; using namespace Parser; using namespace Lexer; using namespace Error; double Parser::expr(bool get) { double left=term(get); for(;;) switch(curr_tok) { case PLUS: left+=term(true); break; case MINUS: left-=term(true); break; default: return left; } } double Parser::term(bool get) { double left=prim(get); for(;;) switch(curr_tok) { case MUL: left*=prim(true); break; case DIV: if(double d=prim(true)) { left/=d; break; } throw Zero_divide(); default: return left; } } double Parser::prim(bool get) { if (get) get_token(); switch(curr_tok) { case NUMBER: { double v=number_value; get_token(); return v; } case NAME: { double& v=table; if(get_token()==ASSIGN)v=expr(true); return v; } case MINUS: return -prim(true); case LP: { double e=expr(true); if(curr_tok!=RP) throw Syntax_error("')'expected"); get_token(); return e; } default: throw Syntax_error("primary expected"); } } Token_value Lexer::get_token() { char ch; do { if(!input->get(ch))return curr_tok=END; }while(ch!='\n'&&isspace(ch)); switch(ch) { case '\n': return curr_tok=PRINT; case ';': case '*': case '/': case '+': case '-': case '(': case ')': case '=': return curr_tok=Token_value(ch); case '0':case '1':case '2':case '3':case '4': case '5':case '6':case '7':case '8':case '9': input->putback(ch); *input>>number_value; return curr_tok=NUMBER; default: if(isalpha(ch)) { string_value=ch; while(input->get(ch)&&isalnum(ch))string_value.push_back(ch); input->putback(ch); return curr_tok=NAME; } throw Syntax_error("bad token"); } } void Driver::sta() { while(*input){ try { get_token(); if(curr_tok==END)break; if(curr_tok==PRINT)continue; cout<<expr(false)<<endl; } catch(Zero_divide) { cerr<<"attempt to divide by zero\n"; if(curr_tok!=PRINT)skip(); } catch(Syntax_error e) { cerr<<"syntax error:"<<e.p<<endl; if(curr_tok!=PRINT)skip(); } } } void Driver::skip() { no_of_errors++; while(*input) { char ch; input->get(ch); switch(ch) { case '\n': case ';': return; } } } int main(int argc, char*argv) { switch(argc) { case 1: input=&cin; break; case 2: input=new istringstream(argv); break; default: cerr<<"too many arguments\n"; return 1; } sta(); if(input!=&cin)delete input; return no_of_errors; } [ Last edited by Michael on 2005-8-16 at 21:37 ] |
|
| Floor7 brglng | Posted 2005-08-17 15:46 |
| 银牌会员 Posts 466 Credits 1,200 From 上海 | |
|
Hehe, I've programmed one with VB.
|
|
| Floor8 willsort | Posted 2005-08-19 20:31 |
| 元老会员 Posts 1,512 Credits 4,432 | |
|
Re: brglng:
Very good code, three suggestions are put forward: 1. Add command-line parameter support, that is, allow writing expressions or /? in command-line parameters; 2. The prompt string of set /p can be written in the set statement, for example set /p SaveEval=Do you want to save the expression and calculation result to the file ? 3. The switch /i can be used in the if statement for case-insensitive judgment, for example: if /i "%SaveEval%"=="Y" goto save if /i "%SaveEval%"=="N" goto next In addition, after the code is improved, I am interested in including it in my batch processing collection post {8905} "Abnormalities in Batch Processing Programming", but due to layout restrictions, most of the explanatory document code may be deleted. I wonder if Brother brglng agrees? |
|
| Floor9 agboy888 | Posted 2005-08-20 01:20 |
| 新手上路 Posts 1 Credits 1 | |
|
Not bad, thanks
|
|
| Floor10 brglng | Posted 2005-08-23 14:56 |
| 银牌会员 Posts 466 Credits 1,200 From 上海 | |
Originally posted by willsort at 2005-8-19 08:31 PM: Thanks to expert Willsort for the suggestions. Regarding inclusion, I have no opinion, anyway, it was just written casually. |
|
| Floor11 brglng | Posted 2005-08-25 11:39 |
| 银牌会员 Posts 466 Credits 1,200 From 上海 | |
|
Here is the translation of the provided code's relevant description part:
The following is the improved code according to the suggestions of willsort (added many functions): |
|
| Floor12 defrag | Posted 2005-08-26 00:54 |
| 中级用户 Posts 570 Credits 456 | |
|
It's not very difficult to compile a calculator with GW-BASIC...
This hasn't been tested No error handling main.bas: It can also be done with QB7.1 (needs to be run with QBX, can't be compiled) Has error handling Also not tested main.bas: [ Last edited by defrag on 2005-8-30 at 19:41 ] |
|
| Floor13 willsort | Posted 2005-08-26 11:28 |
| 元老会员 Posts 1,512 Credits 4,432 | |
|
Re Brglng:
Some structural changes have been made to make the program execution flow clearer, and the core code has not been changed. Please Brother Brglng do the testing. Regarding the expression usage help, I initially used the for statement to save code, but later considered the readability issue and finally discarded it. You can also test together. [ Last edited by willsort on 2005-9-11 at 13:19 ] |
|
| Floor14 pfox | Posted 2005-08-26 15:01 |
| 银牌会员 Posts 446 Credits 1,451 | |
|
A few friends who wrote in other languages, can they compile into exe and upload casually?
|
|
| Floor15 defrag | Posted 2005-08-27 16:43 |
| 中级用户 Posts 570 Credits 456 | |
|
Said, mine can only run in the IDE (urgently become the development environment)...
|
|
| 1 2 Next |
|
[ Contact the Union admin team -
中国DOS联盟 -
Standard version ] Sponsored by ifanr Inc | © 2001–2023 |