2012-10-07 28 views
2

首先,我對Bison和Flex很新。我知道這些工具被設計用於C語言,我有一種感覺,我所有的問題都來自在C++中使用它們。我不確定我是否以正確的方式做到了這一點。yyparse()未在Bison/Flex C++項目中聲明僅適用於gcc/bison/flex的某些版本

該代碼在我的電腦上編譯得很好,但不在我的大學服務器上。我已將此問題隔離在此處。

在我的大學:

 
$ (g++ --version; bison --version; flex --version)|grep '[0-9]\.' 
g++ (Debian 4.4.5-8) 4.4.5 
bison (GNU Bison) 2.4.1 
flex 2.5.35 

在家:

 
HOME $ (g++ --version; bison --version; flex --version)|grep '[0-9]\.' 
g++ (GCC) 4.7.1 20120721 (prerelease) 
bison (GNU Bison) 2.6.2 
flex 2.5.37 

我用下面的命令編譯: bison -d parse.y && flex lex.l && g++ main.cpp lex.yy.c parse.tab.c -lfl

正如我已經說過,它編譯罰款(沒有警告)在我的電腦上,但我得到這個在服務器上:

 
main.cpp: In function 'int main()': 
main.cpp:28: error: 'yyparse' was not declared in this scope 

由於SO有一些支架問題,I've also uploaded a tarball

lex.l

 
%{ 
#include 
#include "dict.hpp" 
#include "parse.tab.h" 
%} 

%% 

[0-9]+ yylval.num = atoi(yytext); return NUM; 
[a-z]+ yylval.id = dict.id(yytext); return ID; 
[:space:] ; 

parse.y

 
%{ 
#include 
#include "dict.hpp" 
void yyerror (const char* e) { 
    puts(e); 
} 
int yylex(); 
%} 

%union{ 
    uint id; 
    int num;  
} 

%token ID; 
%token NUM; 

%% 

S : ID NUM S { 
     dict.set($1, $2); 
    } 
|; 

dict.hpp

 
#ifndef _DICT_HPP_ 
#define _DICT_HPP_ 
#include 
#include 

typedef std::pair dpair; 
typedef unsigned int uint; 

class Dict { 
    std::vector tab; 
public: 
    uint id(char* s); 
    void set(uint i, int v); 
    void print(); 
}; 

extern Dict dict; 

#endif /* _DICT_HPP_ */ 

的main.cpp

#include <vector> 
#include <string> 
#include <cstdio> 
#include "dict.hpp" 
#include "parse.tab.h" 

Dict dict; 

uint Dict::id (char* s) { 
    for(uint i = 0; i < tab.size(); i++) 
     if(tab[i].first == s) 
      return i; 
    tab.push_back(dpair(std::string(s), tab.size())); 
    return tab.size()-1; 
} 

void Dict::set (uint i, int v) { 
    tab[i].second = v; 
} 

void Dict::print() { 
    for(uint i = 0; i < tab.size(); i++) 
     printf("%20s = %d\n", tab[i].first.c_str(), tab[i].second); 
} 

int main() 
{ 
    yyparse(); 
    dict.print(); 
} 

OFFTOPIC:flex is not a GNU software

回答

5

你可以在你的main.cpp文件中添加

extern "C" int yyparse (void); 

(或許也是在parser.y),或在一些常見的#include -d頭文件。

而且你真的應該用g++ -Wall -g來編譯你的代碼。

+0

在main.cpp和parser.y中添加它使之有效,謝謝。但我仍然不明白爲什麼我需要聲明兩者都來自C代碼,因爲我正在編譯C++中的所有內容。有人能爲我澄清這件事嗎? – knarf

+0

除非在命令行上做了額外的事情,否則gcc會將'lex.yy.c'編譯爲C文件,因爲這就是它的擴展名。 'parse.tab.c'一樣。我的猜測是,如果你試圖以C++來做這些文件,那麼這些文件就不會編譯。 –

相關問題