使用$ x从规则中获取字符串 [英] Using $x to grab string from rule

查看:87
本文介绍了使用$ x从规则中获取字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图在野牛中做类似的事情...

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应该只适用于整数吗?

我什至尝试添加一个联合并为新类型使用char *,但是我仍然可以从上述操作中获取(空).


我尝试使用所提供问题的提示来修复它,但仍然无法完美解决.

有问题的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吗?


我这次再次尝试了

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

但是接下来的几个字符仍然在myvar中.

解决方案

我设法通过用flex中的正则表达式标识变量名并将它们传递给一个字符串,该字符串随后被extern'ed来解决Bison的$ x问题.可以从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;}

野牛

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

野牛

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 .

I'm trying to do something like this in Bison...

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

What I'm trying to do is convert a for statement from the fake language's syntax to C's. However, the $2 I've used to grab var_name doesn't seem to work as the program crashes when it reaches there. Is $x supposed to work only for integers?

I even tried adding a union and using char* for a new type, but I still get (null) from the above actions.

EDIT:
I tried to fix it using the hints from the questions that were provided, but I still can't get it perfect.

FLEX rules in question:

"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 rules:

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

Thing is, for input:

FOR i := 0 TO 10 STEP 1

I get as output:

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

Can't I avoid having the := symbols getting in the strV?

EDIT 2:
I tried again, this time with

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

But still the next few characters get in myvar.

解决方案

I managed to get around working with the Bison's $x by identifying variable names with a regular expression in flex and passing them to a string which is then extern'ed from Bison, and available for use anytime.

So some of the changes made are...

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

EDIT: With credit due to Jonathan Leffler, this (below) should also work, allowing access via the usual $x in Bison.

Partial code

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 reports that although this works, it should be used carefully as strdup() used in this manner without free() statements should result in major memory leaks.

See also SO 3539416 for more info.

这篇关于使用$ x从规则中获取字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆