Qt и flex/bison или antlr + Visual Studio

 
0
 
C++
ava
Elfenlide | 24.03.2013, 21:01
Доброго всем времени суток, передомной такая задача: разработать собственный язык разметки на замену Html, разработать браузер который будет поддерживать этот язык и отображать странички. Так как использовать нужно Qt, есть там замечательная штука как компенент QWebView, можно свой язык переводить в html а затем выводить через компоненту.
Для того чтобы описать свой язык нужно использовать какой-то парсер, преподавательпредложил использовать flex/bison или antlr, но сам по этим библиотекам ничего не сказал."разбирайтесь сами." Я решил использовать Qt 5 подключив его к Visual Studio 2010.
Вот моя идея:
Открыть текстовый файл с моим текстом в обработке собственными тегами, парсить строку а затем сохранять результат в новый файл формата html, после чего выводить его на экран как html файл через QWebView.

Проблема:Облазил всё что мог, гуглил как умею и как не умею, но так и не нашёл как можно подключить flex/bison или antlr для работы с С++.
Прошу объяснить значиющих как это делается.

P.S: У меня походу совсем кривые руки, тут в поиске ввожу слово "flex"  в ответ вижу фигу в виде строки "по вашему запросу ничего не найдено", хотя на форум забёрл по одной из сылок о flex-е из гугла
Kommentare (28)
ava
kosmonaFFFt | 25.03.2013, 07:21 #
flex и bison это не библиотеки, а генераторы кода - они принимают на вход файл с описанием грамматики (bison), или с описанием лексем (flex), и по ним генерируют C код, который потом можно включить в проект...
Я бы рекомендовал использовать flexc++ и bisonc++ (http://flexcpp.sourceforge.net/), они генерируют c++ код (flex и bison вроде тоже умеют C++, но код там получается довольно корявый)...
ava
math64 | 25.03.2013, 07:21 #
Если твой язык разметки основан на xml - никакие бизоны не нужны.
В Qt есть классы для работы с xml, можно непосрадственно отображать xml (примеры этого есть в Qt), можно преобразовать xml в html и отображать полученный html (в самом Qt таких примеров нет, но думаю найти в инете можно).
ava
Elfenlide | 26.03.2013, 11:49 #
Цитата (math64 @  25.3.2013,  07:21 findReferencedText)
Если твой язык разметки основан на xml - никакие бизоны не нужны.

В Qt есть классы для работы с xml, можно непосрадственно отображать xml (примеры этого есть в Qt), можно преобразовать xml в html и отображать полученный html (в самом Qt таких примеров нет, но думаю найти в инете можно). 

Нет, мне надо что-то своё придумать аля "BigWrods(hello world)" и чтобы парсер обработав это дело вывел мне "HELLO WORLD" что бы было проще сказали можно преобразовывать в html и выводить на компоненту QWebView.
ava
baldina | 26.03.2013, 12:08 #
Цитата (Elfenlide @  24.3.2013,  20:01 findReferencedText)
flex/bison или antlr

попробуй antlr, можно использовать довольно дружественный antlrworks, это визуальная среда.

как вариант библиотеки безо всяких внешних генераторов и заморочек с make - boost::spirit
ava
kosmonaFFFt | 26.03.2013, 13:18 #
Цитата (baldina @  26.3.2013,  16:08 findReferencedText)
попробуй antlr, можно использовать довольно дружественный antlrworks, это визуальная среда.

А с другой стороны придется избавляться от левой рекурсии, что многим очень трудно дается, аналогично и с boost::spirit, но там еще и огромные нечитаемые портянки сообщений об ошибках компилятора, если что-то не так сделаешь...

Цитата (Elfenlide @  26.3.2013,  15:49 findReferencedText)
Форумы и сайты которые я находил с данной тематикой иллюстрируют примеры и что-то говорят о работе flex/bison, как они работают и что делают я вроде как понял, но я нигде не нашёл описания того, как пользоваться этими генераторами...препод сказал что можно использовать CMake для генерации проекта с включенным бизоном и флексом, но как это делать.."я давно это делал и уже не помню"...

Это зависит от инструментов разработки... Если хочется интегрировать генерацию кода в процесс сборки, то можно Makefile или CMake использовать... А можно просто на эту тему не заморачиваться (это же не реальный проект, а учебный, если я правильно понимаю) и генерировать исходники лексера и парсера вручную после каждого изменения входных файлов для генератора...

Хеллоуворлд уже давно написан, нужно только поискать: http://flexcpp.sourceforge.net/flexc++man.html

З.Ы. В VisualStudio можно настроить pre build step, чтобы на нем генерировались файлы кода из спецификаций (предварительно сгенерив файлы руками и включив их в проект)...
ava
baldina | 26.03.2013, 13:32 #
идеала нет.
все средства требуют определенной подготовки пользователя
ava
Elfenlide | 26.03.2013, 13:37 #
Цитата (kosmonaFFFt @  26.3.2013,  13:18 findReferencedText)
Хеллоуворлд уже давно написан, нужно только поискать: http://flexcpp.sourceforge.net/flexc++man.html

Дело в том что примеров кучу я уже находил, а вот где написано будет куда нажимать итд, такого не видел. Тоесть, вот есть у меня например исходники простого примера, как мне заставить их работать? Я конкретно не знаю и не понимаю того, что нужно сделать для того чтобы запустить написанную программулину.
Вот я выложил файлик, там калькулятор с граматикой итд..что делать дальше если я написал грамматику...логично сгенерировать парсер работающий на её основе, но как это сделать я не знаю так как у меня flex и bison это просто две папки с множеством файлов.
ava
Elfenlide | 26.03.2013, 13:38 #
Я сижу под Windows, а везде где я читал про генерирование, там какие-то g++ . Я так понял это Unix системы
ava
bsa | 26.03.2013, 13:47 #
Elfenlide, g++ входит в состав mingw, работающего под windows.
ava
Elfenlide | 26.03.2013, 14:05 #
Цитата (bsa @  26.3.2013,  13:47 findReferencedText)
g++ входит в состав mingw, работающего под windows. 

Понятно, спасибо, почитаю.
Но всё же, что делать с архивами? для меня сейчас bison и flex это просто две папки с файлами\
Если не трудно, объясните на примере исходников которые нуждаються в генерации.
ava
baldina | 26.03.2013, 14:10 #
Цитата (Elfenlide @  26.3.2013,  13:37 findReferencedText)
 а вот где написано будет куда нажимать

этого, батенька, вам никто не скажет. тут все умели когда-то нажимать, но давно забыли. спросите преподавателя: много проще и короче показать пальцем, сидя рядом.
ava
Elfenlide | 26.03.2013, 15:55 #
Цитата (baldina @  26.3.2013,  14:10 findReferencedText)
 тут все умели когда-то нажимать, но давно забыли.

Вот и препод мне тоже самое сказал....
Вот, вы сказали то что я знаю, файлы составлять итд....но вот каким образом 
Цитата (baldina @  26.3.2013,  14:10 findReferencedText)
дальше напускаете на него bison:
. У меня flex и bison это две папки с кучей файлов. Видимо с ними(папками) что-то нужно сделать, чтобы потом иметь возможность bison-ом творить чудеса, вот что именно, мне и интересно\
ava
baldina | 26.03.2013, 16:25 #
Цитата (Elfenlide @  26.3.2013,  15:55 findReferencedText)
каким образом

в текстовом редакторе  smile 
серьезно, надо а) изучать синтаксис б) для начала составить БНФ своего языка, она уже преобразуется в синтаксис bison
Цитата (Elfenlide @  26.3.2013,  15:55 findReferencedText)
flex и bison это две папки с кучей файлов. Видимо с ними(папками) что-то нужно сделать

ваша куча файлов - http://downloads.sourceforge.net/gnuwin32/...n-2.4.1-bin.zip
разворачиваете архив в папку (видимо это уже сделано)
в папке bin видим bison.exe - вот его и надо запускать, передавая в качестве параметра ваш .y файл
автоматизировать это дело можно, настроив в VS pre-build шаг, прописав туда вызов bison

später ergänzt:
с flex аналогично
ava
Elfenlide | 26.03.2013, 18:32 #
Цитата (baldina @  26.3.2013,  16:25 findReferencedText)
в папке bin видим bison.exe

Вот, у меня левые какие-то архивы были, скачал bison, flex с екзешкой не нашёл, но примеры не работают...я беру отсюда http://flexcpp.sourceforge.net/flexc++man.html и делаю как написано. bison ругается. Поискал flex, нашёл архив где под винду flex/bison сразу, вроде работают, но ошибки всё-равно есть, пробовал пример выше сделать бизоном calc.tab.c, а флексом лексический анализатор сделать не вышло. Брал такой исходник:


%%
[ \t\n]+                            // skip white space chars.
[0-9]+                              return NUMBER;
[[:alpha:]_][[:alpha:][:digit:]_]*  return IDENTIFIER;
.

получил: C:\Flex & Bison\win_flex_bison-latest>win_flex lexer.l
lexer.l:5: EOF encountered inside an action


Когда попробовал ваш готовый анализатор взять и просто сделать преокт в Visual Studio, как я понял всё что нужно было сделать, это добавить туда эти два файла, получил в студии ошибки:
Ошибка    1    error C2065: yylval: необъявленный идентификатор    c:\flex & bison\win_flex_bison-latest\lexerp.c    13
Ошибка    2    error C2065: NUM: необъявленный идентификатор    c:\flex & bison\win_flex_bison-latest\lexerp.c    14
    7    IntelliSense: идентификатор "yylval" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    13
    8    IntelliSense: идентификатор "NUM" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    14
    9    IntelliSense: недопустимый неполный тип    c:\flex & bison\win_flex_bison-latest\lexerp.c    22
    10    IntelliSense: требуется объявление    c:\flex & bison\win_flex_bison-latest\lexerp.c    24
    11    IntelliSense: идентификатор "yyparse" не определен    c:\flex & bison\win_flex_bison-latest\lexerp.c    29

Цитата (baldina @  26.3.2013,  16:25 findReferencedText)
проще будет свой парсер написать
 Я уже подумываю, но парсеры нормальные писать не умею, миллион ифов писать не хочеться потому что это не правильно, а вот разобраться в такой штуке как генератор парсера вроде как очень полезно.

Цитата (baldina @  26.3.2013,  16:25 findReferencedText)
разработать собственный язык разметки 
 тут разрабатывать то нечего,  я буду просто писать в файле текст типа: Hello Kursive(World) newLine, и он мне должен вызвать функцию Kursive для букв в скобках, преобразовать в строку <i>World</i> и вывести уже в html тегах обработанную как курсив, ну итд...а вместо <br> нужно писать что-то типа newLine для перевода на новую строку...
Вообще я взялся за флекс и бизон потому что не знаю как по другому сделать, ну, не включая парсера из пары сотен ифов..это даже не парсер а ересь какая-то...а препод только о бизоне, флексе и antlr заикнулся, antlr  пробовал разобрать, но на с++ как с ним работать не особо въехал, везде про Java почти написано и интеграцию с Eclipse, думал сделать на Java парсер чтобы вызывался от с++ готовый джавовский екзешник и превращал мой язык в html, после чего выводил бы на QWebView уже готовую страничку просто, идея сразу не очень понравилась, а когда решил попробоввать убедился в том что тупня это....
ava
baldina | 26.03.2013, 18:45 #
Цитата (Elfenlide @  26.3.2013,  18:32 findReferencedText)
миллион ифов писать не хочеться потому что это не правильно

простейший парсер сверху вниз - не надо много if, а для поиска ключевых слов используйте std::map

давайте-ка придумайте полностью ваш язык, опишите, дальше подумаем что и как делать
ava
fish9370 | 27.03.2013, 12:10 #
может к черту бизон?

регулярные выражения, парсер, шаблонизатор, пара шаблонов..
ava
Elfenlide | 27.03.2013, 15:04 #
Цитата (baldina @  26.3.2013,  18:45 findReferencedText)
давайте-ка придумайте полностью ваш язык, опишите, дальше подумаем что и как делать

нужно реализовать возможность:
◦ указывать ссылки на другие страницы;
◦ вставлять изображения в текст;
◦ устанавливать выравнивание текста и его стиль (аналоги тегов <b><i><u><font>).
Я придумал так: $ это будет главное отличие, тоесть если не знак доллара, то свободно читаем как обычный символ и выводим как читаем.
вместо тегов b, i, u, font, ,будут: $Bold() , $Kursiv(), $UnderLine(), $Font() - для простоты я решил изменить его, html эквивалентный имеет 3 параметра: высота символа, тип шрифта, цвет. Следовательно будут отдельные теги: $Color(), $Size(), $TypeText(). Ну и в таком стиле остальные: ссылки, загрузка картики.
Просто если я буду считывать каждый символ, то это ифы итд...я уже накидал код такой, который по сиволам разбирает, но исключительно из-за того что скоро здавать нужно будет, и не хочу двойку. А вот что-то толковое изучить, какой-то метод которым можно парсер хороший написать я не знаю, поэтому и хотел взять бизон и флекс...
Мой код на данный момент\ я думаю это не очень красивый вариант решения данной задачи. Я пишу на Qt, но тут от Qt только QString, остальное как в стандартном с++.


void KursiveText(QString& KursiveStr, int& i, QString& str, QString& tempStr, int& tempStrInd);
void BoldText(QString& BoldStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void UnderLineText(QString& UnderLineStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void SizeText(QString& SizeStr,int& i, QString& str, QString& tempStr, int& tempStrInd);
void Endl(int& tempStrInd, QString& tempStr, int& i);

QString WebBrowser::parsing(QString str)
{
    QString tempStr;
    QString KursiveStr = "";
    QString BoldStr = "";
    QString UnderLineStr = "";
    QString SizeStr = "";
    int tempStrInd = 0;

    for(int i = 0; i < str.size(); i++)
    {
        if(str[i] == '$')
        {
            i++;

            if(str[i] == 'K' && str[i+1] == '(')
            {
                KursiveText(KursiveStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'e' && str[i+1] == 'n'
                && str[i+2] == 'd' && str[i+3] == 'l'
                && str[i+4] == '(' && str[i+5] == ')')
            {
                Endl(tempStrInd, tempStr, i);
            }
            else if(str[i] == 'B' && str[i+1] == '(')
            {
                BoldText(BoldStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'U' && str[i+1] == '(')
            {
                UnderLineText(UnderLineStr, i, str, tempStr, tempStrInd);
            }
            else if(str[i] == 'S' && str[i+1] == '(')
            {
                SizeText(SizeStr, i, str, tempStr, tempStrInd);
            }
            
        }
        else
        {
            tempStr[tempStrInd] = str[i];
            tempStrInd++;
        }        

    }

    return tempStr;
}

void KursiveText(QString& KursiveStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int KursiveInd = i+2;
    i = KursiveInd;

    while(str[i] != ')')
    {
        KursiveStr[tempINDEX] = str[KursiveInd];
        tempINDEX++; i++; KursiveInd++;
    }

    QString htmlRezult;
    htmlRezult = "<i>";
    htmlRezult += KursiveStr + "</i>";
    KursiveStr = htmlRezult;

    tempStr += KursiveStr;
    tempStrInd += KursiveStr.size();
    KursiveStr = "";
}

void BoldText(QString& BoldStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int BoldInd = i+2;
    i = BoldInd;

    while(str[i] != ')')
    {
        BoldStr[tempINDEX] = str[BoldInd];
        tempINDEX++; i++; BoldInd++;
    }

    QString htmlRezult;
    htmlRezult = "<b>";
    htmlRezult += BoldStr + "</b>";
    BoldStr = htmlRezult;

    tempStr += BoldStr;
    tempStrInd += BoldStr.size();
    BoldStr = "";
}

void UnderLineText(QString& UnderLineStr, int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int UnderLineInd = i+2;
    i = UnderLineInd;

    while(str[i] != ')')
    {
        UnderLineStr[tempINDEX] = str[UnderLineInd];
        tempINDEX++; i++; UnderLineInd++;
    }

    QString htmlRezult;
    htmlRezult = "<u>";
    htmlRezult += UnderLineStr + "</u>";
    UnderLineStr = htmlRezult;

    tempStr += UnderLineStr;
    tempStrInd += UnderLineStr.size();
    UnderLineStr = "";
}

void SizeText(QString& SizeStr,int& i, QString& str, QString& tempStr, int& tempStrInd)
{
    int tempINDEX = 0;
    int  SizeStrInd = i+2;
    i =  SizeStrInd;

    while(str[i] != ')')
    {
        SizeStr[tempINDEX] = str[ SizeStrInd];
        tempINDEX++; i++;  SizeStrInd++;
    }

    QString htmlRezult;
    htmlRezult = "<font size = 7>";
    htmlRezult += SizeStr + "</font>";
    SizeStr = htmlRezult;

    tempStr += SizeStr;
    tempStrInd += SizeStr.size();
    SizeStr = "";
}

void Endl(int& tempStrInd, QString& tempStr, int& i)
{
    tempStr += "<br/>";
    tempStrInd += 5;
    i += 5;
}
ava
math64 | 27.03.2013, 15:39 #
У тебя не $Bold() , а $B() и т. д.
Не обрабатывается вложенность типа $B($I(Hello) $U(World))
т.е нужно искать не первую ), а парную и внутренность рекурсивно обрабатывать.
Поиск $:

int index = str.indexOf('$', from);


Генерировать html проще так:

QString boldStr = QString("<b>%1</b>").arg(str);
ava
Elfenlide | 27.03.2013, 17:07 #
Да, у меня $B() а не $Bold(), но это временно, для того чтобы быстрее писать программу, когда будет готова, чутка буду поправлять. Но честно говоря заканчивать её с кучей инструкций а не толковым парсером, желания нет.
baldina с мапом предлагает как-то замутить, вот мне это интересно. Может что-то классное выйдет.

Цитата (math64 @  27.3.2013,  15:39 findReferencedText)
Не обрабатывается вложенность типа $B($I(Hello) $U(World))

Я её думал сделать вызвав проверку на вложенность внутри методов путём просмотра строки между "()", но чуть позже.
Я считаю что это вообщей самый ущербный метод, которые для "лишь бы сделать и забыть"...ну...я про это выше писал.
Я знаю ещё есть метод конечного автомата со стеком состояний, как-то мне нужно было вводить строку типа {a,b,c,d,g,{u,j,k}} и создавать объекты собственного класса "множества" с элементами, ну и при этом должна быть фишка что множество может быть элементом другого множества.
Но там только {} из символов,а тут нужно кучу разных тегов замутить...
Вот как-то так:

Set Set::parse(stringstream &str)
{
    enum {
        OPEN,
        ELEMENT,
        NEXT
    } state = OPEN;

    Set theSet;
    while (!str.eof()) {
        switch (state) {
        case OPEN:
            switch (str.get()) {
            case ' ':   continue;

            case '{':  state = ELEMENT;
                continue;
            default:    return Set();
            }
        case ELEMENT:
            switch (str.peek()) {
            case ' ':  
                {
                    str.ignore();
                    continue;
                }

            case ',':  { return Set(); }

            case '}': 
                {
                    str.ignore();
                    return theSet;
                }

            case '{':
                {    
                    theSet.add(parse(str));
                    state = NEXT;
                    continue;
                }

            default:    theSet.add(str.get());
                state = NEXT;
                continue;
            }
        case NEXT:
            switch (str.get()) {
            case ' ':  { continue; }

            case ',':  
                {
                    state = ELEMENT;
                    continue;
                }


            case '}':   return theSet;

            default:    return Set();
            }
        }
    }
    return Set();
}

ava
math64 | 27.03.2013, 20:03 #
QMap можно использовать так:

QMap<QString,QString> map;
map["Bold"]="<b>%1</b>";

Ключи - теги между $ и (
Значения - код html с %1 на месте вставки аргумента.
ava
Elfenlide | 27.03.2013, 21:10 #
QMap<QString,QString> map;
map["Bold"]="<b>%1</b>";

Ключи - теги между $ и (
Значения - код html с %1 на месте вставки аргумента.[/quote]
не совсем понял как работает, если я создам map["Bold"] то когда считывание строки будет происходить, он сам определит последовательность символов map?
Если можно с каким-то простеньким примером поясните пожалуйста.
ava
math64 | 28.03.2013, 07:32 #
Ищешь $ или ) - что первое встретится.

QRegExp re("(\\$([A-Za-z]+)\\()|\\)");

Если найден ) - преобразуешь то, что до ) и выходишь из рекурсивной функции разбора
Если найден $ - выбираешь имя тега

QString key = re.cap(2);
if (!map.contains(key)) {
  << неверный тег >>
}
QString html = map[tag];

далее делаешь рекурсивный вызов parse() - на выходе индекс должен стоять на ')'

QString tmp = parse();
if (index >= str.lengh() || str[index] != ')') {
  << нет парной скобки >>
}
res += html.arg(tmp);

и повторяшь поиск.
ava
Elfenlide | 28.03.2013, 09:46 #

QString key = re.cap(2);

эта строка отвечает за то что следующие 2 символа будут считаны из потока я так понял?которые идут после знака $ 
ava
math64 | 28.03.2013, 12:13 #
cap(0) - вся найденная строка $Bold(
cap(1) - первый фрагмент - $Bold( - выделен аргумент | - (\\$([A-Za-z]+)\\()
cap(2) - второй фрагмент - Bold  - специально выделено скобочками - ([A-Za-z]+)
На всякий случай проверь:

qDebug() << "re.cap(0)=" << re.cap(0);
qDebug() << "re.cap(1)=" << re.cap(1);
qDebug() << "re.cap(2)=" << re.cap(2);
ava
xvr | 28.03.2013, 14:49 #
А я бы все же посмотрел в сторону bison'а. Ваша грамматика вся умещается в пару строк -

%union {
char* str;
ProgItem* prog;
}
%token<str> vCTRL
%token<str> vSTR
%type<prog> prog p_item
$$
top: prog {set_output($1);} ;
prog: p_item | prog p_item {$$=join($1,$2);};
p_item: vSTR {$$=new PIString($1);}
       | vCTRL '(' prog ')' {$$=new PICtrl($1,$3);}
       ;

Где vCTRL - все слова, начинающиеся с $, а vSTR - все остальные символы (кроме скобок)

Если делать это на flex'е, то это будет так

$[a-f]+  { yylval.str = strdup(yytext); return vCTRL;}
[()]        { return yytext[0]; }
[^()$]+ { yylval.str = strdup(yytext); return vSTR;}
Вместо strdup лучше взять что нибудь поближе к С++  smile 

Базовый класс ProgItem представляет кусок текста или фидективу форматирования. Он умеет вязаться в списки (функция ProgItem* join(ProgItem*,ProgItem*) )
Классы PIString и PICtrl - его наследники для чистых строк текста и директив форматирования соотвественно.
Функция set_output передает наружу результат парсинга - дерево, соотвествующее вашему тексту.

bison можно взять обычный С'ный - результат соберется в режиме С++
ava
Elfenlide | 28.03.2013, 18:41 #
Цитата (xvr @  28.3.2013,  14:49 findReferencedText)
Если делать это на flex'е, то это будет так

Я чутка не понял, так можно либо на флексе, либо на бизоне делать? я просто из всего что читал, понял что нужно их вместе использовать, лексер задаёт правила, парсер по ним работает.
И я попробовал написать ваш код флекса, и получил в консоли кучу ошибок, насколько я понял синтаксис, правила должны быть заключены в %% %%, я добавил, вроде нормально сгенерировалось, осталось теперь только понять одно\ как этим делом пользоваться. Радость что теперь понимаю как генерировать это всё дело)Спасибо за это огромное).

math64 и вас спасибо большое за помощь, попробую двумя способами сделать, лишним не будет.
ava
math64 | 28.03.2013, 21:34 #
бизон работает в паре в флексом.
Если планируестя усложнение грамматики, можно воспользоваться бизоном+флексом,
а на теперешнем уровне для разбора достаточно одной рекурсивоной функции - так проще.
В том числе и для отладки - отдаживаться в коде, сгенерированном бизоном неудобно.
ava
lexxmark | 08.04.2013, 21:37 #
Привет, попробую помоч с flex/bison для Qt.
Прежде всего добавь в начало своего *.pro файла вот этот кусок кода. Тут настраивается qmake, что бы обрабатывать flex/bison файлы.

# объявляем новый обработчик файлов
flex.name = Flex ${QMAKE_FILE_IN}
# определяем что входными данными будет список файлов FLEX_SOURCES
flex.input = FLEX_SOURCES
# определяем какие будут получаться выходные файлы
flex.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp
# определяем какую команду надо вызвать для каждого входного файла
win32:flex.commands = win_flex --wincompat -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
# это версия команды для linux
unix:flex.commands = flex -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.lexer.cpp ${QMAKE_FILE_IN}
# говорим что наш генератор должен выполняться до основной компиляции
flex.CONFIG += target_predeps
# говорим что выходные файлы - исходники на C++, что бы они попали в компиляцию
flex.variable_out = GENERATED_SOURCES
# регистрируем только что настроенный объект flex  как внешний компилятор в qmake
QMAKE_EXTRA_COMPILERS += flex

# аналогично с bison
bison.name = Bison ${QMAKE_FILE_IN}
bison.input = BISON_SOURCES
bison.output = ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp
win32:bison.commands = win_bison -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}
unix::bison.commands = bison -Wmidrule-value -t -d -o ${QMAKE_FILE_PATH}/${QMAKE_FILE_BASE}.parser.cpp ${QMAKE_FILE_IN}
bison.CONFIG += targets_predeps
bison.variable_out = GENERATED_SOURCES
QMAKE_EXTRA_COMPILERS += bison


Далее ниже в этом же *.pro файле прописываешь свои flex и bison файлы, например так:

FLEX_SOURCES += MyFile.l
BISON_SOURCES += MyFile.y


После этого перестраиваешь проект и у тебя должны генерироваться MyFile.lexer.cpp и MyFile.parser.cpp файлы.
Сами команды генерации (flex.commands/bison.commands) можешь адаптировать под свои нужды - менять параметры запуска.
Как видишь для windows версии используется win_flex/win_bison. Их можешь взять отсюда: http://sourceforge.net/projects/winflexbison/
Это более компактные версии flex/bisоn.
Как работать с flex/bison - можешь почитать pdf-ки с того же источника.
Registrieren Sie sich oder melden Sie sich an, um schreiben zu können.
Unternehmen des Tages
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Mitwirkende
advanced
Absenden