Просто напишите простой скрипт на Лиспе или Схеме, который зацикливается на чтении и рекурсивно обрабатывает ваш s-expr по мере необходимости. В Linux я бы рекомендовал использовать Guile (хороший интерпретатор Scheme) или, возможно, Clisp (простая реализация Common Lisp) или даже SBCL (очень мощный Common Lisp ).
(Вы можете рассмотреть DSSSL , но в вашем случае это излишне)
Обратите внимание, что ваш пример ввода не S-выражение [ 117], потому что (layer F.Fab)
не одно (поскольку после точки у вас должно быть другое s-выражение, а не атом, как Fab
). Я думаю, что это опечатка и должно быть (layer "F.Fab")
; или, может быть, ваше программное обеспечение KiCad не обрабатывает S-выражения, но какой-то другой язык ввода (который должен быть указан, вероятно, в нотации EBNF ) вдохновлен S-выражениями.
Также обратите внимание, что KiCad является свободным программным обеспечением и имеет сообщество с форумами и списком рассылки. Возможно, вам стоит спросить о вашей настоящей проблеме?
PS. Мы не знаем, какую трансформацию вы имеете в виду, но Scheme и Common Lisp действительно подходят для таких задач. В большинстве случаев они чрезвычайно просты для кодирования (возможно, всего несколько строк).
Существует полезное List<T>.RemoveAll(Predicate<T> match)
метод, который я думаю, разработан для этого: http://msdn.microsoft.com/en-us/library/wdka673a.aspx
Это довольно бесхитростно, но когда я планирую удалить объекты из IEnumerable/IList, я обычно просто делаю копию:
foreach (MyObject myObject in new List<MyObject>(MyListOfMyObjects))
{
if (condition) MyListOfMyObjects.Remove(myObject);
}
Это не самый эффективный способ сделать это, но легко читать. Преждевременная оптимизация и все это.
Сделайте инверсию, создав новый список:
List myFilteredList = new List();
foreach (MyObject myObject in myListOfMyObjects)
{
if (!condition) myFilteredList.Add(myObject);
}
Затем используйте новый список везде, где Вам нужен он.
Можно также использовать выражение LINQ легко, снова, inversing условие. Это обладает дополнительным преимуществом не создания новой структуры, но также и ловушек ее являющийся ленивым счетным:
var myFilteredList = from myObject in myListOfMyObjects
where !condition
select myObject;
Однако, если действительно необходимо удалить объекты из списка, я обычно использую, "создают новый список, затем повторяют и удаляют" подход.
Мне не нравится обратное за идею цикла, с тех пор тот единственные работы над определенными структурами данных.
В целом я использовал бы вторую технику и накопил бы объекты, которые будут удалены в отдельном 'удаленном будущим образом' наборе. Если удаление может вызвать существующий, выполняет итерации, чтобы делаться недействительным (как это произойдет с любым набором сбалансированного дерева, например), затем, я не вижу путь вокруг этого.
Единственная другая техника, которую я иногда использовал, состоит в том, чтобы перезапустить целое повторение, когда Вы находите, что первый элемент удаляет. Если Вы удаетесь, не находя, что любые объекты для удаления затем функции закончены. Это неэффективно, но иногда необходимо, если удаление одного объекта от набора может изменить набор объектов, которые должны быть удалены.
Я понимаю, что это может быть мертвым, но я всегда делаю это следующим образом:
foreach (MyObject myObject в MyListOfMyObject)
{{1 }} {
if (условие) MyListOfMyObjects.Remove (myObject);
break;
}
Объект удаляется, а затем цикл завершается, альт!