我需要使用flex和Bison解析以下文件:
新文件
BEGIN BLOCK BLK_ROWDEC
NAME cell_rowdec
SIZE UNI_rowdecSize
ITERATE itr_rows
DIRECTION lgDir_rowdec
STRAP STRD1,STRD3,STRD2
WRAP WRD1
VIA VIAB,VIAC,VIAD
ENDS BLK_ROWDEC
我想阅读上面的文件,为此我写了这段代码
lex.l
%{
#include <iostream>
#include <stdio.h>
#include "yacc.tab.h"
#define YY_DECL extern "C" int yylex()
using namespace std;
%}
DOT "."
COLON ":"
SEMICOLON ";"
COMMA ","
ANGLE_LEFT "<"
ANGLE_RIGHT ">"
AT "@"
EQUAL "="
SQUARE_OPEN "["
SQUARE_CLOSE [^\\]"]"
OPENBRACE "\("
CLOSEBRACE "\)"
QUOTE "\""
QUOTE_OPEN "\""
QUOTE_CLOSE [^\\]"\""
SPACE " "
TAB "\t"
CRLF "\r\n"
QUOTED_PAIR "\\"[^\r\n]
DIGIT [0-9]
ALPHA [a-zA-Z]
QTEXT [0-9a-zA-Z!#$%&'()*+,\-.\/:;<=>?@\[\]^_`{|}~]
%%
[a-zA-Z0-9]+ { yylval.sval = strdup(yytext); return TOK_STRING; }
{SPACE}* {return TOK_SPACE; }
^{SPACE}*Name {return TOK_NAME; }
{SPACE}*SIZE.* {return TOK_SIZE; }
{SPACE}*ITERATE.* {return TOK_ITERATE; }
{SPACE}*DIRECTION.* {return TOK_DIRECTION; }
^{CRLF} { return TOK_EMPTY_LINE; }
{CRLF} {}
. {}/* ignore unknown chars */
yacc.y
%{
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdio.h>
using namespace std;
extern "C" int yylex();
extern "C" FILE *yyin;
void yyerror(const char* s);
%}
// Symbols.
%union
{
char* sval;
};
%token <sval> TOK_NAME
%token <sval> TOK_SIZE
%token <sval> TOK_STRING
%token <sval> TOK_ITERATE
%token <sval> TOK_DIRECTION
%token <sval> TOK_EMPTY_LINE
%token TOK_SPACE
%%
str:
TOK_SPACE TOK_NAME TOK_SPACE TOK_STRING
{
cout << "Value:" << $2 << "->" << $4;
}
;
%%
int main(void) {
FILE * pt = fopen("new file ", "r" );
if(!pt)
{
cout << "Bad Input.Noexistant file" << endl;
return -1;
}
yyin = pt;
do
{
yyparse();
}while (!feof(yyin));
}
void yyerror(const char *s)
{
cout << "Error. " << s << endl;
exit(-1);
}
#include "lex.yy.c"
首先,我只是尝试打印第二行文件,但我无法打印任何内容。请帮帮我,我该怎么办?
编译由以下人员完成:
flex lex.l
bison -d yacc.y
g++ yacc.tab.c -lfl -o scanner.exe
答案 0 :(得分:2)
了解如何调试解析器非常重要。在文件的第一部分#define YYDEBUG 1
和主集yydebug = 1
中。这将允许您在运行解析器时查看确切的步骤,然后您就会知道错误的位置。知道这一点非常重要,因为很难找到错误。所以调试你的程序!
%{
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdio.h>
#define YYDEBUG 1 // This is new
using namespace std;
extern "C" int yylex();
extern "C" FILE *yyin;
void yyerror(const char* s);
%}
int main(){
yydebug = 1; // This is new
yyparse();
}
此后yylval.sval = strdup(yytext);
你需要检查yylval.sval是否为NULL,因为strdup(yytext)
首先分配内存,并且在该函数复制字符串之后,所以strdup(yytext)
将返回NULL如果内存分配失败。