我正在尝试在Flex和Bison文件中实现树。
%{
#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); */ }
%{
#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
答案 0 :(得分:1)
通常,您要在.l或.y文件的操作中使用的任何函数或全局变量或类型都需要在%{
... {{1}中声明在该文件顶部的声明部分。最常见的是,这意味着您将声明放在头文件(或多个)中,%}
表示#include
... %{
部分中的头文件。