Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Паскаль, Turbo Pascal, PascalABC.NET
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.12.2010, 20:45   #1
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию анализатор

Добрый вечер! Задали писать многопроходной транслятор. Я реализовала модуль ввода/выводы, обработку ошибки и сканнер(лексически анализатор).
В результате работа сканнера у меня создается 2 таблицы
1. таблица лексем программы
Код:
table_lex=^t_table_lex; //таблица лексем программы
  t_table_lex=record  //элемент таблицы лексем программы
    cod:integer;  //код
    lex:string; //лексема
    value_i:integer;  //значение целое
    value_s:string; //значение строковое
    line:integer; //строка
    next:table_lex; //ссылка на следующий элемент
  end;
2. таблица идентификаторов
Код:
table_ident=^t_table_ident; //таблица идентификаторов
  t_table_ident=record  //элемент таблицы идентификаторов
    name_ident:string[count_char_ident];  //имя
    type_ident:integer; //тип 0-целые 1-символный
    value_i:integer;  //значение целой
    value_s:string; //значение строковой
    next:table_ident; //ссылка на следующийэелемент
  end;
Вот после работы анализатора эти таблицы заполняются. Теперь нужно реализовать синтаксический анализатор использующий рекурсивный спуск. Пробовала несколько вариантов, начинаю реализовывать и сталкиваюсь с разными проблемами.
Не могли бы вы описать как же его реализовать?
Вложения
Тип файла: doc __Basic.doc (32.0 Кб, 13 просмотров)
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 02.12.2010, 20:45   #2
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

Код:
//==============================================================================
//    синтаксический анализатор
//==============================================================================
unit sintax_analizator;

interface
//==============================================================================
//  описание процедур доступных из этого модуля
//==============================================================================
  procedure sin_analiz();forward; //синтаксический анализатор

implementation
uses module_error, table, scanner;

//==============================================================================
//  описание типов данных и переменных этого модуля
//==============================================================================
var
  start_table_lex:table_lex;  //указатель на таблицу лексем

//==============================================================================
//    код модуля
//==============================================================================
procedure next_input(); //обработка аргументов input 
begin
  if(start_table_lex^.cod=18) or (start_table_lex^.cod<>2) then
    error('no argument',start_table_lex^.line)
  else start_table_lex:=start_table_lex^.next;
end;


procedure opr_input();  //оператор input
var
  temp_err:integer; //строка передаваемая в ошибку
begin
  temp_err:=start_table_lex^.line;  //сохранили номер строки
  start_table_lex:=start_table_lex^.next;
  if (start_table_lex<>nil) then  
  begin
    next_input();
    while ((start_table_lex<>nil) and (start_table_lex^.cod=19)) do
    begin
      temp_err:=start_table_lex^.line;
      start_table_lex:=start_table_lex^.next;
      if (start_table_lex<>nil) then next_input()
      else error('no argument',temp_err);
    end;
  end
  else error('no argument',temp_err);
  
end;


procedure sin_analiz(); //синтаксический анализатор
begin
  start_table_lex:=head_table_lex;
//==============================================================================
//    основная работа модуля
//==============================================================================
  while(start_table_lex<>nil) do
  begin
//==============================================================================
//    input
//==============================================================================
    if (start_table_lex^.cod=3) then
    begin
      opr_input();
    end
//==============================================================================
//    print
//==============================================================================
    else if (start_table_lex^.cod=4) then
    begin

    end
//==============================================================================
//    while
//==============================================================================
    else if (start_table_lex^.cod=5) then
    begin

    end
//==============================================================================
//    if
//==============================================================================
    else if (start_table_lex^.cod=7) then
    begin

    end
//==============================================================================
//    for
//==============================================================================
    else if (start_table_lex^.cod=11) then
    begin

    end
//==============================================================================
//    присвоение
//==============================================================================
    else if (start_table_lex^.cod=2) then
    begin

    end;
//==============================================================================
//      обработка разделителя
//==============================================================================
    if ((start_table_lex<>nil)and (start_table_lex.cod<>18)) then error('no separator',start_table_lex^.line)
    else if(start_table_lex<>nil) then start_table_lex:=start_table_lex^.next;
  end;


end;

end.
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 02.12.2010, 20:48   #3
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

это один из последних вариантов попробовать его. Но вот какой вопрос: встречаю лексему while допустим условие я каким нибудь образом обработаю, но вот как быть с тем, что этот оператор заканчивается wend? т.е. обработала условие и поидее нужно еще раз запускать sin_analiz но если wend нет то ошибка должна выйти

по идее можно реализовать флагами, но как сделать поумному?
Единственное, что ограничивает полет мысли программиста-компилятор

Последний раз редактировалось artemavd; 17.12.2010 в 07:43.
Sparky вне форума Ответить с цитированием
Старый 02.12.2010, 20:59   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Я делаю так.
Ищу wend после while. но если встречаю еще while увеличиваю счетчик вложенности, если встречаю wend счетчик уменьшаю.
Если счетчик равен нулю и встретился wend - считай цикл верен
Если счетчик ушел в минуса или плюсы - ошибка, и так до конца кода.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 03.12.2010, 03:52   #5
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

Код:
//==============================================================================
//    синтаксический анализатор
//==============================================================================
unit sintax_analizator;

interface
//==============================================================================
//  описание процедур доступных из этого модуля
//==============================================================================
  procedure sin_analiz();forward; //синтаксический анализатор

implementation
uses module_error, table, scanner;

//==============================================================================
//  описание типов данных и переменных этого модуля
//==============================================================================
var
  start_table_lex:table_lex;  //указатель на таблицу лексем

//==============================================================================
//    код модуля
//==============================================================================
procedure next_input(); //обработка аргументов input
begin
  if(start_table_lex^.cod=18) or (start_table_lex^.cod<>2) then
    error('no argument',start_table_lex^.line)
  else start_table_lex:=start_table_lex^.next;
end;


procedure opr_input();  //оператор input
var
  temp_err:integer; //строка передаваемая в ошибку
begin
  temp_err:=start_table_lex^.line;  //сохранили номер строки
  start_table_lex:=start_table_lex^.next;
  if (start_table_lex<>nil) then
  begin
    next_input();
    while ((start_table_lex<>nil) and (start_table_lex^.cod=19)) do
    begin
      temp_err:=start_table_lex^.line;
      start_table_lex:=start_table_lex^.next;
      if (start_table_lex<>nil) then next_input()
      else error('no argument',temp_err);
    end;
  end
  else error('no argument',temp_err);
end;



procedure next_print(); //обработка аргументов print
begin
  if(start_table_lex^.cod=18) or (start_table_lex^.cod<>2) then
    error('no argument',start_table_lex^.line)
  else start_table_lex:=start_table_lex^.next;
end;


procedure opr_print();  //оператор print
var
  temp_err:integer; //строка передаваемая в ошибку
begin
  temp_err:=start_table_lex^.line;  //сохранили номер строки
  start_table_lex:=start_table_lex^.next;
  if (start_table_lex<>nil) then
  begin
    next_input();
    while ((start_table_lex<>nil) and (start_table_lex^.cod=19)) do
    begin
      temp_err:=start_table_lex^.line;
      start_table_lex:=start_table_lex^.next;
      if (start_table_lex<>nil) then next_input()
      else error('no argument',temp_err);
    end;
  end
  else error('no argument',temp_err);
end;


function functions():boolean; //функция
begin
  if (start_table_lex^.cod in [14,23]) then functions:=true
  else functions:=false;
end;


function operators():boolean; //операция
begin
  if (start_table_lex^.cod in [15..16,22..31]) then operators:=true
  else operators:=false;
end;
;
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 03.12.2010, 03:53   #6
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

Код:
procedure expression(); //
var
  temp_err:integer; //строка передаваемая в ошибку
begin
  if ((start_table_lex^.cod<>20) and (start_table_lex^.cod<>21)and (start_table_lex^.cod<>0)
  and (start_table_lex^.cod<>1)and (start_table_lex^.cod<>2)and (not functions())) then error('expression is expected',start_table_lex^.line) 
//если не встретили ожидаемое ошибка
  else if ((start_table_lex^.cod in[0..2])) then start_table_lex:=start_table_lex^.next 
//если число,строка,идентификатор все хорошо идем дальше
  else if (start_table_lex^.cod=20) then  //если (
  begin
    temp_err:=start_table_lex^.line;  //сохранили номер строки
    start_table_lex:=start_table_lex^.next;
    if (start_table_lex<>nil) then
    begin
      expression();
      if (start_table_lex^.cod=21) then start_table_lex:=start_table_lex^.next
      else error('',start_table_lex^.line);
    end
    else error('',start_table_lex^.line);
  end
  else if(functions) then //если функция
  begin
    temp_err:=start_table_lex^.line;  //сохранили номер строки
    start_table_lex:=start_table_lex^.next;
    if (start_table_lex<>nil) then
    begin
      if (start_table_lex^.cod=20) then
      begin
        temp_err:=start_table_lex^.line;  //сохранили номер строки
        start_table_lex:=start_table_lex^.next;
        if (start_table_lex<>nil) then
        begin
          expression();
          if (start_table_lex^.cod=21) then start_table_lex:=start_table_lex^.next
          else error('',start_table_lex^.line);
        end
        else error('',start_table_lex^.line);
      end
      else error('',start_table_lex^.line);
    end
    else error('',start_table_lex^.line);
  end
  else if (operators()) then  //если оператор
  begin
    temp_err:=start_table_lex^.line;  //сохранили номер строки
    start_table_lex:=start_table_lex^.next;
    if (start_table_lex<>nil) then
    begin
      expression();
    end;
  end
  else  error('',start_table_lex^.line);
end;


procedure assigment();  //
var
  temp_err:integer; //строка передаваемая в ошибку
begin
  temp_err:=start_table_lex^.line;  //сохранили номер строки
  start_table_lex:=start_table_lex^.next;
  if (start_table_lex<>nil) then
  begin
    if (start_table_lex^.cod=17) then //встретили знак присваивание будем обрабатывать правую часть
    begin
      temp_err:=start_table_lex^.line;  //сохранили номер строки
      start_table_lex:=start_table_lex^.next;
      if (start_table_lex<>nil) then expression()
      else error('no argument',temp_err);
    end
    else error('no argument',temp_err);
  end
  else error('no argument',temp_err);
end;


procedure sin_analiz(); //синтаксический анализатор
begin
  start_table_lex:=head_table_lex;
//==============================================================================
//    основная работа модуля
//==============================================================================
  while(start_table_lex<>nil) do
  begin
//==============================================================================
//    input
//==============================================================================
    if (start_table_lex^.cod=3) then
    begin
      opr_input();
    end
//==============================================================================
//    print
//==============================================================================
    else if (start_table_lex^.cod=4) then
    begin
      opr_print();
    end
==============================================================================
//    присваивание
//==============================================================================
    else if (start_table_lex^.cod=2) then
    begin
      assigment();
    end;
//==============================================================================
//      обработка разделителя
//==============================================================================
    if ((start_table_lex<>nil)and (start_table_lex.cod<>18)) then error('no separator',start_table_lex^.line)
    else if(start_table_lex<>nil) then start_table_lex:=start_table_lex^.next;
  end;


end;

end.
Некорректно работает для ситуации y=3+2; как исправить? Если нужно прикреплю проект
Единственное, что ограничивает полет мысли программиста-компилятор

Последний раз редактировалось Stilet; 03.12.2010 в 09:33.
Sparky вне форума Ответить с цитированием
Старый 03.12.2010, 04:10   #7
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

вроде бы исправила, но хотела бы чтобы вы посмотрели код, может можно сделать, то что делаю более правильно
Единственное, что ограничивает полет мысли программиста-компилятор
Sparky вне форума Ответить с цитированием
Старый 03.12.2010, 09:36   #8
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
вы посмотрели код
Я бы не против его поколупать но... Он для меня слишком сложен...
В следующем номере должна выйти моя статья где я описал свой парсер кода.
Не знаю как ты но я лично бы переосмыслил стратегию... ибо твой пример, не знаю на что он рассчитан, но он по-моему чертовски сложен.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 03.12.2010, 17:24   #9
Sparky
Участник клуба
 
Аватар для Sparky
 
Регистрация: 15.05.2009
Сообщений: 1,222
По умолчанию

находила в книге Свердлова ЯП и методы трансляции еще одну стратегию разбора, пробовала, но почему-то остановилась на этой. Может будет интересно или пригодится выкладываю то что пока наработала

продолжаю мучать с транслятором, окончательно запуталась и прошу помощи необходимо реализовать синтаксический анализатор, у меня он почти сделан, не работают операторы while и if, не работает вложение в циклы и еще ряд глюков. Прикрепляю полностью свой транслятор. Синтаксический анализатор в модуле kernel_2. Модуль kernel моя попытка переписать заново. Как раз этим и начала заниматься.
Хотелось бы чтобы кто-нибудь помог
Вложения
Тип файла: rar translator.rar (111.8 Кб, 8 просмотров)
Тип файла: rar translator.rar (125.3 Кб, 12 просмотров)
Единственное, что ограничивает полет мысли программиста-компилятор

Последний раз редактировалось artemavd; 17.12.2010 в 07:41.
Sparky вне форума Ответить с цитированием
Старый 16.12.2010, 15:43   #10
Utkin
Старожил
 
Аватар для Utkin
 
Регистрация: 04.02.2009
Сообщений: 17,351
По умолчанию

Цитата:
не работают операторы while и if, не работает вложение в циклы и еще ряд глюков.
А вообще когда-нибудь работали? В смысле управляющие конструкции и их вложенность были предусмотрены?
Маньяк-самоучка
Utkin появился в результате деления на нуль.
Осторожно! Альтернативная логика
Utkin вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Анализатор! gallion Помощь студентам 2 19.05.2010 09:32
Анализатор текста Xeon332 Помощь студентам 1 14.03.2010 17:24
Лексический анализатор С++ EniOk Помощь студентам 1 06.12.2009 15:43
морфологический анализатор Lavisa Помощь студентам 0 19.10.2009 23:11
Анализатор формул KJIOyH Помощь студентам 1 05.11.2007 18:18