2011-04-28 4 views
10

저는 flex와 bison의 아주 짧은 예제를 찾고 있는데, 내장 된 규칙을 사용하는 Makefile이 있습니다. 난 지저분한, 빌드되지 않았거나 C++에서 허용되지 않는 몇 가지 Google 결과를 시도했습니다. 좋은 온라인 리소스와 짧은 샘플 코드는 높이 평가됩니다.플렉스, 들소, C : 아주 기본적인 소개를 찾고 있습니다.

 # Makefile example -- scanner and parser. 
    # Creates "myprogram" from "scan.l", "parse.y", and "myprogram.c" 
    # 
    LEX  = flex 
    YACC = bison -y 
    YFLAGS = -d 
    objects = scan.o parse.o myprogram.o 

    myprogram: $(objects) 
    scan.o: scan.l parse.c 
    parse.o: parse.y 
    myprogram.o: myprogram.c 

I 임의로 간단한 무언가를 첨부 소스 파일로 대략 다음과 같습니다 Makefile을 원하는 추가


.

답변

19

flex 프로젝트 자체에는 make 파일과 bison 파일을 비롯한 적절한 예제가 포함되어 있습니다.

http://oreilly.com/catalog/9781565920002

마지막으로

, 빠른 뇌관을 위해 여기 : 주제에 대한 훌륭한 소개를 들어 https://github.com/westes/flex/releases

, 나는 렉스와 Yacc에 제 2 판을 제안 :

http://ds9a.nl/lex-yacc/cvs/lex-yacc-howto.html

편집 :

바트가 언급 한 바와 같이, 다른 소스는 다음과 같습니다 http://oreilly.com/catalog/9780596155988/

그리고 다음 내가 플렉스 프로젝트를 시작하는 데 사용하는 골격 파일입니다. 커맨드 라인 옵션을 파싱하고 파일 이름을 얻기 위해 gnu getopts를 사용합니다. 나는 이식성이나 사용 편의성에 대한 어떠한 주장도하지 않습니다! :) 사람들이 이것을 계속 확인 이후

/* 
* This file is part of flex. 
* 
* Redistribution and use in source and binary forms, with or without 
* modification, are permitted provided that the following conditions 
* are met: 
* 
* 1. Redistributions of source code must retain the above copyright 
* notice, this list of conditions and the following disclaimer. 
* 2. Redistributions in binary form must reproduce the above copyright 
* notice, this list of conditions and the following disclaimer in the 
* documentation and/or other materials provided with the distribution. 
* 
* Neither the name of the University nor the names of its contributors 
* may be used to endorse or promote products derived from this software 
* without specific prior written permission. 
* 
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
* PURPOSE. 
*/ 

    /************************************************** 
     start of definitions section 

    ***************************************************/ 

%{ 
/* A template scanner file to build "scanner.c". */ 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <getopt.h> 
/*#include "parser.h" */ 

//put your variables here 
char FileName[256]; 
FILE *outfile; 
char **myOut; 
char inputName[256]; 




// flags for command line options 
static int specificFile_flag = 0; 
static int output_flag = 0; 
static int help_flag = 0; 

%} 


%option 8bit outfile="scanner.c" 
%option nounput nomain noyywrap 
%option warn 

%x header 
%x fileType 
%x final 

%% 
    /************************************************ 
     start of rules section 

    *************************************************/ 


    /* these flex patterns will eat all input */ 
. { } 
\n { } 


%% 
    /**************************************************** 
     start of code section 


    *****************************************************/ 

int main(int argc, char **argv); 

int main (argc,argv) 
int argc; 
char **argv; 
{ 
    /**************************************************** 
     The main method drives the program. It gets the filename from the 
     command line, and opens the initial files to write to. Then it calls the lexer. 
     After the lexer returns, the main method finishes out the report file, 
     closes all of the open files, and prints out to the command line to let the 
     user know it is finished. 
    ****************************************************/ 

    int c; 

    // the gnu getopt library is used to parse the command line for flags 
    // afterwards, the final option is assumed to be the input file 

    while (1) { 
     static struct option long_options[] = { 
      /* These options set a flag. */ 
      {"specific-file", no_argument,  &specificFile_flag, 1}, 
      {"help", no_argument,  &help_flag, 1}, 
      /* These options don't set a flag. We distinguish them by their indices. */ 

      {"debug", no_argument,  0, 'd'}, 
      {"specificFile", no_argument,  0, 's'}, 
      {"useStdOut", no_argument,  0, 'o'}, 
      {0, 0, 0, 0} 
     }; 
      /* getopt_long stores the option index here. */ 
     int option_index = 0; 
     c = getopt_long (argc, argv, "dso", 
      long_options, &option_index); 

     /* Detect the end of the options. */ 
     if (c == -1) 
      break; 

     switch (c) { 
      case 0: 
       /* If this option set a flag, do nothing else now. */ 
       if (long_options[option_index].flag != 0) 
       break; 
       printf ("option %s", long_options[option_index].name); 
       if (optarg) 
       printf (" with arg %s", optarg); 
       printf ("\n"); 
       break; 

      case 'd': 
       break; 

      case 's': 
       specificFile_flag = 1; 
       break; 

      case 'o': 
       output_flag = 1; 
       break; 


      case '?': 
       /* getopt_long already printed an error message. */ 
       break; 

      default: 
       abort(); 
      } 
    } 

    if (help_flag == 1) { 
     printf("proper syntax is: addressGrabber.exe [OPTIONS]... INFILE OUTFILE\n"); 
     printf("grabs address from prn files\n\n"); 
     printf("Option list: \n"); 
     printf("-s --specific-file changes INFILE from a prn list to a specific prn\n"); 
     printf("-d    turns on debug information\n"); 
     printf("-o      sets output to stdout\n"); 
     printf("--help     print help to screen\n"); 
     printf("\n"); 
     printf("list example: addressGrabber.exe list.csv\n"); 
     printf("prn example: addressGrabber.exe -s 01110500.prn\n\n"); 
     printf("If infile is left out, then stdin is used for input.\n"); 
     printf("If outfile is a filename, then that file is used.\n"); 
     printf("If there is no outfile, then infile-EDIT.tab is used.\n"); 
     printf("There cannot be an outfile without an infile.\n"); 
     return 0; 
    } 

    //get the filename off the command line and redirect it to input 
    //if there is no filename or it is a - then use stdin 


    if (optind < argc) { 
     FILE *file; 

     file = fopen(argv[optind], "rb"); 
     if (!file) { 
      fprintf(stderr, "Flex could not open %s\n",argv[optind]); 
      exit(1); 
     } 
     yyin = file; 
     strcpy(inputName, argv[optind]); 
    } 
    else { 
     printf("no input file set, using stdin. Press ctrl-c to quit"); 
     yyin = stdin; 
     strcpy(inputName, "\b\b\b\b\bagainst stdin"); 
    } 

    //increment current place in argument list 
    optind++; 


    /******************************************** 
     if no input name, then output set to stdout 
     if no output name then copy input name and add -EDIT.csv 
     if input name is '-' then output set to stdout 
     otherwise use output name 

    *********************************************/ 
    if (optind > argc) { 
     yyout = stdout; 
    } 
    else if (output_flag == 1) { 
     yyout = stdout; 
    } 
    else if (optind < argc){ 
     outfile = fopen(argv[optind], "wb"); 
     if (!outfile) { 
       fprintf(stderr, "Flex could not open %s\n",FileName); 
       exit(1); 
      } 
     yyout = outfile; 
    } 
    else { 
     strncpy(FileName, argv[optind-1], strlen(argv[optind-1])-4); 
     FileName[strlen(argv[optind-1])-4] = '\0'; 
     strcat(FileName, "-EDIT.tab"); 
     outfile = fopen(FileName, "wb"); 
     if (!outfile) { 
       fprintf(stderr, "Flex could not open %s\n",FileName); 
       exit(1); 
      } 
     yyout = outfile; 
    } 


    yylex(); 
    if (output_flag == 0) { 
     fclose(yyout); 
    } 
    printf("Flex program finished running file %s\n", inputName); 
    return 0; 
} 

마지막으로, 나는 또한 GitHub의에 메이크와 함께 example lexer and parser 있습니다.

+0

우수한 자료. 아마도 http://oreilly.com/catalog/9780596155988/을 포함할까요? –

+0

@Bart Kiers 내 뼈대 플렉스 파일의 링크와 소스를 추가했습니다. –

+0

위대한, 불행히도 한 번만 투표 할 수 있습니다. –

2

위키 피 디아 bison page을 보면 시작할 수 있습니다. 바이슨으로 작성된 재진입 구문 분석기의 전체 샘플 코드가 있습니다. 그것은 lexer로 flex를 사용하고 또한 그것을 사용하는 방법에 대한 샘플 코드를 가지고 있습니다.

당신이 어떤 수정 사항이 있으면 내가

LATER 사전 :)에 감사 : 위키 피 디아의 코드가 리눅스 (GCC)에서 테스트되었으며 창 (비주얼 스튜디오) 및 다른 컴파일러와 함께 작동합니다.

+0

이것은 Makefile이 없어도 괜찮은 예입니다. 본질적으로 Hello World 유형 예제를 찾고 있습니다. 필자는 다른 것들을 만들기에 익숙하지만 flex/bison을위한 간결한 Makefile을 작성하는 데 성공하지 못했습니다. – colechristensen

+0

미안 wiki 페이지에서 제공하지는 않았지만 파일의 첫 번째 부분에서 볼 수 있듯이 c 컴파일러로 컴파일 할 때 필요한 파일을 얻는 데 사용되는 명령이 있습니다. flex 파일과 bison 파일에 대해이 명령을 실행하기 만하면됩니다. – INS

+0

flex 파일의 C 파일 용 makefile을 작성하는 방법을 알고 있다면 다음과 같은 경우가 있습니다 (이 경우) : 파서 이 .c : Parser.y 들소 --defines = Parser.h Parser.y Lexer.c : Lexer.l 플렉스 --outfile = Lexer.c --header 파일 = Lexer.h Lexer.l – INS

0

Bison documentation은 계산기의 좋은 예와 함께 완벽합니다. 들소에서 시작하는 데 사용했습니다. 그리고 C++ 예제는 플렉스 스캐너를 사용합니다. C로 작성하는 것이 쉽습니다.

-1

Compilers: Principles, Techniques, and Tools, Alfred V. Aho, Ravi Sethi, Jeffrey D.Ullman

+0

두 번째 버전에는 yacc/lex 툴체인에 관한 15 페이지가 있습니다 (빠른보기). 책에 대한 링크 만 대답하기 때문에 질문과 어떻게 관련이 있습니까? –

관련 문제