использование внешнего yyin в другом пространстве имен

Я пытаюсь использовать инструменты flex и bison в своем небольшом проекте.
Для того, чтобы правильно понять и использовать инструменты, я пишу мини-калькулятор.

Проблема в том, что я не могу использовать переменную yyin внутри функций класса я объявил в другом пространстве имен.

main() функция должна читать аргументы выполнения и использовать Example::parse_file() в пространстве имен ExNameSpace,

Связывая скомпилированные файлы, я получаю:

make all
bison --defines=parser.hpp --output=parser.cpp parser.y
flex --outfile=scanner.cpp scanner.l
g++ -o program scanner.cpp parser.cpp Example.cpp -lfl
/tmp/ccyQN7z9.o: In function `ExNameSpace::Example::parse_file(std::string const&)':
parser.cpp:(.text+0xabc): undefined reference to `ExNameSpace::yyin'
parser.cpp:(.text+0xac3): undefined reference to `ExNameSpace::yyin'
parser.cpp:(.text+0xb3e): undefined reference to `ExNameSpace::yyin'
collect2: error: ld returned 1 exit status
make: *** [app] Error 1

Мое предложение состоит в том, что переменная yyin внешне определяется как flex, но не правильно портирован на ExNameSpace Пространство имен.

Прикрепление исходных файлов, которые я использую

Example.h:

#include <string>
#include <iostream>

#ifndef EXAMPLE_H_
#define EXAMPLE_H_

namespace ExNameSpace {
/* global namespace variable */
extern std::ostream *err;
class Example {
public:
bool parse_file (const std::string &file);
};
}
#endif /* EXAMPLE_H_ */

Example.cpp:

#include "Example.h"namespace ExNameSpace {
std::ostream *err = &std::cout;
Example::Example() {}
Example::~Example() {}
}

parser.y:

%{
#include <stdio.h>
#include "Example.h"
void yyerror (const char *);
int yylex();

using namespace ExNameSpace;
%}

%%
/* bison rules */
%%

void yyerror(const char *message)
{
extern int yylineno;
*err << "(line " << yylineno << ") " << message << std::endl;
}

bool Example::parse_file(const std::string &file)
{
extern FILE* yyin;
if(!(yyin=fopen(file.c_str(), "r")))
{
*err << "Could not open " << file << std::endl;
return true;
}
int result=yyparse();
fclose(yyin);
return result;
}

scanner.l:

%{
#include "parser.hpp"#include "Example.h"
using namespace ExNameSpace;
%}

%%
/* flex rules */
%%

Makefile:

all: app
app: scanner.l parser.y
bison --defines=parser.hpp --output=parser.cpp parser.y
flex --outfile=scanner.cpp scanner.l
g++ -o program scanner.cpp parser.cpp Example.cpp -lfl

clean:
rm parser.hpp parser.cpp scanner.cpp

1

Решение

Проблема в декларации

extern FILE* yyin;

в функции Example::ParseFile, Поскольку этот декларатор не имеет явной области видимости, и содержащий метод является частью пространства имен ExNameSpaceобъявление неявно находится в этом пространстве имен. Но, как вы никогда не определяете ExNameSpace::yyin в любом месте вы получаете сбои ссылок. По умолчанию yyin созданный Bison находится в глобальном пространстве имен. Так что вам нужно изменить эту строку на

extern FILE * ::yyin;

или просто полностью избавиться от него, как декларация yyin должен уже быть видимым в этой точке файла, поэтому нет необходимости в локальном объявлении, чтобы скрыть файл-область видимости.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector