Неожиданное значение в yytext в производственном правиле для объявления функции - PullRequest
0 голосов
/ 27 октября 2019

Я пишу компилятор с flex и bison для назначения в колледже. У меня проблемы с добавлением идентификатора функции в мою таблицу символов - при оценке объявления функции я получаю открывающую скобку в yytext, где я ожидаю идентификатор. В моем гибком файле, где yylval - это объединение, а vlex - это struct:

abc         [A-Za-z_]
alphanum    [A-Za-z_0-9]
id          {abc}+{alphanum}*

...

#define STORE_YYLVAL_NONE\
  do{\
    ... // location control irrelevant to the problem
    yylval.vlex.type = none_t;\
    yylval.vlex.value.sValue = yytext;\
  }while(0)

...

{id} {
  LOG_DEBUG("id: %s\n", yytext);
  STORE_YYLVAL_NONE;
  return TK_IDENTIFIER;
}

[,;:()\[\]\{\}\+\-\*/<>!&=%#\^\.\|\?\$] {
  LOG_DEBUG("special\n");
  STORE_YYLVAL_NONE;
  return *yytext;
}

...

И в моем файле зубров:

new_identifier_with_node: TK_IDENTIFIER {
  hshsym_add_or_exit(&hshsym, yylval.vlex.value.sValue, &(yylval.vlex));
  $$ = ast_node_create(&(yylval.vlex));
};

func: type new_identifier_with_node '(' param_list ')' func_block { ... };

У меня также есть журнал внутри hshsym_add_or_exit, который добавляет идентификатор в мою таблицу символов. При синтаксическом анализе следующей программы:

int k(int x,int y, int z){}
int f(){
        k(10,20,30);
}

я получаю следующий отладочный вывод:

yylex: DEBUG! id: k
yylex: DEBUG! special
hshsym_add_or_exit: DEBUG! Declaring: (

То есть, когда вычисляется продукция new_identifier_with_node, содержание yytext это ( вместо k, как я и ожидал. Код выше причины? У меня есть некоторые еще нерешенные конфликты сдвига / уменьшения, которые, я думаю, могут быть виноваты, но я не вижу, как в этом конкретном случае. Я верю, что упускаю что-то действительно простое, но я не вижу, чтоНа данный момент проект довольно большой (и позорно неорганизованный), но я могу предоставить полный и воспроизводимый пример, если это будет необходимо.

1 Ответ

3 голосов
/ 27 октября 2019

Основная проблема в том, что вы используете yylval в производстве new_identifier_with_node вместо $1. $1 - это семантическое значение первого символа в производстве, в данном случае TK_IDENTIFIER.

В действии бизона yylval обычно является значением токена предпросмотра, который является токеном next во входном потоке. Вот почему в этом случае это выглядит как скобка. Но в общем случае вы не можете рассчитывать на это, потому что bison выполнит сокращение по умолчанию перед чтением токена. В общем, использование yylval в действии зубров очень редко полезно, за исключением некоторых приложений для восстановления после ошибок.

Даже после того, как вы исправите это, вы обнаружите, что семантические значения неверны, поскольку ваше действие flexпересылка указателя во внутренний буфер данных вместо копирования строки токена. См., Например, этот вопрос .

...