Пытаюсь посредством утилит Flex, Bison написать модуль программы, который по заданному исходному c++ тексту классов, строит список, содержащий название класса, названия его родителей.
Проблема в том, что я не пойму как бы мне создать эту структуру для Bison и затем передать её "внешнему" коду основной программы
Грамматика для Flex
Код: Выделить всё
%option c++
%option yylineno
%option never-interactive
%option noyywrap
%{
#include"parser.h"
%}
ws [ \t]+
nl [\n]+
Semi ,
Par1 [\(\)]
Par2 [\{\}]
dd1;
dd2 :
ALNUM [a-zA-Z0-9]+
%%
class {yylval.string = strdup(yytext);return CLASS_KW;}
public {yylval.string = strdup(yytext);return PUBLIC_KW;}
private {yylval.string = strdup(yytext);return PRIVATE_KW;}
protected {yylval.string = strdup(yytext);return PROTECTED_KW;}
{ALNUM} {yylval.string = strdup(yytext);return WORD_KW;}
{Semi} {yylval.string = strdup(yytext);return SEMI_KW;}
{Par1} {yylval.string = strdup(yytext);return PAR1_KW;}
{Par2} {yylval.string = strdup(yytext);return PAR2_KW;}
{dd1} {yylval.string = strdup(yytext);return DD1_KW;}
{dd2} {yylval.string = strdup(yytext);return DD2_KW;}
{nl} {}
{ws} {}
. return -1;
%%Грамматика для Bison (для начала, пытаюсь хотя бы вывести на экран информацию, но даже это не работает):
Код: Выделить всё
%{
#include <iostream>
#include <stdlib.h>
void yyerror(char const* msg);
int yylex();
int lineno();
%}
%union {
char *string;
}
%token <string> CLASS_KW PUBLIC_KW PRIVATE_KW PROTECTED_KW WORD_KW SEMI_KW PAR1_KW PAR2_KW DD1_KW DD2_KW
%%
acsiom : class;
class : CLASS_KW WORD_KW PAR2_KW PAR2_KW
{std::cout<<"Class name is:"<<$2<<"\n";}
| CLASS_KW WORD_KW DD2_KW inheritance PAR2_KW PAR2_KW
{std::cout<<"Class name is:"<<$2<<"\n";};
inheritance: PUBLIC_KW WORD_KW
{std::cout<<" it is a child of"<<$2<<" class\n";}
| PROTECTED_KW WORD_KW
{std::cout<<" it is a child of"<<$2<<" class\n";}
| PRIVATE_KW WORD_KW
{std::cout<<" it is a child of"<<$2<<" class\n";}
| SEMI_KW inheritance;
%%Код программы:
Код: Выделить всё
#include <iostream>
#include <fstream>
#include "FlexLexer.h"
extern int debug;
yyFlexLexer* lexer = NULL; //this is reference to global scanner
int debug = 1; // parser to produce debug info output
int yyparse();//parser function,implemented by bison declaration
int yylex() // wrapper for scanner function, bison looks it
{
if (lexer != NULL)
return lexer->yylex();
else
return 0;
}
void yyerror(char const* msg) // bison looks for it
{
std::cerr << msg << std::endl;
}
int lineno()
{
if (lexer != NULL)
return lexer->lineno();
else
return 0;
}
int main (int argc, char* argv[])
{
if (argc < 2) {
std::cout << "USE: cbisonparser <source file>"
<< std::endl;
return 0;
}
std::ifstream infile(argv[1]);
lexer = new yyFlexLexer(&infile);
if (yyparse() != 0)
{
std::cout << "Syntax error, document rejected"
<< std::endl;
} else
std::cout << "Success" << std::endl;
return 0;
}Пример входного файла:
Код: Выделить всё
class parent{}