我正在尝试使用lex / yacc程序解析以下配置文件。
我的配置文件如下所示。
[ main ]
e_type=0x1B
我的lex文件如下(test.l)
%option noyywrap
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum{
T_E_TYPE = 1,
T_MAIN_SECTION = 3,
T_NUMBER = 4,
T_EQUAL = 5,
};
/**
* Forward declerations
**/
void Number ();
void HexaNumber ();
%}
%option nounput
%option noinput
%option case-insensitive
/*-----------------------------------------------------------------
Some macros (standard regular expressions)
------------------------------------------------------------------*/
HEXALETTER [a-fA-F]
HEXANUMBER [0][x](({DIGIT}|{HEXALETTER})+)
NUM {DIGIT}+
HEXA ({DIGIT}|{HEXALETTER}|[*])
STR \"[^\"]*\"
WSPACE [ \t]*
NEWLINE [\n\r]
/*----------------------------------------------------------------
The lexer rules
------------------------------------------------------------------*/
%%
%{
yylval = 0; /* do this for every token not using yylval, to be on the safe side */
%}
e_type { return T_E_TYPE; }
main { return T_MAIN_SECTION;}
HEXANUMBER { HexaNumber(); return T_NUMBER; }
= { return T_EQUAL; }
[^\t\n\r] { }
%%
void Number () {
yylval.l = atol(yytext);
}
void HexaNumber () {
//yylval.l = (unsigned int) strtol(yytext, (char **)NULL, 16);
yylval.l = dagstrtol16 (yytext);
}
我的yacc文件如下。 (test.y)
%{
#include <ctype.h>
#include <stdio.h>
#ifdef E_PARSE_DEBUG
// Some yacc (bison) defines
#define YYDEBUG 1 // Generate debug code; needed for YYERROR_VERBOSE
#define YYERROR_VERBOSE // Give a more specific parse error message
#endif
static FILE *scan_log_file = NULL;
static void debug_log_message(const char* location , const char *fmt,...);
static void found_main_section_complete(void);
void yyerror(const char *str)
{
fprintf(stderr,"error: %s\n",str);
}
int yywrap()
{
return 1;
}
int main()
{
printf("> ");
yyparse();
return 0;
}
%}
/*------------------------------------------------------------------
Yacc declarations
------------------------------------------------------------------ */
/* The structure for passing value between lexer and parser */
/* In the lexer we know it by the name 'yylval'*/
%union {
char *str;
unsigned long l;
void * distr;
void * command;
}
%token T_E_TYPE
%type <l> number
%%
config_file_sections
: main
;
main
: main_attribute_list
{
debug_log_message(E_DEBUG_AT,"Found main_section\n");
parse_found_main_section_complete();
}
;
main_attribute_list
: T_E_TYPE number
{
debug_log_message(E_DEBUG_AT,"Found main section token T_E_TYPE\n");
}
number
: NUMBER { $$ = (unsigned long) $1; }
;
%%
void debug_log_message(const char* location , const char *fmt,...)
{
#ifdef E_PARSE_DEBUG
va_list ap;
if (scan_log_file)
{
fprintf(scan_log_file, "At %s:(line%d) ", location, lineno);
va_start(ap, fmt);
(void) vfprintf(scan_log_file, fmt, ap);
va_end(ap);
}
#endif
return;
}
static void parse_found_main_section_complete(void)
{
int i = 0;
dagutil_verbose_level(1,"Parsed main section rules\n");
if (dagutil_get_verbosity() > 0 )
{
//:TODO
}
return;
}
我按如下方式编译文件。
flex test.l
yacc -d test.y
gcc lex.yy.c y.tab.c -Wall -ll -o test
我收到以下错误
yacc: e - line 67 of "test.y", $1 (NUMBER) is untyped
test.l: In function ‘yylex’:
test.l:44:5: error: ‘yylval’ undeclared (first use in this function)
yylval = 0; /* do this for every token not using yylval, to be on the safe side */
^
test.l:44:5: note: each undeclared identifier is reported only once for each function it appears in
test.l: In function ‘Number’:
test.l:57:5: error: ‘yylval’ undeclared (first use in this function)
}
^
test.l: In function ‘HexaNumber’:
test.l:62:5: error: ‘yylval’ undeclared (first use in this function)
}
^
test.l:62:5: warning: implicit declaration of function ‘dagstrtol16’ [-Wimplicit-function-declaration]
我不知道yylval应该在哪里声明。生成的“y.tab.h”似乎是空的
答案 0 :(得分:2)
您的.l文件需要
#include "y.tab.h"
它应该不包含它自己的令牌声明。它们应该或者应该在y.tab.h中。
我认为还有其他问题:见评论。