Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [CamlP4] О лексерах, парсерах и CamlP4 
V
    Опции темы
Sardar
Дата 10.1.2006, 05:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бегун
****


Профиль
Группа: Модератор
Сообщений: 6986
Регистрация: 19.4.2002
Где: Нидерланды, Groni ngen

Репутация: нет
Всего: 317



Ого... у меня обычно получаеться читать код на не знакомом языке сразу и без проблем, но такой код... млин убил целый вечер, потому сначала о языке smile

Возможно буду говорить глупости, прошу прощения, впервые вижу OCaml и вообще с подобными мозгодробильными вещами не знаком smile

OCaml ставят как функциональный язык ООП "фичами". Как то не проходит "workaround" чувство, как будто OOП притянуто за уши. По коду вижу обьектов "нет", есть классы/модули с функциями принимающими обьекты своих типов, так и C можно назвать ООП языком...

Синтаксис убойный, особено добило отсутсвие явной return операции, надо постоянно думать что последнее выражение и есть возвращаемое, если я правильно понял...
В сборке строк flatten_parts вижу Buffer.create 32, это случайно не ограниченный по размеру буффер? Тогда PHP рулит smile
И Hashtbl.create принимает аргумент число, это что, количество ковшей или максимальная длина ключа? Здесь PHP рулит, он лимитов вроде не имеет smile

Вся прога это туева хуча closures, что правильно, это же функциональный язык. А в практическом плане, проц не любит прыжки по коду, как эффективно тогда исполняеться код?

Вся сила как я понял в match ... with конструкции, что очень загадочна, т.к. принимает строки, типы и даже... собсно
<scheme name=name> _+ as parts </>
что это? Не строка, видел что строки (по крайней мере один символ) в кавычках должны быть. Также не хороший это парсер если парой пробелов больше между <scheme и name и он не сможет найти. match принимает слева XML, видать какая то либа, что логику поиска и реализует, а match "перевызовет" эти функции из XML. А что тогда возвращаеться и вообще что это в языке <...>, какая то особая структура?

Млин теперь вопросов море(конкретно возможности match и её возможные формы), а разбираться с OCaml нет времени/возможности, да и язык своим синтаксисом не приятен. Особено добило правило именования, нафига сокращать имя хеш-таблицы и писать функции/замыкания через '_'... не привычно smile


--------------------
 Опыт - сын ошибок трудных  © А. С. Пушкин
 Процесс написания своего велосипеда повышает профессиональный уровень программиста. © Opik
 Оценить мои качества можно тут.
PM   Вверх
Void
Дата 10.1.2006, 12:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
OCaml ставят как функциональный язык ООП "фичами". Как то не проходит "workaround" чувство, как будто OOП притянуто за уши.

Не то чтобы за уши... Говорят, ООП в OCaml появилось, чтобы Didier Remy защитил диссертацию smile В каждой шутке есть доля... шутки. Сейчас многие OCaml библиотеки, прежде всего, обертки для GUI, используют его. Тот же PXP (Polymorphic XML Parser) полностью объектный.

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
По коду вижу обьектов "нет", есть классы/модули с функциями принимающими обьекты своих типов, так и C можно назвать ООП языком...

Слово "нет" можно без кавычек smile Объектов в моем коде действительно нет, не пригодились. Полиморфизм и инкапсуляцию здесь обеспечивают вариантные типы и модули.
Вообще, ООП в OCaml достаточно интересное... Отношение наследования (is-a) нет, есть отношение subtyping'а (like-a); все методы всегда виртуальны. Т.е. получается такая статическая утиная типизация.

Впрочем, без лишних разговоров пример ООП на OCaml (прим.: private здесь эквивалентно protected в C++/Java):
Код
class virtual expression = object
    method virtual eval : unit -> float
end

class constant value = object
    inherit expression
    method eval () = value
end

class virtual binary_node lhs rhs = object(this)
    method private virtual do_op : float -> float -> float
    method eval () = this#do_op (lhs#eval ()) (rhs#eval ())
end

class plus lhs rhs = object
    inherit binary_node lhs rhs
    method private do_op = (+.)
end


let _ =
    let x = new plus (new constant 3.) (new constant 2.) in
    print_float (x#eval ())


Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
последнее выражение и есть возвращаемое, если я правильно понял...

Да, для любого оператора это так.

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
В сборке строк flatten_parts вижу Buffer.create 32, это случайно не ограниченный по размеру буффер?

Нет, это всего лишь начальный размер буфера, он растет по мере необходимости.
Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
И Hashtbl.create принимает аргумент число, это что, количество ковшей или максимальная длина ключа?

Это тоже начальное число ковшей, хинт для создания хэш-таблицы.

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
Вся прога это туева хуча closures, что правильно, это же функциональный язык. А в практическом плане, проц не любит прыжки по коду, как эффективно тогда исполняеться код?

Слышу ли я это от любителя скриптовых языков? smile Нативный кодогенератор OCaml сравним с компилятором Си средней руки, и иногда обгоняет GCC - несмотря на GC и кучу рантайм проверок. Мелкие closures он вполне может заинлайнить. (Хотя, надо признаться, избытком разума оптимизатор не страдает. Статический анализ явно проигрывает GHC, и если бы не ленивая по умолчанию семантика Haskell...)

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
Вся сила как я понял в match ... with конструкции, что очень загадочна, т.к. принимает строки, типы

Нет, при всей своей мощи pattern matching с типами, к сожалению, не работает smile Или ты имеешь в виду конструкторы вариантных типов (вроде type 'a option = None | Some of 'a)?

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
и даже... собсно
<scheme name=name> _+ as parts </>
что это? Не строка, видел что строки (по крайней мере один символ) в кавычках должны быть. Также не хороший это парсер если парой пробелов больше между <scheme и name и он не сможет найти. match принимает слева XML, видать какая то либа, что логику поиска и реализует, а match "перевызовет" эти функции из XML. А что тогда возвращаеться и вообще что это в языке <...>, какая то особая структура?

Вот! В этом-то вся фишка smile Я недаром говорил про CamlP4. Это архинавороченный препроцессор, фактически программируемый фронтэнд компилятора OCaml. Мы можем писать свои модули, которые с его помощью будут вклиниваться в процесс генерации AST. С помощью CamlP4 можно изменять синтаксис OCaml абсолютно произвольным образом, не затрачивая на это особых усилий - писать CamlP4 расширения в общем-то несложно. Что примечательно, механизм обработки ошибок будет работать по-прежнему, и сообщения об ошибках будут указывать точную позицию в коде до препроцессинга. Т.е. никакого геморроя, с которым обычно ассоциируются препроцессоры, нет в помине.
Но CamlP4 с таким же успехом можно использовать и для создания собственных пасеров, не привязанных к бэкэнду OCaml. Грамматика CamlP4 - это в конечном счете всего лишь функция, преобразующая поток лексем в значение любого типа. Чтобы работать, как синтаксическое расширение, она должна возвращать описанный в специальном модуле тип AST OCaml, но это совсем не обязательно. Впрочем, опять-таки лучше привести пару строк кода; итак, мини-калькулятор на CamlP4:
Код
let grammar = Grammar.gcreate (Plexer.gmake ())
let expr_eoi = Grammar.Entry.create grammar "expr_eoi"

EXTEND
    GLOBAL: expr_eoi;
    expr_eoi:
    [ [ e = expr; EOI -> e ] ];
    expr:
    [ [ x = expr; "+"; y = expr -> x +. y
      | x = expr; "-"; y = expr -> x -. y ]
    | [ x = expr; "*"; y = expr -> x *. y
      | x = expr; "/"; y = expr -> x /. y ]
    | [ x = INT -> float_of_string x
      | x = FLOAT -> float_of_string x
      | "("; e = expr; ")" -> e ] ];
END

let eval s = Grammar.Entry.parse expr_eoi (Stream.of_string s)

let _ =
    while true do
        try
            Printf.printf "%g\n" (eval (read_line ()))
        with
              Stdpp.Exc_located _ -> print_endline "Syntax error"
            | End_of_file -> exit 0
    done

Теперь, думаю, понятно, почему Spirit вызывает у меня улыбку smile
CamlP4 в состоянии разбирать LL(1) грамматики, автоматически производить факторизацию правил, устранение леворекурсивности и заботиться о приоритетах и ассоциативности операторов.

Собственно, вернемся к XML smile OX состоит из двух частей: библиотеки, собственно обеспечивающей разбор XML, и расширения CamlP4, добавляющего синтаксические конструкции XML match и XML { ... }. (Да, XML в коде можно не только разбирать, но и создавать. Получается эдакий встроенный в язык XSLT.) И это расширение, правильно, транслирует XML pattern-matching в вызовы функций первой части. Кстати, внутри, насколько я понял из исходников, строится именно конечный автомат. Исходников там в общей сложности всего на 40 с лишним Кб. Сделать бы этот парсер валидирующим, да поток XML-токенов ленивым, чтобы уменьшить потребление памяти (если это возможно конечно, надо еще разбираться) - вообще вещь получится smile
Да, забыл сказать, лишние пробелы, естественно, не помеха, парсер отнюдь не берет конструкции из кода буквально.

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
конкретно возможности match и её возможные формы

В базовой форме (без расширений) match декомпозирует любые значения, кроме функций (ну это понятно) и объектов (наверное, чтобы не нарушать инкапсуляцию?).

Цитата(Sardar @ 10.1.2006, 07:28 Найти цитируемый пост)
Особено добило правило именования, нафига сокращать имя хеш-таблицы и писать функции/замыкания через '_'... не привычно

Вот тут немного не понял smile Единственное (но обязательное) правило именования - это имена функций и типов с маленькой буквы, а конструкторов и модулей - с большой.

P. S.
Прошу прощения, только сейчас заметил, что код escaped_xml_string скопировал вместе с фатальной ошибкой: незавершенная &...; последовательность приводит к unhandled exception Not_found. Уже поправил.

Это сообщение отредактировал(а) Void - 10.1.2006, 13:44


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
Void
Дата 14.1.2006, 00:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


λcat.lolcat
****


Профиль
Группа: Участник Клуба
Сообщений: 2206
Регистрация: 16.11.2004
Где: Zürich

Репутация: 1
Всего: 173



Guest
Послушайте, не стоит здесь разговаривать в таком тоне.
Цитата(Guest @ 14.1.2006, 01:30 Найти цитируемый пост)
слабО за 10 минут разобраться с любым новым синтаксисо?

С любым? За 10 минут? Если честно, мне - слабо.
Хотя я считаю, что синтаксис - дело вторичное, и предпочитаю видеть его расширяемым.


--------------------
“Coming back to where you started is not the same as never leaving.” — Terry Pratchett
PM MAIL WWW GTalk   Вверх
sergejzr
Дата 19.1.2006, 03:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Un salsero
Group Icon


Профиль
Группа: Админ
Сообщений: 13285
Регистрация: 10.2.2004
Где: Германия г .Ганновер

Репутация: нет
Всего: 360



[offtop] Ребят, а почему у нас не подсвeчивается OCalm? Если пишется столько кода, надо бы и подсвртку для него сообразить, не правда ли? smile может кто займётся определением ключ. слов и структур языка?[/offtop]


--------------------
PM WWW IM ICQ Skype GTalk Jabber AOL YIM MSN   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума «Функциональные языки: общие вопросы»
Void
  • Пожалуйста, создавайте темы с содержательными названиями. Если у Вас вопрос по конкретному языку, укажите его в заголовке, например: «[Haskell] Как использовать монаду State».
  • Уважаемые учащиеся, здесь всегда рады помочь Вам, но не делать за Вас вашу работу. У вас гораздо больше шансов получить помощь, если Вы приложите усилия и поделитесь с нами проблемами и результатами. В противном случае добро пожаловать в раздел Центр Помощи.
  • Получив ответ на интересующий Вас вопрос, не забудьте пометить его как решённый.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Void.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Функциональные языки: общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1010 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.