LINUX.ORG.RU

ECL + ASDF


0

2

Помогите, пожалуйста, освоиться с Embedded Common Lisp.

Хочу распарсить XML с помощью одного из множества парсеров для CL.

Проблема в том, что у меня не получается подключить пакет ASDF. Делаю так:

(require 'asdf)

(push «/путь/к/xmls/» asdf:*central-registry*)

(require 'xmls)

Получаю

Internal error:
;;; ** (SYSTEM «i486-linux-gnu-gcc и т.д.


erred while invoking #<ASDF:COMPILE-OP NIL 155795840> on #<ASDF:CL-SOURCE-FILE „xmls“ 155710184>

Available restarts:

1. (TRY-RECOMPILING) Try recompiling xmls
2. (RETRY) Retry performing #<ASDF:COMPILE-OP NIL 155795840> on #<ASDF:CL-SOURCE-FILE „xmls“ 155710184>.
3. (ACCEPT) Continue, treating #<ASDF:COMPILE-OP NIL 155795840> on #<ASDF:CL-SOURCE-FILE „xmls“ 155710184> as having been successful.
4. (RESTART-TOPLEVEL) Go back to Top-Level REPL.

Broken at ASDF:PERFORM. In: #<process SI:TOP-LEVEL 0826afc0>.

Очевидно, что ECL пытается запустить gcc, но такого нет есть i686-linux-gnu-gcc.

В связи с этим два вопроса:

1. Если я не хочу, чтобы файлы компилировались в нативный код (хочу байткод)?

2. Если хочу, как мне указать правильную версию GCC?

Пробовал переменную среды CC, но не помогло.

★★

Ответ на: комментарий от k_andy

Результат тот же. Все равно компилирует с помощью GCC. Как я понял, он по любому с помощью GCC компилит. Т.е. скорее первый вопрос отпадает, а вот второй остается.

olegk ★★ ()
Ответ на: комментарий от olegk

У cffi-grovel есть переменная *cc*, у ECL тоже должно быть что-то в этом роде - поищите в документации. В крайнем случае можно сделать символическую ссылку i486-linux-gnu-gcc -> i686-linux-gnu-gcc.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Искал, но не нашел. Я только Lisp осваиваю. Может быть есть способ посмотреть список всех глобальных переменных?

olegk ★★ ()
Ответ на: комментарий от archimag

Как раз меня и заинтересовала возможность компилировать в С и встраивать. Сам по себе Lisp не столь важен для меня. Т.е. именно идея ECL меня заинтересовала.

До этого пробовал TinyScheme (для встраивания), но он оказался слабоват с точки зрения поддержки библиотек.

olegk ★★ ()

Никогда не работал с ECL, но из того, что ты написал, не следует,что он пытается запустить gcc. Приведи полное сообщение об ошибке. И приведи ещё содержимое файла твой-xml-парсер.asd

Попробуй просто сделать какой-нибудь файл *.lisp, например, a.lisp (defun foo () ) и скомпилируй его:

(load (compile-file «a.lisp»))

Насколько я знаю (могу ошибаться), ECL компилирует путём вызова компилятора C. Если ошибка связана с этим, то, скорее всего,она и здесь вылезет. Насчёт ECL, да, не лучший выбор для начала. Возьми лучше ccl. SBCL, когда я с ним последний раз работал, не показывал имена переменных в отладчике.

den73 ★★★★★ ()
Ответ на: комментарий от olegk

apropos - первым аргументом строка-начало символа (если пустая строка - все символы), вторым можно указать пакет (тоже строкой, всё в верхнем регистре, если не указывать, то будет поиск по всем пакетам). http://ecls.sourceforge.net/new-manual/ch05.html - это какие у них пакеты.

(apropos "" "SYSTEM")
(apropos "" "CMP")
quasimoto ★★★★ ()
Ответ на: комментарий от olegk

>Может быть есть способ посмотреть список всех глобальных переменных?
нет, но можно написать

(apropos «cc»)

- покажет все символы, в имена которых входит cc.

den73 ★★★★★ ()
Ответ на: комментарий от den73

Спасибо, добрый человек! Наполовину помогло.

(setq C:*CC* «gcc»)

И оно смогло собрать мне *.o. Дальше запускается линкер:

i486-linux-gnu-gcc -o ...

Опять ошибка.

Ну я как человек Вами обученный сразу понял надо искать следующую переменную и она есть:

C::*LD* has value: «i486-linux-gnu-gcc»

Задаю так же:

(setq C:*LD* «gcc»)

Debugger received error: Cannot find the external symbol *LD* in #<«C» package>.
Error flushed.

И получаю ошибку.

olegk ★★ ()
Ответ на: комментарий от quasimoto

(setq C::*LD* «gcc»)


Спасибо. Ну это я уже от перенапряжения:))) Все сработало. Спасибо Всем, кто принял участие в обсуждении.

olegk ★★ ()
Ответ на: комментарий от den73

Он просил список глобальных переменных.

А можно только перечислить символы. Хотя, можно ещё отфильтровать их по использованию #\* в символе:

(defun global-variables/external (package-designator)
  (loop :for symbol :being :the :external-symbol :in package-designator
        :when (char= #\* (char (string symbol) 0))
        :collect symbol))

(defun global-variables (package-designator)
  (loop :for symbol :being :the :symbol :in package-designator
        :when (char= #\* (char (string symbol) 0))
        :collect symbol))

или сделать так:

(defun constant-or-variable-p (symbol)
  (and (boundp symbol) (not (fboundp symbol))))

(defun globals (package-designator)
  (loop :for symbol :being :the :symbol :in package-designator
        :when (constant-or-variable-p symbol)
        :collect symbol))

(defun globals/external (package-designator)
  (loop :for symbol :being :the :external-symbol :in package-designator
        :when (constant-or-variable-p symbol)
        :collect symbol))

но так не получится получить unbound переменные.

quasimoto ★★★★ ()
Ответ на: комментарий от olegk

Да уж, далее пошло еще веселее.

(with-open-file (stream «/путь/к/Test.xml»)
(xmls:parse stream))

Debugger received error: Detected access to an invalid or protected memory address.
Error flushed. (И так много раз...)

Debugger received error: Ошибка сегментирования

Спрашивается: зачем такое счастье надо, если оно как C падает с ошибками сегментации. Как раз была идея с помощью Lisp склеивать куски кода на C, т.к. я считал, что с перехватом ошибок тут все будет хорошо. Или может можно заставить его быть более безопасным?


olegk ★★ ()
Ответ на: комментарий от olegk

Ты всё-таки сделай то, что я тебя в первом ответе попросил. А именно, полный текст ошибки и текст твоего .asd. Может быть, дело вообще в другом.

den73 ★★★★★ ()
Ответ на: комментарий от den73

;;; -*- Lisp -*-
;;; $Id: xmls.asd 579 2010-12-09 23:53:08Z rpgoldman $

(defpackage #:xmls-system (:use #:cl #:asdf))
(in-package :xmls-system)

(defsystem :xmls
:version «1.4.0»
:components ((:file «xmls»)
(:file «xmlrep-helpers»
;; package is defined in XMLS. [2009/02/24:rpg]
:depends-on («xmls»))))

Ошибку привести не могу, т.к. после того как правильно указал компилятор ошибок нет.

olegk ★★ ()
Ответ на: комментарий от quasimoto

А если так?

(defun is-global-var-or-const (symbol) 
   (not 
     (search "warning" 
       (with-output-to-string (*error-output*) 
         (compile `(defun ,(gensym) () ,symbol))) 
      :test 'char-equal)))

(do-symbols (s :cl-user) 
  (when (is-global-var-or-const s) (print s)))

den73 ★★★★★ ()
Ответ на: комментарий от olegk

Система вполне безобидная на вид. Я просто подумал, вдруг там, в системе, есть какие-то файлы на С? А их нет.

Ошибку привести не могу, т.к. после того как правильно указал компилятор ошибок нет.


Ну, тогда я пас. Предположительно, что ты всё же неправильно указал компилятор (например, нужны какие-то флаги), или что компилятор каким-то образом не подходит к данному образу. Может, надо ECL собрать самому. Тут я могу сказать только RTFM, т.к. с ECL почти не работал (поставил один раз под офтопиком, быстро добился первого краха и на этом решил, что клиент ещё не созрел).

В общем-то, другие реализации лиспа тоже можно заставить работать с кодом на C, правда, не факт,что ты будешь при этом встраивать лисп в С,вполне может оказаться, что и наоборот.

den73 ★★★★★ ()
Ответ на: комментарий от den73

А если так?

Это жуткий изврат и вообще не будет работать (нужно (compile nil `(lambda () ,symbol))) и точно в стандарте есть про warning в *error-output*? В SBCL, например, там «WARNING» :) Лучше так:

(defun globals (package-designator)
  (sb-impl::collect ((global-symbol))
    (do-symbols (symbol package-designator)
      (unless (fboundp symbol)
        (global-symbol symbol)))
    (global-symbol)))

(defun all-globals ()
  (sb-impl::collect ((global-symbol))
    (do-all-symbols (symbol)
      (unless (fboundp symbol)
        (global-symbol symbol)))
    (global-symbol)))

(defun bounded-globals (package-designator)
  (sb-impl::collect ((global-symbol))
    (do-symbols (symbol package-designator)
      (when (and (boundp symbol) (not (fboundp symbol)))
        (global-symbol symbol)))
    (global-symbol)))

(defun all-bounded-globals ()
  (sb-impl::collect ((global-symbol))
    (do-all-symbols (symbol)
      (when (and (boundp symbol) (not (fboundp symbol)))
        (global-symbol symbol)))
    (global-symbol)))
quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

> Это жуткий изврат и вообще не будет работать (нужно (compile nil

`(lambda () ,symbol)))

Может и не будет, но пока что работает (lispworks 6.0). Я это скопипастил из REPL. WARNING годится, т.к. :test 'char-equal

den73 ★★★★★ ()
Ответ на: комментарий от olegk

Скорее всего у вас плохая сборка:

~ $ sudo USE="threads gengc debug" emerge ecls
...
~ $ sudo emerge alexandria xmls drakma
...
~ $ ecl
...
> (require 'asdf)
...
> (asdf:oos 'asdf:load-op :alexandria)
...
> (asdf:oos 'asdf:load-op :xmls)
...
> (alexandria:write-string-into-file
 "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>
<note>
  <to>a</to>
  <from>b</from>
  <heading>c</heading>
  <body>d</body>
</note>"
 "a.xml")
...
> (with-open-file (s "a.xml") (xmls:parse s))

("note" NIL ("to" NIL "a") ("from" NIL "b") ("heading" NIL "c") ("body" NIL "d"))

Правда при попытке загрузить drakma:

> (asdf:oos 'asdf:load-op :drakma)
...
LOAD: Could not load file #P"/home/treep/.cache/common-lisp/ecl-10.4.1-linux-x86/usr/share/common-lisp/source/usocket/backend/sbcl.fas" (Error: "/home/treep/.cache/common-lisp/ecl-10.4.1-linux-x86/usr/share/common-lisp/source/usocket/backend/sbcl.fas: undefined symbol: cl_alloc_atomic")

при этом всё остальное (flexi-streams, babel, cffi, и т.д.) загружается - нужно патчить usocket.

И ещё quicklisp не работает:

~ $ wget http://beta.quicklisp.org/quicklisp.lisp
...
~ $ ecl -load quicklisp.lisp
...
> (quicklisp-quickstart:install)
...
> (ql:add-to-init-file)
...
> (ql:system-apropos "xml")

#<QL-DIST:SYSTEM bknr.xml / bknr-datastore-20101006-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cl-libxml2 / cl-libxml2-0.3.4 / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cl-libxml2-test / cl-libxml2-0.3.4 / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cl-xmlspam / cl-xmlspam-20101006-http / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml / cxml-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-dom / cxml-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-klacks / cxml-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-rng / cxml-rng-2008-11-30 / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-rpc / cxml-rpc-20101006-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-stp / cxml-stp-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-stp-test / cxml-stp-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-test / cxml-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM cxml-xml / cxml-20101107-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM hu.dwim.perec+hu.dwim.quasi-quote.xml / hu.dwim.perec-20101107-darcs / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM hu.dwim.quasi-quote.xml / hu.dwim.quasi-quote-20101107-darcs / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM hu.dwim.quasi-quote.xml+cxml / hu.dwim.quasi-quote-20101107-darcs / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM hu.dwim.quasi-quote.xml+hu.dwim.quasi-quote.js / hu.dwim.quasi-quote-20101107-darcs / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM hu.dwim.util.flexml / hu.dwim.util-20101207-darcs / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM pithy-xml / pithy-xml-20101006-git / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM s-xml / s-xml-20101006-http / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM s-xml-rpc / s-xml-rpc-20101006-http / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM xml-render / cl-typesetting-20101006-svn / quicklisp 2010-12-07>
#<QL-DIST:SYSTEM xmls / xmls-1.3 / quicklisp 2010-12-07>
NIL

> (ql:quickload "xmls")
...
> (ql:quickload "drakma")
...
LOAD: Could not load file #P"/home/treep/.cache/common-lisp/ecl-10.4.1-linux-x86/usr/share/common-lisp/source/usocket/backend/sbcl.fas" (Error: "/home/treep/.cache/common-lisp/ecl-10.4.1-linux-x86/usr/share/common-lisp/source/usocket/backend/sbcl.fas: undefined symbol: cl_alloc_atomic")

> (quit)

~ $ ecl
...
Upgrading ASDF package from version 1.655 to version 2.010
ASDF could not load sockets because Error while trying to load definition for
                                    system sockets from pathname
                                    /usr/lib/ecl-10.4.1/sockets.asd:
                                    No applicable method for SOURCE-FILE-TYPE with arguments of types
 COMPILED-FILE
 PREBUILT-SYSTEM.
An error occurred during initialization:
Error while trying to load definition for system sockets from pathname
/usr/lib/ecl-10.4.1/sockets.asd:
No applicable method for SOURCE-FILE-TYPE with arguments of types
 COMPILED-FILE
 PREBUILT-SYSTEM.

~ $ 

видимо потому что quicklisp ставит новый ASDF, а у ECL он свой должен быть.

quasimoto ★★★★ ()
Ответ на: комментарий от olegk

> Спрашивается: зачем такое счастье надо, если оно как C падает с ошибками сегментации.

Падает потому что по умолчанию ECL собирает c (SAFETY 0). Такая избыточная оптимизация:( Если воспользоваться DECLAIM и выставить (SAFETY 2), то все станет проще. А еще там все инлайнится, а еше все в документации написано. Но её никто, никогда...

antares0 ★★★★ ()
Ответ на: комментарий от quasimoto

Я пытался пересобирать. Думаю дело в размере XML.

(xmls:parse «<x a=\„qq\“> </x>») работает на ура:)

А вот при 26 кБ ему как-то плохеет.

Если у Вас есть возможность проверить на реальном XML посмотрите, пожалуйста.

olegk ★★ ()
Ответ на: комментарий от quasimoto

нужно патчить usocket

http://www.mail-archive.com/usocket-devel@common-lisp.net/msg00157.html

72: - "cl_alloc_atomic(sizeof(fd_set))" :one-liner t))
72: + "ecl_alloc_atomic(sizeof(fd_set))" :one-liner t))

100: - "{ char *buf = cl_alloc_atomic(257);
100: + "{ char *buf = ecl_alloc_atomic(257);

После чего работает даже Drakma:

> (drakma:http-request "http://google.ru")
...
quasimoto ★★★★ ()

ECL - бинарная сборка откуда-то чтоли стащена?
Его надо самому собирать, на конкретной системе, чтобы нормально работал.

anonymous ()
Ответ на: комментарий от olegk

А вот при 26 кБ ему как-то плохеет.

Попробовал на каталоге размером 100 кб - никаких проблем, сразу возвращает список.

quasimoto ★★★★ ()
Ответ на: комментарий от olegk

Попробуйте ещё, действительно, выставить debug и safety:

;; почистите кэш ecl, потом

(declaim (optimize (debug 3) (safety 3) (speed 1)))
(require 'asdf)
(asdf:oos 'asdf:load-op :xmls)
(with-open-file (s "...") (xmls:parse s))
quasimoto ★★★★ ()
Ответ на: комментарий от antares0

Падает потому что по умолчанию ECL собирает c (SAFETY 0). Такая избыточная оптимизация:( Если воспользоваться DECLAIM и выставить (SAFETY 2), то все станет проще. А еще там все инлайнится, а еше все в документации написано. Но её никто, никогда...


Зря Вы так. Я читал. Вот я читаю: http://ecls.sourceforge.net/new-manual/ch02.html The OPTIMIZE declaration includes three concepts: DEBUG, SPEED, SAFETY and SPACE.

И как мне их задать?

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

olegk ★★ ()
Ответ на: комментарий от quasimoto

(declaim (optimize (debug 3) (safety 3) (speed 1)))


Спасибо за совет, а то я до этого declaim не сам бы не дошел по документации.

olegk ★★ ()
Ответ на: комментарий от quasimoto

Кэш почистил $HOME/.cache/common-lisp.

И сделал как было сказано. Все тоже самое. Та с которой я начинал эту тему была из убунты. Эта версия собрана самостоятельно (уже нет проблем с компилятором).

http://www.mail-archive.com/usocket-devel@common-lisp.net/msg00157.html


Попробую найти, что пропатчить, но у меня такой строчки нет (да и комментарий был про очень старую версию)

olegk ★★ ()
Ответ на: комментарий от den73

den73 писал

(defun is-global-var-or-const (symbol)
   (not (search "warning"
                (with-output-to-string (*error-output*)
                   (compile `(defun ,(gensym) () ,symbol)))
                :test 'char-equal)))

Да вы с ума сошли. Во-первых есть boundp, во-вторых warning-и обычные condition и ловяся обчными средствами.

antares0 ★★★★ ()
Ответ на: комментарий от antares0

А библиотеку перезагрузили?


Я перезапускал ecl полностью (и уже не раз, так он, как я сказал, падает на раз у меня).

olegk ★★ ()
Ответ на: комментарий от olegk

Попробую найти, что пропатчить, но у меня такой строчки нет (да и комментарий был про очень старую версию)

Это не надо - то для usocket. У вас xmls не работает, у него нет зависимостей и он простой как пробка - там всё на уровне работы со streams. Так что проблемы могут быть только в сборке ecl - почему-то он не работает с потоками для больших фалов.

(alexandria:read-file-into-string "big.xml")

Так хотя бы работает?

Для работы с XML есть ещё cl-libxml2, который строит FFI к libxml2 - у меня он тоже работает на ECL.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Для работы с XML есть ещё cl-libxml2


Я ставлю перед собой задачу выбрать надежную кроссплатформенную реализацию встраиваемого языка (cl или scheme). Поэтому меня беспокоит не сама по себе библиотека xmls (пусть в ней что-то не так). Мне гораздо более интересно, почему при этом падает ecl (такого как раз быть не должно).

olegk ★★ ()
Ответ на: комментарий от olegk

Тогда при некоторой доли упорства после declaim и asdf попробывать (step ваш-код) и попутно заглядывая в исходники xmls посмотреть кула придем.

antares0 ★★★★ ()
Ответ на: комментарий от olegk

Тогда при некоторой доли упорства после declaim и asdf попробывать (step ваш-код) и попутно заглядывая в исходники xmls посмотреть кула придем.

antares0 ★★★★ ()
Ответ на: комментарий от quasimoto

Скачал из GIT alexandria. Проверил (alexandria:read-file-into-string «big.xml») - все считалось и вывелось на экран.

Может мне куда-нить кинуть мой XML файл?

olegk ★★ ()
Ответ на: комментарий от olegk

Может мне куда-нить кинуть мой XML файл?

Давайте, я проверю.

Ещё - вы собираете ecl из git? И собираете ли с поддержкой unicode — в их майл-листе гуглится это ошибка, там человек пытается читает из файла в UTF-8 кодировке, но собрал ECL без unicode. У меня работающая версия собрана с поддержкой X (это для CLX), unicode, debug, gengc и threads; без поддержки precisegc.

quasimoto ★★★★ ()
Ответ на: комментарий от antares0

А если переменная декларирована, но unbound? Ловятся-то ловятся,но это я написал за одну минуту, а обычными средствами это заняло бы дольше.

den73 ★★★★★ ()
Ответ на: комментарий от olegk

Ещё могут быть проблемы с кодировками:

(with-open-file (s "foo.xml" :external-format '(:unicode :little-endian nil :eol-style :crlf))
  (xmls:parse s))

:external-format можно разный выставлять, но это implementation depends параметер.

(with-open-file (s "foo.xml")
  (let ((s (flexi-streams:make-flexi-stream s :external-format '(:utf-8 :eol-style :lf))))
    (xmls:parse s)))

Это перекодировка с помощью flexi-stream — должно работать даже если ecl чего-то не поддерживает.

У меня при неправильной кодировке пишется что-то вроде

Debugger received error: Unable to find mapping file sys:encodings;EOL-STYLE.BIN for encoding EOL-STYLE
Error flushed.

или

Debugger received error: In function GETHASH, the value of the second argument is
  SI::UCS-2
which is not of the expected type HASH-TABLE
Error flushed.

но никак не seg. fault.

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

но никак не seg. fault.

А, я же ещё с USE=«debug» собирал :)

quasimoto ★★★★ ()
Ответ на: комментарий от quasimoto

Ладно, в другой раз об этом поговрим, а то тут люди делом заняты.

den73 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.