Написание рекурсивного макроса M4 для обозначения точечных изображений

#m4

#м4

Вопрос:

Я пытаюсь написать макрос M4 для создания точечной записи, но я борюсь с рекурсией.

Я хотел бы иметь макрос, который принимает первый параметр и добавляет отношение точечной диаграммы для всех остальных параметров. Например

 coachExisting(a, b, c, d)  

будет производить

 a -gt; b; a -gt; c; a -gt; d;  

Это была моя попытка сделать это:

 define(coachExisting, `ifelse(eval($#==2), 1, `ifdef(first, first, $1) -gt; $2;', ifelse(eval($#gt;2), 1, `ifdef(first, ,define(first, $1)) first -gt; $2; $0(shift($*))') )')  

Однако это, похоже, работает только в том случае, если я использую числа

 coachExisting(1, 2, 3, 4) 1 -gt; 2; 1 -gt; 3; 1 -gt; 4;  

Когда я пытаюсь использовать буквы, кажется, что они теряют first определение.

 coachExisting(a, b, c, d) b -gt; b; b -gt; c; c -gt; d;  

Ответ №1:

Вы играете быстро и свободно с цитированием. Пожалуйста, внимательно прочитайте руководство m4 для получения инструкций по цитированию и рекурсивной оценке макросов. При первом расширении вы получаете define(first, $1) =gt; gt; define(first, a) . Но при втором выполнении он расширяется как define(first, $1) =gt; gt; define(first, b) =gt; gt; define(a, b) (потому first что расширяется как макрос). Вам нужно цитировать first везде, где вы можете, так define(`first', `$1')' что для начала.

Гораздо более чистый способ реализации вашего макроса-это с самого начала избегать временного макроса. Я бы рекомендовал что-то вроде:

 define(`coachExisting', `ifelse(eval($#==2), 1,  `$1 -gt; $2',  `$1 -gt; $2; $0(`$1', shift(shift($@)))')')  

(однако будьте осторожны-я не разработал этот макрос для обработки случаев с аргументом 0 или 1).