【问题标题】:Unsure about error Building Flex and Bison Compiler from Link不确定从 Link 构建 Flex 和 Bison 编译器的错误
【发布时间】:2019-03-12 07:44:35
【问题描述】:

我试图从http://gnuu.org/2009/09/18/writing-your-own-toy-compiler 编译 并且一直有一些问题。 https://github.com/lsegal/my_toy_compiler

使用自带的make文件时报错

C:\New Compile\my_toy_compiler-master\my_toy_compiler-master>make
bison -d -o parser.cpp parser.y
parser.y: warning: 48 shift/reduce conflicts [-Wconflicts-sr]
g++ -c `llvm-config --cppflags` -std=c++11 -o parser.o parser.cpp
g++ -c `llvm-config --cppflags` -std=c++11 -o codegen.o codegen.cpp
g++ -c `llvm-config --cppflags` -std=c++11 -o main.o main.cpp
flex -o tokens.cpp tokens.l parser.hpp
g++ -c `llvm-config --cppflags` -std=c++11 -o tokens.o tokens.cpp
tokens.cpp: In function 'void yy_init_buffer(YY_BUFFER_STATE, FILE*)':
tokens.cpp:1464:48: error: 'fileno' was not declared in this scope

                                                ^
tokens.cpp:1464:48: note: suggested alternative: 'file'

                                                ^
                                                file
make: *** [Makefile:27: tokens.o] Error 1

我查看了词法分析器生成的文件并复制了方法,

    static void yy_init_buffer  (YY_BUFFER_STATE  b, FILE * file )

{
    int oerrno = errno;

    yy_flush_buffer( b );

    b->yy_input_file = file;
    b->yy_fill_buffer = 1;

    /* If b is the current buffer, then yy_init_buffer was _probably_
     * called from yyrestart() or through yy_get_next_buffer.
     * In that case, we don't want to reset the lineno or column.
     */
    if (b != YY_CURRENT_BUFFER){
        b->yy_bs_lineno = 1;
        b->yy_bs_column = 0;
    }

        b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;

    errno = oerrno;
}

使用博客中给出的常规方式,我得到了大量的错误。

C:\New Compile\my_toy_compiler-master\my_toy_compiler-master>g++ -o parser parser.cpp tokens.cpp main.cpp
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV20NFunctionDeclaration[.refptr._ZTV20NFunctionDeclaration]+0x0): undefined reference to `vtable for NFunctionDeclaration'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV18NExternDeclaration[.refptr._ZTV18NExternDeclaration]+0x0): undefined reference to `vtable for NExternDeclaration'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV20NVariableDeclaration[.refptr._ZTV20NVariableDeclaration]+0x0): undefined reference to `vtable for NVariableDeclaration'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV16NReturnStatement[.refptr._ZTV16NReturnStatement]+0x0): undefined reference to `vtable for NReturnStatement'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV20NExpressionStatement[.refptr._ZTV20NExpressionStatement]+0x0): undefined reference to `vtable for NExpressionStatement'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV6NBlock[.refptr._ZTV6NBlock]+0x0): undefined reference to `vtable for NBlock'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV11NAssignment[.refptr._ZTV11NAssignment]+0x0): undefined reference to `vtable for NAssignment'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV15NBinaryOperator[.refptr._ZTV15NBinaryOperator]+0x0): undefined reference to `vtable for NBinaryOperator'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV11NMethodCall[.refptr._ZTV11NMethodCall]+0x0): undefined reference to `vtable for NMethodCall'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV11NIdentifier[.refptr._ZTV11NIdentifier]+0x0): undefined reference to `vtable for NIdentifier'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV7NDouble[.refptr._ZTV7NDouble]+0x0): undefined reference to `vtable for NDouble'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc6vUDwi.o:parser.cpp:(.rdata$.refptr._ZTV8NInteger[.refptr._ZTV8NInteger]+0x0): undefined reference to `vtable for NInteger'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x24): undefined reference to `LLVMLinkInMCJIT'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x24): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMLinkInMCJIT'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x9e): undefined reference to `createCoreFunctions(CodeGenContext&)'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x9e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `createCoreFunctions(CodeGenContext&)'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0xb4): undefined reference to `CodeGenContext::generateCode(NBlock&)'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0xb4): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `CodeGenContext::generateCode(NBlock&)'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0xc3): undefined reference to `CodeGenContext::runCode()'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0xc3): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `CodeGenContext::runCode()'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x16e): undefined reference to `llvm::LLVMContext::LLVMContext()'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text+0x16e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `llvm::LLVMContext::LLVMContext()'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x9): undefined reference to `LLVMInitializeX86TargetInfo'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMInitializeX86TargetInfo'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0xe): undefined reference to `LLVMInitializeX86Target'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0xe): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMInitializeX86Target'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x13): undefined reference to `LLVMInitializeX86TargetMC'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm22InitializeNativeTargetEv[_ZN4llvm22InitializeNativeTargetEv]+0x13): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMInitializeX86TargetMC'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm32InitializeNativeTargetAsmPrinterEv[_ZN4llvm32InitializeNativeTargetAsmPrinterEv]+0x9): undefined reference to `LLVMInitializeX86AsmPrinter'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm32InitializeNativeTargetAsmPrinterEv[_ZN4llvm32InitializeNativeTargetAsmPrinterEv]+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMInitializeX86AsmPrinter'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm31InitializeNativeTargetAsmParserEv[_ZN4llvm31InitializeNativeTargetAsmParserEv]+0x9): undefined reference to `LLVMInitializeX86AsmParser'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN4llvm31InitializeNativeTargetAsmParserEv[_ZN4llvm31InitializeNativeTargetAsmParserEv]+0x9): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `LLVMInitializeX86AsmParser'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN14CodeGenContextC1Ev[_ZN14CodeGenContextC1Ev]+0x73): undefined reference to `llvm::Module::Module(llvm::StringRef, llvm::LLVMContext&)'
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.text$_ZN14CodeGenContextC1Ev[_ZN14CodeGenContextC1Ev]+0x73): additional relocation overflows omitted from the output
/cygdrive/c/Users/Joey/AppData/Local/Temp/cc4uUJR7.o:main.cpp:(.rdata$.refptr._ZN4llvm11LLVMContextD1Ev[.refptr._ZN4llvm11LLVMContextD1Ev]+0x0): undefined reference to `llvm::LLVMContext::~LLVMContext()'
collect2: error: ld returned 1 exit status

C:\New Compile\my_toy_compiler-master\my_toy_compiler-master>g++ -o parser `llvm-config --libs core jit native --cxxflags --ldflags` *.cpp
g++: error: `llvm-config: No such file or directory
g++: error: core: No such file or directory
g++: error: jit: No such file or directory
g++: error: native: No such file or directory
g++: error: unrecognized command line option '--libs'
g++: error: unrecognized command line option '--cxxflags'
g++: error: unrecognized command line option '--ldflags`'

C:\New Compile\my_toy_compiler-master\my_toy_compiler-master>

我不确定下一步该采取什么步骤,因为我正在使用 Cygwin 和不同的软件包。起初我以为可能是 Github 声明的版本,它只支持 llvm 到 4.0,所以我回溯并安装了 4.0,但仍然遇到同样的问题。

【问题讨论】:

  • 看来您使用的是 Windows,并且该教程以 linux 或其他 unix 为前提。最好学习一下cygwin和linux之间的区别,或者切换到linux。本教程停留在 LLVM4 并不是什么大问题,自那以后 LLVM 发生了变化,但大事保持不变。

标签: compiler-construction llvm bison flex-lexer


【解决方案1】:

Flex 可以生成三种词法分析器:

  • 交互式

  • 非交互式(“批处理”)

  • 有时是交互式的(默认)。

非交互式词法分析器是最有效的;他们一次读取输入缓冲区。这对于解析文件非常有用,但对于解析控制台输入却很烦人,尤其是当意图响应输入的每一行时。交互式词法分析器通过一次读取一个字符来避免这个问题,以便尽快报告一个标记。但这对于大型令牌的输入可能效率低下。

默认词法分析器测试其输入是否为控制台,并使用该信息在交互式和非交互式缓冲区处理之间进行选择。这种策略的唯一问题是标准 C 库没有提供任何方法来判断输入流是否是控制台。 Unix(类)系统确实有一个函数可以回答这个问题,但它不适用于标准 C FILE* 流;它需要底层的“文件号”。 fileno 函数从 FILE* 中提取底层文件号,但它显然不是标准的 C 函数。

所以如果你有一个默认的词法分析器,它需要调用fileno。但是,fileno 不会在任何标准标头中声明,除非您使用 #define 功能测试宏。但是你必须在 C 程序的开头定义这些宏,这在 C 程序自动生成时很难做到。最简单的解决方案是使用-D 选项在编译器命令行中添加宏定义:

g++ -c `llvm-config --cppflags` -D_POSIX_C_SOURCE -std=c++11 -o tokens.o tokens.cpp

这只是您可以使用的宏之一;我在这里选择它是因为它是man fileno 中的那个,但我通常使用-D_XOPEN_SOURCE=700,它请求更新Posix 版本的接口。另一种可能性是_GNU_SOURCE,它可以让 Gnu 标头很好地包含所有内容,包括 Gnu 特定的扩展函数。

在我的 (linux) 系统上,llvm-config --cppflags 包括 -D_GNU_SOURCE,但这并不重要,因为当前版本的 g++ 和 clang++ 都会自动为 C++ 目标定义 _GNU_SOURCE。显然,Cygwin 并非如此。参见,例如:

两者都建议将-std=c++11 更改为-std=gnu++11

另一种方法是通过请求非交互式词法分析器来回避问题,或者使用 flex 命令行选项:

flex --batch -o tokens.cpp tokens.l parser.hpp

或者通过添加

%option batch

到你的 flex 输入文件。见the flex manual

(显然,如果您正在编写交互式计算器,请不要请求批处理词法分析器。在这种情况下,您可能希望请求始终交互式词法分析器。)

【讨论】:

  • 正是我想要的,谢谢!我不确定如何使用 makefile,所以我采用了简单的方法,将文件中的 -std=c++11 更改为 -std=gnu+11 ,它立即工作,我现在可以使用编译器了!
  • 出于某种原因,如果没有 g++ 命令中的 make 文件,我就无法使用 llvm-config。奇怪
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-21
  • 1970-01-01
  • 1970-01-01
  • 2020-09-03
  • 1970-01-01
相关资源
最近更新 更多