你如何得到一个标题作为flex + bison解析器的输出?

时间:2014-10-29 14:06:23

标签: c++ bison flex-lexer

所以,我正在制作一个使用f lex和bison解析器读取配置文件的巨型程序。

我需要在main.cpp程序中包含解析器的输出

使用

%output "config.cc"
%defines "config.h"

只是为"未识别的字符串"添加错误。其他选择没有'工作也很好。知道为什么这不起作用吗?

这是我的词法分析器和野牛文件

%{
#include <stdio.h>
#include <string>
#include <map>
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include "Monopoly.h"
using namespace std;
extern int yylex();
extern void yyerror(char*);
Monopoly game;
void yyerror(const char *str)
{
        fprintf(stderr,"error: %s\n",str);
}


%}

%token LTOKEN INTEGER LOCATIONWORD WORD GTOKEN CURRENCYTOKEN JAILFINETOKEN STARTINGMONEYTOKEN RTOKEN COSTTOKEN RENTTOKEN FILEPATHTOKEN OBJEXTENSION MODELTOKEN TAXTOKEN PERCENTSIGN


%union{
  std::string *str;
  int number;
}
%token <number> INTEGER
%token <str> WORD


%%
commands: /* empty */
        | command commands
        ;

command:
        currency_set
        |
        location_set
        |
        startingMoney_set
        |
        jailFine_set
        |
        route_add
        |
        cost_set
        |
        rent_set
        |
        filepath_found
        |
        tax_set
        ;
filepath_found:MODELTOKEN LTOKEN INTEGER FILEPATHTOKEN WORD OBJEXTENSION
        {
            printf(" File %s HAS BEEN IMPORTED for location number %d \n",$5,$3 );
        }

rent_set:RENTTOKEN LTOKEN INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER   
        {
            printf("rent for house no 4 is %d \n",$7);
        } 
cost_set:COSTTOKEN LTOKEN INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER INTEGER
        {
            printf("prices set to %d\n",$10 );
        }
currency_set:CURRENCYTOKEN WORD
            {

                game.currency=($2);
                printf("Currency set to %s",game.currency->c_str());
            }

location_set:
            LOCATIONWORD LTOKEN INTEGER WORD GTOKEN INTEGER
            {
            printf("location number %d  set to  %s in froup number %d",$3,$4,$6);
            }
startingMoney_set:
            STARTINGMONEYTOKEN INTEGER
            {
            printf("starting money set to %d \n",$2 );
            }
jailFine_set:
            JAILFINETOKEN INTEGER
            {
                printf("jailfine set to %d\n",$2);
            }

route_add:
            RTOKEN LTOKEN INTEGER LTOKEN INTEGER
            {
                printf("Route set up between location no %d and %d\n",$3,$5);
            }

tax_set:
        TAXTOKEN INTEGER PERCENTSIGN INTEGER
        {
            printf("tax set to %d percent\n",$2 );
        }


%%


int yywrap()
{
        return 1;
} 
extern FILE * yyin;

int main()
{
    yyin=fopen("config.txt","r");
    yyparse();


    string json="{ \"hello\" : \"world\"} ";
    rapidjson::Document d;
    d.Parse<0>(json.c_str());

    printf("%s\n", d["hello"].GetString());
    return 1;
} 


%{
#include <stdio.h>
#include <string>
#include "bisoner.tab.h"
using namespace std;
%}
%%
"Tax"                       return TAXTOKEN;
"rent"                      return RENTTOKEN;
"cost"                      return COSTTOKEN;
"route"                     return RTOKEN;
"Currency"                  return CURRENCYTOKEN;
"StartingMoney"             return STARTINGMONEYTOKEN;
"JailFine"                  return JAILFINETOKEN;
"location"                  return LOCATIONWORD;
"@l"                        return LTOKEN;
"@g"                        return GTOKEN;
"model"                     return MODELTOKEN;
"#"[a-zA-Z0-9.-_= ]+            printf("comment ignored\n");
[0-9]+                      yylval.number=atoi(yytext);return INTEGER;
[a-zA-Z]+                   yylval.str=new string(yytext);return WORD;
"./"([[a-zA-Z0-9]+"/"]*)?               return FILEPATHTOKEN;
".obj"                      return OBJEXTENSION;
"%"                         return PERCENTSIGN;

%%

2 个答案:

答案 0 :(得分:2)

现代C ++项目中适当的flex / bison设置是一个主要的PITA,因为示例质量相当差,生成的代码鼓励过时的实践,例如非重入代码和全局变量。这在#80;而不是2014年是可以的。

尝试调整我几周前制作的例子。该设置非常简单,因为它将Flex lexer和Bison解析器封装在单独的命名空间中的一个单独的类(称为Interpreter)中。它是可重入的,并与良好的旧C ++ 03兼容。

https://github.com/ezaquarii/bison-flex-cpp-example

唯一棘手的部分是重构类名以满足您的需求。一旦你编译它,你就可以开始使用* .y和* .l文件来实现你有趣的东西,而无需对抗Bison / Flex设置特性。享受!

答案 1 :(得分:0)

我想出的解决方案是将文件一起编译。只需将yyparse()函数声明为其他cpp文件中的extern,以及任何其他变量。我将附上我的makefile

CFLAGS=-ll
CC=g++
all:example2
example2: main.cpp lex.yy.c bisoner.tab.c
    $(CC) main.cpp lex.yy.c bisoner.tab.c Player.cpp Location.cpp Monopoly.cpp -o example2 -ll
bisoner.tab.c:bisoner.y
    bison -d bisoner.y
lex.yy.c:lexer.l 
    lex lexer.l

clean:
    rm -rf *o example2