vimdiff: показать только разницу между "базовым" и "удаленным"

Формулировки «контекст списка» и «контекст строки» пришли из Perl, но аналогичные концепции применимы к языку оболочки. Обратите внимание, что это похожие понятия :виды контекстов и последствия типа контекста различны.

Слово контекст является техническим термином в семантике языка программирования. Его точное значение привязано к конкретной семантической формализации, которая выходит за рамки данного ответа. Когнитивное значение — это природа окружения фрагмента кода. Например, заявление о том, что фрагмент кода $fooимеет разное значение в разных контекстах, означает, что поведение программы, содержащей $foo, зависит от природы того, что происходит вокруг этого вхождения $fooв программе.

Семантика оболочки довольно сложна. Он не подпадает под традиционные категории, которые вы найдете во вводных учебниках по языкам программирования. Выполнение программы оболочки можно разбить на две фазы (обратите внимание, что это способ представить семантику,это не означает, что интерпретатор оболочки должен быть разбит таким образом):

  1. Этап синтаксического анализа превращает строку (содержимого исходного файла или аргумента в-c)в абстрактное синтаксическое дерево. В спецификации POSIX это соответствует шагам 2 и 3 (распознавание и разбор токена ). Спецификация POSIX определяет правила грамматики , которые описывают форму дерева. Обратите внимание, что это не контекстная -свободная грамматика – представление основано на обычном представлении контекстных -свободных грамматик, но аннотации «применить правило N » делают его более сложным математическим объект.

  2. Этап выполнения выполняет некоторую оценку узлов дерева и вызывает внешние команды. В спецификации POSIX это соответствует шагам 4–7 (раскрытие, перенаправление, выполнение команды и ожидание ).

Расширение — это процесс, который применяется к определенному типу узла в абстрактном синтаксическом дереве, который POSIX называет WORDи который обычно называют «словом». Его можно разделить на две группы.

  1. Первая группа расширений состоит, в терминологии POSIX, из расширения с тильдой (, например. ~foo/home/foo), расширение параметра(напр. $foobar, если значение fooравно bar), подстановка команды (, например. $(foo)bar, если выводом команды fooявляетсяbarарифметическое расширение (, например. $((2+2))4). Эта первая группа расширений выполняется для каждого слова, за исключением символов, которые «заключены в кавычки» в силу того, что они заключены в одинарные кавычки или им предшествует обратная косая черта. Результатом этой группы расширений является приблизительно строка с аннотациями (. Я объясню приближение ниже ).

  2. Вторая группа расширений состоит из разделения полей и расширения пути (, широко известного как «генерация имени файла» или «подстановка» ). Эта группа расширений превращает аннотированную строку в список строк. Эта группа расширений выполняется на подмножестве мест, где выполняется первая группа :не выполняется на частях слов, заключенных в двойные кавычки, и вообще не выполняется, если слово в определенных позициях в абстрактном синтаксическом дереве . Именно здесь контексты списка и строки вступают в :в определенных контекстах, т.е. для определенных классов позиций в абстрактном синтаксическом дереве выполняется вторая группа расширений. Это контексты списка , названные так потому, что результатом процесса раскрытия является список (строк ). В других контекстах, называемых строковыми контекстами , вторая группа расширений не выполняется, и результатом процесса раскрытия является одна строка.

POSIX описывает удаление кавычек как последнюю стадию расширения. Это один из способов объяснить заключение в кавычки, когда все раскрытия перед разделением полей определяются как преобразование строки в строку. Например, для слова '$foo'$bar\$quxпри условии, что значение переменной barравно value, расширение параметра превращает его в '$foo'value\$qux, а другие первые -групповые расширения оставляют строку неизменной. Удаление кавычек, наконец, удаляет кавычки, чтобы получить $foovalue$qux.

Представление с удалением кавычек требует выполнения сопоставления кавычек на каждом этапе. Презентация, которая проще для понимания и реализации и дает тот же конечный результат, заключается в выполнении этапа расшифровки кавычек, результатом которого является список частей. Каждая часть аннотируется, чтобы помнить, цитировалась ли она. Например, '$foo'$bar\$quxзаключает в кавычки следующие части :, заключает в кавычки $foo, расширение переменной barбез кавычек,цитируемый $, голый q, голый u, голый x. (Различие между «кавычками» и «голыми» необходимо для таких вещей, как определение присвоений и принятие решения о том, следует ли расширять псевдонимы. )Второй этап раскрытия -происходит только для частей без кавычек в контексте списка.

POSIX указывает, происходит ли вторая группа расширений, путем явного перечисления этапов расширения. Например, «Каждое назначение переменной должно быть расширено для расширения с помощью тильды, расширения параметра, подстановки команд, арифметического расширения и удаления кавычек перед присвоением значения». Более простой способ сформулировать это так: происходят только первые раскрытия группы -, т. е. это присваивание является строковым контекстом. Контекста всего два, потому что есть только два набора правил выполнения раскрытий :либо выполняется вся первая группа (контекст строки ), либо обе группы выполняются по порядку (контекст списка ).

(На самом деле, чтобы быть полным, существует третий вид контекста,:caseконтекст шаблона. В шаблоне caseвыполняются только раскрытия первой -группы (, как и в строковом контексте ), но часть второй группы расширений имеет значение — символы подстановки без кавычек являются подстановочными знаками для сопоставления строк.)

Определение языка определяет, какие контексты являются контекстами списка, а какие строковыми контекстами. В принципе, это может быть произвольно. Однако за этим стоит интуиция :в тех местах, где грамматика ожидает список из WORDтокенов, над этими токенами выполняется второе -групповое расширение, тогда как в местах, где грамматика требует одиночный WORD, второй -Расширение группы не выполняется. Простой способ объяснить это так: там, где грамматика ожидает список, это контекст списка, а там, где грамматика ожидает одну строку, это строковый контекст.

0
20.11.2017, 06:09
0 ответов

Теги

Похожие вопросы