1
votes

I am trying to implement tree within my Flex and Bison files.

rs.l

%{
#include <iostream>
#include <stdio.h>
const char s[2] = " ";
#include "sr.tab.h"
char *token;
#define YY_DECL extern "C" int yylex()
int line_num = 1;

#ifdef DEBUG
#define RETURN(x)       cerr << "\n--> found " << #x << "\n"; return x;
#else
#define RETURN(x)       return x;
#endif


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-z+]
QTEXT           [0-9a-zA-Z!#$%&&'()*+,\-.\/:;<=>?@\[\]^_`{|}~""]
STAR        [*]

/* [ \t]         ; */


/* [ \s]         ; */

%option case-insensitive

%%



[ \t]       ;

"X".*       { yylval.sval = strdup(yytext);
      return TOK_X; }


"M".*       { yylval.sval = strdup(yytext);
      return TOK_M; }

{ALPHA}*      { yylval.sval = strdup(yytext);
      return TOK_PINS; }

.SUBCKT           { yylval.sval = strdup(yytext);
         return TOK_SUBCKT; }


.ends        { yylval.sval = strdup(yytext);
      return TOK_Ends; }

"*".*       { cout << "Comment: " << yytext << endl; }


{QTEXT}*    { yylval.sval = strdup(yytext);
      return TOK_MASTERNAME; }

"D".*       { yylval.sval = strdup(yytext);
      return TOK_D; }

"R".*       { yylval.sval = strdup(yytext);
      return TOK_R; }


"+".*       { yylval.sval = strdup(yytext);
      return TOK_PORTS; }


\\\n            { printf("c> "); }


"//".*      /* ignore comments */

^{CRLF}                         { return TOK_EMPTY_LINE; }
 {CRLF}                          {}
.                               {}/* ignore unknown chars */
\n                      { ++line_num; /*RETURN(ENDL); */ }

sr.y

%{
#include <cstdio> 
#include <cstring>
#include <iostream>
#include <stdio.h>

#define YYDEBUG 1

using namespace std;

extern "C" int yylex();
extern "C" FILE *yyin;
extern int line_num;


void yyerror(const char* s);

struct Node {
char nodeType;
struct Node *firstChild;
struct Node *nextSibling; 
};

%}


// Symbols.
%union
{
char* sval;
struct  Node *node;
};


%token <sval> TOK_X
%token <sval> TOK_PINS
%token <sval> TOK_M
%token <sval> TOK_D
%token <sval> TOK_R
%token <sval> TOK_STRAP
%token <sval> TOK_WRAP
%token <sval> TOK_VIA
%token <sval> TOK_EMPTY_LINE 
%token <sval> TOK_BLOCK
%token <sval> TOK_LINE
%token <sval> TOK_BEGIN
%token <sval> TOK_END
%token <sval> TOK_VERSION
%token <sval> TOK_STRUCT
%token <sval> TOK_UNIQUE
%token <sval> TOK_REF
%token <sval> TOK_POS
%token <sval> TOK_CON
%token <sval> TOK_ORI
%token <sval> TOK_SUBCKT
%token <sval> TOK_MASTERNAME
%token <sval> TOK_PORTS
%token <sval> TOK_Ends
%token END ENDL

%type <sval> program
%type <sval> block

%%

language : program ;

program : block { printNode($1); }
| program block
;


block : TOK_SUBCKT TOK_MASTERNAME PortsContent XContents { $$ = makeRootNode($2); }
| XContents 
| TOK_Ends
;


PortsContent : PORTS
     | PortsContent PORTS
     ;


PORTS   : TOK_PORTS { cout << endl << $1  ; }
;


XContents : XContents PORTS
   | item
   ;


item :      TOK_X { cout << endl << $1 ; }
 |  TOK_M { cout << endl << $1 ; }
 |  TOK_D { cout << endl << $1 ; }
 |  TOK_R { cout << endl << $1 ; }
    ;

%%

struct Node *makeRootNode(char mastername) {
Node *node = malloc(sizeof struct Node);
node->nodeType = mastername;
node->firstChild = null;
node->nextSibling = null;
return node;
}

void printNode (struct Node* node) {
switch (node->nodeType) {
case mastername :
    printf("%i", node->nodeType);
    return;
}
}


int main(int argc, char *argv[]) 
{
FILE* inputF;


inputF = fopen(argv[1], "r");
if(!inputF)
{
cout << "Bad Input.Noexistant file" << endl;
return -1;
}
yyin = inputF;
do
{
//yydebug = 1;
    yyparse();
}while (!feof(yyin));      
}
void yyerror(const char *s) {
cout << "parse error on line " << line_num << "!  Message: " << s << endl;
exit(-1);
}

extern "C" int yywrap()
    {
        return (1 == 1);
    }



#include "lex.yy.c"

But I found error regarding Function was not declared in this scope so how can I recover my error?

Where should I declare and define functions within Flex and Bison files.

And is there any other idea regarding to implement tree within flex and bison file. If yes please share with me.

File I am parsing:

**********************************************************************
* Main Circuit Netlist:
*
* Block: SPSMHD_BB_1024x8m4_aTlmr
*
**********************************************************************

.subckt SPSMHD_BB_1024x8m4_aTlmr 
+ A<6> A<5> A<4> A<3> A<2> A<1> A<0> ATP CK 
+ CSN D<7> D<6> D<5> D<4> D<3> D<2> D<1> D<0> IG INITN Q<7> Q<6> Q<5> Q<4> Q<3> 
+ Q<2> Q<1> Q<0> RRA<5> RRA<4> RRA<3> RRA<2> RRA<1> RRA<0> RRAE RRMATCH SCTRLI 
+ SCTRLO SDLI SDLO SDRI SDRO SE STDBY TA<6> TA<5> TA<4> TA<3> TA<2> TA<1> TA<0> 
+ TBIST TBYPASS TCSN TED TOD TRRAE TWEN WEN gndm vddm gndsm vddsm 
DDSMRI gndm gndm tdndsx 15.222f perim=526.0n 
DDSDRI gndm SDRI tdndsx 15.222f perim=526.0n 
XITOP A<6> A<5> A<4> A<3> A<2> A<1> A<0> ATP CK CSN D<7> D<6> D<5> D<4> D<3> 
+ D<2> D<1> D<0> gndm IG INITN gndm gndm gndm gndm gndm gndm gndm gndm gndm Q<7> 
+ Q<6> Q<5> Q<4> Q<3> Q<2> Q<1> Q<0> gndm gndm gndm RRA<0> RRA<1> RRA<2> RRA<3> 
+ RRA<4> RRA<5> RRAE RRMATCH SCTRLI SCTRLO SDLI SDLO SDRI SDRO SE gndm gndm SMLO 
+ gndm SMRO STDBY gndm TA<6> TA<5> TA<4> TA<3> TA<2> TA<1> TA<0> TBIST TBYPASS 
+ TCSN TED TEDO gndm TEMO TOD TODO gndm TOMO TORS TRRAE TWEN WEN gndm gndm gndm 
+ gndsm vddm vddmo vddm vddsm 
+ SPHDDR_TOPLEVEL_112x8m2B1_aTRST_SPSMHD_BB_1024x8m4_aTlmr 
.ends

Error message:

sr.y: In function ���int yyparse()���:
sr.y:70: error: ���printNode��� was not declared in this scope
sr.y:75: error: ���makeRootNode��� was not declared in this scope
sr.y: In function ���Node* makeRootNode(char)���:
sr.y:104: error: expected primary-expression before ���struct���
sr.y:106: error: ���null��� was not declared in this scope
sr.y: In function ���void printNode(Node*)���:
sr.y:113: error: ���mastername��� was not declared in this scope

Command for parsing:

flex rs.l
bison -d sr.y
g++ sr.tab.c -lfl -o scanner.exe
1
Please include the command line you used and the exact error message, identifying the source file and the function name. The message sounds like it comes from your C++ compiler and is related to calling a function before there's a declaration of the function — but which function?Jonathan Leffler
Using #include "lex.yy.c" as the last line of the sr.y file is unorthodox. I'm not sure whether that's part of your trouble or not.Jonathan Leffler
no it is not part of trouble and I have edited my post so check and please help me @Jonathan Lefflershailavi shah
The error message is error: `printNode' was not declared in this scope. Your code doesn't declare or define a function printNode before it is used in the grammar, so it isn't a big surprise to me that you get the error message. You are, after all, coding in C++, which means functions must be defined or declared before you use them. You need to place either the function or a declaration of the function in the %{%} section at the top of the grammar — as Chris Dodd saidJonathan Leffler
ok.. I got it. Thank you so muchshailavi shah

1 Answers

2
votes

In general, any function or global variable or type that you want to use in the actions of your .l or .y file(s) needs to be declared in the %{...%} declarations section in the top of that file. Most commonly, that means you put the declaration in a header file (or several), and #include that header file(s) in the %{...%} section.