Возможно ли yylval быть структурой, а не объединением? - PullRequest
0 голосов
/ 25 ноября 2018

На Бизоне, возможно, yylval будет структурой, а не объединением?Я знаю, что могу определить yylval как объединение с %union{}, но есть ли способ определить yylval как struct?вернуть строку и строку идентификатора для примера и получить доступ к этой информации при действии какого-то правила грамматики для бизонов.

Ответы [ 2 ]

0 голосов
/ 26 ноября 2018

Если вы хотите сохранить информацию о местоположении (номер строки и номер столбца) для своих токенов, вы можете использовать средство определения местоположения Bison, которое хранит объект местоположения для каждого токена и нетерминал отдельно от семантического значения.В действии вы обозначаете местоположение символа как @n.

Стек локаций создается и поддерживается автоматически зубром, если он обнаруживает, что вы указали местоположение в любом месте правила.

По умолчанию тип данных местоположения:

typedef struct YYLTYPE {
  int first_line;
  int first_column;
  int last_line;
  int last_column;
} YYLTYPE;

Информация о местоположении токенов должна быть задана лексером.Если вы используете API по умолчанию, он сохраняется в глобальной переменной yylloc.Парсер создаст информацию о местоположении для нетерминалов, используя диапазон от начала первого элемента производства до конца последнего элемента.(Для пустых производств создается объект местоположения нулевой длины, начинающийся и заканчивающийся начальной позицией токена предпросмотра.)

Оба эти значения по умолчанию могут быть переопределены при необходимости.Подробности см. В руководстве Bison .

Flex будет отслеживать номера строк при запросе с помощью %option yylineno, но не отслеживает позиции столбцов, что немного раздражает.Кроме того, yylloc требует как начального, так и конечного номера строки;yylineno в действии flex будет номером строки в конце токена.Чаще всего вы будете использовать макрос YY_USER_ACTION для поддержания значения yylloc;пример реализации (взят из этого ответа , который вы должны прочитать, если используете этот код):

%option yylineno
%{
#define YY_USER_ACTION                                       \
  yylloc.first_line = yylloc.last_line;                      \
  yylloc.first_column = yylloc.last_column;                  \
  if (yylloc.first_line == yylineno)                         \
     yylloc.last_column += yyleng;                           \
  else {                                                     \
     int col;                                                \
     for (col = 1; yytext[yyleng - col] != '\n'; ++col) {}   \
     yylloc.last_column = col;                               \
     yylloc.last_line = yylineno;                            \
  }
%}
0 голосов
/ 25 ноября 2018

Да, вы можете #define YYSTYPE быть любым типом, который вы хотите вместо использования %union.Тем не менее, это редко полезно сделать 1 - если вам нужна информация о положении источника, вам гораздо лучше использовать %position в сочетании с %union.

.можно (и часто) использовать структуры в пределах декларации %union.Это позволяет некоторым правилам возвращать несколько значений (эффективно).


1 Основная проблема заключается в том, что если вы используете %type, чтобы указать использованиеодно структурное поле, больно использовать другие поля в одном действии.Вы должны делать все вручную, таким образом теряя преимущество проверки типа объединения бизонов

...