Как использовать C++ во flex и bison?

У меня есть проект для школы, где нам нужно использовать flex и bison. Я хочу использовать C++, чтобы иметь доступ к STL и своим собственным классам, которые я написал. Нам был предоставлен следующий Makefile:

CC = gcc 
CFLAGS = -g 

OBJs = parse.tab.o symtab.o attr.o lex.yy.o 

default: parser

parser: ${OBJs}
    ${CC} ${CFLAGS} ${OBJs} -o parser -lfl

lex.yy.c: scan.l parse.tab.h attr.h
    flex -i scan.l

parse.tab.c: parse.y attr.h symtab.h
    bison -dv parse.y

parse.tab.h: parse.tab.c

clean:
    rm -f parser lex.yy.c *.o parse.tab.[ch] parse.output

depend:
    makedepend -I. *.c

В scan.l и parse.y есть начальный материал flex/bison для генерации сканера и синтаксического анализатора. Мне нужно добавить свои собственные вещи в эти файлы. symtab.{h, c} должен быть реализацией таблицы символов. attr.{h, c} предназначены для некоторой магии атрибутов. Я хочу сделать symtab.c файлом .cc, чтобы я мог использовать STL. У меня также есть другие причины использовать C++.

Я попытался использовать файл parse.ypp, чтобы был создан файл .cpp. Но проблема в том, что я не получаю нужный файл .h. Я изменил Makefile, чтобы он выглядел так:

CC = g++          # Change gcc to g++
CFLAGS = -g 

OBJs = lex.yy.o parse.tab.o symtab.o attr.o

default: lex.yy.c parser    # added lex.yy.c so I could just keep lex stuff in C since I don't really need C++ there

parser: ${OBJs}
    ${CC} ${CFLAGS} ${OBJs} -o parser -lfl

lex.yy.o: scan.l parse.tab.h attr.h      # added this rule to use gcc instead of g++
    gcc -c -o lex.yy.o lex.yy.c

lex.yy.c: scan.l parse.tab.h attr.h
    flex -i scan.l

parse.tab.cpp: parse.ypp attr.h symtab.h
    bison -dv parse.ypp

parse.tab.h: parse.tab.cpp      # I want a parse.tab.h but I get parse.tab.hpp

clean:
    rm -f parser lex.yy.c *.o parse.tab.cpp parse.tab.h parse.output

depend:
    makedepend -I. *.c

Может ли кто-нибудь сказать мне, что мне нужно добавить или сделать, чтобы C++ работал? Следует отметить, что я добавил кое-что в файл .y (или .ypp), чтобы справиться с переходом с C на C++. В частности, мне пришлось объявить некоторые вещи как внешние. Моя основная проблема заключается в том, что когда я запускаю make, в файле scan.l появляется куча синтаксических ошибок, и они, похоже, связаны с тем, что он не может включать parse.tab.h (поскольку он никогда не генерируется).


person Tom    schedule 22.04.2009    source источник
comment
Для справки, flex имеет флаги командной строки --+ или --c++ для создания лексера C++ вместо C. Подумайте об этом, хотя я не думаю, что это ваша проблема в данном случае.   -  person Chris Lutz    schedule 22.04.2009


Ответы (5)


Вам не нужно ничего делать с flex или bison, чтобы использовать C++, я делал это много раз. Вам просто нужно убедиться, что вы используете g++, а не gcc.

Ваши проблемы с Makefile, а не с кодом.

person Zifre    schedule 22.04.2009
comment
Принять это довольно поздно :-)... но, насколько я помню, это было правильно, и мне просто нужно было поиграть с моим make-файлом. Благодарю. - person Tom; 26.12.2009

Есть некоторые отличия, с которыми вы можете подробно ознакомиться здесь.

person justinhj    schedule 23.04.2009

Используйте либо компилятор C, либо компилятор C++, но не оба (пока вы не знаете, что делаете). В противном случае вы наверняка прострелите себе много раз обе ноги. Смешивать gcc и g++ нехорошо.

Эта строка подозрительна:

lex.yy.o: scan.l parse.tab.h attr.h      # added this ...
gcc -c -o lex.yy.o lex.yy.c

Кроме того, вы, кажется, нигде не используете CC, это сделало бы жизнь проще.

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

person dirkgently    schedule 22.04.2009

Если вы делаете парсеры на C++, я бы порекомендовал взглянуть на Boost Spirit. С ним гораздо приятнее обращаться, чем с bison/yacc.

Из здесь:

Spirit — это объектно-ориентированный генератор парсеров с рекурсивным спуском, реализованный с использованием методов метапрограммирования шаблонов. Шаблоны выражений позволяют нам полностью аппроксимировать синтаксис расширенной нормальной формы Бэкуса (EBNF) в C++.

person lothar    schedule 22.04.2009
comment
Я не согласен. Я пробовал оба, и мне больше нравится bison (хотя я предпочитаю ANTLR обоим). Странный синтаксис, необходимый для встраивания EBNF в C++, очень затрудняет чтение грамматики. - person Zifre; 22.04.2009
comment
В данном случае это не вариант, так как он должен использовать bison/flex для своего проекта. Кроме того, не все в C++ нужно делать с помощью Boost. - person Scottie T; 23.04.2009
comment
Spirit — одна из худших и чрезмерно сложных библиотек C++. Во всяком случае, это не более чем причудливая попытка увидеть, какие операторы можно перегрузить в C++. - person Hippicoder; 01.07.2010
comment
Более того, Дух ужасно нестабилен. Даже самые тривиальные примеры не могут быть скомпилированы из одной версии в другую, часто просто с необъяснимой ошибкой компилятора. - person Kasper Peeters; 02.08.2010
comment
Другим комментаторам не нравится Spirit. На самом деле, мне очень нравится Spirit. Он вполне разумно использует перегрузку операторов и работает так, как рекламируется. Это очень удобно для замены специального синтаксического анализа небольших вещей, таких как JSON, CSV и т. д. Однако, попробовав серьезно использовать его в паре нетривиальных проектов, я нашел его функциональным и производительным, но несколько утомительным для использования для больше, чем маленькие грамматики. - person wjl; 08.07.2011

person    schedule
comment
Например, для моего гибкого синтаксического анализатора robots.txt, созданного с помощью scons, это так же просто, как: thisenv.CXXFile(target='Robots_flex.cc',source='robots.ll') И конструктор Robots.cc имеет: Роботы(std::istream* in): yyFlexLexer(in,0), [...] - person piotr; 24.04.2009