使用$ x从规则中获取字符串

时间:2010-08-21 23:47:21

标签: string bison flex-lexer

我正试图在野牛做这样的事情......

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

我要做的是将for语句从假语言的语法转换为C语言。但是,当我到达那里时程序崩溃时,我曾经用来获取var_name的2美元似乎不起作用。 $ x是否只适用于整数?

我甚至尝试添加一个union并使用char *作为新类型,但我仍然从上面的操作得到(null)。

修改:
我尝试使用提供的问题中的提示修复它,但我仍然无法完美。

有问题的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;}

BISON规则:

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 个答案:

答案 0 :(得分:1)

我设法通过在flex中使用正则表达式识别变量名称并将它们传递给字符串然后可以随时使用来设法绕过Bison的$ x工作。

所以做出的一些改变是......

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

编辑:由于Jonathan Leffler的信用额度,此(下方)也应该有效,允许通过Bison中通常的$ x进行访问。

部分代码

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); }

Jonathan报告说虽然这有效但是应该谨慎使用,因为strdup()以这种方式使用而没有free()语句会导致主要的内存泄漏。

有关详细信息,另请参阅SO 3539416

答案 1 :(得分:1)

你需要考虑的是yytext是一个指向角色的指针。这个字符序列在flex中一直在变化,但是yytext(指针)是不变的。您的原始flex规则只是在yylval中设置该指针。因此,当解析器继续时,它也会从输入中吞没:=。这就是为什么在flex中,你应该复制字符串并在匹配时将其存储在某处。那个地方可能是yylval联盟的一个领域。在Bison中使用它们之前,我总是为所有常量和变量名称设置malloc空间。

答案 2 :(得分:0)

不,$x表示法并不仅限于整数值(嗯,x必须是整数,但$x表示的值不是)。

看看这个问题是否有帮助: