从串矢量输入野牛

时间:2015-03-20 15:02:37

标签: c++ compiler-construction bison

我有要在野牛解析的字符串向量。我应该远程接收这个,我不想写入文件并回读。我的字符串向量可能非常大。

这是我到目前为止所尝试的内容

  1. 将所有字符串添加到一个字符串并使用yy_scan_string

  2. 我也尝试将所有字符串添加到缓冲区和yy_scan_string。

  3. 我尝试按如下方式构建可执行文件:

    bison -d logic.y
    flex logic.l
    g++ logic.tab.c lex.yy.c -lfl -o logic
    

    但我收到错误:

    undefined reference to `yy_scan_string'.
    

    这是我的解析器:

    %{
    
    #include <cstdio>
    #include <iostream>
    #include <string.h>
    #include <vector>
    #include <algorithm>
    #include <Server.h>
    using namespace std;
    
    //stuff from flex that bison needs to know about:
    extern "C" int yylex();
    typedef struct yy_buffer_state * YY_BUFFER_STATE;
    extern "C" int yyparse();
    extern "C" YY_BUFFER_STATE yy_scan_string(const char * str);
    //extern "C" void yy_delete_buffer(YY_BUFFER_STATE buffer);
    extern int line_num;
    
    vector<string> statements;
    
    void yyerror(const char *s);
    
    %}
    
    //C union holding each of the types of tokens that Flex could return
    %union { 
        char const *sval;
    }
    
    //symbol defination
    
    //end of declaration section
    %%        
    //Start of grammar section
    
    //grammar
    
    //end of grammar section
    %%
    
    int main(int argc, char *argv[]) {
        try
        {
            logicMessage = server.getLogic();
    
            statements = logicMessage->get_LogicStatements ();       
    
            string  single = "";
    
            for (vector<string>::iterator it=statements.begin(); it!=statements.end(); ++it)
                single += *it; 
    
            char* buffer = new char[single.length()+1];
            strcpy(buffer,single.c_str());
    
            yy_scan_string(single.c_str());
            yyparse();
    
            //yy_delete_buffer(buffer);
            return 0;
        }
        catch(IPC_RETURN_CODE IPC_CODE)
        {
            std::cerr<< "IPC Error Code:" <<IPC_CODE;
        }
    }
    
    void yyerror(const char *s) {
        cout << "Parse error on line " << line_num << "!  Message: " << s << endl;
        // might as well halt now:
        exit(-1);
    }
    

2 个答案:

答案 0 :(得分:1)

您真的不需要那些extern "C"声明,并且它们会使您的构建过程变得复杂。

两个(现代)bisonflex都生成可以编译为C或C ++的代码,但如果以相同的方式编译它们,您会发现它更简单。在这种情况下,您将不需要使用extern声明,因为所有外部函数都将针对您正在使用的语言进行正确编译。

请注意,使用g++进行编译时,扩展名为.c的文件将编译为C ++程序。因此,lex.yy.c被编译为C ++程序,外部函数(包括yylexyy_scan_string)具有正常的C ++链接(和名称修改),并将它们声明为{{1}在不同的翻译单元中会产生链接错误。

尽管如此,我通常使用external "C"选项-oflex来创建具有适当扩展名的文件名。使用bison的{​​{1}}选项生成包含导出函数声明的头文件也很有用,例如--header-file

答案 1 :(得分:-1)

我已经读过你需要放置&#34;&#34;%选项可重入&#34;在词法分析器文件中#39;查看here以获取更多信息。好像你需要创建一个yyscan_t类型的对象来传入。