2013-01-22 88 views
1

我想在我的小型项目中使用flex和bison工具。 为了正确理解和使用我正在写迷你计算器的工具。在另一个命名空间中使用外部yyin

问题是,我无法使用变量yyin里面的类我在另一个名称空间中声明的函数。

main()函数应该读取运行参数并在名称空间ExNameSpace中使用Example::parse_file()

虽然联编译后的文件获得:

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由柔性外部定义但没有正确移植到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 
+0

也许尝试'的extern “C” FILE * yyin中;'... –

+0

现在我得到这样的: 'parser.y:在成员函数 '布尔ExNameSpace ::例子:: parse_file(常量字符串&)': 解析器.y:62:10:错误:预期在字符串常量之前的非限定id parser.y:63:8:错误:'yyin'未在此范围内声明 parser.y:72:10:error:'yyin'未在此范围内声明“ – agoldis

+0

请在标记问题之前查看标签上的”信息弹出窗口“。我删除了Flex标签,因为这与Adobe/Apache UI框架无关,并添加了用于词法分析器的gnu-flex标签。 – JeffryHouser

回答

1

问题是声明

extern FILE* yyin; 

功能Example::ParseFile。由于此声明符没有明确的范围,并且包含方法是名称空间ExNameSpace的一部分,所以该声明隐含在该名称空间中。但是,由于您从未在任何地方定义过ExNameSpace::yyin,因此会导致链路故障。由bison创建的默认yyin位于全局名称空间中。所以,你需要这条线变为

extern FILE * ::yyin; 

或只是摆脱它完全,作为yyin的文件范围的声明应在文件中的这一点上已经是可见的,所以没有必要为一个局部声明以遮蔽文件范围的一个。

相关问题