如何根据产品类型更改令牌类型?
How can I change the type of a token basing on the production's type?
我正在使用 Lex 和 Yacc 开发一个小项目,我必须处理数学表达式。
在我的文件syntax.y中,我有这两种产生式规则:
%union {
char* lexeme;
double value;
}
%token <lexeme> NUM
%type <lexeme> expr
%type <value> comp_expr
expr : expr "+" expr { $$ = strcat(,"+"); $$ = strcat($$,); }
| NUM
;
comp_expr: comp_expr "+" comp_expr { $$ = + ; }
| NUM
;
我使用 "expr" 以便 return 将表达式作为字符串,我使用 "comp_expr" 以便 return 将表达式作为计算表达式,在此算一笔账。
基于 syntax.y 中的其他部分(我没有包括在内,因为这里无关紧要)我有一个系统可以正确识别何时使用 "expr" 以及何时使用 "comp_expr".
但是当我使用 "comp_expr" 时出现错误,因为令牌 NUM 被声明为一个词位,因此是一个字符串,而产生式 "comp_expr" 有一个值,因此是一个双精度值,如类型。
如何将词位和值都分配给令牌 NUM?或者我如何根据我正在使用的生产更改 NUM 的值?
此外,我post还有我在文件中保存NUM的方式lexic.l:
{NUM} { yylval.lexeme = strdup(yytext); return NUM; }
在此先感谢您的关注。
冒着陈述显而易见的风险,我建议您在需要时将 NUM
转换为双精度数。单元制作非常适合此类转换,而您恰好手头有一个:
comp_expr: NUM { $$ = strtod(, NULL); }
您可以通过调用 strtod
进行更仔细的错误检查,但假设词素已经被词法扫描器验证可能是合理的。
顺便说一句,有一个很大的问题:
expr : expr "+" expr { $$ = strcat(,"+"); $$ = strcat($$,); }
</code> 大概是词法扫描器中调用 <code>strdup
的 return 值。在那种情况下,它正好足以容纳词位 而不再是 。所以在最后连接更多的东西是缓冲区溢出;您将覆盖不属于您的内存。那会让你很快陷入困境。
您需要为 expr
分配一个正确长度的新字符串; asprintf
对于这个目的来说非常方便,并且比一系列 strcat
更具可读性。
您可能还应该考虑在连接 strdup
ed 词位后未 free
ing 导致的内存泄漏。
我正在使用 Lex 和 Yacc 开发一个小项目,我必须处理数学表达式。
在我的文件syntax.y中,我有这两种产生式规则:
%union {
char* lexeme;
double value;
}
%token <lexeme> NUM
%type <lexeme> expr
%type <value> comp_expr
expr : expr "+" expr { $$ = strcat(,"+"); $$ = strcat($$,); }
| NUM
;
comp_expr: comp_expr "+" comp_expr { $$ = + ; }
| NUM
;
我使用 "expr" 以便 return 将表达式作为字符串,我使用 "comp_expr" 以便 return 将表达式作为计算表达式,在此算一笔账。
基于 syntax.y 中的其他部分(我没有包括在内,因为这里无关紧要)我有一个系统可以正确识别何时使用 "expr" 以及何时使用 "comp_expr".
但是当我使用 "comp_expr" 时出现错误,因为令牌 NUM 被声明为一个词位,因此是一个字符串,而产生式 "comp_expr" 有一个值,因此是一个双精度值,如类型。
如何将词位和值都分配给令牌 NUM?或者我如何根据我正在使用的生产更改 NUM 的值?
此外,我post还有我在文件中保存NUM的方式lexic.l:
{NUM} { yylval.lexeme = strdup(yytext); return NUM; }
在此先感谢您的关注。
冒着陈述显而易见的风险,我建议您在需要时将 NUM
转换为双精度数。单元制作非常适合此类转换,而您恰好手头有一个:
comp_expr: NUM { $$ = strtod(, NULL); }
您可以通过调用 strtod
进行更仔细的错误检查,但假设词素已经被词法扫描器验证可能是合理的。
顺便说一句,有一个很大的问题:
expr : expr "+" expr { $$ = strcat(,"+"); $$ = strcat($$,); }
</code> 大概是词法扫描器中调用 <code>strdup
的 return 值。在那种情况下,它正好足以容纳词位 而不再是 。所以在最后连接更多的东西是缓冲区溢出;您将覆盖不属于您的内存。那会让你很快陷入困境。
您需要为 expr
分配一个正确长度的新字符串; asprintf
对于这个目的来说非常方便,并且比一系列 strcat
更具可读性。
您可能还应该考虑在连接 strdup
ed 词位后未 free
ing 导致的内存泄漏。