Зависит от того, что вернуло правило 'id'!
%%
start : TKN id '{' '}' {cout<<$2<<endl;} ;
id : ID { return "XXXXX"; } // What is returned here
// Is what will be printed out by $2
%%
Примечание:
Соглашение состоит в том, что терминальные токены являются заглавными (TKN). Пока нетерминальные токены являются строчными (id). В соответствии с этим соглашением, я ожидаю, что у id будет правило о том, как оно расширяется.
Я подозреваю, что вы делаете:
%%
id : ID { return yytext; }
%%
Указатель на буфер lex. Это энергозависимый буфер. Вы можете НЕ полагаться на то, что его содержимое остается неизменным (и при этом вы не можете полагать, что оно завершено '\ 0'). Вам нужно сделать копию токена в том месте, где вы его идентифицируете.
%%
id : ID { return strndup(yytext, yylen); }
%%
Редактировать на основе нового ввода:
В этих строках:
{Id} { strcpy(yylval.strVal,yytext);
cout<<"lex= "<<yytext<<endl;
return Id;
}
strcpy (), вероятно, плохой.
- Вы зарезервировали место для копии?
- Вы не можете полагаться на прекращение действия yytext '\ 0'.
Cout опасен, так как вы не можете полагаться на завершение yytext '\ 0'.
Я бы сделал:
{ID} { cout << "lex=" << std::string(yytext,yytext+yylen); // use yylen
return Id;
}
Не связывайтесь со структурами yacc в lex. Он тесно связывает ваш файл lex с yacc (что не обязательно). Просто верните токен. Затем yacc может получить значение токена вручную.
Затем в файле YACC:
Q_ID : Q_ID '.' ident {$$ = $3; cout<<"Q.id="<<$$<<endl;}
| ident {$$ = $1; cout<<"ID ="<<$$<<endl;}
ident : Id {$$ = strndup(yytext, yylen);}
Для каждого терминала (Id), который имеет длинный токен, есть нетерминал для декодирования терминала и генерирования правильного значения в структуре объединения yacc. В этом случае у нас есть идентификатор, а не терминал. Он просто декодирует терминал Id и правильно устанавливает токен (этот Id не имеет типа в структуре объединения).
Также Примечание:
- Традиционно для терминалов все заглавные буквы. Идентификатор не работает.
- Традиционно для нетерминалов строчные буквы. Q_ID не работает.
Дополнительно:
Эта строка:
%token <strVal> STR_VAL INT FLOAT STRING Id ;
Выглядит неправильно, хотя трудно сказать, не зная, что такое INT, FLOAT и STRING. Я предполагаю, что это терминальные токены для ключевых слов int, float, string. В этом случае вам не нужно хранить актуальную строку токена. Достаточно того, что вы знаете, что это INT / FLOAT или STRING.
Это должно быть:
%token <strVal> STR_VAL;
%token <strVal> ident;