Вот я опять и появился. Теперь у меня задание еще более интересное. Смысл следующий: есть текстовый файл с исходником программы на Паскале, нужно- 1) первые буквы служебных слов сделать заглавными 2) текст комментариев заменить на их номер по порядку 3) переписать текст в новый файл с удалением лишних пробелов. Я понимаю, что тут может быть только один путь решения: создать массив (или множество) служебных слов, затем считывать текст файла посимвольно (т.к. служебные слова обязательно должны быть отделены от других пробелами или знаками препинания). Я прав? С комментариями попроще: просто найти символ '{' и проверить следующий после него, и если это не '$' то удалить все символы начиная с этого до символа '}'. Удаление пробелов еще проще. Но с первой частью задания у меня небольшие трудности. Решайте! :yes:
В следующий раз давайте более подходящий заголовок
volvo
6.04.2005 16:33
Цитата(Jaxx @ 6.04.05 11:26)
Но с первой частью задания у меня небольшие трудности. Решайте! :yes:
Посмотри вот эту мою программку... Программа форматирования Паскаль-программ Может, она натолкнет тебя на идею? ;) Кстати, я выкладывал на форум и программу удаления комментариев. Попробуй поискать и чуть-чуть подправить ее ...
Кстати, не все так просто:
Цитата
С комментариями попроще: просто найти символ '{' и проверить следующий после него, и если это не '$' то удалить все символы начиная с этого до символа '}'.
Есть еще комментарии вида "(* ... *)"
Jaxx
6.04.2005 16:44
Насчет (* *) я знаю. Тут смысл будет такой же, только символы другие. А тему я правильно назвал, ибо редактироваться будет текстовый файл, а не исходник. А что если первое задание поменять на немного другое: вывести на экран использованные в тексте служебные слова и для каждого из них вывести количество вхождений в текст.
volvo
6.04.2005 17:03
Цитата(Jaxx @ 6.04.05 11:44)
Насчет (* *) я знаю. Тут смысл будет такой же, только символы другие.
А ты в курсе, что есть Nested Comments, что усложняет работу? Ты бы попробовал, а потом посмотрим, просто это, или не очень...
Цитата(Jaxx @ 6.04.05 11:44)
А тему я правильно назвал, ибо редактироваться будет текстовый файл, а не исходник.
Но это не просто текстовый файл, а файл содержащий исходник паскаль-программы. Или тебе не важно, что твоя программа НЕ будет компилироваться после обработки? А если важно, то тема должна называться так, как она называется сейчас...
Цитата(Jaxx @ 6.04.05 11:44)
А что если первое задание поменять на немного другое: вывести на экран использованные в тексте служебные слова и для каждого из них вывести количество вхождений в текст.
Это катастрофически упрощает задачу, т.к. тебе не надо заменять слова в тексте, а достаточно просто запомнить их... А вот прежде чем запостить что-нибудь, надо решить, что ИМЕННО тебе нужно. Потому как если ты и далее будешь менять условия, то зачем надо начинать думать?
Jaxx
6.04.2005 17:23
Ладно, я все понял. Условие задачи остается начальное. У меня основная сложность заключается в поиске служебных слов. Я составил массив этих слов и массив разделителей (пробел, точка, точка с запятой и т.д.), но не знаю как в массив разделителей добавить знак конца строки и табуляции. Во-вторых, у меня вот какой вопрос (сразу говорю - тупой), файловую переменную какого типа нужно брать- Text? А вашу программку еще не смотрел - я на работе, а тут Паскаля нетути.
Altair
6.04.2005 18:38
Jaxx, привет! Почти год тебя не было! С возвращением! :thanks:
Цитата
файловую переменную какого типа нужно брать- Text?
Да в принципе любую, но с TEXT будет проще работать Так что ее.
Цитата
но не знаю как в массив разделителей добавить знак конца строки и табуляции.
Ну во-первых проще взять множетсво (и работать с ним проще будет в данном случае, и памяти меньше съест ) Во-вторых - зачем тебе знак конца строки? такого нету вообще
Что до задачи, то алгоритм можно такой выбрать - разбить текс на слова (алгоритм ф FAQ"e моджернизировать что бьы только слова зарезервированные - из списка брал). И делаешь по заданию.
Jaxx
6.04.2005 20:30
Привет и тебе, OlegZ !!! :thanks: У меня ни на что нет времени. Значит, переменная будет Text. Понял. Насчет конца строки тоже понял. А что с табуляцией? Как ее в массив (множество) записать?
Jaxx
7.04.2005 18:57
Я тут вот чего-то написал, правда нифига не работает. Гляньте, да поправьте, а то вроде с виду все должно работать (по крайней мере. идея симпатичная).
uses crt; const cycle:array[1..11] of string=('do','downto','else','for','if','in','repeat','then','to','until','while'); base:array[1..12] of string=('begin','else','end','function','goto','label','not','or','procedure','program','uses','var'); spec1:array[1..8] of string=('and','asm','constructor','destructor','external','forward','implementation','inline'); spec2:array[1..7] of string=('interface','interrupt','nil','object','shl','shr','packed'); types:array[1..9] of string=('array','case','const','file','record','set','string','type','unit'); math:array[1..6] of string=('div','mod','of','or','with','xor'); direct:array[1..6] of string=('absolute','assembler','far','near','private','virtual'); symbols:array[1..14] of char=('{','}','(',')','=',' ',';',':','+','-','/','*','.',','); var f,f_new:text; s,s1:string; i:byte; kol:byte; mas:array[1..59] of string; mas2:array[1..59] of byte; temp:array[1..59] of string;
procedure massiv(cycle,base,spec1,spec2,types,math,direct:array of string); var mas2:array [1..59] of byte; begin for i:=1 to 59 do temp[i]:=''; for i:=1 to 11 do mas[i]:=cycle[i]; for i:=11 to 23 do mas[i]:=base[i]; for i:=23 to 31 do mas[i]:=spec1[i]; for i:=31 to 38 do mas[i]:=spec2[i]; for i:=38 to 47 do mas[i]:=types[i]; for i:=47 to 53 do mas[i]:=math[i]; for i:=53 to 59 do mas[i]:=direct[i]; for i:=1 to 59 do mas2[i]:=kol; end;
begin clrscr; writeln('Vvedite imya faila: '); readln(s); assign(f,s); {$I-} reset(f); {$I+} if ioresult<>0 then writeln('Cannot open file to read!'); writeln('Vvedite imya novogo faila: '); readln(s1); assign(f_new,s1); {$I-} rewrite(f_new); {$I+} if ioresult<>0 then writeln('Cannot create file to input!'); massiv(cycle,base,spec1,spec2,types,math,direct); s:=''; s1:=''; i:=0; kol:=0; while not seekeof(f) do begin readln(f,s); massiv(cycle,base,spec1,spec2,types,math,direct); if s=symbols[i]+mas[i]+symbols[i] then begin mas2[i]:=kol+1; writeln('slovo' ,mas[i],' vstrechaetsia ',mas2[i],' raz'); end; end; readln; end.
Jaxx
12.04.2005 18:09
Ну так что, никто мне не поможет?! Скажите, в где у меня ошибка! Только не говорите, что в генах...Главная проблема - в поиске и определении служебных слов. Остальное - сам справлюсь (по крайней мере постараюсь).
volvo
12.04.2005 18:22
Jaxx, ты ходил по первой ссылке, которую я тебе дал? Там что, по-твоему служебные слова для красоты в массив собраны? Наверное не просто так, а все-таки там тоже ищутся вхождения служебных слов. Читается файл строка за строкой, каждая строка разбивается на токены, и проверяешь, является ли очередной токен служебным словом. Как - смотри в том исходнике...
А в твоей программе есть проблема:
const base:array[1..12] of string=('begin','else','end','function','goto','label','not', 'or','procedure','program','uses','var'); spec1:array[1..8] of string=('and','asm','constructor','destructor','external', 'forward','implementation','inline'); ... procedure massiv(cycle,base,spec1,spec2,types,math,direct:array of string); ... begin ... for i:=11 to 23 do mas[i]:=base[i]; { а что, в Base имеется элемент с индексом > 12 ??? } for i:=23 to 31 do mas[i]:=spec1[i]; { а в Spec1 - с индексом > 8 ??? } ... { и так далее... } end;
Altair
12.04.2005 18:54
А зачем разбивать на слова? вот еще способ без разбиения, прога во всех зарез. словах первую букуву делает большой.
var zar:array[1..51] of string[15];
function progwork(s:string):string; var i:integer; n:byte; begin for i:=1 to 51 do if pos(zar[i],s)<>0 then begin n:=pos(zar[i],s); s[n]:= upcase(s[n]); end; progwork:=s; end;
прога во всех зарез. словах первую букуву делает большой.
:no: "Во всех зарезервированных словах, записанных только маленькими буквами". А если "FUNCTION a: integer", то что будет с FUNCTION ?
P.S. Вроде типизированные константы еще не отменили ...
Jaxx
12.04.2005 20:27
Между прочим, OlegZ, твоя программа работает неправильно. Проверь сам. Ты пропустил проверку зарезервированных слов. То есть, после твоей проги из слова begin получается слово begIn и т.д. Нужно проверить, стоит ли слово отдельно, какие символы и знаки препинания стоят перед ним и после него. Точнее, после знаков препинания все работает замечательно, а вот если зарезервированное слово входит в состав другого слова -
volvo
12.04.2005 20:45
Цитата(Jaxx @ 12.04.05 16:27)
после знаков препинания все работает замечательно, а вот если зарезервированное слово входит в состав другого слова -
Oleg_Z, вот и ответ на твой вопрос:
Цитата(Olez_Z @ 12.04.05 14:54)
А зачем разбивать на слова?
Jaxx
12.04.2005 21:05
Вот в этом то и моя проблема. Как проверить, является ли слово действительно зарезервированным. Каким образом проверить символ, идущий перед этим словом и после него?
volvo
12.04.2005 21:30
Ты меня понимать не хочешь? Я же тебе привел ссылку на рабочий код, который корректно определяет зарезервированные слова, что еще нужно?
Что-то по-моему, тема становится переливанием из пустого в порожнее... Я решение предлагаю - следует вопрос, "а как же это реализовать?"... Я еще раз повторяю - опять "В этом моя проблема".
volvo
12.04.2005 22:30
Кстати, если функцию progwork, написанную Oleg_Z чуть-чуть подредактировать, то она будет работать гораздо более корректно:
function is_letter(ch: char): boolean; begin is_letter := ch in ['a'..'z', 'A'..'Z', '_']; end; function progwork(s:string):string; var i:integer; prev_n, n:byte; before, after: integer; begin for i:=1 to 51 do begin prev_n := 0; repeat
n := pos(zar[i], s); if prev_n = n then break; before := n - 1; after := n + length(zar[i]);
if n <> 0 then begin if ( (before >= 1) and is_letter(s[before]) ) or ( (after <= length(s)) and is_letter(s[after]) ) then else s[n]:= upcase(s[n]); end; prev_n := n
until n = 0; end;
progwork:=s; end;
Altair
13.04.2005 18:13
Ну раскритиковали Я шаблон для рассуждений дал такие элементы как BegIn легко устраняются путем изменения кода. (проверять на вхождениеодного словав другое). Так что разбивать на слова необязательно
Цитата
Во всех зарезервированных словах, записанных только маленькими буквами". А если "FUNCTION a: integer", то что будет с FUNCTION ?
Ну для этого добавить в программуфункцию:
Код
Function UpStr(S:String):String; {перевод строки в верхний регистр} Var I:Byte; Begin For I:=1 To ORD(S[0]) Do Begin Case S[I] Of 'a'..'z':S[I]:=Chr(Ord(S[I])-$20); 'а'..'п':S[I]:=Chr(Ord(S[I])-$20); 'р'..'я':S[I]:=Chr(Ord(S[I])-$50) End End; UpStr:=S End;
И вот эти строчки:
Код
for i:=1 to 51 do if pos(zar[i],s)<>0 then begin n:=pos(zar[i],s); s[n]:= upcase(s[n]);
Заменитиь на:
Код
for i:=1 to 51 do if pos(UpStr(zar[i]),ipstr(s))<>0 then begin n:=pos(Upstr(zar[i]),upstr(s)); s[n]:= upcase(s[n]);
Хотя возникает вопрос -если уже в большом регистре слово, зачем первую букву поднимать?
Jaxx
13.04.2005 20:02
А в моём варианте проги, кроме заполнения массива есть ещё какие-нибудь ошибки? Если да, то покажите... :p2:
volvo
13.04.2005 20:11
А ты проверь, работает она, или нет. Если работает, то нет ошибок. Или ты думаешь мы как-то по другому будем определять ее корректность?
Jaxx
13.04.2005 20:17
Цитата(volvo @ 13.04.05 16:11)
А ты проверь, работает она, или нет. Если работает, то нет ошибок. Или ты думаешь мы как-то по другому будем определять ее корректность?
Я и так знаю, что она не работает. И вообще. Меня на работе загрузили немного более серьезным языком программирования (RLL называется). Забот полон рот, как говорится. А тут ещё учёба со своим Паскалем. Ну не понимаю я его, и все!!! :fire:
Jaxx
15.04.2005 19:51
А почему не пашет такой вариант:
Код
Uses CRT; var znak:array[1..8] of string; slovo:array[1..51] of string[15]; kolvo:array[1..51] of byte; kol:byte; ch:char; i,n:integer; t:integer; s,s1:string; f:text; begin clrscr; write('Vvedite imya redaktiruemogo faila: '); readln(s); assign(f,s); reset(f); {$I-}if ioresult<>0 then begin write('Oshibka chteniya faila!'); halt(1); end; {$I+} s:=''; s1:=''; kol:=0; slovo[1]:='and';slovo[2]:='asm';slovo[3]:='array';slovo[4]:='begin';slovo[5]:='case'; slovo[6]:='const';slovo[7]:='constructor';slovo[8]:='destructor';slovo[9]:='div';slovo[10]:='do'; slovo[11]:='downto';slovo[12]:='else';slovo[13]:='end';slovo[14]:='exports';slovo[15]:='file'; slovo[16]:='for';slovo[17]:='function';slovo[18]:='goto';slovo[19]:='if';slovo[20]:='implementation'; slovo[21]:='in';slovo[22]:='inherited';slovo[23]:='inline';slovo[24]:='interface'; slovo[25]:='label';slovo[26]:='library';slovo[27]:='mod';slovo[28]:='nil';slovo[29]:='not'; slovo[30]:='object';slovo[31]:='of';slovo[32]:='or';slovo[33]:='packed';slovo[34]:='procedure'; slovo[35]:='program';slovo[36]:='record';slovo[37]:='repeat';slovo[38]:='set';slovo[39]:='shl'; slovo[40]:='shr';slovo[41]:='string';slovo[42]:='then';slovo[43]:='to';slovo[44]:='type';slovo[45]:='unit'; slovo[46]:='until';slovo[47]:='uses';slovo[48]:='var';slovo[49]:='while';slovo[50]:='with';slovo[51]:='xor'; i:=0; znak[1]:=' ';znak[2]:='.';znak[3]:=',';znak[4]:=';';znak[5]:=':'; znak[6]:='(';znak[7]:=')';znak[8]:='='; for i:=1 to 51 do kolvo[i]:=kol; while not seekeof(f) do begin readln(f,s); n:=length(s); t:=n-(n+1); if s=slovo[i] then begin if (s[t]=znak[i]) and (s[n+1]=znak[i]) then kolvo[i]:=kol+1; end; end; s1:=''; s:=''; for i:=1 to 51 do begin if kolvo[i]>0 then begin writeln('Slovo ',slovo[i],' vstrechaetsia ',kolvo[i],' raz'); end; end; readln; close(f); close(f1); end.
volvo
15.04.2005 20:59
Возьмем вот эти 2 цикла:
for i:=1 to 51 do kolvo[i]:=kol;
{ СТОП !!! Дальше можешь не ходить } { Значение i после выхода из цикла НЕ ОПРЕДЕЛЕНО }
while not seekeof(f) do begin readln(f,s); n:=length(s); t:=n-(n+1); if s=slovo[i] then begin if (s[t]=znak[i]) and (s[n+1]=znak[i]) then kolvo[i]:=kol+1; end; end; s1:=''; s:=''; for i:=1 to 51 do begin if kolvo[i]>0 then begin writeln('Slovo ',slovo[i],' vstrechaetsia ',kolvo[i],' raz'); end; end;
Может, в "немного более серьезном языке программирования (который RLL называется)" это и не так, но в Паскале ИМЕННО так... И никак иначе...
Jaxx
19.04.2005 18:36
А вот так:
uses crt; const znak:array[1..14] of byte=(9,10,13,32,40,41,44,46,47,58,59,92,123,125); var slovo:array[1..51] of string[15]; {mass:array[1..51] of string;} mask:array[1..51] of byte; txt:array[1..60000] of char; kol:byte; ns:byte; f1:text; f:file of char; simv:char; flag:boolean; j:byte; n:byte; dtxt:word; i:word; s,s1,temp:string; begin clrscr; write('Vvedite ymia ishodnogo faila: '); readln(s); assign(f,s); {$I-} reset(f); {$I+} if ioresult<>0 then begin writeln('file not found or read error!'); readkey; close(f); halt(1); end; i:=1; for i:=1 to 51 do mask[i]:=0; i:=1; slovo[1]:='and';slovo[2]:='asm';slovo[3]:='array';slovo[4]:='begin';slovo[5]:='case'; slovo[6]:='const';slovo[7]:='constructor';slovo[8]:='destructor';slovo[9]:='div';slovo[10]:='do'; slovo[11]:='downto';slovo[12]:='else';slovo[13]:='end';slovo[14]:='exports';slovo[15]:='file'; slovo[16]:='for';slovo[17]:='function';slovo[18]:='goto';slovo[19]:='if';slovo[20]:='implementation'; slovo[21]:='in';slovo[22]:='inherited';slovo[23]:='inline';slovo[24]:='interface';slovo[25]:='label'; slovo[26]:='library';slovo[27]:='mod';slovo[28]:='nil';slovo[29]:='not';slovo[30]:='object'; slovo[31]:='of';slovo[32]:='or';slovo[33]:='packed';slovo[34]:='procedure';slovo[35]:='program'; slovo[36]:='record';slovo[37]:='repeat';slovo[38]:='set';slovo[39]:='shl';slovo[40]:='shr'; slovo[41]:='string';slovo[42]:='then';slovo[43]:='to';slovo[44]:='type';slovo[45]:='unit'; slovo[46]:='until';slovo[47]:='uses';slovo[48]:='var';slovo[49]:='while';slovo[50]:='with';slovo[51]:='xor'; write('Vvedite imia novogo faila: '); readln(s1); assign(f1,s1); {$I-} rewrite(f1); {$I+} if ioresult<>0 then begin writeln('error writing file!'); readkey; close(f1); halt(1); end; s:=''; s1:=''; temp:=''; kol:=0; n:=0; while not eof(f) do begin read(f,simv); inc(dtxt); ns:=ord(simv); txt[dtxt]:=chr(ns); for i:=1 to dtxt do begin ns:=ord(txt[i]); flag:=true; for j:=1 to 14 do begin if ns=znak[j] then flag:=false; if flag then s:=s+txt[i]; for n:=1 to 51 do begin if s=slovo[n] then begin mask[n]:=kol+1; i:=1; for i:=1 to 51 do begin n:=i; if mask[n]>0 then begin write('Slovo : ' ,slovo[n]); writeln('vstrechaetsia : ',mask[n],' raz'); s1:=slovo[n]; writeln(f1,s1); end; end; end;end;end;end;end; {<== ЗДЕСЬ ПРОГРАММА ОСТАНАВЛИВАЕТСЯ НАМЕРТВО, ВЫХОЖУ ctrl+break} readln; close(f); close(f1); end.
volvo
19.04.2005 18:57
А здесь - я прогнал пошагово... Посмотри внимательно, что происходит вот тут:
... for j:=1 to 14 do begin if ns=znak[j] then flag:=false; if flag then s:=s+txt[i]; { <-- следующий символ из файла НЕ читается... } ...
Я взял файл с первым словом 'const', но после 5-ой итерации получил в строке s значение "ссссс", т.е. просто дублирование первого символа. Это будет продолжаться бесконечно... Да и вложенных циклов достаточно много - даже если исправишь этот недочет, программа будет медленно работать...
А чего ты не хочешь воспользоваться функцией, которую я приводил в посте №17 (немного переделанная функция Oleg_Z)? Я ее вроде погонял, сбоев не нашел... Нормально работает...
Jaxx
19.04.2005 19:54
Цитата(volvo @ 19.04.05 14:57)
А чего ты не хочешь воспользоваться функцией, которую я приводил в посте №17 (немного переделанная функция Oleg_Z)? Я ее вроде погонял, сбоев не нашел... Нормально работает...
Да я бы взял, но хочется понять, где я допускаю ошибки, чоб знать на будущее. Ошибки-то глупейшие! А из-за них курсач стоит на месте...
Romtek
20.04.2005 1:09
Не сочтите за оффтоп, но есть готовые программы форматирования исходников Паскаля, одна их них - PTOP - Free Pascal source formatter - входит в дистриб компилятора FreePascal, её описание здесь: http://www.freepascal.org/tools/ptop.html
Цитата
ptop is a configurable source formatter. It pretty-prints your pascal code, much like indent does for C code.
Кстати, и исходники её доступны...
Jaxx
20.04.2005 17:50
Цитата(Romtek @ 19.04.05 21:09)
Не сочтите за оффтоп, но есть готовые программы форматирования исходников Паскаля, одна их них - PTOP - Free Pascal source formatter - входит в дистриб компилятора FreePascal, её описание здесь: http://www.freepascal.org/tools/ptop.html Кстати, и исходники её доступны...
Вот только с примерами всего-то 40 Мб :p2:
Romtek
20.04.2005 20:30
Вот исходник и ЕХЕ вместе.
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.