Использование $ x для получения строки из правила - PullRequest
0 голосов
/ 22 августа 2010

Я пытаюсь сделать что-то подобное в Бизоне ...

loop_for:   FOR var_name COLONEQUALS expression TO
            {printf("%s<=", $2);} expression STEP
            {printf("%s+=", $2);} expression {printf(")\n");}
            Code ENDFOR

Я пытаюсь преобразовать оператор for из синтаксиса поддельного языка в C. Тем не менее, $ 2, которые я использовал для получения var_name, похоже, не работает, так как программа аварийно завершает работу, когда достигает ее. $ X должен работать только для целых чисел?

Я даже пытался добавить объединение и использовать char * для нового типа, но я все еще получаю (ноль) из вышеуказанных действий.

EDIT:
Я попытался исправить это, используя подсказки из вопросов, которые были предоставлены, но я все еще не могу сделать это идеально.

Правила FLEX, о которых идет речь:

"FOR"   {printf("for ("); lisnew=0; return FOR;}
"TO"    {printf("; "); return TO;}
"STEP"  {printf("; "); return STEP;}
"ENDFOR"    {printf("\n"); t--; instabs(); printf("}\n"); instabs(); lisnew=1; return ENDFOR;}
[a-zA-Z]+   {printf("%s",yytext); lisnew=0; yylval.strV = yytext; return CHARACTERS;}
":="    {printf("="); lisnew=0; return COLONEQUALS;}

ЗУБНЫЕ правила:

loop_for:   FOR var_name {strcpy(myvar, $<strV>2);} COLONEQUALS expression TO {printf("%s<=", myvar);} expression STEP {printf("%s+=", myvar);} expression {printf(")\n");} Code ENDFOR
var_name:   name_first_is_char
name_first_is_char: character | character name2
name2:  | character name2 | digit name2

Дело в том, для ввода:

FOR i := 0 TO 10 STEP 1

Я получаю в качестве вывода:

for ( i = 0 ; i :=<= 10 ; i :=+= 1

Могу ли я избежать попадания символов: = в strV?

РЕДАКТИРОВАТЬ 2:
Я попробовал еще раз, на этот раз с

var_name:   name_first_is_char {memset(myvar, '\0', BUFFER_LENGTH); sprintf(myvar, "%s", $<strV>1);}

Но все же следующие несколько персонажей попадают в myvar.

Ответы [ 3 ]

1 голос
/ 22 августа 2010

Мне удалось обойти работу с $ Bison Bison, идентифицировав имена переменных с помощью регулярного выражения в flex и передав их в строку, которая затем была извлечена из Bison и доступна для использования в любое время.

Итак, некоторые из внесенных изменений ...

FLEX

char tempvar[1000];
[a-zA-Z][a-zA-Z0-9]*    {printf("%s",yytext); strcpy(tempvar,yytext); lisnew=0; yylval.strV = yytext; return VARNAME;}

BISON

extern char tempvar[];
var_name:    VARNAME {strcpy(myvar, tempvar);}
loop_for:   FOR var_name COLONEQUALS number TO {printf("%s<=", myvar);} number STEP {printf("%s+=", myvar);} number {printf(")\n"); instabs(); printf("{\n"); t++; instabs();} Code ENDFOR

РЕДАКТИРОВАТЬ: С кредитом из-за Джонатан Леффлер , это (ниже) также должно работать, позволяя доступ через обычный $ х в зубров.

Неполный код

FLEX

[a-zA-Z][a-zA-Z0-9]*    { yylval = strdup(yytext); return VARNAME;}
[1-9][0-9]*|0           { yylval = strdup(yytext); return NUMBER; }

BISON

loop_for:   FOR var_name COLONEQUALS NUMBER TO NUMBER STEP NUMBER
    { printf("for (%s = %s; %s <= %s; %s += %s)\n", $2, $4, $2, $6, $2, $8); }

Джонатан сообщает, что, хотя это работает, его следует использовать осторожно, так как strdup (), используемый таким образом без операторов free (), может привести к значительным утечкам памяти.

См. Также SO 3539416 для получения дополнительной информации.

1 голос
/ 26 августа 2010

Что нужно учитывать, так это то, что yytext - это указатель на символ.Эта последовательность символов все время изменяется в flex, но yytext (указатель) является константой.Ваше оригинальное правило flex просто устанавливает этот указатель в yylval.Поэтому, когда анализатор продолжается, он также охватывает входные данные: =.Вот почему в flex вы должны скопировать строку и сохранить ее где-нибудь, как только она совпадет.Это где-то может быть поле в Yylval Union.Я всегда выделяю пространство для всех констант и имен переменных, прежде чем использовать их в Bison.

0 голосов
/ 22 августа 2010

Нет, запись $x не ограничивается только целочисленными значениями (ну, x должно быть целым числом, но значение, представленное $x, не имеет).

Проверьте,этот вопрос помогает вообще:

...