使用flex和bison解析文件

时间:2016-01-21 05:41:53

标签: bison flex-lexer text-parsing fileparsing

我需要使用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

1 个答案:

答案 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如果内存分配失败。

相关问题