Эвалюатор с разбором в дерево

Здесь можно найти готовые «кирпичики» — части кода, пригодные для построения более крупных проектов, а также решения различных типовых и не очень задач на VB.

Модератор: Brickgroup

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Эвалюатор с разбором в дерево

Сообщение tyomitch » 30.10.2006 (Пн) 20:27

Решил написать образцово-показательный (в своём понимании) эвалюатор, который бы разбирал строку автоматом, а не через InStr и Mid.

Получилось несколько коряво в смысле кода, но зато вроде бы юзабельно.

Оформлено в виде ActiveX DLL, чтобы в классах были публичные UDT и енумы.

Интерфейс класса clsParser:
Go -- получает строку, разбирает её и строит дерево.
Root -- корень получившегося дерева. Его метод Evaluate возвратит результат вычисления.
Symbols -- коллекция под символы. Константы могут быть любого типа, приводимого к Double; функции должны быть классами-функторами, принимающими массив Double (см. пример).

Коллекция символов должна быть задана до вызова Go, потому что ссылки на неё расползаются по дереву. Но сами символы в неё добавлять и удалять можно в любое время.

Класс clsParser одноразовый: после первого вызова Go он превращается в зомби. Можно взять из него Root, а сам класс выбросить.

Предусмотрена многоуровневая обработка ошибок. У всех ошибок в Err.Source записывается позиция в строке, в которой эта ошибка возникла.

Таблицы, управляющие автоматами, сгенерированы парой flex/yacc. Менять их вручную, чтобы потвикать грамматику -- сомнительное удовольствие. Может, кто-нибудь сподобится написать кк для VB6? Для всех остальных популярных языков (C, C++, C#, Java) их уже навалом.


Распознаваемые выражения состоят из чисел, символов, и четырёх арифметических действий.
Число -- это последовательность вида [0-9]*(\.[0-9]*)?([Ee][+-]?[0-9]+)? (в мантиссе должна быть хотя бы одна цифра)
Символ -- это последовательность вида [A-Za-z_][0-9A-Za-z_]*

Распознаваемая грамматика:
Код: Выделить всё
expr:   NUMBER
   | NAME args
   | expr '+' expr
   | expr '-' expr
   | expr '*' expr
   | expr '/' expr
   | '-' expr
   | '+' expr
   | '(' expr ')'
;

args:   | '(' seq ')' ;

seq:   exp | exp ',' seq ;
Вложения
eval.rar
(7.24 Кб) Скачиваний: 229
Изображение

pronto
Постоялец
Постоялец
 
Сообщения: 597
Зарегистрирован: 04.12.2005 (Вс) 6:20
Откуда: Владивосток

Сообщение pronto » 31.10.2006 (Вт) 18:19

На выражение "2**2" выдает: Неожиданные токен: "*" - и - вылетает в трубу :?
O, sancta simplicitas!

GSerg
Шаман
Шаман
 
Сообщения: 14286
Зарегистрирован: 14.12.2002 (Сб) 5:25
Откуда: Магадан

Сообщение GSerg » 31.10.2006 (Вт) 18:23

А что должен делать? Правильно, генерит ошибку. Err.Raise.
Как только вы переберёте все варианты решения и не найдёте нужного, тут же обнаружится решение, простое и очевидное для всех, кроме вас

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 01.11.2006 (Ср) 23:36

Версия 2:
* задействование Универсальных Индексеров позволило использовать в качестве символов естественные функторы (в том числе из скриптов), а также массивы;
** (бонус: из JS можно использовать анонимные функции и методы объектов (в т.ч. стандартных) без создания переходников. Такой вот мощный язык.)
** (облом: из JS нельзя использовать родные массивы и безаргументные функторы, потому что у них не работает свойство по умолчанию. Такой вот кривой язык.)
* ручные твики автоматов сократили их размеры на 20%.

Изменения в интерфейсе:
* Свойство Root у clsParser заменено методом Evaluate. Из скриптов возникали большие проблемы с классами, имеющими несколько диспинтерфейсов (в определённых случаях приходит не тот, который нужно). Соответственно, метод Parse переименован в Go.
* У свежесозданного clsParser автоматически создаётся коллекция Symbols; опять же, ради использования из скриптов, где VBA.Collection напрямую не создать.

Примеры использования из VBS и JS прилагаются.
Вложения
eval.rar
(8.3 Кб) Скачиваний: 238
Изображение

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Сообщение Хакер » 02.11.2006 (Чт) 23:18

Эх, прекрасная вещь, вот только документации в том виде в котором она должна быть нет. :wink:

Надеюсь появится.

ЗЫ. Какая то массовая эпидемия создание Эвалютаторов.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 02.11.2006 (Чт) 23:28

Собственно, не нутро же документировать? а интерфейс я, сколько смог, описал.
Изображение


Вернуться в Кирпичный завод

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 12

    TopList