使用 flex 和 bison 解析文件
Parse File using flex and bison
我需要使用 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:" << << "->" << ;
}
;
%%
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
了解如何调试解析器非常重要。在文件的第一部分 #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)
将 return NULL 如果内存分配失败。
我需要使用 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:" << << "->" << ;
}
;
%%
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
了解如何调试解析器非常重要。在文件的第一部分 #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)
将 return NULL 如果内存分配失败。