Как получить строковое значение токена в flex и bison?

У меня есть этот токен в моем файле .lex:

[a-zA-Z0-9]+    { yylval = yytext; return ALPHANUM; }

и этот код в моем файле .y:

Sentence: "Sphere(" ALPHANUM ")."
{
FILE* file = fopen("C:/test.txt", "a+");
char st1[] = "polySphere -name ";
strcat(st1, $2);
strcat(st1, ";");
fprintf(file,"%s", st1);
fclose(file);
}

Я получаю эту ошибку, когда пытаюсь скомпилировать:

предупреждение: передача аргумента 2 из «strcat» делает указатель из целого числа без приведения

Итак, $2 — это int, как мне сделать его строкой?

Например: "Сфера(worldGlobe)". Я хочу, чтобы $2 имел здесь строковое значение worldGlobe.

Спасибо за любую помощь


person user1007632    schedule 26.12.2011    source источник
comment
Можете ли вы показать нам свое объявление союза из файла .y и объявление вашего токена для ALPHANUM из файла .y?   -  person MtnViewJohn    schedule 26.12.2011
comment
Предполагая, что у вас есть несколько типов yylval. Если все, что вы когда-либо возвращаете, это char*, тогда вы должны иметь #define YYSTYPE char* в прологовой части файла .y.   -  person MtnViewJohn    schedule 26.12.2011


Ответы (1)


В отсутствие объявления %union bison определяет YYSTYPE как целое число, поэтому все значения символов являются целыми числами. На самом деле у вас есть несколько решений этой проблемы:

1) yylval|union решение (РЕКОМЕНДУЕТСЯ):
Как вы, возможно, знаете, yylval — это глобальная переменная, используемая лексером для хранения переменной yytext (yylval = yytext;), поэтому вы должны сообщить своему лексеру, какие типы вы бы to store.you можете просто добавить эту строку в заголовок вашей грамматики YACC:

#define YYSTYPE char *

вы будете хранить здесь только строковые значения.

Кстати, если вы хотите хранить разные типы, вы должны указать в файле yacc:

%union {
    char *a;
    double d;
    int fn;
}

тогда в вашем lex у вас будет

[a-zA-Z0-9]+    { **yylval.a** = yytext; return ALPHANUM; }

2) Использование yytext:

Совет: для обратных вызовов после правил в yacc я лично предпочитаю использовать функции. не весь код, как у вас :)

это решение очень простое .
Sentence: "Sphere("{callback_your_function(yytext);} ALPHANUM ")."

yytext здесь будет иметь значение вашего токена ALPHANUM, потому что это следующий токен.

person Aymanadou    schedule 26.12.2011
comment
Я бы поостерегся вставлять необработанный указатель yytext в yylval. В следующий раз, когда вы что-то лексируете, буфер перезаписывается. Это не подходящий подход, если у вас есть парсер, который будет собирать несколько таких токенов в правило, и вы ссылаетесь на них с помощью $1, $2 одновременно. Это может быть нормально, если вы просто вызываете yylex() в цикле и обрабатываете токены один за другим. - person Kaz; 06.03.2012