shailavi shah
shailavi shah

Reputation: 181

Parse File using flex and bison

I need to parse following file using flex and Bison:

new file

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  

I want to read above file and for that I write this code

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"

First, I just try to print second line of file but I am not able to print anything. Please help me what could I do??

Compilation is done by:

flex lex.l
bison -d yacc.y
g++ yacc.tab.c -lfl -o scanner.exe

Upvotes: 0

Views: 6700

Answers (1)

Aleksandar Makragić
Aleksandar Makragić

Reputation: 1997

It is very important knowing how to debug your parser. In first part of the file, #define YYDEBUG 1, and in main set yydebug = 1. This will allow you to see exact steps when you run your parser ant then you'll know where your error is. Knowing this is extrimely important, because mistakes are very hard to find. So debug your program!

%{
#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();
}

Also yylval.sval = strdup(yytext); after this you need to check whether yylval.sval is NULL, because strdup(yytext) is first allocating memory, and after that function is copying string, so strdup(yytext) will return NULL if memory allocation fails.

Upvotes: 4

Related Questions