Как разобрать S-выражение в Erlang? - PullRequest
2 голосов
/ 18 марта 2011

Я использую клиентский агент для Robocup Soccer simulator in Erlang .Симулятор отправляет сенсорную информацию клиенту в виде S-выражений .Вот так

(see 15 ((f c) 2 0 0 0) ((f r t) 64.1 -32) ((f r b) 64.1 32) ((f g r b) 55.1 7) 
 ((g r) 54.6 0) ((b) 2 0 -0 0) ((l r) 54.6 90)) 
(see 16 ((f r t) 72.2 -44) ((f r b) 54.1 20) ((f g r b) 52.5 -10) ((g r) 54.1 -17)
 ((l r) 51.4 -89))

Имитатор отправляет данные сенсора такого типа в каждом цикле (100-200 мсек).Основной формат информации:

(see Time ObjInfo ObjInfo . . . )

ObjInfos имеют следующий формат:

(Направление расстояния ObjName [DistChange DirChange [BodyFacingDir HeadFacingDir]])

где объекты похожи: (b) мяч, (gr) правильная цель, (f ...) представляет различные флаги.

Что я хочу, это анализ эта информация и сохранение / обновление в некоторой базе данных (записи) для использования для анализа.Основная сложность, с которой я сталкиваюсь - это разобрать эту информацию.Пожалуйста предложите мне какой-нибудь способ сделать это ?(есть ли в Erlang библиотека для такой работы)

Ответы [ 3 ]

4 голосов
/ 18 марта 2011

Yecc и Leex - ваши друзья: http://erlang.org/doc/apps/parsetools/index.html

Leex - генератор лексического анализатора для Erlang, который будет токенизировать ваши данные. Yecc - генератор синтаксического анализа LALR-1, который может анализировать ваши токены в значимые структуры.

Есть хороший блог от Relops, Leex And Yecc , подробно описывающий некоторые основы.

2 голосов
/ 20 марта 2011

Если вы загрузите LFE (Erlang со вкусом Lisp) , он содержит сканер lisp и анализатор.Модули, которые вам нужны, это lfe_scan, lfe_parse и lfe_io, которые обертывают два других.Сканер написан с использованием leex (источник lfe_scan.xrl), в то время как анализатор написан от руки, поскольку есть некоторые особенности работы yecc, которые не совсем подходят.

0 голосов
/ 18 марта 2011

Правильный подход - написать небольшого читателя LISP.

Быстрый и (очень) грязный способ (ТОЛЬКО для первоначального тестирования): заменить пробел запятой, "(" на "{" и ")" на "}". Тогда у вас есть литерал Erlang.

Посмотрите на erl_scan и erl_parse.

...