Если вы хотите написать свой собственный код, лучший способ - определить выражение в форме грамматики. Чтобы легко разобрать грамматику, лучше сделать ее проще.
Например, чтобы разобрать выражения в такой форме (1+ (3 * 4 + x) * y) +1, вы можете написать такую грамматику:
Expression -> Addition | null
Addition -> Multiplication RestOfAddition
RestOfAddition -> null | + Addition
Multiplication -> Element RestOfMultiplication
RestOfMultiplication -> null | * Element
Element -> number | variable | ( Expression )
Затем в вашей программе для каждого нетерминала в этой грамматике (те, что слева от ->) вы пишете одну функцию, например:
ExpTree *Expression(char *exp, int *position)
{
if (exp[*position])
{
ExpTree *node = malloc(sizeof(*node));
node->type = LAMBDA;
node->value = 0;
return node;
}
else
return Addition(exp, position);
}
ExpTree *Addition(char *exp, int *position)
{
ExpTree *node = malloc(sizeof(*node));
node->type = ADDITION;
node->left = Multiplication(exp, position);
node->right = RestOfAddition(exp, position);
return node;
}
ExpTree *RestOfAddition(char *exp, int *position)
{
ExpTree *node;
if (exp[*position] == '+')
{
++*position;
return Addition(exp, position);
}
else
{
ExpTree *node = malloc(sizeof(*node));
node->type = LAMBDA;
node->value = 0;
return node;
}
}
Аналогично, Multiplication
и RestOfMultiplication
будут записаны как функции.
ExpTree *Element(char *exp, int *position)
{
if (exp[*position] == '(')
{
ExpTree *node;
++*position;
node = Expression(exp, position);
if (!exp[*position] != ')')
printf("Expected ) at position %d\n", *position);
else
++*position;
return node;
}
else if (exp[*position] == ')')
{
printf("Unexpected ) at position %d\n", *position);
return NULL;
}
else if (exp[*position] >= '0' && exp[*position] <= '9')
{
ExpTree *node = malloc(sizeof(*node));
node->type = INTEGER;
node->value = extract_int(exp, position);
return node;
}
else if ((exp[*position] >= 'a' && exp[*position] <= 'z') ||
(exp[*position] >= 'A' && exp[*position] <= 'Z') ||
exp[*position] == '_')
{
ExpTree *node = malloc(sizeof(*node));
node->type = VARIABLE;
node->value = extract_variable(exp, position);
return node;
}
else
{
printf("Warning: unexpected character %c in location %d\n", exp[*position], *position);
return NULL;
}
}
Где extract_int
и extract_variable
- это две функции, которые принимают выражение и позицию в нем, продолжая, пока они видят число (или букву в функции extract_variable
), они строят число (переменную) из строки выражения и вернуть его, установив позицию после того, где они закончили.
Примечание: это не код для копирования-вставки. Он не является полным и не содержит достаточной проверки ошибок. Некоторые детали были опущены и предлагаются в качестве решения, чтобы научить, как выполняется простой анализ, а не простое решение.