Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > [ "Начинающим" ]
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 01.10.2010, 15:19
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
Сообщение Парсинг скобок

И опять Здравствуйте!
Есть вопрос, про парсинг.
Дан текст и надо проверить на кол-во открывающихся/закрывающихся скобок, и если они не совпадают, то выдать ошибку. Притом:
если скобка (любая) записана в комментарии, то ее считать не надо и
если скобка записана в двойных кавычках "...", то ее тоже считать не надо.
Комментарии могут быть такие:
1. // это одно строчный комментарий (как в делфи)
2. /* это много строчный
комментарий (как в С)
*/

Скобки могут быть такие:
{ }
[ ]
( )
< >

Посылать в гугл не надо, только оттуда... Поэтому ссылки типа " http://www.google.com.ua/search?sour...BB%D1%84%D0%B8 " не подходят.

ЗЫ Обычные функции (delete, pos, posEx) тут, как я думаю, не совсем подойдут, точнее подойдут, но ну уж очень надо сильно много проверок.

Есть идеи?
Ответить с цитированием
  #2  
Старый 01.10.2010, 15:22
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Так же думаю надо вставить приоритет скобок.
Поидее '{' имеет больший приоритет чем '(', а она в свою очередь выше '['...

И вот еще одна проблемка:
({)} так стоять скобки не могут... Вот тут то как раз и начинаются сложности...

Вот только что нашел вот такую реализацию (через стек):

Код:
function Check(const S:string):boolean;
var
 i:integer;
 Stack:TStack;
 c:char;
begin
 Result:=false;
 Stack:=TStack.Create; 
 for i:=1 to Length(S) do 
  begin
   if not (S[i] in ['{','[','(','}',']',')']) then continue;
   if S[i] in ['{','[','('] then Stack.Push(@S[i]) 
   else        
    if Stack.Count>0 then
     begin
      case Char((Stack.Peek)^) of 
       '[': c:=']';                
       '(': c:=')';
       '{': c:='}';
       else c:=Chr(0);
      end;
      if c<>S[i] then           
       begin
        if Stack.Count=0 then ShowMessage('ошибка в '''+S[i]+'') 
                         else ShowMessage('ошибка в '''+c+'');  
        exit;             
       end else Stack.Pop; 
     end else 
     begin
      ShowMessage('ошибка в '''+S[i]+'');
      exit;
     end;
  end;
 if Stack.Count>0 then  
  begin                  
   ShowMessage('ошибка в '''+Char((Stack.Pop)^)+'');
   exit;
  end;
 Stack.Free;  
 Result:=true;
end;

Может есть другой вариант? (хотя и этот не плох, нашел его после создания темы...)

Последний раз редактировалось v1s2222, 01.10.2010 в 15:39.
Ответить с цитированием
  #3  
Старый 01.10.2010, 15:40
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Для компиляции выше описанной реализации надо подключить модуль: "Contnrs", для стека.
Ответить с цитированием
  #4  
Старый 03.10.2010, 02:14
yanot yanot вне форума
Прохожий
 
Регистрация: 03.10.2010
Сообщения: 7
Репутация: 12
По умолчанию

Почему бы не использовать Pos.
Не так и громоздко

Особо не тестировал, но вроде работает.

Тут нет проверки на обязательный закрывающий комментарий */
и на правильность кавычек


PHP код:
function Valid(LinesTStrings): boolean;

const
  
InnerArr: array[0..3of char = (
  
'{',
  
'[',
  
'(',
  
'<'
  
);

  
OuterArr: array[0..3of char = (
  
'}',
  
']',
  
')',
  
'>'
  
);

var
  
InnerCount: array[0..3of integer;
  
OuterCount: array[0..3of integer;
  
ijainteger;
  
Commentboolean;
  
CommentPosPos2integer;
  
Kavboolean// Кавычки
  
Startinteger;

begin

  
for := 0 to 3 do
  
begin
    InnerCount
[a] := 0;
    
OuterCount[a] := 0;
  
end;

  
Result := True;
  
Comment := False;

  for 
:= 0 to Lines.Count-do
  
begin
    
if Comment then
    begin
      CommentPos 
:= Pos('*/'Lines[i]);
      if 
CommentPos 0 then
        
Continue
      else
      
begin
        Comment 
:= False;
        
Start := CommentPos+2;
      
end;
    
end
    
else
      
Start := 1;

    
CommentPos := Pos('//'Lines[i]);
    
Pos2 := Pos('/*'Lines[i]);
    if (
Pos2 0) and ((CommentPos 0) or (Pos2 CommentPos)) then
    begin
      CommentPos 
:= pos2;
      
Comment := True;
    
end;

    if 
CommentPos Start then
      CommentPos 
:= LengthLines[i] );

    
Kav := False;
    for 
:= Start to CommentPos do
    
begin

      
if Lines[i][j] = '"' then
        Kav 
:= not Kav;

      if 
not Kav then
        
for := 0 to 3 do
        
begin
          
if Lines[i][j] = InnerArr[athen
            Inc
InnerCount[a] );

          if 
Lines[i][j] = OuterArr[athen
            
if InnerCount[a] > OuterCount[athen
              Inc
OuterCount[a] )
            else
              
Result := False;   // Ошибка: закрывающая скобка раньше открывающей
        
end;
    
end;

  
end;

  if 
Result then
    
for := 0 to 3 do
      if 
InnerCount[a] <> OuterCount[athen
      begin
        Result 
:= False;
        Break;
      
end;

end
Ответить с цитированием
  #5  
Старый 03.10.2010, 11:29
Аватар для v1s2222
v1s2222 v1s2222 вне форума
Продвинутый
 
Регистрация: 07.09.2010
Сообщения: 726
Репутация: 26711
По умолчанию

Ща посмотрим, спасибо! +

Посмотрел, впринципе нормально, но не совсем то что надо. Если например писать:
{ ( } ) - то должна быть ошибка, т.к. нет приоритета скобок, а у тебя все правильно.
Ну да ладно, взял уже пример работы через стек.
__________________
Помогаю за Спасибо

Последний раз редактировалось v1s2222, 03.10.2010 в 11:35.
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 20:52.


 

Сайт

Форум

FAQ

Соглашения

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2025