compiler-construction - yacc 和 lex 中令牌的字符串值
问题描述
我开始学习 lex 和 yacc 来解析 aa shell 的输入。现在我只是想为这样的命令编写解析器 | 命令 | 命令。我在尝试捕获命令的字符串值时失败了,打印它会给我一个分段错误。这是它的代码:
.lex 文件:
%{
#include <stdio.h>
#include "y.tab.h"
#include <string.h>
%}
%%
grep|vim|ls|who {yylval = strdup(yytext); return COMMAND;}
"|" return PIPE;
%%
yacc 文件:
%{
#include <stdio.h>
#include <string.h>
#define YYSTYPE char*
void yyerror(const char* str)
{
fprintf(stderr, "error: %s\n", str);
}
int yywrap()
{
return 1;
}
main()
{
yyparse();
}
%}
%token PIPE COMMAND
%%
statement:
command
|
statement PIPE command
;
command:
COMMAND
{
printf("command: %s encountered\n", $1);
}
;
我相信由于某种原因,命令块中的 $1 为空,这意味着 strdup 也返回空。如果有人能告诉我我缺少什么,我将不胜感激,谢谢!
解决方案
如果你#define YYSTYPE
在你的 yacc/bison 语法文件中使用,你也必须在你的 flex 扫描器文件中使用完全相同的#define
内容,并且它必须在包含 bison/yacc 头文件之前。否则,yylval
扫描仪中的类型将错误,分配给它的将是未定义的行为。
这应该会产生编译器警告。请确保您始终在启用警告的情况下进行编译。
推荐阅读
- visual-studio-code - File Utils plugin - command 'fileutils.duplicateFile' not found
- php - 包含 PHP 和 CSS 文件 -> 相对路径
- python - Streaming from Python logging/stdout to a redis connection
- php - PHP interface in extended class not recognized as instance
- html - 使用 HTML 和谷歌应用脚本突出显示谷歌表格单元格中的文本
- android - Firebase & 按值/键过滤排序
- c++ - 如何使用算法将一个容器中对象中的成员复制到另一个容器?
- python - 试图在python中比较两个字符串
- c# - 如何将所选日期转换为字符串并在 DataGrid 上查看
- javascript - commons.js 错误地引用 HEAD 而不是 head