четверг, 26 мая 2011 г.

Краткость

Тут недавно взяли на слабо. Задача почти стандартная, известная как K Problem + большая грамматика.

Далее "моя" реализация. "Моя" - потому что я заиспользовал комбинаторы.

Парсер комбинаторы - круто. Смотрим и писаем кипятком кончаем наслаждаемся.

Эта часть легко находится по подстроке "-- Carsten Schuermann: From: Monadic Parser Combinators [Hutton, Meijer]"


Тут пока некоторая магия, в которую за 5 минут не въехать. Далее должно быть понятнее.

AST - это или ссылка на ячейку, или число, или бинарный оператор из AST.
Вводим парсер для AST. Опишем стандартные арифметические операторы.

А теперь *барабанная дробь*



Собственно все, парсер (лексер + синтАнализатор) готов.
Запускаем и оно работает.



Где вы еще сможете в 3-4Кб уложится? Это вам не парсер-генератор, здесь все сделано вручную... Правда, исходя из этого - это LL. Бывает кое-что затруднительно выразить в LL, да еще и следить за левой рекурсией. LR вручную непросто реализовать, но мне местами такая грамматика больше нравится. Есть еще всякие PEG/Packrat, с не очень понятной теорией (трудно понять, выразима ли конкретная грамматика в них), и куча непрактичных но теоретических парсеров.

Далее опишем типы для "excel". Ячейка - есть строка, лист как коллекция пар из (ячейка, строковая формула) и так далее. В идеале надо бы абстрактный маппинг (словарь/функцию) из ячейки в формулу.



Простая вычислялка AST и вычислялка для строки.



Пара тривиальных вещей:



Несколько типов для вычислителя excel-я.
EvaluatedCellBuffer - это результат вычислений. Далее его как аккумулятор и будем вычислять.



Вся логика вычислений в следующем:



Далее очевидная вода:



Вычисление одной ячейки:


Тривиальный вычислитель



Пара утилитных функций



И вычисление всего листа



Примеры листов:



И примеры:


Еще можно добавить шапочку :)


В 8Кб имеет парсер, AST, вычислитель, и обход и расчет листа excel.
Несложно расширяемо на
- функции и несложную типизацию в встроенном языке
- отказаться от дву(3 ли 3.5 как в excel) мерности задачи и перейти к произвольной размерности.

У меня в текущем проекте есть нечто похожее, но это явно не 8Кб.

ЗЫ. Научиться бы здесь нормальное форматирование делать... В процессе.

Комментариев нет: