If a C programmer asks "do you want to see something cool?", run away.
--John Van Enk

Thursday, January 25, 2007

Joel on Software

Читал Джоэля . У-у-ух! Вставляет мужик. Пишет классно. Зачитаться! В гуру его добавлю.

Tuesday, January 23, 2007

Подсветка

Кажись исправил
Ну ка посмотрим...

//классический hello world куда ж без него
#include <iostream>
using std::cout;
using std::endl;

int main(int argc,char**argv){

cout<<"Hello world"<<std::endl;
} 

Новый Firefox

Ура!!! Поставил себе новый Firefox - просто прелесть! А с foxmarks так просто одни удобства - нет больше тасканиям закладок с работы домой и обратно!!! Ура товарищи (море восторга)!!!
О грустном: сменил темплейт надо перенастраивать подсветку кода :(

Monday, January 22, 2007

2b|~2b

Algorithms + C++=success or sucksass?
Это так навеяно...
Можно не обращать внимания (а никто собственно и не обращает :)

Sunday, January 21, 2007

Education

Вот классно было бы, если бы одним из предметов на выбор в университете был предмет "эстетика кода" - я б его точно выбрал. Все больше замечаю, что чем больше пишу на С++ тем более высокие требования предъявляю к качеству и изящности кода. По моему тернарная условная операция - одна из наиболее элегантных конструкций языка
 ((a < b)?a:b)=1;

Просто, банально, но тем не менее ...

Saturday, January 20, 2007

Firefox

Как это я раньше жил без такого замечательного браузера? Диву даюсь. Накачал аддонов для чтения RSS, почты, синхронизации закладок и тихо радуюсь. Просто высший класс - все что надо в одной программе и ничего лишнего. Приятно удивил размер расширений - несколько сотен килобайт - зато какая функциональность! Время установки самого Firefox на машину тоже приятно порадовало - быстро и без лишнего шума. Может и IE начнут развивать, а то как Netscape загнулся так и он на месте застыл. Про его 7'ю версию не слишком лестные отзывы, к тому же вроде как он основан на движке IE4, т.е. изменения чисто косметические. Ну добавили вкладки, ну и что? Все, буду пользоваться Firefox.

Tuesday, January 16, 2007

Среда разработки

Среда разработки (Интегрированная среда кому как нравится) довольно полезная, приятная и во многих случаях облегчающая жизнь вещь. Сейчас на работе пользуюсь Kdevelop ( www.kdevelop.org ). На мой взгляд довольно продуманная и грамотно реализованная среда - в том плане что предоставляет интерфейс к уже хорошо зарекомендовавшим себя средствам (системы сборки (autotools, qmake, cmake, ant), контроля версий (cvs, svn, perforce) и т.п.).

Programming Languages: Ada Bash C/C++ Fortran Haskell Java Pascal Perl PHP Python Ruby SQL

Build tools: GNU Autotools, Qmake, Ant, custom makefiles, generic scripts.

Documentation Formats: XML, HTML, doxygen, kdoc, DevHelp, kdeveloptoc, TXT, CHM, PDF, Djvu and PDB.

Revision Control Systems: CVS, preforce, subversion, ClearCase.

Code editors: Kate, Qeditor, kyzis.

Development toolkits: Qt, gtk, wxWindows, superwabba, GBA.

Other plugins: console, debugger, find-and-replace-in-files, code completion, classviwer, as-you-type-problem-reporter and many others.

Не сильно уступает MS Visual Studio а в некоторых вещах превышает (ну например у меня проект управляется при помощи autotools и бОльшая часть кода генерируется из более высокоуровневых описаний путем простого вызова соответствующих программ (Flex/Bison/Gperf) ) - все таки эти makefile не такая уж и страшная вещь а очень даже функциональная и удобная. В целом прятное впечатление.

Хочу попробовать Eclipse & CDT посмотрим что из этого выйдет. Java'исты хвалят IntelliJ IDEA, и спорят Eclipse vs NetBeans. Интересно посмотреть чем все это закончится. NetBeans наверное победит - и среда удобная и расширяемая, и диски с ней высылают совершенно бесплатно как только выходит новый релиз (причем "Runs on Windows, Linux, MacOS, as well as Solaris"). Тут вспоминается аналогия с Ubuntu Linux, который так же бесплатно распространяется на дисках, и вроде бы является самым распространенным из семейства Linux

Friday, January 12, 2007

Flex & Bison C++ Interoperability - Intro

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

Flex можно найти на flex.sourceforge.net
Bison можно найти на www.gnu.org/software/bison
Там же ссылки на мануалы и кроме того при установке тулзов становится доступна довольно качественная документация в виде manpages & info pages (это так если вдруг кто захочет поподробнее покопаться, позже приведу ссылки на ресурсы в сети - как только выкопаю их где то у себя в закладках :).

Так вот, неожиданно вдруг у меня появилась задача написать простенький интерпритатор и решил я для этого использовать вышеупомянутую парочку. Кроме всех прочих требований и бла-бла-бла были требования о thread safety &reentrancy. Естественно, сгенерированные по умолчанию ни лексер ни парсер этим условиям не удовлетворяют (если использовать С в качестве target language) - но вот как бы насколько я помню этим условиям удовлетворяют классы С++ (при некоторых оговорках). Оба инструмента поддерживают возможность генерации классов С++, но они не стыкуются по интерфейсам так как парсер все так же требует функции лексического анализа со следующей сигнатурой вызова
yylex (semantic_type* lval [,location_type* lloc])
Притом второй аргумент присутствует лишь в том случае если используется location tracking (отслеживание позиции).
Flex обеспечивает 2 способа генерации сканеров для их последующего использования в программах на С++. Первый - просто скомпилировать сгенерированный сканер при помощи С++ компилятора - однако необходимо некоторые функции при этом обьявить как
extern "C"
Такой способ мне не подошел по вышеупомянутым причинам (одной non reentrancy хватило). Второй - сгенерировать сканнер на С++, который представляет собой реализацию классов, интерфейс которых определен в заголовочном файле FlexLexer.h, который в свою очередь устанавливается в системе вместе с Flex. Вот он (за исключением неинтересующих на данном этапе функций-членов классов):

#ifndef __FLEX_LEXER_H
#define __FLEX_LEXER_H
extern "C++" {
class FlexLexer {
public:
virtual ~FlexLexer() { };
virtual int yylex() = 0;
int yylex( FLEX_STD istream* new_in,
FLEX_STD ostream* new_out = 0 );
};
}
#endif

#if defined(yyFlexLexer) || ! defined(yyFlexLexerOnce)
#define yyFlexLexerOnce

extern "C++" {

class yyFlexLexer : public FlexLexer {
public:
yyFlexLexer( FLEX_STD istream* arg_yyin = 0,
FLEX_STD ostream* arg_yyout = 0 );
virtual ~yyFlexLexer();
virtual int yylex();
};
}
#endif


Если обратить внимание на стражи включения (#ifndef - #define-#endif) то можно заметить что при повторном включении данного заголовочного файла в одну и ту же единицу трансляции базовый класс FlexLexer повторно вкючен не будет а вот его наследник yyFlexLexer при определенных условиях (о них в следующих постах) может быть включен поторно, что естественно приведет к ошибке компиляции.

Итак о "стыковке" парсера и лексера. Наиболее простым решением , на мой взгляд, является создать наследника от yyFlexLexer и добавить в него
operator()(semantic_type* lval ,location_type* lloc)
и далее передавать екземпляр унаследованного класса в конструктор парсера (благо такую возможность предусмотрели разработчики Bison). Но параметры lval & lloc должны быть доступны внутри yylex(). Далее, читая мануалы, наткнулся на возможность указать в опциях генерации буквально следующее "сгенерировать реализацию функции yylex() для класса унаследованного от yyFlexLexer". Естественно имя унаследованного класса указывается в качестве параметра.

Ну вот в принципе и решение проблемы:
1) наследуем от yyFlexLexer класс с оператором
operator()(semantic_type* lval ,location_type* lloc)

2) указываем "сгенерировать реализацию yylex() для класса унаследованного от yyFlexLexer"

3) указываем что конструктор парсера принимает дополнительный параметр с идентификатором yylex ( внутри парсера вызывается функция yylex - таким образом при вызове
yylex(yylval, yylloc)
на самом деле будет вызван
 yylex.operator()(yylval,yylloc) )

Но есть еще some tricks которые необходимо проделать чтобы все что в итоге нагенерировалось скомпилировать... :) О них напишу чуть позже.