С Новым годом! Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
4 / 4 / 3
Регистрация: 29.10.2015
Сообщений: 39
1

Используя стек, проверить правильность вложений операторных скобок (begin/end)

25.01.2016, 19:27. Показов 1930. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
В файле находится текст программы на pascal. используя стек проверить правильность вложений операторных скобок (begin/end) в этой программе. В полноэкранке.

Вот нашёл код, но как я понял здесь идет проверка на ()
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
type stack = record
      data : array [0..100000] of char;
      size : longint;
end;
 
var
   Myst : stack;
   i : longint;
   fin, fout : text;
   tmp : char;
   line, row : longint;
   Flag : boolean;
 
procedure push(ch : char; var st : stack);
begin
 inc(st.size);
 st.data[st.size] := ch;
end;
 
function isempty(st : stack) : boolean;
begin
 if (st.size = 0) then
        isempty := true
 else
        isempty := false;
end;
 
procedure pop(var st : stack);
begin
        if(NOT isempty(st)) then begin
                st.data[st.size] := ' ';
                dec(st.size);
        end else
                writeln('Stack is empty!');
end;
 
procedure OpenFileIn(var f : text);
var
    NameF : string;
begin
  write('Введите название проверяемого файла');
  readln(NameF);
  assign(f, NameF);
  reset(f);
end;
 
procedure OpenFileOut(var f : text);
var
    NameF : string;
begin
 NameF := 'result.txt';
 writeln('Результат в файле: ',NameF);
 assign(f, NameF);
 rewrite(f);
end;
function compare(ch : char) : boolean;
begin
 if (ch = '(') or (ch = '[') or (ch = '{') then
    push(ch, Myst)
 else begin
    if(ch = ')') then
     if (Myst.data[Myst.size] = '(') then
       pop(Myst)
     else
      compare := false;
 
    if(ch = ']') then
     if (Myst.data[Myst.size] = '[') then
       pop(Myst)
     else
      compare := false;
 
    if(ch = '}') then
     if (Myst.data[Myst.size] = '{') then
       pop(Myst)
     else
      compare := false;
 end;
 
end;
BEGIN
 row := 1;
 line := 1;
 Flag := true;
 OpenFileIn(fin);
 while (NOT EOF(fin)) do begin
        while(NOT EOLn(fin)) do begin
                read(fin, tmp);
                Flag := compare(tmp);
                if (Flag = false) then begin
                  OpenFileOut(fout);
                  writeln(fout, 'Error: ', line, ' ', row);
                  close(fout);
                  exit();
                end;
                inc(row);
        end;
        readln(fin);
        row := 1;
        inc(line);
 end;
 OpenFileOut(fout);
 if (isempty(Myst)) then
        writeln(fout, 'No errors!')
 else
        writeln(fout, 'Not enough of closing brackets');
 Close(fout);
 Close(fin);
END.
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
25.01.2016, 19:27
Ответы с готовыми решениями:

Проверить парность блочных скобок begin-end
Привет,форумчане!помогите с задачкой,пожалуйста)) Напишите программу, которая во входной...

Проверить правильность расстановки скобок
Помогите написать программу.Проверить правильно ли в операторе b:=(cos(a+x)+exp(ln(a)*x)/sqr(x)...

Проверить правильность расстановки круглых скобок
помогите пожалуйста. дан текст в котором могут быть круглые скобки. Проверить правильность...

Проверить правильность расстановки круглых и квадратных скобок в выражениях
задание дана строка символов проверить правильность расстановки круглых и квадратных скобок в...

5
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
27.01.2016, 11:57 2
Лучший ответ Сообщение было отмечено Кирилл_В как решение

Решение

Цитата Сообщение от Кирилл_В Посмотреть сообщение
В файле находится текст программы на pascal. используя стек проверить правильность вложений операторных скобок (begin/end)...
Решение с использованием стека, построенного на динамическом однонаправленном списке.
Программа предназначена для исследования исходных текстов программ и модулей Pascal и Delphi - *.pas и *.dpr.
Для правильной работы программы должно выполняться условие:
- Слова UNIT, RECORD, CLASS, OBJECT, BEGIN, END, с любым регистром букв, не должны находиться внутри строковых литералов или комментариев.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
program Project1;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils, Windows;
 
type
  //Тип основных данных.
  TData = String;
  //Указатель на элемент списка (в данном случае - стека).
  TPElem = ^TElem;
  //Элемент списка.
  TElem = record
    Data : TData;
    PNext : TPElem; //Указатель на следующий элемент списка.
  end;
 
//Добавление элемента на вершину стека.
procedure Push(var aPStack : TPElem; const aData : TData);
var
  PElem : TPElem;
begin
  New(PElem);
  PElem^.Data := aData;
  PElem^.PNext := aPStack;
  aPStack := PElem;
end;
 
{Изъятие элемента с вершины стека.
Если стек не пуст, то с вершины стека изымается элемент и возвращается
через параметр aData. В этом случае, функция возвращает значение True.
Если стек пуст, то операция отменяется, а функция возвращает значение False.}
function Pop(var aPStack : TPElem; var aData : TData) : Boolean;
var
  PDel : TPElem;
begin
  Pop := False;
  if aPStack <> nil then
  begin
    PDel := aPStack;
    aData := PDel^.Data;
    aPStack := aPStack^.PNext;
    Dispose(PDel);
    Pop := True;
  end;
end;
 
//Освобождение памяти, занятой под стек (очистка стека).
procedure StFree(var aPStack : TPElem);
var
  Data : TData;
begin
  while Pop(aPStack, Data) do;
end;
 
const
  //Относительный путь файла. (Относительно директория, в котором расположен исполняемый файл программы).
  Fn = 'files\project1.dpr';
  //Fn = 'files\Unit1.pas';
  //Множество разделителей.
  D = ['.', ',', ':', ';', '-', '+', '*', '/', '(', ')', '[', ']', '{', '}',
    '''', ' ', #9, #10, #13];
 
var
  f : TextFile;
  PSt : TPElem;
  i, L, P, Len, LenW : Integer;
  S : String;
  Sw : TData;
begin
  {Переключение окна консоли на кодовую страницу CP1251 (Win-1251).
  Если после переключения русские буквы показываются неверно, то
  следует открыть системное меню консольного окна - щелчком мыши в левом
  верхнем углу окна консоли и выбрать:
  Свойства - вкладка "Шрифт" - выбрать шрифт: "Lucida Console" или "Consolas".}
  SetConsoleCP(1251);
  SetConsoleOutputCP(1251);
 
  PSt := nil; //Начальная инициализация стека.
 
  repeat
    Writeln('------------------------------');
    Writeln('Файл: ', Fn);
    //ExtractFilePath(ParamStr(0)) - полный путь директория, в котором лежит исполняемый файл программы.
    AssignFile(f, ExtractFilePath(ParamStr(0)) + Fn);
    Reset(f);
    L := 0;   //Строка, на которой обнаружена ошибка.
    P := 0;   //Позиция (в пределах строки), на которой обнаружена ошибка.
    while not Eof(f) do //Если не конец файла, то продолжаем цикл.
    begin
      Readln(f, S);     //Читаем очередную строку из файла.
      Inc(L);           //Номер очередной строки.
      Len := Length(S); //Длина строки.
      LenW := 0;        //Длина лексемы.
      for i := 1 to Length(S) do //Перебор всех символов строки.
        if not (S[i] in D) then  //Если символ не является разделителем.
        begin
          Inc(LenW); //Учёт текущего символа в длине лексемы.
          if (i = Len) or (S[i + 1] in D) then //Если обнаружен конец лексемы.
          begin
            Sw := AnsiUpperCase(Copy(S, i - LenW + 1, LenW)); //Выделяем лексему и преобразуем её буквы к верхнему регистру.
            if (Sw = 'BEGIN') or (Sw = 'RECORD') or (Sw = 'CLASS')
              or (Sw = 'OBJECT') or (Sw = 'UNIT')
            then                    //Если обнаружена открывающая скобка.
              Push(PSt, Sw)         //Помещаем открывающую скобку в стек.
            else if Sw = 'END' then //Если обнаружена закрывающая скобка.
            begin
              if not Pop(PSt, Sw) then //Берём с вершины стека открывающую скобку.
              begin
                P := i - LenW + 1;
                Break;
              end;
            end;
            LenW := 0; //Обнуление длины лексемы.
          end;
        end;
      if P > 0 then
        Break;
    end;
    CloseFile(f);
    
    if P > 0 then
      Writeln('Ошибка! Нет соответствующей открывающей скобки. Строка: ', L, ', Позиция: ', P)
    else if PSt <> nil then
      Writeln('Ошибка! Открывающих скобок больше, чем закрывающих.')
    else
      Writeln('Скобки расставлены правильно!');
 
    StFree(PSt); //Освобождение памяти, занятой для стека.
    Writeln('-----');
    Write('Повторить - Enter. Выход - любой символ + Enter. ');
    Readln(S);
  until S <> '';
end.
1
4 / 4 / 3
Регистрация: 29.10.2015
Сообщений: 39
28.01.2016, 22:04  [ТС] 3
Спасибо большое, останется только в полноэкранку перевести.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
29.01.2016, 08:04 4
Для переделки в GUI-приложение (GUI Graphic User Interface), надо заменить консольный вывод (Writeln) на вывод в экземпляр TMemo, например.
Например, так. На форму надо положить компоненты:
Delphi
1
2
3
    Button1: TButton;
    Edit1: TEdit;
    Memo1: TMemo;
В Edit1 пользователь должен ввести относительный путь файла (относительно директория, в котором расположен исполняемый файл программы). В Memo1 осуществляется вывод программы.
Для кнопки Button1 надо создать обработчик события OnClick - TForm1.Button1Click(). Код раздела implementation в модуле оформить следующим образом:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
implementation
 
{$R *.dfm}
 
type
  //Тип основных данных.
  TData = String;
  //Указатель на элемент списка (в данном случае - стека).
  TPElem = ^TElem;
  //Элемент списка.
  TElem = record
    Data : TData;
    PNext : TPElem; //Указатель на следующий элемент списка.
  end;
 
//Добавление элемента на вершину стека.
procedure Push(var aPStack : TPElem; const aData : TData);
var
  PElem : TPElem;
begin
  New(PElem);
  PElem^.Data := aData;
  PElem^.PNext := aPStack;
  aPStack := PElem;
end;
 
{Изъятие элемента с вершины стека.
Если стек не пуст, то с вершины стека изымается элемент и возвращается
через параметр aData. В этом случае, функция возвращает значение True.
Если стек пуст, то операция отменяется, а функция возвращает значение False.}
function Pop(var aPStack : TPElem; var aData : TData) : Boolean;
var
  PDel : TPElem;
begin
  Pop := False;
  if aPStack <> nil then
  begin
    PDel := aPStack;
    aData := PDel^.Data;
    aPStack := aPStack^.PNext;
    Dispose(PDel);
    Pop := True;
  end;
end;
 
//Освобождение памяти, занятой под стек (очистка стека).
procedure StFree(var aPStack : TPElem);
var
  Data : TData;
begin
  while Pop(aPStack, Data) do;
end;
 
procedure TForm1.Button1Click(Sender: TObject);
const
  //Множество разделителей.
  D = ['.', ',', ':', ';', '-', '+', '*', '/', '(', ')', '[', ']', '{', '}',
    '''', ' ', #9, #10, #13];
var
  f : TextFile;
  PSt : TPElem;
  i, L, P, Len, LenW : Integer;
  S, FileName : String;
  Sw : TData;
begin
  PSt := nil; //Начальная инициализация стека.
 
  Memo1.Lines.Add('------------------------------');
  //ExtractFilePath(ParamStr(0)) - полный путь директория, в котором лежит исполняемый файл программы.
  //Относительный путь (относительно директория, в котором лежит исполняемый файл программы)
  //указан в Edit1.
  FileName := ExtractFilePath(ParamStr(0)) + Edit1.Text;
  Memo1.Lines.Add('Файл: ' + FileName);
  Memo1.Lines.Add('Проверка операторных скобок.');
  AssignFile(f, FileName);
  Reset(f);
  L := 0; //Строка, на которой обнаружена ошибка.
  P := 0; //Позиция (в пределах строки), на которой обнаружена ошибка.
  while not Eof(f) do //Если не конец файла, то продолжаем цикл.
  begin
    Readln(f, S);     //Читаем очередную строку из файла.
    Inc(L);           //Номер очередной строки.
    Len := Length(S); //Длина строки.
    LenW := 0;        //Длина лексемы.
    for i := 1 to Length(S) do //Перебор всех символов строки.
      if not (S[i] in D) then  //Если символ не является разделителем.
      begin
        Inc(LenW); //Учёт текущего символа в длине лексемы.
        if (i = Len) or (S[i + 1] in D) then //Если обнаружен конец лексемы.
        begin
          Sw := AnsiUpperCase(Copy(S, i - LenW + 1, LenW)); //Выделяем лексему и преобразуем её буквы к верхнему регистру.
          if (Sw = 'BEGIN') or (Sw = 'RECORD') or (Sw = 'CLASS')
            or (Sw = 'OBJECT') or (Sw = 'UNIT')
          then                    //Если обнаружена открывающая скобка.
            Push(PSt, Sw)         //Помещаем открывающую скобку в стек.
          else if Sw = 'END' then //Если обнаружена закрывающая скобка.
          begin
            if not Pop(PSt, Sw) then //Берём с вершины стека открывающую скобку.
            begin
              P := i - LenW + 1;
              Break;
            end;
          end;
          LenW := 0;        //Обнуление длины лексемы.
        end;
      end;
    if P > 0 then
      Break;
  end;
  CloseFile(f);
 
  if P > 0 then
    Memo1.Lines.Add('Ошибка! Нет соответствующей открывающей скобки. Строка: '
      + IntToStr(L) + ', Позиция: ' + IntToStr(P))
  else if PSt <> nil then
    Memo1.Lines.Add('Ошибка! Открывающих скобок больше, чем закрывающих.')
  else
    Memo1.Lines.Add('Скобки расставлены правильно!');
 
  StFree(PSt); //Освобождение памяти, занятой для стека.
  Memo1.Lines.Add('-----');
  Memo1.Lines.Add('Память, выделенная для стека - освобождена.');
end;
 
end.
1
4 / 4 / 3
Регистрация: 29.10.2015
Сообщений: 39
01.02.2016, 22:33  [ТС] 5
Помогите пожалуйста разобраться, как подключить текстовый файл?

Добавлено через 2 часа 13 минут
А вроде разобрался. Спасибо еще раз.
0
13107 / 5888 / 1707
Регистрация: 19.09.2009
Сообщений: 8,808
01.02.2016, 22:34 6
А для чего здесь текстовый файл? Или имеется в виду входной файл с исходным кодом, который надо анализировать? Имя входного файла задаётся в Edit1 - надо указать путь относительно директория, в котором лежит исполняемый файл программы. Т. е., например, если входной файл лежит в одном директории с программой, то относительный путь файла будет совпадать с его именем.
0
01.02.2016, 22:34
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
01.02.2016, 22:34
Помогаю со студенческими работами здесь

Проверку соблюдения баланса операторных скобок
Задан текст,написанный и находящийся в файле.Произвети проверку соблюдения баланса операторных...

begin...end тупик!
Здравствуйте!Сново тупик у меня!При решение ax^4+bx^2+c=0 у меня программа бежит сразу в низ!В чём...

Теория BEGIN..END;
Снова здрасьте! Довольно часто я встречаю примеры кода, подобные этому var F: TextFile; ...

Ошибка при if end then begin
При выполнении проверки - ошибка ! В чем может быть дело ? if...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Как проводить научные вычисления на Python
InfoMaster 15.01.2025
Python стал одним из наиболее востребованных языков программирования в области научных вычислений благодаря своей простоте, гибкости и обширной экосистеме специализированных библиотек. Научные. . .
Создание игры типа Minecraft на PyGame/Python: пошаговое руководство
InfoMaster 15.01.2025
В данном руководстве мы рассмотрим процесс создания игры в стиле Minecraft с использованием библиотеки PyGame на языке программирования Python. Этот проект идеально подходит как для начинающих. . .
Как создать свою первую игру в стиле Doom на Unreal Engine
InfoMaster 15.01.2025
Разработка шутера от первого лица в стиле классического Doom представляет собой увлекательное путешествие в мир игрового программирования, где сочетаются творческий подход и технические навыки. . . .
Параллельное программировани­е: основные технологии и принципы
InfoMaster 15.01.2025
Введение в параллельное программирование Параллельное программирование представляет собой фундаментальный подход к разработке программного обеспечения, который позволяет одновременно выполнять. . .
Как написать микросервис на C# с Kafka, MediatR, Redis и GitLab CI/CD
InfoMaster 15.01.2025
В современной разработке программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот подход позволяет разделить сложную систему. . .
Что такое CQRS и как это реализовать на C# с MediatR
InfoMaster 15.01.2025
Концепция CQRS и её роль в современной разработке В современном мире разработки программного обеспечения архитектурные паттерны играют ключевую роль в создании масштабируемых и поддерживаемых. . .
Как настроить CI/CD с Azure DevOps
InfoMaster 15.01.2025
CI/ CD, или непрерывная интеграция и непрерывное развертывание, представляет собой современный подход к разработке программного обеспечения, который позволяет автоматизировать и оптимизировать процесс. . .
Как настроить CI/CD с помощью Jenkins
InfoMaster 15.01.2025
Введение в CI/ CD и Jenkins В современной разработке программного обеспечения непрерывная интеграция (CI) и непрерывная доставка (CD) стали неотъемлемыми элементами процесса создания качественных. . .
Как написать микросервис на Go/Golang с Kafka, REST и GitHub CI/CD
InfoMaster 14.01.2025
Определение микросервиса, преимущества использования Go/ Golang Микросервис – это архитектурный подход к разработке программного обеспечения, при котором приложение состоит из небольших, независимо. . .
Как написать микросервис с нуля на C# с RabbitMQ, CQRS, Swagger и CI/CD
InfoMaster 14.01.2025
В современном мире разработки программного обеспечения микросервисная архитектура стала стандартом де-факто для создания масштабируемых и гибких приложений. Этот архитектурный подход предполагает. . .
Как создать интернет-магазин на PHP и JavaScript
InfoMaster 14.01.2025
В современном мире электронная коммерция стала неотъемлемой частью бизнеса. Создание собственного интернет-магазина открывает широкие возможности для предпринимателей, позволяя достичь большей. . .
Как написать Тетрис на Ассемблере
InfoMaster 14.01.2025
Тетрис – одна из самых узнаваемых и популярных компьютерных игр, созданная в 1984 году советским программистом Алексеем Пажитновым. За прошедшие десятилетия она завоевала симпатии миллионы людей по. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru