|
||
| Правила | Регистрация | Пользователи | Сообщения за день | | Поиск | | Справка по форуму | Файлообменник | |
|
![]() |
Поиск в этой теме |
![]() |
#1 | |
Как создать маркер c использованием acadЛИСП?
инженер
Оренбург
Регистрация: 18.04.2007
Сообщений: 71
|
||
Просмотров: 4606
|
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,432
|
Попробуй поиск по форуму (слово "автонум*") - может, и найдешь решение.
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Спасибо всем, кто откликнулся.
Позволю себе несколько уточнить задачу. Начнем с примера U-1.1.0 здесь U это префикс и он может быть любым, т.е. должна быть возможность задать его в виде набора символов (U, DD, AA, etc); - черточка это дефис, он тоже может быть любым из набора символов '-', '.',' ', либо его может и не быть вовсе; первая единица - это инфикс - просто целое число, которое задается; точка за первой единицей - это разделитель из набора символов '.', '-', '/', ' ', последнее это пробел, присутствует в выражении обязательно. Разелитель и дефис в одном выражении могут быть разными, а могут и совпадать, поэтому это разные синтаксические конструкции; вторая единица - это тоже инфикс; точка за ним это разделитель; инфиксов может быть произвольное количество либо вообще может и не быть; 0 - это постфикс или суффикс, к нему должна применятся операция инкремент, т.е. его значение увеличивается каждый раз на 1 начиная с некоторого заданного значения. В первом свое посте я привел синтаксическую нотацию данного маркера. Это просто описание синтаксиса данного регулярного выражения. Никаких пояснений я не привел в надежде на то, что программисты понимают без дополнительных разъяснений что это такое. Так вот задачу можно перефразировать следующим образом. 1. Необходимо создать генератор регулярного выражения с указанным синтаксисом. 2. Создать парсер, который будет разбирать поданное ему на вход регулярное выражение и, если оно соответствует указанному синтаксису, то принимать его выделяя из него синтаксические конструкции - префикс, инфикс, постфикс и разделители, создавая при этом список значений и принимая его за образец для генерации последующих выражений. Это необходимо для того, что бы при использовании данной команды мне не надо было каждый раз вводить все параметры регулярного выражения, а я мог бы просто ткнуть в существующее регулярное выражение, которое послужит образцом либо задать образец прямо в командной строке, например ВВ1-2. Тем самым избавляясь от необходимости создавать диалоги, иметь кучу опций и прочие неудобства. Кроме того, имея такой парсер можно будет создать команду, которая будет анализировать весь текст, выбирать из него те выражения, которые будут соответствовать данному регулярному выражению, подсчитывать число типов вхождений по префиксу, заполнять спецификацию, да и еще много чего можно придумать. И при этом можно обходиться без блоков, без атрибутов. А если нужны дополнительные данные для заполнения, к примеру спецификации, всегда можно создать обычный текстовый файл, в котором будут хрвнится эти данные и выбирать их от туда по ключу, значением которого выступает префикс регулярного выражения. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Мне нужен только маркер. Но этот маркер должен быть в состоянии сгенерировать и разобрать регулярное выражение указанного типа.
У меня создается такое впечатление, что необходимо еще растоковать что такое регулярное выражение, хотя, все же я надеюсь на то, что господа программисты, обитающие на этом форуме, все же знают что такое регулярное выражение и что такое синтаксис регулярного выражения и как он записывается. Ну и можно обратиться к вики http://ru.wikipedia.org/wiki/%D0%A0%...BD%D0%B8%D1%8F На С или С++ такого рода программа делается со скоростью с которой вы можете набивать текст и никаких трудностей не предствляет. В использовании лиспа у меня очень малый опыт, поэтому я и обратился сюда. И мне нужна программа на лиспе именно в такой постановке - обработка регулярного выражения указанного типа. |
|||
![]() |
|
||||
Помогаю, кому делать нечего. Регистрация: 27.03.2009
Русская деревня
Сообщений: 394
|
Извините, здесь к сожалению не все профессиональные программисты.
Я, например, инженер-механик, работаю конструктором, программироыванием балуюсь по долгу службы. Если Вы профессиональный программист, Вам должно быть легко освоить еще один язык. Классический Lisp достаточно прост для понимания. А разбираться с парсерами грабберами и регулярными выражениями мне уже не по годам. С уважением, E-degtyarev. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Цитата:
![]() |
|||
![]() |
|
||||
Moderator
LISP, C# (ACAD 200[9,12,13,14]) Регистрация: 25.08.2003
С.-Петербург
Сообщений: 40,432
|
По-моему, именно из-за неопределенности префикса и разделителя нарисовывается некоторая проблема: к примеру, текст 11.1.1 - его как разбирать? Может, я просто не задал префикс? Или он равен "1"?
По идее надо вводить какие-то ограничения. Или я ошибаюсь?
__________________
Моя библиотека lisp-функций --- Обращение ко мне - на "ты". Все, что сказано - личное мнение. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Да, я не расписал достаточно подробно префикс.
Префикс это текст. А текст это буква за которой следуют буквы. В этом случае разночтений не возникнет потому как за префиксом следует дефис, это либо '-', либо '.', либо ничего, либо пробел. И даже в случае "ничего" следующим символом будет цифра (и еще цифры). И если за ней следует точка или другой разделитель, то это инфикс, которого может быть несколько. Если разделителя нет, то это однозначно постфикс. Тотже синтаксис, но другими словами и более сжато [a-zA-Z]+[-|\.|' ']?([0-9]+[\.|-])*[0-9]+ где ? это один из указанных символов, которого может и не быть + это один или более * это 0 или более под данный синтаксис попадают выражения DD-1, DD-2, DD1, DD2 A-1.1.2, А-1.2.5 К1.2, К1.3 Е-1.12.41.1000.100 и т.д DD, A, K, E это префиксы. И префикс по условию присутствует всегда. Привожу исправленный синтаксис. Код:
Последний раз редактировалось Serge_BN, 07.09.2009 в 11:31. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
О, это чудо! Это работает! И даже, еще получаем остаток.
Просто замечательно. По ходу дела у меня есть вопросы. Функция wsmatch принимает в качестве параметра некое выражение. В хелпе я не нашел правила и синтаксис этих выражений. В частности символы @, #, где можно найти подробнее об этом? Почему написано '. и '/ я догадываюсь, но, опять-таки, где это можно прочитать? И следующее, если вас не затруднит, обратная задача. Сгенерировать по заданному шаблону выражение с инкрементом постфикса. Пожалуйста. ![]() |
|||
![]() |
|
||||
Конструирование в области нефтеразведки Регистрация: 10.02.2006
Гомель
Сообщений: 321
|
|
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Спасибо за дополнительную инфу.
Пытаюсь понять как это работает и заодно начинаю осознавать, что лисп обладает очень большой мощьностью при минимальном количестве выразительных средств. Интересно, как бы можно было создать на нем некий шаблон конечного автомата со стеком для обработки контекстно свободных грамматик? Но это так, пока теория. ![]() Я впишу в код свои комменты. Если что не правильно, поправьте, плз. Код:
Не понятно вот что, зачем нужны операции ' и как работает mapcar в паре с apply. И в завершении этого цикла необходим некий драйвер для использования написанных функций. т.е. вызывается команда, например mmark (make marker), она запрашивает образец, который можно ввести в командной строке либо указать мышкой в существующий на чертеже, после чего команда запрашивает точку вставки сформированного маркера, потом следующую точку и т.д. пока не будет нажата клавиша Esc. либо правая кнопка мыши ![]() Замечание. Протестировал функцию (test "21A-1.2.10") и пр. с намеренными "неправильными" выражениями. Обнаружил побочный эффект. 21A-1.2.10 попало в остаток??? и естественно инкремент не может быть применен. Т.е. получается, что все выражения попадают под эту грамматику. Это не правильно. Функция, все-таки должна вернуть либо nil либо пустой список (что удобнее и правильнее??) в случае, если тестируемое выражение не удовлетворяет шаблону регулярного выражения. Последний раз редактировалось Serge_BN, 09.09.2009 в 08:50. |
|||
![]() |
|
|||||
Конструирование в области нефтеразведки Регистрация: 10.02.2006
Гомель
Сообщений: 321
|
Цитата:
Здесь Код:
Код:
Цитата:
Код:
Код:
Цитата:
Код:
Возвращает Т для "правильного" списка: Код:
Цитата:
Последний раз редактировалось CB, 09.09.2009 в 11:54. |
||||
![]() |
|
||||
Конструирование в области нефтеразведки Регистрация: 10.02.2006
Гомель
Сообщений: 321
|
Цитата:
PS: Естественно функция test, сделанная раньше, должна быть загружена. Код:
Последний раз редактировалось CB, 10.09.2009 в 16:49. |
|||
![]() |
|
||||
инженер Регистрация: 18.04.2007
Оренбург
Сообщений: 71
|
Команду протестировал. Работает нормально и по Esc выходит в пустом чертеже. Огромное спасибо. Получилось то, что надо. Уже применяю в работе.
Некоторые строки мне не понятны Код:
Код:
![]() А из этого что-либо мне видится следующее. Сейчас имеется функция test, я бы обозвал ее, все-таки mparse, потому как она выполняет именно разбор выражения. Далее, есть небольшой довесок к ней, который определяет принадлежит ли данное выражение указанной грамматике. Этот довесок можно оформить в виде функции mtest, котороя будет принимать список от mparse и возвращать Т если выражение соответствует грамматике М (маркер). Таким образом применяя эти две функции к множеству всех выражений мы можем получить подмножество всех маркеров в данном чертеже. И есть, надо только оформить в виде функции, генератор регулярного вражения удовлетворяющего грамматике М, обзавем ее mgen (marker generator). Но само по себе множество всех маркеров не очень интересно. Хотелось бы иметь функцию mfind, которая была бы способна находить среди множества всех маркеров маркер удовлетворяющий заданному условию. Например, найти все маркеры с прeфиксом R, или BTH. Префикс можно задать списком (R), (К, ВТН, ВТМ) и т.п. Кроме того, можно было бы критерием поиска задать поиск маркеров с заданными префиксом и инфиксом, ну и для полноты можно задать префикс, инфикс и потфикс, что бы найти конкретный маркер. Возможно задать не полный префикс или инфикс, например (префикс ВТН инфикс 2.*) или (префикс ВТ*)(инфикс 2.*) Найденные маркеры можно размещать в списке, который будет пуст, если ничего не найдено. Имея такой список можно довольно легко подсчитать количество вхождений всех маркеров заданного типа, например количество R, C, D. Там где есть поиск, может быть и замена. Заменить префикс, заменить инфикс для указанного префикса. Ну и конечно функция delete. На основе этого можно создать довольно мощный инструмент для работы с текстовыми данными в чертеже, и областью применения которого могут быть чертежи из разделов СС, автоматизации, ЭО и т.п. Эх как меня занесло далеко. Но, вообще, меня интересуют сейчас возможности лисп по обработке контекстно свободных грамматик. Потому как регулярные выражения обладают наименьшей мощностью из всех типов грамматик, хотя и довольно часто применяются на практике. Но для реализации КС-грамматики необходим автомат со стеком. Как, интересно, обстоят дела в лиспе со стеком? Как его тут можно реализовать? Да и автомат как реализовать мне не ясно? Но это уже от недостаточного знания лиспа. Блн, последний абзац надо воспринимать как свободные блуждания в туманной области. Ну что же. Первый цикл завершен успешно. Приступим к следующему. ![]() Дополнение. Для полноты поиска надо еще сделать поиск первого маркера и поиск последнего маркера. Причем P1.1.5>P1.1.2, P1.3.1>P1.2.100, т.е. при сравнении учитывать инфиксы поразрядно, а потом сравнивать постфикс. Попробую сконструировать функцию mfind_last. Как всегда m - приставка, означающая функцию для работы с маркерами, find_last - наити последний (с наибольшим номером) маркер Код:
Точка в шаблоне говорит о том что это инфикс а не постфикс. Тогда функция mfind_last будет выглядеть так Код:
Далее. На основе фильтра mf можно создать функцию mcount для подсчета количества элементов по шаблону, например (mcount "DD"), (mcount "BTH"), (mcount "RJ*"), (mcount "BTM1.2.*) - все BTM в первом подъезде на втором этаже или от ЩА2, кто как там обозначает. Код:
На основе функции mfind_last можно создать функцию madd.template, которая будет находить последний (с наибольшим номером) элемент и генерировать новый маркер (функция mgen). Тем самым будет гарантировано, что разные элементы имеют разные маркеры. У функции mgen должен быть параметр - 0 - не изменять постфикс; - 1 (или +) - инкремент постфикса; - 2 (или -) - декремент постфикса. - по умолчанию действует 1 (или +), т.е. инкремент. Блоки. Маркер может быть привязан к атрибуту блока. При вставке блока будет вызываться mgen, генерируя новый маркер. Ну обработка блоков с маркерами и прочими атрибутами это уже отдельная песня. Ее споем чуть по позже. Сейчас надо определить функции замены и удаления маркера. Код:
Последний раз редактировалось Serge_BN, 11.09.2009 в 11:25. |
|||
![]() |
![]() |
|
|
![]() |
||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Как в Акад 2006 программно создать подшивку с заданным набор | kp+ | Программирование | 4 | 16.03.2009 23:23 |
Как создать функцию с необязательным вводом параметра | Krieger | Программирование | 2 | 14.02.2009 11:49 |
SW подскажите как создать радиальное отверстие | Chives | SolidWorks | 23 | 17.12.2008 00:54 |
Как создать виртуальный принтер | Владислав Кулигин | Компьютерная и бытовая техника, электроника и инструмент | 4 | 03.01.2008 17:54 |
Юмор 2007 | Огурец | Разное | 1172 | 29.12.2007 11:16 |