Запретить использование псевдонима в скрипте [closed]

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

@(repeat)
@  (cases)
@    (collect :gap 0 :mintimes 1)
@line
@      (require (search-str line "logical IO"))
@    (end)
@    (do (put-line (first line)))
@  (or)
@line
@    (do (put-line line))
@  (end)
@(end)

Run:

$ txr first-log-IO.txr data
select * from test1 where 1=1
testing logical IO 24
select * from test2 where condition=4
parsing logical IO 45
select * from test5 where 1=1
testing logical IO 24
select * from test5 where condition=78
parsing logical IO 346

@ (repeat) устанавливает обход данных без сбора привязок переменных; когда эта конструкция видна, это обычно указывает на то, что в итерации имеет место некоторый побочный эффект. В этом случае он выводится.

Внутри @ (repeat) у нас есть конструкция @ (case) : многостороннее соответствие, состоящее из вариантов, разделенных @ (или) .Вторая ветвь, резервный вариант, это просто @line , которая соответствует строке. Следующая за ним директива @ (do (put-line (first line))) печатает эту строку.

Основная ветвь @ (case) собирает материалы через @ (collect) . Совпадения должны быть последовательными, требуется : пробел 0 , и должен быть хотя бы один, требуемый : mintimes 1 . Тело сбора соответствует одной строке, связанной с переменной line . Затем есть утверждение @ (require ...) , которое не выполняется, если строка не содержит подстроку «логический ввод-вывод» . Таким образом, сбор данных будет остановлен при обнаружении несовпадающей строки, поскольку : gap 0 не позволяет ему пропустить его. Соответствующие строки неявно собираются в список под названием line , который появляется из collect (переменная, привязанная внутри набора, автоматически становится списком за пределами сбора, всех связанных значений за несколько итераций). Мы просто печатаем первый, как требуется, подавляя остальные.

Обратите внимание, что два совпадения @line не имеют ничего общего друг с другом; они связывают переменную строки в разных областях.

Другой способ - выполнить функциональное программирование над ленивыми списками в TXR Lisp:

[(opip (partition-by (do cond
                       ((search-str @1 "logical IO") t)
                       (t @1)))
       (mapcar* first)
       put-lines)
 (get-lines)]

$ txr first-log-IO.tl

opip ] - это синтаксический сахар для построения конвейера функций.Все его аргументы обрабатываются как синтаксис op : макрос для создания анонимных функций с неявными пронумерованными аргументами.

Общая форма - [(opip ...) (get-lines)], что означает просто «вызвать функцию, созданную opip , с результатом (get-lines) в качестве аргумента ". Этот (get-lines) преобразует стандартный входной поток в ленивый список строк. (Его «противоположность» - put-lines , которая появляется).

Теперь в конвейере мы используем partition-by , чтобы (лениво!) Преобразовать список строк в список списков, которые являются его разделами. Условие разделения таково, что каждая строка, содержащая логического ввода-вывода , отображается на символ t , а все остальные строки просто отображаются на себя. Это означает, что последовательные строки, содержащие логического ввода-вывода , отображаются как раздел, а все остальные строки отображаются изолированными как разделы длины один. Теперь все, что нам нужно сделать с этими данными, - это сопоставить каждый раздел с его первым элементом через (mapcar * first) и передать его в put-lines , чтобы вывести результат.

Мы используем mapcar * , потому что это ленивая версия mapcar . Мы хотим, чтобы все было ленивым, чтобы действие действительно запускалось строками .Когда put-lines марширует по выходному списку, он извлекает элементы из ленивого mapcar * , что заставляет элементы, созданные разделением , разделяться на , что заставляет список, созданный (get-lines) , заставляет ввод-вывод читать эти строки.

Если мы по ошибке воспользуемся обычным mapcar , то возникнет проблема, заключающаяся в том, что весь вывод создается в памяти перед выгрузкой,что плохо для больших файлов.

0
16.06.2015, 22:18
0 ответов

Теги

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