LINUX.ORG.RU

regexp, код на perl, исправляющий код на lua, НЁХ и непонимание

 , ,


0

2
use strict;
use warnings;

use constant INDENT => "\t";
my($currIndent, $nextIndent, $prevLength) = (0, 0, 0);

while (<>) {
  chomp;
  s/^\s+|\s+$//g; # remove all spaces on both ends
  s/\s+/ /g; # replace all whitespaces inside the string with one space

  my $orig = $_;

  s/(['"])[^\1]*?\1//g; # remove all quoted fragments for proper bracket processing
  s/\s*--.+//; # remove all comments; this ignores long bracket style comments

  # open a level; increase next indentation; don't change current one
  if (/^((local )?function|repeat|while)\b/ && !/\bend\s*[\),;]*$/
   || /\b(then|do)$/ && !/^elseif\b/     # only open on 'then' if there is no 'elseif'
   || /^if\b/ && /\bthen\b/ && !/\bend$/ # only open on 'if' if there is no 'end' at the end
   || /\bfunction\s*\([^\)]*\)$/) {
    $nextIndent = $currIndent + 1;
  }
  # close the level; change both current and next indentation
  elsif (/^until\b/
      || /^end\s*[\),;]*$/
      || /^end\s*\)\s*\.\./ # this is a special case of 'end).."some string"'
      || /^else(if)?\b/ && /\bend$/) {
    $nextIndent = $currIndent = $currIndent - 1;
  }
  # keep the level; decrease the current indentation; keep the next one
  elsif (/^else\b/
      || /^elseif\b/) {
    ($nextIndent, $currIndent) = ($currIndent, $currIndent-1);
  }

  my $brackets = y/(// - y/)//; # capture unbalanced brackets
  my $curly = y/{// - y/}//; # capture unbalanced curly brackets

  # close (curly) brackets if needed
  $currIndent += $curly if $curly < 0 && /^\}/;
  $currIndent += $brackets if $brackets < 0 && /^\)/;

  warn "WARNING: negative indentation at line $.: $orig\n" if $currIndent < 0;

  print((length($orig) ? (INDENT x $currIndent) : ''), $orig, "\n")
    if $prevLength > 0 || length($orig) > 0; # this is to collapse empty lines

  $nextIndent += $brackets + $curly;

  $currIndent = $nextIndent;
  $prevLength = length($orig);
}

warn "WARNING: positive indentation at the end\n" if $nextIndent > 0;

Мне тут на форуме подогнали по запросу код на perl, благодаря которому можно привести в порядок код на lua - а именно, избавиться от смеси табов и пробелов. Я натравил этот код на мой конфиг rc.lua (Awesome) - вроде, стало лучше.

Но я по-прежнему не понимаю некоторых моментов. Конкретно:

  s/(['"])[^\1]*?\1//g; # remove all quoted fragments for proper bracket processing
  s/\s*--.+//; # remove all comments; this ignores long bracket style comments

Я правильно понимаю, что это должно грохнуть все комменты, а так же «что-то со скобочками»? У меня почему-то все комменты в коде остались живы.

Буду очень благодарен, если кто-нибудь мне подробно объяснит, что вообще делает этот код (кроме очевидного - выполнения своей задачи). Не пропало ли из моего конфига что-нибудь важное, чего я пока не заметил? Заранее спасибо

★★

Последнее исправление: Valdor (всего исправлений: 1)

remove all comments; this ignores long bracket style comments

по идее, это должно обозначать, что удаляются однострочные комментарии --, но остаются скобочные --[[ ыыы ]]--

sevenredlines
()

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

а как-же бэкапы ?
при их наличии сделал бы $ diff -u config.bak config.new и не задавал бы лишних вопросов

anTaRes ★★★★
()

Первое выражение s/(['«])[^\1]*?\1//g

убирает кавычки и всё*, что находится между ними.

Пример:

Привет тебе 'Гордый Варяг'! Не желаешь ли сдаться „Врагу“? И нет ли среди твоих обитателей, тех кто хочет „Пощады“?

Привет тебе ! Не желаешь ли сдаться ? И нет ли среди твоих обитателей, тех кто хочет ?

Второе выражение s/\s*--.+// убирает всё* что находится после »--"

Пример:

Что тебе снится, крейсер Аврора? — да сколько ж можно уже спать-то!

Что тебе снится, крейсер Аврора?

anonymous
()

А в виме gg=G:retab<CR> религия не позволяет?

arturpub ★★
()

По сабжу:

while (<>) {
  ...
  my $orig = $_;

  s/.../.../;

  print((length($orig) ? (INDENT x $currIndent) : ''), $orig, "\n") if ...;
  ...
}
Фактически, кроме индента оригинал строки меняется так:
  s/^\s+|\s+$//g; # remove all spaces on both ends
  s/\s+/ /g; # replace all whitespaces inside the string with one space

arturpub ★★
()
Последнее исправление: arturpub (всего исправлений: 1)
Ответ на: комментарий от anTaRes

Бэкапы есть, но выхлоп diff сравним по длине с самим конфигом

Valdor ★★
() автор топика
Ответ на: комментарий от sevenredlines

Я так и понял эти слова, но у меня все комменты на месте остались

Valdor ★★
() автор топика
Ответ на: комментарий от arturpub

Там аноним высказался про удаление комментов и фраз в скобках. Но у меня вот такие вещи остались:

-- "Run once" function
Почему так?

Valdor ★★
() автор топика
Ответ на: комментарий от anonymous

Второе выражение s/\s*--.+// убирает всё* что находится после »--"

Вообще-то, этот шаблон буквально означает: 0 или более пробельных символов, далее --, далее, любой символ кроме переноса строки 1 и более раз

Хз может в епрле специфика своя, но вообще так.

drMits
()
Ответ на: комментарий от Valdor

Скрипт *копирует* строку, удаляет из нее все, что мешает «парсингу», своеобразно парсит, понимает какой должен быть индент, и подставляет его в *оригинал*. Т.о. меняются только инденты (+см. мой прошлый коммент). Что анон говорил не знаю, искать лень.

arturpub ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.