Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум «Всё о Паскале» _ Задачи _ Интерпретатор

Автор: chessman 12.04.2005 20:32

Нужна прога на паскале-"Интерпретатор".
Может у кого -нибудь уже есть такая прога.
Или помогите советом.

Автор: volvo 12.04.2005 20:41

Интерпретатор чего имеется в виду? Чего интерпретировать должен?
Вот тут есть кое-что: http://pascal.sources.ru/parsing/index.htm

Автор: Atos 12.04.2005 21:02

Поищи поиском по форуму, может быть здесь уже были похожие темы.

Посмотри вот эти исходники в прикреплённом файле(не гарантирую, что рабочие)


Прикрепленные файлы
Прикрепленный файл  Arifm.rar ( 21.7 килобайт ) Кол-во скачиваний: 440

Автор: chessman 12.04.2005 21:04

Цитата(volvo @ 12.04.05 20:41)
Интерпретатор чего имеется в виду? Чего интерпретировать должен?
Вот тут есть кое-что: http://pascal.sources.ru/parsing/index.htm

Огромное спасибо! Я там нашел многое что мне нужно.Я в паскале новичок ,так что если будут проблемы с пониманием кода надеюсь вы мне поможитеsmile.gif

Автор: Atos 12.04.2005 21:06

Если хочешь почитать теорию компиляторов, то завтра выложу одну книжку
Вот ещё статья из DRKB (правда о Object Pascal)


З. Ы. И volvo опять меня опередил с ответом :p4: smile.gif


Прикрепленные файлы
Прикрепленный файл  Faq.rar ( 3.03 килобайт ) Кол-во скачиваний: 315

Автор: Atos 13.04.2005 8:40

См. присодинённые файлы. Первые две книжки по теории грамматик и компиляторов, третья - "Программирование для математиков" Кушниренко и Лебедева, классная книжка, на мой взгляд, дожна быть одной из настольных книг начинающего программиста, там тоже можно найти параграф про компиляторы.(Правда она тут только в текстовом формате, без рисунков sad.gif )


Прикрепленные файлы
Прикрепленный файл  softcraft.rar.rar ( 671 килобайт ) Кол-во скачиваний: 400
Прикрепленный файл  _______________________________.rar ( 792.15 килобайт ) Кол-во скачиваний: 429
Прикрепленный файл  kushnirenko_a_001.rar ( 172.5 килобайт ) Кол-во скачиваний: 797

Автор: chessman 13.04.2005 14:51

Цитата(Atos @ 13.04.05 8:40)
См. присодинённые файлы. Первые две книжки по теории грамматик и компиляторов, третья - "Программирование для математиков" Кушниренко и Лебедева, классная книжка, на мой взгляд, дожна быть одной из настольных книг начинающего программиста, там тоже можно найти параграф про компиляторы.(Правда она тут только в текстовом формате, без рисунков sad.gif )


Спасибо,но не могли бы выложить в .zip, с .rar проблемы...

Автор: volvo 13.04.2005 14:58

chessman, скажи куда переслать (можно в приват ;) ), я вышлю... Сюда-то их зачем выкладывать? Они же в ZIP-е в 1.5 раза больше по размеру получатся (только softcraft займет 951К вместо 671К)

Общий размер в ZIP-е: 1.94Мб

Автор: chessman 3.05.2005 18:29

Цитата(volvo @ 12.04.05 20:41)
Вот тут есть кое-что: http://pascal.sources.ru/parsing/index.htm


К сожалению там все проги написаны очень сложно для меня. Мне нужно сделать прогу-калькулятор: читает из файла текст,интерпретирует его и считает результат.Может кто-нибудь поможет сделать часть процедур.smile.gif
В принцепе они должны быть подобными...

Автор: volvo 3.05.2005 18:50

Цитата(chessman @ 3.05.05 14:29)
К сожалению там все проги написаны очень сложно для меня.
В чем именно заключается сложность понимания тех программ?

Цитата(chessman @ 3.05.05 14:29)
Мне нужно сделать прогу-калькулятор: читает из файла текст,интерпретирует его и считает результат.
Ну, извините, это в две строчки и не уложишь, для написания такой программы необходимо хорошо знать динамические структуры данных (в частности - стеки и списки), по другому анализатор выражений просто не напишешь... И какая разница, будем писать мы или взять то, что уже написано. Принцип-то один...

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

Автор: chessman 3.05.2005 20:46


{
Ђ­ «Ё§ в®а/Є «мЄг«пв®а бва®ЄЁ :-)
 ‹ аоиЄЁ­ ћаЁ©. 2:5059/9.58
}
uses crt;
const fn=['a'..'z'];
     fn2=['*','/','+','_'];
     ch=['0'..'9','.','-'];

var s:string;

{ преобразует число в строковое представление
  с точностью 10 знаков }
function stt(e:extended):string;
var s:string;
begin
str(e:0:10,s);
stt:=s;
end;

{ обратное преобразование - преобразует строку
  в число типа extended }
function stt_(s:string):extended;
var q,w:extended;
i,j:integer;
begin
if pos ('.',s) = 0 then val (s,q,i) else
begin
if s[1]='-' then j:=-1 else j:=1;
val (copy(s,1,pos('.',s)-1),q,i);
val (copy(s,pos ('.',s)+1,byte(s[0])),w,i);
while w>1 do w:=w/10;
q:=j*(abs(q)+w);
end;
stt_:=q;
end;

{ в эту функцию передается простое выражение,
  НЕ содержащее скобок }
function clc (s:string):string;
var i,j,k,l:integer;
e:extended;

{ эта функция заменяет в простом выражении строковое
  представление одной операции (ее обозначение
  передается в строке C) на результат этой операции }
procedure clc_(c:string);
begin
while pos(c,s)<>0 do begin
i:=pos(c,s);k:=i; dec (i);
while (s[i] in ch) and (i>=1) do dec (i);
j:=k; inc (j);
while (s[j] in ch) and (j<=byte(s[0])) do inc (j);
case c[1] of
'+': s:=copy(s,1,i)+stt(stt_(copy (s,i+1,k-i-1))+stt_(copy(s,k+1,j-k-1)))+copy(s,j,byte(s[0]));
'_': s:=copy(s,1,i)+stt(stt_(copy (s,i+1,k-i-1))-stt_(copy(s,k+1,j-k-1)))+copy(s,j,byte(s[0]));
'*': s:=copy(s,1,i)+stt(stt_(copy (s,i+1,k-i-1))*stt_(copy(s,k+1,j-k-1)))+copy(s,j,byte(s[0]));
'/': s:=copy(s,1,i)+stt(stt_(copy (s,i+1,k-i-1))/stt_(copy(s,k+1,j-k-1)))+copy(s,j,byte(s[0]));
end;
s:=clc(s);
end;

end;

{ сама же функция проверяет, есть ли вхождения
  простых арифметических операций (* / + -), и заставляет
  вложенную ф-ю clc_ вычислять результаты операций
  согласно приоритету }
begin
if (pos('*',s)=0) and (pos('/',s)=0) and
(pos('+',s)=0) and (pos('_',s)=0) then clc:=s else begin
clc_('*'); clc_('/'); clc_('_'); clc_('+');
end;clc:=s;
end;

{ это - сердце программы. Эта ф-я ищет в строке с выражением
  обращение к функциям (sin, cos, ...), и выполняет эти функции.
  результат выполнения заносится в ту же строку вместо полного
  написания ф-ии }
function calc(s:string):string;
var i,j,k,l:integer;
s_,ss:string;
begin
for i:=1 to byte (s[0]) do begin
if (s[i]='-') and (s[i-1] in ch) then s[i]:='_';
if (s[i]='-') and (s[i-1] ='+') then s[i]:='_';
end;
calc:=s;
l:=byte (s[0]); i:=l;
if pos ('(',s)<>0 then begin
while (s[i]<>'(') and (i>1) do dec (i);
j:=i;
while (s[i]<>')') and (i<l) do inc (i);
if not(s[j-1] in fn) then begin
s:=copy (s,1,j-1)+(calc(copy(s,j+1,(i-j-1))))+copy (s,i+1,l);
s:=calc(s)
end else begin
s_:=calc(copy(s,j+1,(i-j-1)));
k:=j-1;
while (s[k] in fn) and (k>1) do dec (k);
ss:=copy (s,k+1,j-k-1);
randomize;

{ здесь в строке ss хранится название ф-ии которую необходимо выполнить,
  а в строке s_ - строковое представление аргумента.
  таким образом, имя ф-ии с агрументом просто "вырезается" из строки и
  заменяется результатом }

if ss='sin' then s:=copy (s,1,k)+stt(sin (stt_(s_)))+copy (s,i+1,l);
if ss='cos' then s:=copy (s,1,k)+stt(cos (stt_(s_)))+copy (s,i+1,l);
if ss='tg' then s:=copy (s,1,k)+stt(sin (stt_(s_))/cos (stt_(s_)))+copy (s,i+1,l);
if ss='atctg' then s:=copy (s,1,k)+stt(arctan (stt_(s_)))+copy (s,i+1,l);
if ss='ln' then s:=copy (s,1,k)+stt(ln (stt_(s_)))+copy (s,i+1,l);
if ss='abs' then s:=copy (s,1,k)+stt(abs (stt_(s_)))+copy (s,i+1,l);
if ss='rnd' then s:=copy (s,1,k)+stt(random (round(stt_(s_))))+copy (s,i+1,l);
if ss='exp' then s:=copy (s,1,k)+stt(exp (stt_(s_)))+copy (s,i+1,l);
s:=calc(s);
end; end;
calc:=clc(s);
end;

begin
clrscr;
s:='(34+((-45+56)*abs((54+6+sin(5)*10+46-38)*2)/46))/cos(111)';
writeln (s,'=',calc(s));
writeln(((34+((-45+56)*abs((54+6+sin(5)*10+46-38)*2)/46))/cos(111)):0:10);
end.

Вот собственно програмка,более-менее мне понятная.
Можно объяснить что делает каждая функция?Вообщем хотелось бы комментарии к проге.

Автор: volvo 3.05.2005 21:26

К сожалению, у меня эта программа вылетает с переполнением стека...

Автор: chessman 3.05.2005 21:32

Может быть тогда посоветуете какую из предложенных прог мне лучше взять?

Автор: volvo 4.05.2005 0:53

Цитата(volvo @ 3.05.05 17:26)
К сожалению, у меня эта программа вылетает с переполнением стека...
:no: Просто эта программа очень активно использует стек, рекурсии и т.д., так что размера стека по умолчанию ей не хватает. Первой строкой программы ставим директиву распределения памяти:
{$M 32767, 0, 0}
и все работает...

Автор: chessman 4.05.2005 12:05

Если эта программа работает,то можно к ней комментарии?

Автор: volvo 4.05.2005 13:53

Общие комментарии добавлены. Для более детального объяснения алгоритма работы программы - обращайтесь к автору...

Автор: volvo 4.05.2005 16:33

chessman, кстати эту программу можно немного упростить для понимания, если использовать процедурные типы. Ну, например, вот так:
вместо того, чтобы явно перечислять все функции (и их параметры), как сделано здесь

if ss='sin' then s:=copy (s,1,k)+stt(sin (stt_(s_)))+copy (s,i+1,l);
if ss='cos' then s:=copy (s,1,k)+stt(cos (stt_(s_)))+copy (s,i+1,l);
if ss='tg' then s:=copy (s,1,k)+stt(sin (stt_(s_))/cos (stt_(s_)))+copy (s,i+1,l);
if ss='atctg' then s:=copy (s,1,k)+stt(arctan (stt_(s_)))+copy (s,i+1,l);
if ss='ln' then s:=copy (s,1,k)+stt(ln (stt_(s_)))+copy (s,i+1,l);
if ss='abs' then s:=copy (s,1,k)+stt(abs (stt_(s_)))+copy (s,i+1,l);
if ss='rnd' then s:=copy (s,1,k)+stt(random (round(stt_(s_))))+copy (s,i+1,l);
if ss='exp' then s:=copy (s,1,k)+stt(exp (stt_(s_)))+copy (s,i+1,l);

будет лучше предварительно определить нужные функции и...
type
f_type = function(e: extended): extended;
const
size_func = 8;
cf: array[1 .. size_func] of record
name: string;
func: f_type;
end = (
(name: 'sin'; func: f_sin),
(name: 'cos'; func: f_cos),
(name: 'tg'; func: f_tg),
(name:'atctg'; func:f_atan),
(name: 'ln'; func: f_ln),
(name: 'abs'; func: f_abs),
(name: 'rnd'; func: f_rnd),
(name: 'exp'; func: f_exp)
);
...
{ внутри CALC делать так: }
for ii := 1 to size_func do
if ss = cf[ii].name then
s := copy (s,1,k)+stt(cf[ii].func(stt_(s_)))+copy (s,i+1,l);

Теперь в случае добавления новых функций не нужно будет менять сам CALC, достаточно добавить имя и указатель на функцию в массив CF и увеличить SIZE_FUNC... smile.gif

Автор: Antonio 20.11.2005 14:50

Обьясните пожалуйста программу

Автор: volvo 20.11.2005 14:52

To: Antonio
Что именно в программе не понятно? Я уже добавлял основные комментарии ...

Автор: Antonio 20.11.2005 19:35

После компиляции ничего не происходит!!!
Зачем пример внутри кода???

Автор: volvo 20.11.2005 19:38

To: Antonio
Хотелось бы напомнить, после компиляции ничего и не должно происходить... Запускать не пробовал? А пост №14 внимательно читал?

Автор: Antonio 20.11.2005 19:46

Обьясните, как вводить новые выражения и получить ответ выражения

Автор: volvo 20.11.2005 20:25

blink.gif вообще-то так обычно делается...

...
readln(s);
writeln(s, '=', calc(s));
...