我需要解析以下配置文件。
[ main ]
e_type=0x1B
下面给出了 lex(test.l) 和 yacc(test.y) 文件
测试.l
%option noyywrap
%option yylineno
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
int yylinenu = 1;
int yycolno=1;
/**
* Forward declerations
**/
void Number ();
void HexaNumber ();
unsigned char getHexaLex (char c);
unsigned int strtol16 (char * str);
%}
%option nounput
%option noinput
%option case-insensitive
/*-----------------------------------------------------------------
Some macros (standard regular expressions)
------------------------------------------------------------------*/
DIGIT [0-9]
HEXALETTER [a-fA-F]
HEXANUMBER [0][x](({DIGIT}|{HEXALETTER})+)
NUM {DIGIT}+
HEXA ({DIGIT}|{HEXALETTER}|[*])
STR \"[^\"]*\"
WSPACE [ \t]*
NEWLINE [\n\r]
/*----------------------------------------------------------------
The lexer rules
------------------------------------------------------------------*/
%%
e_type { yylval.str = yytext; return T_E_TYPE; }
main { yylval.str = yytext; return T_MAIN_SECTION;}
{HEXANUMBER} { yylval.n = atoi(yytext); HexaNumber(); return T_NUMBER; }
= { return T_EQUAL; }
"[" { return T_OPEN_BRACKET; }
"]" { return T_CLOSE_BRACKET;}
[^\t\n\r] { }
{WSPACE} { } /* whitespace: (do nothing) */
{NEWLINE} {
yylinenu++;
return T_EOL;
}
%%
void Number () {
yylval.n = atol(yytext);
}
测试.y
%{
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
#include "y.tab.h"
#include "lex.h"
#define E_PARSE_DEBUG
#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
#define E_DEBUG_STRINGIFY(x) #x
#define E_DEBUG_TOSTRING(x) E_DEBUG_STRINGIFY(x)
#define E_DEBUG_AT (__FILE__ ":" E_DEBUG_TOSTRING(__LINE__))
extern int yyparse (void);
extern int yylinenu;
extern int yycolno;
void yyerror(const char *str)
{
fprintf(stderr,"line: %d column: %d error: %s %s \n",yylinenu,yycolno,str,yylval.str);
}
int yywrap()
{
return 1;
}
int main()
{
printf("> ");
// open a file handle to a particular file:
FILE *myfile = fopen("tmp.conf", "r");
// make sure it is valid:
if (!myfile) {
printf("I can't open tmp.conf \n");
return -1;
}else
{
printf("opened config file \n");
}
// set lex to read from it instead of defaulting to STDIN:
yyin = myfile;
yyparse();
return 0;
}
int lineno = 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 int n;
void * distr;
void * command;
}
%token T_E_TYPE T_HOSTID_TYPE T_MAIN_SECTION T_EQUAL T_OPEN_BRACKET T_CLOSE_BRACKET T_EOL
%token <str> STRING
%token <n> T_NUMBER
%type <n> number
%%
config_file
: /* empty */
{
}
| config_file config_file_section
{
}
;
config_file_section
: T_OPEN_BRACKET T_MAIN_SECTION T_CLOSE_BRACKET attribute_list
{
}
;
attribute_list
: /* empty */
{
}
| attribute_list attribute_pair
{
}
;
attribute_pair
: T_E_TYPE T_EQUAL number
{
}
;
number
: T_NUMBER
{
}
;
%%
我有一个包含在 test.y 中的 include lex.h
文件
#ifndef _LEX_H_
#define _LEX_H_
#include <stdio.h>
#ifdef _LEX_CPP_
int lineno = 1; // line number count; this will be used for error messages later
#else
// Import some variables
extern int lineno;
extern FILE *yyin; // the input stream
// Function prototype
int yylex ();
#endif
结束
我按如下方式编译文件。
flex test.l
yacc -d test.y
gcc lex.yy.c y.tab.c -Wall -ll -o test -ldag
我得到的二进制test
正在给出
> opened config file
line: 1 column: 1 error: syntax error main
最佳答案
你的问题就是规则:
attribute_pair
: T_E_TYPE '=' number
您的词法分析器返回 T_EQUAL
但语法需要 '='
并且两者不相等。我很容易发现;当我运行该程序时,我收到报告:
> opened config file
error: syntax error, unexpected T_EQUAL, expecting '='
所以发现问题非常容易。我使用的 yacc
实际上是 bison
:
$ yacc --version
bison (GNU Bison) 2.3
…
$
当我解决这个问题时,错误发生了变化:
> opened config file
error: syntax error, unexpected T_NUMBER, expecting NUMBER
修复涉及更改:
%token T_E_TYPE T_HOSTID_TYPE T_MAIN_SECTION T_EQUAL T_OPEN_BRACKET T_CLOSE_BRACKET
%token <str> STRING
%token <n> T_NUMBER
(从第一行删除 T_NUMBER;将第三行的 NUMBER
更改为 T_NUMBER
。)此外:
number
: T_NUMBER
(将 NUMBER
更改为 T_NUMBER
。)
完成这两项更改后,您将成功运行(除了打开消息之外没有任何输出,但也没有错误)。
关于c - Yacc 程序给出错误 :"syntax error",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31799424/