![]() |
1. Заголовок темы должен быть информативным. В противном случае тема удаляется ...
2. Все тексты программ должны помещаться в теги [code=pas] ... [/code].
3. Прежде чем задавать вопрос, см. "FAQ", если там не нашли ответа, воспользуйтесь ПОИСКОМ, возможно такую задачу уже решали!
4. Не предлагайте свои решения на других языках, кроме Паскаля (исключение - только с согласия модератора).
5. НЕ используйте форум для личного общения, все что не относится к обсуждению темы - на PM!
6. Одна тема - один вопрос (задача)
7. Проверяйте программы перед тем, как разместить их на форуме!!!
8. Спрашивайте и отвечайте четко и по существу!!!
![]() |
chessman |
![]()
Сообщение
#1
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Нужна прога на паскале-"Интерпретатор".
Может у кого -нибудь уже есть такая прога. Или помогите советом. |
![]() ![]() |
volvo |
![]()
Сообщение
#2
|
Гость ![]() |
Интерпретатор чего имеется в виду? Чего интерпретировать должен?
Вот тут есть кое-что: Разбор и анализ строк |
Atos |
![]()
Сообщение
#3
|
![]() Прогрессор ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: ![]() ![]() ![]() |
Поищи поиском по форуму, может быть здесь уже были похожие темы.
Посмотри вот эти исходники в прикреплённом файле(не гарантирую, что рабочие) Прикрепленные файлы ![]() |
chessman |
![]()
Сообщение
#4
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата(volvo @ 12.04.05 20:41) Интерпретатор чего имеется в виду? Чего интерпретировать должен? Вот тут есть кое-что: Разбор и анализ строк Огромное спасибо! Я там нашел многое что мне нужно.Я в паскале новичок ,так что если будут проблемы с пониманием кода надеюсь вы мне поможите ![]() |
Atos |
![]()
Сообщение
#5
|
![]() Прогрессор ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: ![]() ![]() ![]() |
Если хочешь почитать теорию компиляторов, то завтра выложу одну книжку
Вот ещё статья из DRKB (правда о Object Pascal) З. Ы. И volvo опять меня опередил с ответом :p4: ![]() Сообщение отредактировано: Atos - 12.04.2005 17:08 Прикрепленные файлы ![]() |
Atos |
![]()
Сообщение
#6
|
![]() Прогрессор ![]() ![]() ![]() ![]() Группа: Модераторы Сообщений: 602 Пол: Мужской Реальное имя: Михаил Репутация: ![]() ![]() ![]() |
См. присодинённые файлы. Первые две книжки по теории грамматик и компиляторов, третья - "Программирование для математиков" Кушниренко и Лебедева, классная книжка, на мой взгляд, дожна быть одной из настольных книг начинающего программиста, там тоже можно найти параграф про компиляторы.(Правда она тут только в текстовом формате, без рисунков
![]() Прикрепленные файлы ![]() ![]() ![]() |
chessman |
![]()
Сообщение
#7
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата(Atos @ 13.04.05 8:40) См. присодинённые файлы. Первые две книжки по теории грамматик и компиляторов, третья - "Программирование для математиков" Кушниренко и Лебедева, классная книжка, на мой взгляд, дожна быть одной из настольных книг начинающего программиста, там тоже можно найти параграф про компиляторы.(Правда она тут только в текстовом формате, без рисунков ![]() Спасибо,но не могли бы выложить в .zip, с .rar проблемы... |
volvo |
![]()
Сообщение
#8
|
Гость ![]() |
chessman, скажи куда переслать (можно в приват ;) ), я вышлю... Сюда-то их зачем выкладывать? Они же в ZIP-е в 1.5 раза больше по размеру получатся (только softcraft займет 951К вместо 671К)
Общий размер в ZIP-е: 1.94Мб |
chessman |
![]()
Сообщение
#9
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Цитата(volvo @ 12.04.05 20:41) Вот тут есть кое-что: Разбор и анализ строк К сожалению там все проги написаны очень сложно для меня. Мне нужно сделать прогу-калькулятор: читает из файла текст,интерпретирует его и считает результат.Может кто-нибудь поможет сделать часть процедур. ![]() В принцепе они должны быть подобными... |
volvo |
![]()
Сообщение
#10
|
Гость ![]() |
Цитата(chessman @ 3.05.05 14:29) К сожалению там все проги написаны очень сложно для меня. В чем именно заключается сложность понимания тех программ? Цитата(chessman @ 3.05.05 14:29) Мне нужно сделать прогу-калькулятор: читает из файла текст,интерпретирует его и считает результат. Ну, извините, это в две строчки и не уложишь, для написания такой программы необходимо хорошо знать динамические структуры данных (в частности - стеки и списки), по другому анализатор выражений просто не напишешь... И какая разница, будем писать мы или взять то, что уже написано. Принцип-то один...Поэтому лучше выяснить непонятные места в программах, чем писать заново и получить то же самое (зато изобрести велосипед самому)... |
chessman |
![]()
Сообщение
#11
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
{
Ђ «Ё§ (r)а/Є «мЄг«п(r)а бва(r)ЄЁ :-)
‹ аоиЄЁ ћаЁ(c). 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 - 4.11.2010 15:10 |
volvo |
![]()
Сообщение
#12
|
Гость ![]() |
К сожалению, у меня эта программа вылетает с переполнением стека...
|
chessman |
![]()
Сообщение
#13
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Может быть тогда посоветуете какую из предложенных прог мне лучше взять?
|
volvo |
![]()
Сообщение
#14
|
Гость ![]() |
Цитата(volvo @ 3.05.05 17:26) К сожалению, у меня эта программа вылетает с переполнением стека... :no: Просто эта программа очень активно использует стек, рекурсии и т.д., так что размера стека по умолчанию ей не хватает. Первой строкой программы ставим директиву распределения памяти:{$M 32767, 0, 0}
и все работает... |
chessman |
![]()
Сообщение
#15
|
Новичок ![]() Группа: Пользователи Сообщений: 10 Пол: Мужской Репутация: ![]() ![]() ![]() |
Если эта программа работает,то можно к ней комментарии?
|
volvo |
![]()
Сообщение
#16
|
Гость ![]() |
Общие комментарии добавлены. Для более детального объяснения алгоритма работы программы - обращайтесь к автору...
|
volvo |
![]()
Сообщение
#17
|
Гость ![]() |
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... ![]() |
Antonio |
![]()
Сообщение
#18
|
Группа: Пользователи Сообщений: 5 Пол: Мужской Репутация: ![]() ![]() ![]() |
Обьясните пожалуйста программу
|
volvo |
![]()
Сообщение
#19
|
Гость ![]() |
To: Antonio
Что именно в программе не понятно? Я уже добавлял основные комментарии ... |
Antonio |
![]() ![]()
Сообщение
#20
|
Группа: Пользователи Сообщений: 5 Пол: Мужской Репутация: ![]() ![]() ![]() |
После компиляции ничего не происходит!!!
Зачем пример внутри кода??? |
![]() ![]() |
![]() |
Текстовая версия | 27.07.2025 22:57 |