Skip to main content

Posts

Showing posts with the label flex

Зачем мне нужен any_fun_ptr

В предыдущем посте, я высказался о том, что хочу эдакий generalized callback, который мог бы указывать на любую функцию. Возникает вопрос, а зачем это мне? Попробую для начала сделать некоторое введение, которое, надеюсь, немного прольет свет на эту проблему. Давайте рассмотрим простенький калькулятор, поддерживающий 26 переменных (a-z), операции +, -, *, / и скобки, имлементированный при помощи парочки Flex/Bison и с целевым языком С++. Как я уже когда-то писал , для начала необходимо сделать небольшой workaround для того, чтобы состыковать парсер, сгенерированный бизоном, и лексер, сгенерированный флексом. Для этого используется класс наследник от yyFlexLexer. файл lexer.h #ifndef _LEXER_DERIVED_CLASS_H_ #define _LEXER_DERIVED_CLASS_H_ #ifndef __FLEX_LEXER_H #undef yyFlexLexer #include <FlexLexer.h> #endif #include <iostream> #include <parser.h> namespace calc{ class Lexer:public yyFlexLexer { int yylex(); Parser::semantic_type* yylval; Parser::location_type*...

Flex & Bison C++ Interoperability Continued

Итак, возвращаясь к когда-то написанному мной введению об interoperability лексических анализаторов на С++, сгенерированных при помощи Flex, и синтаксических анализаторов, сгенерированных при помощи Bison, в этой статье хочу разобрать простенький примерчик в котором лексический анализатор (далее лексер) распознает строки комментариев командного интерпретатора bash и пустые строки и пропускает их, а все остальные возвращает синтаксическому анализатору (далее парсеру) для последующего вывода в командную строку. Сначала я приведу код, а затем уж постараюсь объяснить по возможности что какая строчка значит, ну и соответственно команды которые необходимы чтобы это все собрать в кучу. Файл intertest.cpp #include <fstream> #include "lexer.h" #include "parser.h" using namespace std; using namespace test; int main(int argc, char *argv[]) { ifstream infile(argv[1]); Lexer lexer(&infile); Parser parser(lexer); return parser.parse(); } Тут я ду...

Ну мужики дают!...

Ага вот еще одна радость - в сканнере, генерируемом Flex'ом на С++ управление памятью осуществляется при помощи malloc/realloc/free. Надо заменить - либо в шаблоне подправить либо конкретно для своего проекта memory management организовать. Ладно, посмотрим...

Flex Bug

Да-а-а... Нечему удивляться. Софта без багов не бывает, как говориться. Вот накопал мемлек в сканнере, сгенерированном на С++. Блин, ну скажите мне, ну как это можно - выделить память под массив указателей - а потом забыть ее осовбодить?!!! Послал багрепорт, но почитав ихний багтрэк, понял, что ждать пока исправят можно еще долго. Пришлось самому... Хорошо, что в сырцах есть шаблон, по которому это все генерируется при помощи макросов, так что проблема благополучно решилась путем добавления новой строчки в заготовку для деструктора и перекомпиляции Flex'а. Именно в таких случаях начинаешь ценить продукт с открытым исходным кодом :). Послал им багфикс, блин хоть бы отписали че нить, хотя там вроде как у администратора проекта свадьба, так что скорее всего сейчас не до этого. Пороюсь, мож эти "people of the C world" еще че нить забыли написать, благо Valgrind и memchek всегда под рукой.

Flex & Bison C++ Interoperability - Intro

Уф давненько я сюда не заглядывал - уже и забыл что у меня есть блог :)! Вот собственно по теме - есть такие замечательные программы как Flex (GNU аналог Lex'а) - генератор лексических анализаторов и Bison (аналог YACC'а - Yet Another Compiler Compiler - "еще один" компилятор компиляторов) - генератор синтаксических анализаторов (парсеров). Каждый из этих тулзов получает на вход файл спецификаций и после обработки его выдает на выходе код на С (можно и на С++, ведутся работы над Java - но об этом дальше) который затем можно собрать и в итоге получить программу осуществляющую грамматический разбор текста и выполняющую определяемые разработчиком действия. В основном данные средства используются в паре так как парсер, генерируемый Bison требует еще наличия функции со ледующим интерфейсом (в простейшем случае): yylex() которая собственно скармливает парсеру лексемы, которые тот уже группирует в различного рода выражения. Именно эту функцию и с таким интерфейсом генер...