Одна нота.Ваша функция find
может называться intern
.Что он делает, так это уменьшает строковый токен до числового атома.Если он не видел строку ранее, он возвращает новый атом, но если он вызывается дважды с одной и той же строкой, он возвращает один и тот же атом каждый раз.Это называется интернированием, которое возникло на языке Lisp.
У вас есть некоторые проблемы в этом коде, поскольку у ваших символов есть место для 100 имен символов, но вы не проверяете это, а просто используете вслепую strcpy.
Теперь об этом правиле грамматики:
locnSpec: tok_LOCN tok_IDENT nameSpec descrSpec exitList {int k = find ($ 2);locList [k] .name = strdup (tmp_name);locList [k] .descr = strdup (tmp_descr);memcpy (locList [k] .exits, tmp_exit, 4 * sizeof (int));}
Что если спецификация местоположения встречается дважды для одного и того же местоположения?Вы просто теряете эту память, перезаписывая locList[k].name
.Вы могли бы хотеть освободить старое значение, которое было там прежде.Если эти структуры инициализируются нулями / нулями, вы можете сделать это:
free (locList [k] .name);locList [k] .name = strdup (tmp_name);
Во-вторых, откуда берутся эти tmp_name
и tmp_descr
переменные?Являются ли эти глобалы наполненными значениями во время сокращения нетерминальных символов namesSpec
и descrSpec
?
Это противный подход;вам действительно следует использовать стек Yacc, чтобы возвращать семантические значения и обращаться к ним через $ 3, $ 4 и $ 5.
Что касается проблемы коррупции, которую вы преследуете;вполне возможно, что статический массив переполнен.Вы не выполняете никаких проверок границ для чего-либо.
Суть проблемы заключается в следующем:
/* two arrays, probably located side by side in the executable image */
static char array1[20][30];
static char array2[40][20];
Если вы получите доступ к array1
за его пределами, вы, вероятно, выбросите какую-то другую переменнуюкак, например, array2
, в зависимости от того, как все расположено в образе времени выполнения.
Одна вещь, которую вы можете сделать, в отсутствие более продвинутых инструментов отладки, это пошагово пройти по коду вотладчик и мониторинг содержимого перезаписанной переменной.Попробуйте поймать программу «с поличным», изменив это значение.
Во-вторых, содержимое этого мусорного массива должно дать вам представление о том, откуда взялся этот материал!Похоже, что это фрагмент текста, который можно проследить до вашего ввода, и оттуда вы можете проследить, где эта часть ввода обрабатывается на вашем анализаторе.