Ошибка рекурсии bison с указателем структуры

У меня есть простая структура под названием Polyn, например:

typedef struct Polyn {
  int sign;
  int coeff;
  int exp;
  struct Polyn *next;
} Polyn;

В моей грамматике bison для рекурсивного построения многочленов я получаю только первый и последний элемент. Я использую эти функции для добавления и согласования со структурой Polyn:


Polyn *addmonomial(Polyn *pol, Polyn *monom) {
    pol -> next = monom;
    return pol; 
}

Таким образом, для a = 1x2 + 2x + 3 он дает мне только 1x2 + 3. Рекурсия построит только первый и последний элементы. Я не знаю, менять ли возвращаемое значение функции добавления или как изменить грамматику, чтобы были включены средние термины. Похоже, проблема в том, что 1 доллар в моих последних двух рекурсивных правилах всегда является первым термином и не становится средним. Мне нужно вернуть первый член для других правил грамматики, а также построить многочлен.

    |poln T_PLUS poln   { $$ = addmonomial($1, $3);}
    |poln T_MINUS poln  { Polyn *p2n = negate($3); $$ = addmonomial($1, p2n); }

person sidthekid    schedule 30.11.2020    source источник


Ответы (2)


Polyn *addmonomial(Polyn *pol, Polyn *monom) {
    pol -> next = monom;
    return pol; 
}

Это заменит существующее значение next, если pol уже имеет значение next. Таким образом, если pol представляет выражение 1x2+2x, а monom представляет 3, тогда часть 2x будет заменена 1.

person sepp2k    schedule 30.11.2020
comment
Как мне изменить грамматику, чтобы она работала? - person sidthekid; 30.11.2020
comment
мне нужно вернуть первый член после всех рекурсивных вызовов, но мне также нужно, чтобы каждое следующее значение указывало на следующий термин, вплоть до последнего члена - person sidthekid; 30.11.2020
comment
@sidthekid Дело не в грамматике - с грамматикой все в порядке. Вам нужно будет исправить вашу addmonomial функцию. - person sepp2k; 30.11.2020
comment
как брат? если я верну monom вместо pol, тогда он забывает первый член и все средние члены. он устанавливает указатель правильно, но возвращает только последний член. Могу ли я сделать так, чтобы monom указывал на pol? - person sidthekid; 30.11.2020
comment
@sidthekid Вы можете сделать это, если порядок не имеет значения (то есть, если вам все равно, что foo + bar будет отображаться как bar + foo) - пока monom действительно мономиальный, указатель next будет NULL и, таким образом, безопасен для перезаписать. Или вы можете добавить monom к фактическому концу pol, следуя за указателем next, пока он не станет NULL - точно так же, как добавление к односвязному списку, что, по сути, и есть. - person sepp2k; 30.11.2020
comment
да!!!! оно работает - person sidthekid; 30.11.2020

Избавьтесь от своей функции addmonomial и используйте вместо нее функцию addpolynomial. Пока вы это делаете, избавьтесь от поля sign, оно повторяется со знаком поля coeff. Вы также можете сделать поле coeff double, а не int.

Ваша addpolynomial функция должна объединить два связанных списка терминов, объединяя термины с одинаковым показателем степени. Наверное, проще всего, если вы всегда будете хранить их в порядке экспоненты.

person Chris Dodd    schedule 30.11.2020