разбор PGN

Тема в разделе "Машинное отделение", создана пользователем krey, 23 ноя 2008.

  1. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    пытаюсь идумать какой-нибудт простой разбор PGN файлов. пишу на PHP. пытаюсь придумать какой-нибудь простой критерий разделения партий, но пока не выходит. может, есть у кого какие идеи?
     
  2. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    "[Event" - это начало партии.
     
  3. Umpire
    Оффлайн

    Umpire баннер

    Репутация:
    0
    :D NS, браво!
    Но, вообще говоря, начало партии - это "1.", поскольку pgn-файл может вовсе не содержать никаких тегов.
    P.S. С другой стороны, "1." может быть в тегах. Так что задача не простая. ;)
     
  4. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Ничего не простого не вижу. У нас стандартная процедура обхода скобочных выражений.
    Пока идут [* вне скобок - это заголовки, как только кончились заголовки - это текст партии.

    Начало партии - это не ходы, а заголовки. Если бы нужен был первый ход - то наверно так и надо ставить вопрос...
     
  5. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    проблема в другом, насколько обязателен тег заголовка [Event "..."]?
     
  6. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    вот. из стандарта цитата:
     
  7. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    да, в своё время я писал парсер на с++, но он мне не нравился. он споступал сл. образом - считывалась строка, убивались лидирующие пробелы. если полученная строка начинается с [, то это заголовок. если нет, то это ходы, когторые читаются до результата партии. но и в комментариях может быть написано что угодно...
     
  8. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    У меня сделано немного не так.
    последовательности спецсимволов и пробелов заменяются одним пробелом,
    после этого пробел служит разделителем, а дальше разбираем скобочные выражения, то есть по каждой скобке передаем параметр - тип скобки (чтоб потом её закрыть), и считаем уровень вложенности (тоже параметр процедуры) ходы в партии - только на нулевом уровне вложенности, информация о партии - только на первом уровне вложенности, пока не начались ходы, с типом скобки "[".

    Описание скобочной рекурсивной процедуры -
    Skob(s:char;Level:Byte) - первый параметр тип скобки, второй уровень вложенности.
     
  9. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    вообще говоря, когда взялся писать парсер на php идея была использовать регулярные выражения. для каждой записи заголовка составить выражение, результат применения его к файлу - массив. сколько нужно данных из заголовка - столько и выражений. итая партия файла будет итыми элементами массивов. другое дело, что таким способом непонятно как выделить текст партии. шаблончик не строится :(
     
  10. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Не знаю что такое регулярные выражения, но просто разделить заголовки и текст партии (без парсинга самого текста) - это 20 строк кода...
     
  11. dt
    Оффлайн

    dt Новичок

    Репутация:
    0
    Есть такая идея - взять формальное описание синтаксиса из стандарта (http://www.chessclub.com/help/PGN-spec параграф 18), подсунуть его генератору парсеров (аля flex/bison) и получить полноценный парсер, грубо говоря, бесплатно. Но, как обычно бывает со всеми простыми идеями, это уже сделано до нас, в т.ч. и для комбинации PHP+PGN :)
    http://greg.chiaraquartet.net/archives/137-a-parser-generator-for-PHP-finally.html
     
  12. WinPooh
    Оффлайн

    WinPooh В.М. Команда форума

    Репутация:
    95
    По стандарту, насколько, помню, обязательны семь тегов: White, Black, Result, Date, Event, Round, Site.
     
  13. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    хитрите, парниша! © естественно, первым делом я гуглил, перед открытием темы. и в данной ссылке человек высказал, что он вовсю работает над pgn-парсером. однако самого парсера не показал.
    я эти и выбрал для данных, добавил еще fen. правда, обязательное наличие тега round сомнительно.
     
  14. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    кстати, насчет флекса - это идея!
     
  15. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    нехорошие люди в стандарте не определили полностью EBNF. Не определены:
    move-number-indication
    SAN-move
    numeric-annotation-glyph
    первое определить несложно:
    move-number-indication ::= [0-9]+ '.'
    а вот дальше - сложнее... никто не знает где можно найти SAN EBNF?
     
  16. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    в общем, забил на нормальный парсер, написал через попочку, извините за выражение. Посчитал [Event за начало каждой партии.
    есть какие комментарии? :rolleyes:
     
  17. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    кстати, спасибо dt за yacpdb - без него я бы не взялся за то, что делаю :)
     
  18. dt
    Оффлайн

    dt Новичок

    Репутация:
    0
    Тогда ой. Я нашел эту страницу, когда искал генератор парсеров для PHP (т.е. без PGN в запросе, просто аналог lex/yacc) и счёл упоминание парсера именно для PGN знаком свыше. Для SAN, наверное, можно самому написать грамматику, но м.б. имелось в виду, что и SAN и FEN это самостоятельные сущности и для их разбора надо использовать отдельные модули?
    На здоровье, конечно! А чего ты делаешь, если не секрет?
     
  19. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    базу для этюдов. собственно, она уже есть, только надо её заполнять. для этого и нужен парсер pgn.
     
  20. Kirr
    Оффлайн

    Kirr Команда форума Команда форума

    Репутация:
    8
    Парсю почти так же:
    Код:
    if (/^\[Event\s/) ...
    Работает нормально так как дело приходится иметь только с PGN файлами записанными оболочками.
     
  21. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Видимо у всех программистов мысль течет в одном направлении :)
    Парсер PGN (полный, вместе с текстом партии, с открытыми исходниками) есть на JAVA.
    Используется на сайте www.crestbook.com :)
     
  22. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    =0
    где?! как я его пропустить смог?!
     
  23. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
  24. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
  25. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    так это же не ява :) а javascript, и Crest этим не пользуется... но ты прав, это парсер. Не полный (варианты не парсит), но рабочий.
     
  26. NS
    Оффлайн

    NS Нефёдов Сергей баннер

    Репутация:
    3
    Да я знаю что скрипт. Сократил название языка :)
    У меня где-то парсеры валяются на Делфи - но мне их не найти, я свои исходники постоянно теряю... Спроси, может я Фрукту высылал исходники парсинга pgn для сбора статистики по проценту совпадения ходов программ.
     
  27. Fruit
    Оффлайн

    Fruit Александр баннер

    Репутация:
    3
    У меня только сама программка.
     
  28. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    а я у себя нашел ошибку в коде. конфликт с тегом "EventDate". Решается добавлением пробела в разбор "Event". Думаю, еще возможны такие ошибки и с другими тегами, потому везде надо повставлять пробелы.
     
  29. Tinefol
    Оффлайн

    Tinefol Учаcтник

    Репутация:
    0
    Полноценный парсер на javascript мною написан давно (в принципе они и на php есть написанные, например DHTML Chess).

    Вот такя я разделял игры:

    Код:
    commentaries = [];
            this.games = [];
            // IE uses \r\n, Gecko browsers use \n
            PGN = PGN.replace(/\r\n/g,"\n");
            // Replace bracket {} commentaries because the can mess up how we determine the game edges, store them in array
            PGN = PGN.replace(/\{([\W\w]*?)\}/g, function($1) {
                commentaries.push($1.substring(1, $1.length - 1));
                return "{" + (commentaries.length - 1) + "}";
            });
    
            // Replace strings (because they can contain the semicolon comments,
            // which could once again cripple our ability to parse the games correctly) and store them in array
            var tagStrings = [];
            PGN = PGN.replace(/"([^"\\\r\n]*(?:\\.[^"\\\r\n]*)*)"/g, function($1) {
                // Also attempt to replace back "nested" {} comments because they can appear inside these strings
                tagValue = $1.replace(/\{([\d]+)\}/g, function ($1) {
                    return commentaries[$1.substring(1, $1.length - 1)];
                });
                tagStrings.push(tagValue.substring(1, tagValue.length - 1));
                return "\"" + (tagStrings.length - 1) + "\"";
            });
    
            // Replace semicolon this.commentaries and store them in array
            PGN = PGN.replace(/(;[\W\w]*?)\n/, function($1) {
                // Also attempt to replace back "nested" {} comments because they can appear inside semicolon commentaries
                    commValue = $1.replace(/\{([\d]+)\}/g, function ($1) {
                    return "{" + commentaries[$1.substring(1, $1.length - 1)] + "}";
                });
                commentaries.push(commValue.substring(1, commValue.length));
                return "{" + (commentaries.length - 1) + "}\n";
            });
            
            // Split the Games
            gamesArray = PGN.match(/(\[[\W\w]*?(?:0-1|1-0|1\/2-1\/2|\*))(?:[\s]+|$)/g);
     
  30. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1
    интересно. для меня
    выглядит откровением. однако логично.
     
  31. krey
    Оффлайн

    krey Михаил Кройтор Команда форума Команда форума

    Репутация:
    1