|
Обратная польская запись, преобразование не туда, а обратно |
|
|
|
May 30 2014, 06:00
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(XVR @ May 30 2014, 10:20)  Я вам уже дал совет - сделать дерево, а не ОПЗ. Чем он вас не устраивает я делаю интерпретатор собственного байт-кода. ОПЗ позволяет получить строго линейный байт-код, т.е. извлекаю байт за байтом и исполняю, не нужно передвигать указатели, помнить предыдущие состояния и т.п., как для дерева. получение ОПЗ из нативной формулы достаточно простое, я его уже реализовал. чем лучше дерево для интерпретации - не понимаю. возможно, был бы смысл в нем для интерпретации не формул, а именно языка более высокого уровня, с ветвлениями, подпрограммами, циклами и т.п., но даже и в этом не уверен. остается небольшое дело: показать байт-код в виде понятного человеку выражения. на сегодня эта проблема уже решена мною примерно на 90%, на Си, без динамического распределения памяти (на статическом массиве байтов). пока что немного вызывает проблему унарные и тренарные операторы - в упомянутый ранее алгоритм эти операторы вписываются плоховато... спасибо за внимание.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
May 30 2014, 06:48
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(ARV @ May 30 2014, 14:10)  я делаю интерпретатор собственного байт-кода. ОПЗ позволяет получить строго линейный байт-код, т.е. извлекаю байт за байтом и исполняю, не нужно передвигать указатели, помнить предыдущие состояния и т.п., как для дерева. получение ОПЗ из нативной формулы достаточно простое, я его уже реализовал. чем лучше дерево для интерпретации - не понимаю. Дерево может быть представлено в виде префиксной записи (ОПЗ - это постфиксная запись). Т.е. в том же линейном виде, без каких либо указателей и предыдущих состояний. Для вычисления (и печати) дерева применяется рекурсивная функция, т.е. если ваш 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(")"); }
|
|
|
|
|
May 31 2014, 17:45
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Цитата(ARV @ May 28 2014, 12:27)  храню и исполняю я в польской, но ведь пользователю надо иной раз показать, что именно там харнится и исполняется? и показать надо в том виде, как он вводил. Имхо, "как он вводил" - не надо. А перевести это в нормальную инфиксную запись и показать - можно. Посмотрите вот здесь, как альфа преобразует введенный бред в строке поле "инпут".
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|