#c #bison #yacc #flex-lexer #lex
#c #зубр #yacc #flex-lexer #lex
Вопрос:
У меня есть следующее определение в моем файле lex:
L [a-zA-Z_]
A [a-zA-Z_0-9]
%%
{L}{A}* { yylval.id = yytext; return IDENTIFIER; }
И я делаю следующее в своем файле YACC:
primary_expression
: IDENTIFIER { puts("IDENTIFIER: "); printf("%s", $1); }
Мой исходный код (тот, который я анализирую) имеет следующее назначение:
ab= 10;
По какой-то причине эта printf("%s", $1);
часть печатается ab=
и не только ab
.
Я почти уверен, что это тот раздел, который печатается ab=
, потому что, когда я удаляю printf("%s", $1);
идентификатор, он вообще не печатается.
У меня действительно закончились идеи. Что я делаю не так?
Дайте мне знать, если я могу быть более ясным.
Ответ №1:
Что я делаю не так?
Вы предполагаете, что строка, на которую указывает, yytext
является постоянной. Это не так.
Время жизни строки, на которую указывает, yytext
является лексическим действием связанного правила. Если это правило в конечном итоге возвращается, yytext
оно сохранится до следующего yylex
вызова. И это все.
bison
-сгенерированные синтаксические анализаторы имеют односимвольный предварительный просмотр. Таким образом, к тому времени, когда анализатор выполняет семантическое действие, yylex
оно было вызвано снова (для предварительного просмотра); следовательно, вы не можете использовать сохраненное значение yytext
даже для последнего (или единственного) токена в правиле.
Решение: скопируйте строку. (Я использую strdup
, но по какой-то причине некоторым людям нравятся malloc и strcpy. Если вы это сделаете, не забудьте о терминаторе NUL.) И не забудьте free()
скопировать, когда закончите с этим.
Для справки: что говорится в руководстве по flex.