Перейти к содержанию
    

Обратная польская запись

я делаю интерпретатор собственного байт-кода. ОПЗ позволяет получить строго линейный байт-код, т.е. извлекаю байт за байтом и исполняю, не нужно передвигать указатели, помнить предыдущие состояния и т.п., как для дерева. получение ОПЗ из нативной формулы достаточно простое, я его уже реализовал. чем лучше дерево для интерпретации - не понимаю.

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

 

Выглядит это приблизительно так (пример):

Исходная формула: (10+20)*30

ОПЗ: 10 20 + 30 *

Префиксная форма: * (+) 10 20 30 (Скобки вокруг операции показывают наличие скобок, используется только для вывода, кодируется старшим битом)

 

Процедура вычисления (кусочек):

char* position;
int eval()
{
int arg1, arg2;
switch(*position++ & 0x7F)
  {
    case '+': arg1=eval(); arg2=eval(); return arg1+arg2;
    case '*': arg1=eval(); arg2=eval(); return arg1*arg2;
    case 'I': /* constant */ arg1=*(int*)position; position+=sizeof(int); return arg1;
...
  }
}

 

Процедура печати (тоже кусочек)

char* position;
void print()
{
char cmd=*position++;
int arg1;

if (cmd&0x80) printf("(");
switch(cmd & 0x7F)
  {
    case '+': print(); printf("+"); print(); break;
    case '*': print(); printf("*"); print(); break;
    case 'I': /* constant */ arg1=*(int*)position; position+=sizeof(int); printf("%d",arg1); break;
...
  }
if (cmd&0x80) printf(")");
}

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хоть убейте, не понимаю, чем лучше префиксная запись. если в байт-код писать признак скобок для будущей "печати", то совершенно без разницы, что пре-, что пост-

вот на счет бита скобок - это хорошая идея, сразу бы ее подкинули - может, я б давно все сделал :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Посмотрите еще раз в мой код - там никаких буферов нет (ни динамических ни статических) :)

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

храню и исполняю я в польской, но ведь пользователю надо иной раз показать, что именно там харнится и исполняется? и показать надо в том виде, как он вводил.

Имхо, "как он вводил" - не надо. А перевести это в нормальную инфиксную запись и показать - можно. Посмотрите вот здесь, как альфа преобразует введенный бред в строке поле "инпут".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если хранить две записи - одну для пользователя, другую, уже преобразованную - для вычислений.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...