c - 为什么我在编译基本的 yacc 程序时会得到 yylex 和 yyerror 的未定义符号?
问题描述
我正在用 yacc/lex 编写一个基本程序,并且我undefined symbol error
在yacc
C 生成的源代码中得到了一个yyerror
和yylex
. 如何指定这些文件是在lex
词法分析器中生成的?
这是我尝试过的:
readfile_grammar.y
%{
#include <time.h>
#include <stdio.h>
%}
%union {
struct tm datetime; /* DATE TIME VALUES */
double float_number; /* 8 BYTES DOUBLE VALUE */
long integer_number; /* 8 BYTES INTEGER VALUE */
}
%token <datetime> DATETIME
%token <float_number> FLOAT_NUMBER
%token <integer_number> INTEGER_NUMBER
%%
lastbid_lastask: DATETIME ',' FLOAT_NUMBER ',' FLOAT_NUMBER ',' INTEGER_NUMBER { printf("MATCH %lf %lf %ld\n", $3, $5, $7); }
;
%%
int main(int argc, char *argv[]) {
yyparse();
return 0;
}
readfile_lexer.l
%{
#include <time.h>
#include "readfile_grammar.h"
%}
%%
/* SKIP BLANKS AND TABS */
[\t ] { ; }
/* YYYYMMDD HHMM DATE */
[12][09][0-9][0-9][0-1][0-9][0-3][0-9][ ][0-2][0-9][0-5][0-9] { read_date_YYYYMMDD_HHMM(); return DATETIME; }
/* FLOAT NUMBER */
[0-9]+\.[0-9]+ { read_float_number(); return FLOAT_NUMBER; }
/* INTEGER NUMBER */
[0-9]+ { read_integer_number(); return INTEGER_NUMBER; }
%%
/* READ FLOAT NUMBER */
void read_float_number(void) {
sscanf(yytext, "%lf", &yylval.float_number);
}
/* READ INTEGER NUMBER */
void read_integer_number(void) {
sscanf(yytext, "%ld", &yylval.integer_number);
}
/* READ YYYYMMDD HHMM DATE */
void read_date_YYYYMMDD_HHMM(void) {
/* DATETIME STRUCT TM */
struct tm dt;
char buffer[80];
/* READ VALUES */
sscanf(yytext, "%4d%2d%2d %2d%2d", &dt.tm_year, &dt.tm_mon, &dt.tm_day, &dt.tm_hour, &dt.tm_min);
/* NORMALIZE VALUES */
dt.tm_year = dt.tm_year - 1900; /* NORMALIZE YEAR */
dt.tm_mon = dt.tm_mon - 1; /* NORMALIZE MONTH */
dt.tm_isdst = -1; /* NO INFORMATION ABOUT DST */
mktime(&dt); /* NORMALIZE STRUCT TM */
/* PRINT DATETIME */
strftime(buffer, 80, "%c %z %Z\n", &dt);a
printf("%s\n", buffer);
/* COPY STRUCT TM TO YACC RETURN VALUE */
memcpy(&dt, &yylval.datetime, sizeof(dt));
}
生成文件
CCFLAGS = -std=c89
YFLAGS = -d # Forces generation of y.tab.h
OBJS = readfile_lexer.o readfile_grammar.o
TARGET = readfile
readfile: $(OBJS)
cc $(OBJS) -std=c89 -lm -o $(TARGET)
readfile_grammar.h readfile_grammar.o: readfile_grammar.y
yacc $(YFLAGS) -oreadfile_grammar.c readfile_grammar.y
cc $(CCFLAGS) readfile_grammar.c
readfile_lexer.o: readfile_lexer.l readfile_grammar.h
lex -oreadfile_lexer.c readfile_lexer.l
cc $(CCFLAGS) readfile_lexer.c
clean:
rm -f $(OBJS) readfile_grammar.[ch] readfile_lexer.c
在尝试编译源代码时,出现上述错误:
% make
yacc -d -oreadfile_grammar.c readfile_grammar.y
cc -std=c89 readfile_grammar.c
ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>> /tmp/readfile_grammar-2d51ee.o:(yyparse)
ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>> /tmp/readfile_grammar-2d51ee.o:(yyparse)
ld: error: undefined symbol: yylex
>>> referenced by readfile_grammar.c
>>> /tmp/readfile_grammar-2d51ee.o:(yyparse)
ld: error: undefined symbol: yyerror
>>> referenced by readfile_grammar.c
>>> /tmp/readfile_grammar-2d51ee.o:(yyparse)
cc: error: linker command failed with exit code 1 (use -v to see invocation)
*** Error code 1
Stop.
解决方案
在您的 makefile 中,在命令中cc $(CCFLAGS) readfile_grammar.c
添加-c
选项以指定这只是一个模块并且应该编译为一个.o
文件:
readfile_grammar.h readfile_grammar.o: readfile_grammar.y
yacc $(YFLAGS) -oreadfile_grammar.c readfile_grammar.y
cc -c $(CCFLAGS) readfile_grammar.c
否则 cc 假定它是整个程序并尝试将其链接到可执行二进制文件中,这当然会失败,因为它调用了其他文件中的函数。
推荐阅读
- c# - 将 GeometryDrawing 画笔绑定到自定义控件依赖属性
- python - 如何在 BS4 `find_all` 中使用正则表达式以返回具有模式优先级的匹配项?
- flutter - 为什么在使用提供程序调用 api 时出现错误?
- c++ - 没有匹配函数调用“regex_match”
- neural-network - 使用 PyTorch 和多层感知嵌入情感分析任务
- javascript - 在应用层(使用 sequelize 或其他)如果已读取的数据 (SELECT) 已更改 (UPDATE),则中止 SQL 事务
- c# - WPF DataGridComboBoxColumn SelectedItem 的属性作为单元格文本
- javascript - 轻量级图表:带图像的时间尺度
- javascript - 以前日期的数组对象的总和
- r - 打印同一张表中关系和相关性的显着性