起因是这个问题
http://zhidao.baidu.com/question/1110099820559411499.html
因为当时我编译原理课根本没有好好听,所以就决定尝试一下自己写这样的东西能写成什么样。
虽然写出来了,不过貌似没有满足,然后就进行魔改。
下面的代码是魔改的结果,能蛋疼成这样,我实在无话可说了……(死鱼眼
输入一个表达式,然后这个程序能计算它的值。支持加减乘除和括号,只支持整数,表达式中不能含有空格
注意:不能在“数据执行保护(DEP)”环境下执行。VC链接的时候不能带/NXCOMPAT选项,系统设置里也不能用“为所有程序启用数据执行保护”。
#define _SCL_SECURE_NO_WARNINGS
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
typedef unsigned char uchar;
typedef vector<uchar> Buf;
typedef const Buf CBuf;
void App(Buf& b, CBuf& c) {
b.insert(b.end(), c.begin(), c.end());
}
Buf Eax(int n, CBuf& c = CBuf()) {
Buf r(5);
r[0] = 0xb8;
copy(reinterpret_cast<uchar*>(&n), reinterpret_cast<uchar*>(&n+1), &r[1]);
App(r, c);
return r;
}
Buf Eax2Edx(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x8b;
r[1] = 0xd0;
App(r, c);
return r;
}
Buf Edx2Eax(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x8b;
r[1] = 0xc2;
App(r, c);
return r;
}
Buf Eax2Ecx(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x8b;
r[1] = 0xc8;
App(r, c);
return r;
}
Buf Ecx2Eax(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x8b;
r[1] = 0xc1;
App(r, c);
return r;
}
Buf Push(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0xff;
r[1] = 0xf0;
App(r, c);
return r;
}
Buf Pop(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x8f;
r[1] = 0xc0;
App(r, c);
return r;
}
Buf Add(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x03;
r[1] = 0xc2;
App(r, Push());
App(r, c);
return Pop(Eax2Edx(Pop(r)));
}
Buf Sub(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0x2b;
r[1] = 0xc2;
App(r, Push());
App(r, c);
return Pop(Eax2Edx(Pop(r)));
}
Buf Mul(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0xf7;
r[1] = 0xe2;
App(r, Push());
return Pop(Eax2Edx(Pop(r)));
}
Buf Div(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0xf7;
r[1] = 0xf1;
App(r, Push());
App(r, c);
return Eax(0, Eax2Edx(Pop(Eax2Ecx(Pop(r)))));
}
Buf Ret() {
Buf r(1);
r[0] = 0xc3;
return r;
}
Buf Neg(CBuf& c = CBuf()) {
Buf r(2);
r[0] = 0xf7;
r[1] = 0xd8;
App(r, Push());
App(r, c);
return Pop(r);
}
bool parseKakko(const char* &p, Buf& x);
bool parseNumber(const char* &p, Buf& x) {
if (parseKakko(p, x)) return true;
const char* lp = p;
if (*lp == '-') {
++lp;
if (parseNumber(lp, x)) {
App(x, Neg());
p = lp;
return true;
}
}
if (*lp >= '0' && *lp <= '9') {
int val = 0;
while(*lp >= '0' && *lp <= '9') {
val = val * 10 + (*lp - '0');
++lp;
}
p = lp;
App(x, Eax(val, Push()));
return true;
} else {
return false;
}
}
bool parseOP1(const char* &p, char &x) {
if (*p == '*' || *p == '/') {
x = *p;
++p;
return true;
} else
return false;
}
bool parseOP2(const char* &p, char &x) {
if (*p == '+' || *p == '-') {
x = *p;
++p;
return true;
} else
return false;
}
bool parseFactor(const char* &p, Buf &x) {
Buf lhs, rhs;
char op;
const char* lp = p;
if ( parseNumber(lp, lhs) ) {
const char* lp2 = lp;
while (parseOP1(lp2, op) ) {
if (parseNumber(lp2, rhs)) {
App(x, lhs);
App(x, rhs);
if (op == '*') App(x, Mul());
if (op == '/') App(x, Div());
lp = lp2;
lhs.clear();
rhs.clear();
} else break;
}
App(x, lhs);
p = lp;
return true;
} else return false;
}
bool parseExpr(const char* &p, Buf &x) {
Buf lhs, rhs;
char op;
const char* lp = p;
if (parseFactor(lp, lhs)) {
const char* lp2 = lp;
while (parseOP2(lp2, op)) {
if (parseFactor(lp2, rhs)) {
App(x, lhs);
App(x, rhs);
if (op == '+') App(x, Add());
if (op == '-') App(x, Sub());
lp = lp2;
lhs.clear();
rhs.clear();
} else break;
}
App(x, lhs);
p = lp;
return true;
} else return false;
}
bool parseKakko(const char* &p, Buf &x) {
const char* lp = p;
Buf t;
if (*lp == '(') {
++lp;
if (parseExpr(lp, t)) {
if (*lp == ')') {
++lp;
p = lp;
App(x, t);
return true;
} else return false;
} else return false;
} else return false;
}
#include <stdio.h>
int main()
{
Buf code;
char str[256];
gets(str);
const char* pstr = str;
if (parseExpr(pstr, code)) {
int i, l = pstr - str;
for(i = 0; i < l; ++i)
putchar(' ');
puts("^ parsed until here");
App(code, Pop(Ret()));
int (*run)() = (int (*)()) &code[0];
printf("%d\n", run());
}
return 0;
}