C语言 Flex、Bison 和 C:寻找非常基本的介绍
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5823838/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Flex, Bison, and C: Looking for a very basic introduction
提问by colechristensen
I am looking for a very short working example of flex and bison with an accompanying Makefile which makes use of the builtin rules. I've tried several google results that were messy, wouldn't build, or were in C++ which isn't acceptable. Good online resources and short sample code is appreciated.
我正在寻找一个非常简短的 flex 和 bison 工作示例,并带有使用内置规则的随附 Makefile。我已经尝试了几个 google 结果,这些结果很混乱,无法构建,或者在 C++ 中是不可接受的。良好的在线资源和简短的示例代码表示赞赏。
ADDITIONAL
额外的
# 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 would like a Makefile which looks approximately like this with attached source files which do something arbitrarily simple.
我想要一个 Makefile,它看起来像这样,附带的源文件可以做一些任意简单的事情。
回答by Spencer Rathbun
The flex project itself comes with a decent set of examples, including make files and bison files.
flex 项目本身带有一组不错的示例,包括 make 文件和 bison 文件。
For an excellent intro to the topic, I suggest lex and yacc 2nd edition:
对于该主题的出色介绍,我建议使用 lex 和 yacc 2nd edition:
Finally, go here for a quick primer:
最后,去这里快速入门:
Edit:
编辑:
As Bart mentioned, another source is: http://oreilly.com/catalog/9780596155988/
正如巴特提到的,另一个来源是:http: //oreilly.com/catalog/9780596155988/
And the following is the skeleton file I use to start a flex project. It uses gnu getopts for parsing command line options and getting the file name. I make no claims as to portability or ease of use! :)
以下是我用来启动 flex 项目的骨架文件。它使用 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] = '##代码##';
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;
}
Finally, since people keep checking this out, I also have an example lexer and parserwith makefile on github.
最后,由于人们不断检查这一点,我在 github 上还有一个带有 makefile的示例词法分析器和解析器。
回答by INS
You could start by looking at the wikipedia bison page. It has a full sample code of reentrant parser written with bison. It uses flex as the lexer and it also has a sample code on how to use it.
您可以从查看维基百科野牛页面开始。它有一个用 bison 编写的可重入解析器的完整示例代码。它使用 flex 作为词法分析器,并且还有一个关于如何使用它的示例代码。
If you have any corrections I thank you in advance :)
如果您有任何更正,我提前感谢您:)
LATER:The code on wikipedia was tested on linux (gcc) and windows (visual studio) and should work with other compilers also.
后来:维基百科上的代码在 linux (gcc) 和 windows (visual studio) 上测试过,也应该与其他编译器一起工作。
回答by Julio Guerra
The Bison documentationis perfect with a very good example of a calculator. I used it to start with bison. And the C++ example uses a flex scanner. It would be easy to make it in C.
Bison文档是完美的计算器示例。我用它从野牛开始。C++ 示例使用了 flex 扫描器。在 C 中实现它会很容易。
回答by Victor Sorokin
What about GNU Manual?
GNU 手册怎么样?
回答by francesco
Compilers: Principles, Techniques, and Tools, Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman
编译器:原则、技术和工具,Alfred V. Aho、Ravi Sethi、Jeffrey D. Ullman

