Транслятор?

02.04.2006 18:11:16

Встав бодренько в восемь часов утра принялся писать транслятор. Собственно, давно была идея что-нибудь этакое сваять-попробовать. Естественно, что ни о чем серьезном речи еще не идет, все что я хотел сделать — это преобразовать обычную инфиксную алгебраическую нотацию в обратную польскую.

Пример частый и популярный, собственно, я его из книжки по основам построения трансляторов и почерпнул. Там он рассматривается схематично, все очень просто и понятно, но так как надо бы уже оттачивать владение инструментами реализации всего этого безобразия (КС-грамматик), то было решено что-нибудь накорябать.

Для начала я взял полюбившийся мне Ragel, который компилятор конечных автоматов. Человек знающий улыбнется уже здесь, ну а я несколько часов все-таки постучался лбом об стену того, что анализ КС-грамматики в принципе невозможно реализовать в рамках конечного автомата, зато с помощью автомата с магазинной памятью — только так. 🙂

Впрочем, стучал не совсем без толку, поскольку на Ragel это сделать все-таки можно, он может делать «странные» переходы и КС-грамматику на его основе проанализировать можно. Можно, но очень некрасиво, а меня это совсем неустраивало.

В результате, пока я обдумывал, как бы мне начать работать с LLnextgen или Flex, правильный человек aka Дрюнь прислал мне ссылку на Bison. На который я резко и накинулся, а в «info bison» как раз обнаружился пример калькулятора что в обратной польской нотации, что в обычной инфиксной.

В общем, я взял за основу постфиксный калькулятор, описал свою грамматику (BTW, vim замечательно подсвечивает синтаксис) и получил не только «переводчик» из инфикса в постфикс, но еще и (заметьте, нахаляву!) калькулятор. По этому поводу сижу и радуюсь.

А описание получилось в таком духе:

%token NUM
%left  '-' '+'
%left  '*' '/'
%left  NEG
%start input
 
 
%%
 
input       : /* empty */
            | input line
;
 
line        : '\n'
            | expr '\n' { printf( "\n\t%.10g\n", $1 ); }
;
 
expr    : NUM                   { $$ = $1; printf("%.10g ", $1); }
        | expr '+' expr         { $$ = $1 + $3; printf("+ "); }
        | expr '-' expr         { $$ = $1 - $3; printf("- "); }
        | expr '*' expr         { $$ = $1 * $3; printf("* ");}
        | expr '/' expr         { $$ = $1 / $3; printf("/ ");}
        | '-' expr %prec NEG    { $$ = - $2; printf("inv ");}
        | '(' expr ')'          { $$ = $2; }
;
 
%%

Маркетинг и языки программирования

30.03.2006 15:52:21

Определенно, это не лишено смысла: раз, два.

For

24.03.2006 22:06:09

Неторопливо копошась сегодня в исходниках Linux, обнаружил забавный пример кода (drivers/md/raid6main.c:220):

for (i=disks; i--; ) {

Оно работает, естественно (ведь совершенно правильная конструкция с точки зрения C!), но выглядит, согласитесь, весьма «интересно». Что еще интереснее, так это то, что ровно такая же конструкция используется по всему этому файлу далее. Собственно, здесь же куча закомментированного кода, причем разными способами…

В общем, наткнулся на откровенный отстойник какой-то, прям воротит.

Закон Вирта

23.03.2006 12:18:14

Оказывается, есть и такой.

Всякое

22.01.2006 13:46:17

Особых поводов писать нету, но, вроде бы, надо что-то. За отчетный период программировал на Ocaml (вот еще прекрасный ресурс) и «программирую» на Bash. Второе довольно отвратно, однако работа. Зато первое было просто чудесно, крышесносящий опыт. К сожалению, пока не добрался до объектно-ориентированных возможностей, постараюсь на следующей неделе, глядишь, и отчет появится.

Смотрел Lost, как обычно, запоем — с пятой по девятую серию второго сезона. Скачал десятую. С трудом нарыл для нее субтитры (на forom.com, куда предыдущие субтитры отсылают, но ресурс на Flash’е и чудовищно спамный, мне не понравилось…), зато нарыл сразу и для одиннадцатой (на привычном divxsubtitles.net, куда у них подевались английский субтитры для десятой серии — ума не приложу) , которую сейчас потихоньку качаю.

Заворочено в Lost лихо, видно, кусок из пленки вырезан не зря был, кто-то до этого уже воспользовался кнопкой не по назначению, с чего, скорее всего, странности там и начались, а теперь вот еще черный брат Михаил туда же… Ну, это wild guess, посмотрим, что там дальше как. Хочется верить, что второй сезон будет завершающим, но пробелы в поле «To» вот здесь наводят на всякие мысли.