Как комментарии работают в контексте оператора switch регулярного выражения

Хорошо, поэтому я не могу понять, как это работает. Прикрепленный код при запуске приводит к недопустимому имени команды " " при выполнении "\ t" ("#" строка 1 руки), вызванной из "switch -regexp -- $line { "(и остальная часть файла в основном)

Я столкнулся с этой проблемой и, наконец, понял, что это делает #, я попытался избежать этого, используя regsub (показано ниже). Единственный способ, которым я могу получить строку для синтаксического анализа, - это удалить # из строки вместе (inputString изменен, чтобы удалить знак #).

Основываясь на утверждении, что TCL читает все строки как текст (включая команды), я мог только предположить, что читаемая строка содержит # и не может завершить строку и, конечно же, возвращает ошибку. Однако экранирование (пробовал 1 \ и 2 \) ничего не сделало, чтобы сделать его лучше. Все, что он сделал, это добавил \ ко всем моим другим «символам без слов» (у меня было - это работало нормально, но теперь есть \ 'SS)

Если я удалю ИЛИ раскомментирую раздел переключателя {^[ \t]TEST.$}, все будет работать нормально.

Я модифицирую скрипт и игнорировал пару конкретных случаев и решил их прокомментировать.

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

Попытка исправить

regsub -all {\W} $line {\\&} line;

Код:

    proc doConversion fname {
    set inputString "* |# Bits\n*  # Bits \n";

    foreach line [split $inputString "\n"] { 
       switch -regexp  -- $line {
                # {^[ \t]*TEST.*$}
                # {
                   # # Do nothing
                # }
               default {

                       }
            }
       }

    }

doConversion "test"

Обновление: я нашел этот ресурс, который объясняет (в некоторой степени) запутанный характер комментариев, но я думаю, я все еще не уверен, что я могу с этим поделать: "Почему я не могу размещать непарные фигурные скобки в комментариях Tcl".


person onaclov2000    schedule 16.07.2012    source источник
comment
Природа механизма комментариев Tcl такова, что # является комментарием только в том месте, где ожидается начало команды. Кроме того, встроенные скрипты (такие как руки switch) могут привести к изменению того, где находится конец комментария. Это отлично от других языков и является следствием общих правил синтаксиса и того, как Tcl выполняет рекурсивную декомпозицию команд. Раз в несколько лет кто-то предлагает это «исправить», но изменить это гораздо сложнее, чем кажется на первый взгляд…   -  person Donal Fellows    schedule 17.07.2012
comment
Да, читая вики TCL, указанную выше.... это немного сбивает с толку... это точно.   -  person onaclov2000    schedule 17.07.2012


Ответы (1)


Я не на 100% понимаю, что вы пытаетесь сделать, поэтому я заранее извиняюсь, если это не отвечает на ваш вопрос, но: в результате # не указывает комментарий, если только это не где-то, что команда ожидал. Например, это:

switch -regexp a#b {
    # {
        echo 'a#b' contains '#'
    }
}

печатает это:

'a#b' contains '#'

потому что строка a#b успешно соответствует регулярному выражению #.

Поскольку $line содержит #, ваш код:

       switch -regexp  -- $line {
                # {^[ \t]*TEST.*$}
                ...
            }

запустит эту команду:

^[ \t]*TEST.*$

который (из-за квадратных скобок) запускает эту команду:

\t

поэтому вы получаете сообщение об ошибке, говорящее вам, что "   " (т. е. символ табуляции) является недопустимым именем команды.

Если вы хотите отключить одну ветвь switch, вам лучше обернуть ее условием, которое никогда не будет выполнено:

    proc doConversion fname {
    set inputString "* |# Bits\n*  # Bits \n";

    foreach line [split $inputString "\n"] { 
       switch -regexp  -- $line {
               this-regexp-will-never-match {
                  {^[ \t]*TEST.*$}
                  {
                   # # Do nothing
                  }
               }
               default {

                       }
            }
       }

    }

doConversion "test"
person ruakh    schedule 16.07.2012
comment
Все еще очень странно (я не очень хорошо знаком с языком), однако удаление # из строки (с помощью regsub # для фунта), похоже, устраняет проблему. - person onaclov2000; 17.07.2012
comment
Кроме того, я попытался удалить закомментированные разделы, просто чтобы посмотреть, будет ли это работать (в моей более крупной программе), и все же не будет, поэтому мне пришлось прибегнуть к обмену #/pound. - person onaclov2000; 17.07.2012
comment
@ onaclov2000: Да, потому что тогда строка не соответствует регулярному выражению #, поэтому switch никогда не пытается запустить проблемную команду. - person ruakh; 17.07.2012
comment
@ onaclov2000: я проверил то, что опубликовал. Если удаление закомментированных разделов не решило вашу проблему, значит, у вас есть и другая проблема. - person ruakh; 17.07.2012
comment
Я действительно просто не могу опубликовать большую часть программы, поэтому на данный момент я не уверен, в чем конкретно заключалась второстепенная проблема, но она все еще была связана с комментариями. Если у меня будет возможность абстрагироваться и опубликовать пример, я обязательно это сделаю! - person onaclov2000; 17.07.2012