Вопрос по Pascal

bes

Пользователь
Пользователь
10 Фев 2005
217
0
0
36
ул. Бакинская
У меня тут задачка небольшая. Чё-то никак алгоритм не могу придумать...
Задача такая:
Задан текстовый файл с текстом программы(на Pascal).
Нужно подсчитать количество необъявленных переменных,
используемых в программе(не используя массивы).

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

Badger

Пользователь
Пользователь
16 Фев 2005
178
0
0
Прикольная задачка...
Это надо научить программу определять секцию объявления переменных, чтобы константы и типы не вмешивались в дело.
Ну, а как не переставляя строк в исходном файле и не используя массивы запомнить, какую переменную уже проверил, а какую нет - ума не приложу...
 

bes

Пользователь
Пользователь
10 Фев 2005
217
0
0
36
ул. Бакинская
Ну допустим для запоминания всё-таки используем массивы.
С этим разберёмся потом, но и в этом случае ни черта не ясно.
Если б можно было бы как-нть отметить строку с var, чтобы затем
к ней легко вернуться... Метки вроде как не желательно использовать...
 
D

DeTkA

Гость
Фи...я в Паскале решала примеры, но никак не задачки=/

ЗЫ Думаю здесь ты помощи не найдёшь)))
 

nit0shi

Воин дзена
Динозавры
Пользователь
10 Фев 2005
642
0
0
Хороший женский ответ!:smile: Здесь ответ ты вполне можешь найти, но я в паске не силён...
 

Badger

Пользователь
Пользователь
16 Фев 2005
178
0
0
bes сказал(а):
Ну допустим для запоминания всё-таки используем массивы.
С этим разберёмся потом, но и в этом случае ни черта не ясно.
Если б можно было бы как-нть отметить строку с var, чтобы затем
к ней легко вернуться... Метки вроде как не желательно использовать...
Нет, ну строку с var помечать и ненадо. Читаешь в массив идентификаторы из секции var, а потом при разборе самого текста файла(то есть строки анализируемого кода) надо просмотреть, встречается ли идентификатор из данной строки в массиве объявленных переменных. Если не встречается, то можно либо на экран выводить сообщения, либо предусмотреть еще какую-нибудь проверку, чтобы одна и таже переменная, которую забыли объявить, встретившись в коде второй, третий... энный раз не выводила одно и тоже сообщение.
С массивами уже есть простор для действий...
 

bes

Пользователь
Пользователь
10 Фев 2005
217
0
0
36
ул. Бакинская
Насчёт массивов я к счастью ошибся! Здесь их использовать можно.
Тока вот не совсем ясно, как считать переменные из секции var в массив?
 

Badger

Пользователь
Пользователь
16 Фев 2005
178
0
0
bes сказал(а):
Насчёт массивов я к счастью ошибся! Здесь их использовать можно.
Тока вот не совсем ясно, как считать переменные из секции var в массив?
Ну, тогда все отлично.
У меня нет возможности щас отладить все, буду писать код прямо сюда, там уже, думаю сам разберешься.

Предполагаем, что секция var записана синтаксически правильно и оформлена примерно так:
Код:
  .... какие-нибудь определения .....

var
  i:integer;
  m:float;
  s:string;

  ..... еще определения или тело программы .....
Признаком начала секции считаем строку содержащую слово var.
Признаком конца секции считаем строку заканчивающуюся не символом ";". Если встрчеается такой признак, то значит открывается либо другая секция объявлений (напр. type или const), либо тело начинается тело самой программы (begin).
Ограничения, которые влом сейчас обходить:
- нет обработки комментариев;
- нет проверки синтаксической правильности текста обследуемой программы;
- если записать все в одну строку в паскале, то он скомпилирует, а мне не очень охота щас вспоминать, как читать в буфер из файла.. поэтому каждая переменная должна объявляться в отдельной строчке, ну и директивы типа const, type, begin и т.д. тоже записываются каждая с новой строки.
- раз уж говорим о паскале, то для учебного примера ограничимся сотней идентификаторов, если есть желание, почитай книжки и узнай, как в паскале динамические массивы использовать.

Код:
Program p1;
var
  vars:array [1..100] of string;
  buf:string;
  i:integer;

function ReadStr(f:text):string;
//возвращает следующую найденную непустую строку
var
  buf:string;
begin
  repeat
	readln(f, buf);
	buf:=trim(buf)
  until (buf<>'') or (eof(f));
  result:=lowercase(buf);
end;

begin
  //открыть для чтения файл f
  write('Введите путь к обрабатываемому файлу:');
  readln(buf);
  assign(f,buf);
  reset(f);
  //найти строку со словом var
  while (not eof(f)) and (ReadStr(f)<>'var') do;
  if eof(f) then begin
	writeln('Текст не содержит объявленных переменных.');
	exit
  end else begin
	//выбрать идентификаторы переменных
	i:=1;
	repeat
	  buf:=ReadStr(f);
	  if pos(';',buf)>0 then begin
		//не конец секции var
		vars[i]:=trim(copy(buf,1,pos(':',buf)-1));
		inc(i);
	  end
	until (i>100) or (eof(f)) or (pos(';',buf)=0);
  end;
  //.......... дальше ............
  // 1)найти тело программы
  // 2)проверить есть ли в массиве vars переменные
  // найденные в тексте программы
  // 3) вывести результаты
  close(f);
end.