2011-04-28 20 views
10

Estoy buscando un ejemplo de trabajo muy breve de flex y bisonte con un archivo Makefile que hace uso de las reglas integradas. Probé varios resultados de Google que fueron desordenados, no se compilaron o que estaban en C++, lo que no es aceptable. Se agradecen los buenos recursos en línea y el código de muestra corto.Flex, Bison y C: buscando una introducción muy básica


ADICIONAL

 # 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 

me gustaría un Makefile que se parece aproximadamente como esto con los archivos de origen asociados que hacen algo arbitrariamente sencilla.

Respuesta

19

El proyecto flex en sí viene con un conjunto decente de ejemplos, incluyendo make files y bison files.

https://github.com/westes/flex/releases

Para una excelente introducción al tema, sugiero lex y yacc 2ª edición:

http://oreilly.com/catalog/9781565920002

Por último, vaya aquí para una cartilla rápida :

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

Editar:

Como se mencionó Bart, otra fuente es: http://oreilly.com/catalog/9780596155988/

Y el siguiente es el archivo de esqueleto que utilizo para iniciar un proyecto Flex. Utiliza gnu getopts para analizar opciones de línea de comando y obtener el nombre del archivo. No reclamo portabilidad o facilidad de uso. :)

/* 
* 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; 
} 

Por último, ya que las personas mantienen la comprobación de esto, también tengo una example lexer and parser con makefile en github.

+0

Excelentes recursos. Tal vez incluya http://oreilly.com/catalog/9780596155988/? –

+0

@Bart Kiers He agregado su enlace y la fuente de mi archivo esqueleto flexible. –

+0

Genial, desafortunadamente solo puedo votar una vez :) –

2

Puedes comenzar por mirar la wikipedia bison page. Tiene un código de muestra completo de analizador reentrante escrito con bisonte. Utiliza flex como lexer y también tiene un código de muestra sobre cómo usarlo.

Si usted tiene ciertas correcciones que gracias de antemano :)

TARDE: El código en la wikipedia fue probado en Linux (GCC) y Windows (Visual Studio) y debe trabajar con otros compiladores también.

+0

Este es un buen ejemplo, aunque le falta un Makefile. Estoy buscando, esencialmente, un ejemplo de Hello World. Soy familliar con make para otras cosas, pero no he tenido éxito escribiendo un Makefile conciso para flex/bison. – colechristensen

+0

lo siento, no lo proporcioné en la página wiki, pero como puede ver en la primera parte del archivo, tiene los comandos utilizados para obtener los archivos necesarios para hacer una compilación con el compilador c. Todo lo que necesita hacer es ejecutar esos comandos en el archivo flexible y en el archivo bison – INS

+0

Si sabe cómo escribir un archivo MAK para un archivo C para un archivo flexible, tiene lo siguiente (en este caso particular): Analizador .c: Parser.y --defines bisontes = parser.h Parser.y Lexer.c: Lexer.l flex --outfile = Lexer.c --header-file = Lexer.h Lexer.l – INS

0

El Bison documentation es perfecto con un muy buen ejemplo de una calculadora. Lo usé para comenzar con bisonte. Y el ejemplo de C++ usa un escáner flexible. Sería fácil hacerlo en C.

-1

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

+0

La segunda edición tiene 15 páginas relacionadas con la cadena de herramientas yacc/lex (en un vistazo rápido). Responde solo los enlaces al libro, entonces, ¿cómo es relevante para la pregunta? –

Cuestiones relacionadas