Не уверены в ошибке сборки Flex и Bison Compiler из Link - PullRequest
0 голосов
/ 12 марта 2019

Я пытался компилятор из 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, но все равно столкнулся с той же проблемой.

1 Ответ

2 голосов
/ 12 марта 2019

Flex может генерировать три вида лексеров:

  • Interactive

  • Неинтерактивный («пакетный»)

  • Иногда интерактивно (по умолчанию).

Неинтерактивные лексеры являются наиболее эффективными; они читают входной буфер одновременно. Это отлично подходит для разбора файлов, но это раздражает для разбора ввода с консоли, особенно когда нужно ответить на каждую напечатанную строку. Интерактивные лексеры избегают этой проблемы, читая ввод по одному символу за раз, так что токен сообщается как можно скорее. Но это может быть неэффективно для ввода с большими токенами.

Лексер по умолчанию проверяет, является ли его ввод консольным, и использует эту информацию для выбора между интерактивной и неинтерактивной обработкой буфера. Единственная проблема этой стратегии состоит в том, что стандартная библиотека 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 ++ автоматически определяют _GNU_SOURCE для целей C ++. Видимо, это не так с Cygwin. Смотрите, например:

оба варианта предлагают изменить -std=c++11 на -std=gnu++11.

В качестве альтернативы можно обойти проблему, запросив неинтерактивный лексер, либо с помощью параметра командной строки flex:

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

Или добавив

%option batch

в ваш гибкий файл ввода. См. Руководство по Flex

(Очевидно, не запрашивайте пакетный лексер, если вы пишете интерактивный калькулятор. В этом случае вы, вероятно, захотите запросить всегда интерактивный лексер.)

...