Как да получа стойност на низ на токен във 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, как да го направя низ?

Например: "Сфера (световен глобус)." Искам $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 като int, така че всички стойности на символа са цели числа. Всъщност имате няколко решения за този проблем:

1) yylval|union решение (ПРЕПОРЪЧИТЕЛНО):
Както може би знаете, yylval е глобална променлива, използвана от лексния инструмент за съхраняване на променливата yytext (yylval = yytext;), така че трябва да кажете на вашия лексен процесор кои типове бихте искали за съхраняване. можете просто да добавите този ред към заглавката на вашата YACC граматика:

#define YYSTYPE char *

тук ще съхранявате само низови стойности.

Между другото, ако искате да съхранявате различни типове, трябва да посочите във вашия yacc файл:

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

тогава във вашия лекс ще имате

[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. Следващият път, когато lex нещо, буферът се презаписва. Не е подходящ подход, ако имате анализатор, който ще събере няколко такива токена в правило и вие се обръщате към тях с $1, $2 едновременно. Може да е добре, ако просто извиквате yylex() в цикъл и обработвате токени един по един. - person Kaz; 06.03.2012