📄 mycalc.cpp
字号:
/*
program:
END // END is end-of-input
expr_list END
expr_list:
expression PRINT // PRINT is semicolon
expression PRINT expr_list
expression:
expression + term
expression - term
term
term:
term / primary
term * primary
primary
primary:
NUMBER
NAME
NAME = expression
- primary
( expression )
*/
#include <string>
#include<iostream>
using namespace std;
double error(const char* s)
{
cerr << "error: " << s << '\n';
exit(1);
}
enum Token_value {
NUMBER, END,
PLUS='+', MINUS='-', MUL='*', DIV='/',
PRINT=';', ASSIGN='=', LP='(', RP=')'
};
Token_value curr_tok = PRINT;
double number_value;
string string_value;
Token_value get_token()
{
char ch = 0;
cin>>ch;
switch (ch) {
case EOF:
return curr_tok=END;
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':
case '.':
cin.putback(ch);
cin >> number_value;
return curr_tok=NUMBER;
default:
error("bad token");
}
}
double expr(bool);
double prim(bool get)
{
if (get) get_token();
switch (curr_tok) {
case NUMBER:
{ double v = number_value;
get_token();
return v;
}
case MINUS: // unary minus
return -prim(true);
case LP:
{ double e = expr(true);
if (curr_tok != RP) error(") expected");
get_token(); // eat ')'
return e;
}
default:
error("primary expected");
}
}
double 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;
}
error("divide by 0");
default:
return left;
}
}
double 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;
}
}
int main()
{
while (cin) {
get_token();
if (curr_tok == END) break;
if (curr_tok == PRINT) continue;
cout << expr(false) << '\n';
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -