在flex和bison中,此范围内未声明函数

时间:2016-03-30 11:57:05

标签: bison flex-lexer

我正在尝试在Flex和Bison文件中实现树。

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"

但我发现有关Function的错误未在此范围内声明,那么如何才能恢复错误?

我应该在Flex和Bison文件中声明和定义函数。

还有其他想法在flex和bison文件中实现树。如果是,请与我分享。

文件我正在解析:

**********************************************************************
* 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

错误讯息:

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

解析命令:

flex rs.l
bison -d sr.y
g++ sr.tab.c -lfl -o scanner.exe

1 个答案:

答案 0 :(得分:1)

通常,您要在.l或.y文件的操作中使用的任何函数或全局变量或类型都需要在%{ ... {{1}中声明在该文件顶部的声明部分。最常见的是,这意味着您将声明放在头文件(或多个)中,%}表示#include ... %{部分中的头文件。