Skip to content

Instantly share code, notes, and snippets.

@suica
Created March 19, 2022 16:24
Show Gist options
  • Save suica/239706003050937e2db6b0ee5a17322a to your computer and use it in GitHub Desktop.
Save suica/239706003050937e2db6b0ee5a17322a to your computer and use it in GitHub Desktop.
幻方笔试题-语言解释器
#include <bits/stdc++.h>
#define ll long long
using namespace std;
bool isEmpty(char c)
{
return c == ' ' or c == '\n' or c == '\t';
}
string inv(string c)
{
if (c == "0")
{
return c;
}
if (c[0] == '-')
{
return c.substr(1);
}
return "-" + c;
}
string sub(string, string);
string add(string a, string b)
{
if (a[0] == '-' and b[0] == '-')
{
return inv(add(a.substr(1), b.substr(1)));
}
else if (a[0] == '-')
{
return sub(b, a.substr(1));
}
else if (b[0] == '-')
{
return sub(a, b.substr(1));
}
int la = a.size();
int lb = b.size();
int c = 0;
string temp;
for (int i = 1; la - i >= 0 or lb - i >= 0; i++)
{
int d1 = la - i >= 0 ? a[la - i] - '0' : 0;
int d2 = lb - i >= 0 ? b[lb - i] - '0' : 0;
int d = (d1 + d2 + c) % 10;
c = (d1 + d2 + c) / 10;
temp += to_string(d);
}
if (c)
{
temp += '1';
}
reverse(temp.begin(), temp.end());
return temp;
}
string sub(string a, string b)
{
if (a[0] == '-' and b[0] == '-')
{
return sub(b.substr(1), a.substr(1));
}
else if (a[0] == '-')
{
return inv(add(a.substr(1), b));
}
else if (b[0] == '-')
{
return add(a, b.substr(1));
}
int la = a.size();
int lb = b.size();
if (la == lb)
{
if (a < b)
{
return inv(sub(b, a));
}
}
else if (la < lb)
{
return inv(sub(b, a));
}
int c = 0;
string temp;
for (int i = 1; la - i >= 0 or lb - i >= 0; i++)
{
int d1 = la - i >= 0 ? a[la - i] - '0' : 0;
int d2 = lb - i >= 0 ? b[lb - i] - '0' : 0;
int d = (10 + d1 - d2 + c) % 10;
if (d1 - d2 + c >= 0)
{
c = 0;
}
else
{
c = -1;
}
temp += to_string(d);
}
reverse(temp.begin(), temp.end());
for (int i = 0; i < temp.size(); i++)
{
if (temp[i] != '0')
{
return string(temp.begin() + i, temp.end());
}
}
return "0";
}
class Eval
{
public:
string s;
int i;
int n;
map<string, string> m;
Eval(string s)
{
n = s.size();
this->s = s;
i = 0;
}
void skip()
{
while (i < n and isEmpty(s[i]))
{
i++;
}
}
string get_id()
{
skip();
string temp;
for (; i < n; i++)
{
if (isEmpty(s[i]))
{
i--;
break;
}
else if (isalnum(s[i]))
{
temp += s[i];
}
else
{
i--;
break;
}
}
i++;
skip();
return temp;
}
string get_value()
{
string num = get_num();
if (num.size())
{
return num;
}
else
{
string id = get_id();
return m[id];
}
}
string get_num()
{
string temp;
skip();
for (; i < n; i++)
{
if (isdigit(s[i]))
{
temp += s[i];
}
else
{
break;
}
}
return temp;
}
void exec_statements(bool dummy = false)
{
while (i < n)
{
skip();
if (s[i] == ';')
{
i++;
continue;
}
if (s[i] == '{')
{
i++;
exec_statements();
continue;
}
if (s[i] == '}')
{
i++;
return;
}
if (s[i] == '!')
{
i++;
string v = get_value();
if (!dummy)
{
cout << "output:" << v << endl;
}
}
else
{
string id = get_id();
string op;
op += s[i];
if (op == "=")
{
i++;
string v = get_value();
if (!dummy)
{
m[id] = v;
}
}
else if (op == "+")
{
i++;
i++;
string v = get_value();
if (!dummy)
{
m[id] = add(m[id], v);
}
}
else if (op == "-")
{
i++;
i++;
string v = get_value();
if (!dummy)
{
m[id] = sub(m[id], v);
}
}
else if (s[i] == '?')
{
i++;
string v = get_value();
if (v == "0")
{
exec_statements();
}
else
{
exec_statements(true);
}
}
}
}
}
};
int main()
{
#ifdef _DEBUG
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
string s = "\
a = 0; \
b = 100000000000000000000000000000000000000000000000000000000000000; \
c = 128937129371929812123789123789012367412347893; \
b += a; \
c -= b; \
? a \
{ \
!b; \
b = 0 \
}; \
? b \
{ \
!c; \
c = 0; \
}; \
? c \
{ \
!a \
} \
";
auto e = Eval(s);
e.exec_statements();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment