Vi неправильно обрабатывает фигурные скобки в моем Perl-скрипте

Vi запутался с моим perl-скриптом! В то время как { в конце кода не соответствует ни одной из закрывающих фигурных скобок, {s в конце строк 27 и 28 соответствует одному и тому же } в 30.

Вот видео с экрана того, как Vi обрабатывает поведение моего скрипта.

мини-скринкаст, демонстрирующий проблему
(источник: abbasinasab.com)

Вот также мой фрагмент кода, вызывающий проблемы:

#CODE                                                                                                               
while ($data =~ m{                                                                                                      
    ^foo_\s+ $X \s* \{                                                                                                  
        ( (?: [^{}]+ | \{(?1)\} )* )                                                                                    
    \}                                                                                                                  
}mgx)                                                                                                                   
{                                                                                                                       
    my $Y = $1;                                                                                                         
    next if $Y !~ m{                                                                                                    
        bar_$Z \s* \{                                                                                                   
            ( (?: [^{}]+ | \{(?1)\} )*? )                                                                               
        \}                                                                                                              
    }mx;                                                                                                                

    my $DO = $1;                                                                                                        
    #CODE                                                                                                               
} 

Мои вопросы:

  1. Как и почему Vi не может справиться с фигурными скобками в этой ситуации.
  2. Как я могу переписать свой уродливо написанный фрагмент кода, чтобы избежать этой путаницы для Vi.

person Community    schedule 02.09.2014    source источник
comment
Вы можете использовать любой разделитель для m. Например: seq 350 | perl -lanE 'say $_ if m 1331', но рекомендуется использовать только знаки препинания, например: / @ или пары () [] <> и тому подобное.   -  person jm666    schedule 02.09.2014
comment
Perl чрезвычайно сложно разобрать, особенно с модификаторами /gmx (особенно с модификатором /x).   -  person Jonathan Leffler    schedule 02.09.2014
comment
Perl на самом деле не поддается разбору. perlmonks.org/?node_id=663393   -  person OmnipotentEntity    schedule 02.09.2014
comment
Если вы считаете, что это ошибка в том, как vim-perl обрабатывает эти фигурные скобки (а это вполне может быть), отправьте заявку в проект vim-perl: github.com/vim-perl/vim-perl vim-perl — это место, где мы курируем файлы Vim, связанные с Perl, которые возвращаются обратно в дистрибутив Vim. Вы также можете попробовать использовать файлы синтаксиса из проекта vim-perl и посмотреть, являются ли более свежие версии более надежными, чем те, которые поставляются с той версией Vim, которую вы используете сейчас.   -  person Andy Lester    schedule 02.09.2014
comment
Эм, извините за вопрос не по теме, но что вы использовали для создания небольшого скринкаста? :П   -  person mechalynx    schedule 02.09.2014
comment
Передозировка сложности.   -  person Ali Abbasinasab    schedule 02.09.2014


Ответы (1)


В Vim есть две функции, которые можно обмануть сложным синтаксисом:

  • Подсветка 'matchpairs' и переходы используют внутреннюю эвристику. На это можно немного повлиять (ср. :help cpo-M):
:set cpo+=M

При этом % правильно переходит к ожидаемой закрывающей фигурной скобке (если у вас нет подключаемого модуля, такого как matchpairs.vim, который переопределяет команду %). Также обратите внимание, что параметр 'cpoptions' является глобальным, поэтому он может отрицательно сказаться на других типах файлов.

  • Подсветка синтаксиса основана на регулярном выражении. Таким образом, он потерпит неудачу с крайними случаями и сложным синтаксисом (например, C++ и Perl), которые не могут быть точно смоделированы с помощью регулярных выражений (но требуют специального синтаксического анализатора).

В общем, я бы не стал переписывать код только для того, чтобы редактор был доволен. Другие люди могут использовать другие редакторы, и вскоре код сильно искажается различными подобными «обходными путями». Единственным исключением является случай, когда код явно сложный и громоздкий, а общая читабельность улучшится после реструктуризации.

person Ingo Karkat    schedule 02.09.2014