2013-01-22 30 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的文件範圍的聲明應在文件中的這一點上已經是可見的,所以沒有必要爲一個局部聲明以遮蔽文件範圍的一個。

相關問題