Разбор математического выражения
Код:
float number()
{
int res = 0;
for (;;)
{
char c = cin.get();
if (c >= '0' && c <= '9')
res = res * 10 + c - '0';
else
{
cin.putback(c);
break;
}
}
return res;
}
float expr();
float func()
{
struct FuncList
{
const char *n; // name
float (*f)(float); // function
};
const FuncList funcList[] =
{
{ "cos", cos },
{ "sin", sin },
{ "tan", tan },
{ "acos", acos },
{ "asin", asin },
{ "atan", atan },
{ "cosh", cosh },
{ "sinh", sinh },
{ "tanh", tanh },
{ "exp", exp },
{ "log", log },
{ "sqrt", sqrt },
{ "ceil", ceil },
{ "fabs", fabs },
{ "floor", floor },
{ 0, 0 }
};
float res;
string name;
for (;;)
{
char c = cin.get();
if (c >= 'a' && c <= 'z')
name += c;
else
{
cin.putback(c);
break;
}
}
res = expr();
for (const FuncList *i = funcList; i -> n != 0; ++i)
{
if (i -> n == name)
return i -> f(res);
}
cerr << "Неизвестная функция: " << name << endl;
return res;
}
float hiLevel()
{
float x;
char c = cin.get();
if (c == '(')
{
x = expr();
cin.get();
}
else
{
cin.putback(c);
if (isdigit(c))
x = number();
else
x = func();
}
return x;
}
float factor()
{
float x = hiLevel();
while (true)
{
char c = cin.get();
switch (c)
{
case '*':
x *= hiLevel();
break;
case '/':
x /= factor();
break;
default:
cin.putback(c);
return x;
}
}
}
float expr(char str[], int size)
{
int i=0;
float x = factor();
while(i < size)
{
char c = str[i];
switch (c)
{
case '+':
x += factor();
break;
case '-':
x -= factor();
break;
default:
cin.putback(c);
return x;
}
i++;
}
}
{
int res = 0;
for (;;)
{
char c = cin.get();
if (c >= '0' && c <= '9')
res = res * 10 + c - '0';
else
{
cin.putback(c);
break;
}
}
return res;
}
float expr();
float func()
{
struct FuncList
{
const char *n; // name
float (*f)(float); // function
};
const FuncList funcList[] =
{
{ "cos", cos },
{ "sin", sin },
{ "tan", tan },
{ "acos", acos },
{ "asin", asin },
{ "atan", atan },
{ "cosh", cosh },
{ "sinh", sinh },
{ "tanh", tanh },
{ "exp", exp },
{ "log", log },
{ "sqrt", sqrt },
{ "ceil", ceil },
{ "fabs", fabs },
{ "floor", floor },
{ 0, 0 }
};
float res;
string name;
for (;;)
{
char c = cin.get();
if (c >= 'a' && c <= 'z')
name += c;
else
{
cin.putback(c);
break;
}
}
res = expr();
for (const FuncList *i = funcList; i -> n != 0; ++i)
{
if (i -> n == name)
return i -> f(res);
}
cerr << "Неизвестная функция: " << name << endl;
return res;
}
float hiLevel()
{
float x;
char c = cin.get();
if (c == '(')
{
x = expr();
cin.get();
}
else
{
cin.putback(c);
if (isdigit(c))
x = number();
else
x = func();
}
return x;
}
float factor()
{
float x = hiLevel();
while (true)
{
char c = cin.get();
switch (c)
{
case '*':
x *= hiLevel();
break;
case '/':
x /= factor();
break;
default:
cin.putback(c);
return x;
}
}
}
float expr(char str[], int size)
{
int i=0;
float x = factor();
while(i < size)
{
char c = str[i];
switch (c)
{
case '+':
x += factor();
break;
case '-':
x -= factor();
break;
default:
cin.putback(c);
return x;
}
i++;
}
}
парсирования переменных находи значение переменной по имени в связном списке или массиве, или в хэш таблице,
или skip-list, rand-tree, splay-tree, rb-tree, avl-tree то есть в любой структуре данных которую реализуешь уникальную ассоциативность, если нет такой переменной выводи сообщение is not found или добавь её со значением 0.
Код:
/* структура данных должна хранить элемент состоящий из ключа где key уникальное название переменной, value значение переменной. */
typedef struct _var {
char key[32];
float value;
} var;
typedef struct _var {
char key[32];
float value;
} var;
Самописная это хорошо но не учитываешь точку или запятую по местной локали и т.п, а если число будет в
экспоненциальной форме записи? ещё переполнение нужно учитывать, лучше использовать strtod или sscanf.