2014-10-29 1 views
1

그래서 필자는 파일과 바이슨 파서를 사용하여 설정 파일을 읽는 거대한 프로그램을 만들고 있습니다.flex + bison 파서의 출력으로 어떻게 헤더를 얻습니까?

나는

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

그냥 "알 수없는 문자열"에 대한 오류를 추가하여 내 MAIN.CPP 프로그램

에 파서의 출력을 포함해야합니다. 다른 옵션도 잘 작동하지 않습니다. 왜 이것이 작동하지 않는가?

여기 ++ 프로젝트는 예 오히려 가난한 품질과있는 그대로, 주요 피타 내 렉서와 들소 파일 현대 C에서

%{ 
#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; 

%% 
+0

메인을 bison/flex의 일부로 구현했거나 이것과 별개입니까? – Tanuki

+0

별도. main에는 실제로 Opengl 코드가 포함되어 있습니다. –

+0

다음으로 바이슨/플렉스의 메인과 명백한 실수가 있습니다. 시간이 있다면 샘플 C++ 구현을 작성하려고합니다. 나는 당신이 main과 C++ 코드없이 다시 작성하도록 제안한다. – Tanuki

답변

2

적절한 플렉스/들소 설정의 생성 된 코드는 비와 같은 오래된 관행을 장려 - 유익한 코드와 전역 변수들. 그게 괜찮 았어 .80 년이 아니라 2014 년.

몇 주 전에 필자가 만든 예를 적용 해보십시오. 별도의 네임 스페이스에 별도의 클래스 (인터프리터라고 함)에 Flex lexer 및 Bison 파서를 캡슐화하므로 설정이 매우 간단합니다. 그것은 재진입 성 좋고 오래된 C++ 03과 호환됩니다.

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

유일한 까다로운 부분은 사용자의 요구에 맞게 클래스 이름을 리팩토링하는 것입니다. 일단 컴파일하면 * .y 및 * .l 파일 작업을 시작하여 Bison/Flex 설정의 특이성에 대항하지 않고 흥미로운 것을 구현할 수 있습니다. 즐겨!

0

내가 생각해 낸 해결책은 파일을 함께 컴파일하는 것이 었습니다. yyparse() 함수를 다른 cpp 파일의 extern 및 다른 변수로 선언하기 만하면됩니다. 아래에 메이크 파일을 첨부하겠습니다.

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