LINUX.ORG.RU

Ещё один экзотический формат сериализации. Как бы вы это парсили?

 


0

2

Доброго времени суток

IBM, родина велосипедов

Вот кусок вывода «lsyscfg -r prof -m $server» с hmc

affinity_group_id=none,
"io_slots=21010284/none/1,21010204/none/1,21010205/none/1,2101028D/none/0",
"virtual_eth_adapters=""72/1/1/704,706,744,714,715,700/1/0/ETHERNET0//all/none"",73/0/199//0/0/ETHERNET0//all/none,74/0/714//0/0/ETHERNET0//all/none",

на строки разбил я, чтобы было понятнее. В выводе утилиты всё это в одной строке слитно, без пробелов

Видны минимум три уровня:

  • на первом уровне параметры разделены запятой
  • на втором уровне ( если в значении параметра есть отдельные элементы, разделённые запятой ), вся пара key=value заключается в кавычки
  • на третьем уровне ( если в параметре есть элементы, разделённые запятой, которые в свою очередь разделены на подэлементы, также запятой ), подэлемент заключается в двойные кавычки

Насколько я понимаю, обойтись лямбдами не получится, придётся перебирать всю строку по символу, учитывая на каком уровне сейчас находишься.

Есть идеи лучше? Или может это не велосипед, а более-менее стандартный формат и есть готовые библиотеки?

★★★★★

Последнее исправление: router (всего исправлений: 1)

обойтись лямбдами не получится

При чём тут лямбды?

Может стоит начать с прототипа PEG парсера?

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

При чём тут лямбды?

split, map, вот это всё

Может стоит начать с прототипа PEG парсера?

спасибо, посмотрю. до этого думал писать что-то с логикой конечного автомата

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

В Jobs!

Нет. Мне за решение не заплатят ( автоматизирую свои задачи ), так что и смысла аутсорсить нет. Тем более что мне нужен не готовый код, а пинок в нужном направлении

Кстати, один костыль уже давно работает, для обычных lpar'ов. Но появление третьего уровня ( в профиле vios'а ) стало для меня сюрпризом

router ★★★★★
() автор топика
Последнее исправление: router (всего исправлений: 1)
Ответ на: комментарий от router

split, map, вот это всё

Это функциональщина, а не лямбды, кмк.

Тут уже на этом примере видно, что split не поможет. Нужна или граматика или простой pull parser.

Прога FOSS? Если да, то почему бы не посмотреть как она формирует вывод?

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

Прога FOSS? Если да, то почему бы не посмотреть как она формирует вывод?

lssyscfg? Ни разу. Входит в ibm hmc ( hardware management console ), пак для управления power'ами

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

О_о. Вот об этом я даже не подумал. Если так, геморроя будет минимум :)

Спасибо, пойду проверять

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

Код парсера CSV из Go мне запомнился фразой «We make the simplifying assumption». Я его смотрел как источник вдохновения, но потом бросил. В моём парсере (на другом ЯП) нет никаких стрёмных оговорок :)

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

Только содержимое ячеек по-прежнему нужно парсить как-то.

Неа. Тут уже никаких проблем, содержимое оказывается тем же самым cvs, т.к. стандартный парсер исправляет разделители и

"virtual_eth_adapters=""72/1/1/704,706,744,714,715,700/1/0/ETHERNET0//all/none"",73/0/199//0/0/ETHERNET0//all/none,74/0/714//0/0/ETHERNET0//all/none"

превращается в

virtual_eth_adapters="72/1/1/704,706,744,714,715,700/1/0/ETHERNET0//all/none",73/0/199//0/0/ETHERNET0//all/none,74/0/714//0/0/ETHERNET0//all/none
router ★★★★★
() автор топика

А чё тут думать то

имя_ключа = далее фиксированный порядок значений

ключ=значение
ключ=группа,связанных,значений/другая,группа
ключ=// тут нет значения

Я думаю что порядок значений гвоздями прибит иначе фигня какая-то получается. Если это так то парсер надо писать самому, заранее узнав этот порядок как-то. В том смысле что строки, чиста, всё в каше идёт какой-то.

Dron ★★★★★
()
Последнее исправление: Dron (всего исправлений: 1)

Выглядит как «свой» формат, внутри кошерного csv. Т.е. парсить как csv а каждое поле парсить как «свой» формат (который тоже очень даже смахивает на csv, с оговоркой что для первого поля разделитель другой).

Тут даже двумя регулярками можно было бы обойтись если бы не случай когда простое выражение не заключается в кавычки.

Удвоенная кавычка явно экранирует кавычку внутри выражения в кавычках.

Тебе какое представление на выходе то нужно? Вот главный вопрос.

pon4ik ★★★★★
()

Ну смотри, на уровни ты можешь не смотреть ибо они все одинаковые. Насколько я могу судить формат k1=v11,v12,v13,k2=v21,v22,v23 где v может быть либо простым значением без символов =, либо закавыченным, причём вложенные кавычки дубируются. Уровни парсятся одним и тем же парсером рекурсивно, логика совершенно тривиальна - захват литерала до одного из трёх символов ,=", в третьем случае поиск завершающей кавычки и вызов рекурсивного парсера, потом его результат, либо в остальных случаях готовый литерал, складываются в структуру.

slovazap ★★★★★
()

Недавно проскакивала новость про язычек Red, в нем аналог PEG встроен в язык, примерно так получилось:

Red [
   description: {lsyscfg parser for LoR}
]

text: {
affinity_group_id=none,
"io_slots=21010284/none/1,21010204/none/1,21010205/none/1,2101028D/none/0",
"virtual_eth_adapters=""72/1/1/704,706,744,714,715,700/1/0/ETHERNET0//all/none"",73/0/199//0/0/ETHERNET0//all/none,74/0/714//0/0/ETHERNET0//all/none",
}

ws-chars: charset reduce [space tab newline]

quoted-value: [ keep any [ not [ #"^"" |  #"," ] skip ] ]
double-quoted-value: [ {""} keep any [ not {""} 2 skip ] {""} ]
quoted-comma-value: [ ahead "^"^"" double-quoted-value | quoted-value ]
quoted-comma-values: [ quoted-comma-value any [ #"," quoted-comma-value ] ]
quoted-key-pair: [ #"^"" keep any [not #"=" skip ] #"=" quoted-comma-values #"^"" ]
key-pair: [ keep any [not #"=" skip] #"=" keep any [not #"," skip] ]
group: [ ws [ ahead #"^"" collect quoted-key-pair | collect key-pair ] ]
rules: [ collect [ group any [ #"," group ] ] ]
ws: [any ws-chars]

probe parse text rules
 ~/red  red lor.red
[["affinity_group_id" "none"] ["io_slots" "21010284/none/1" "21010204/none/1" "21010205/none/1" "2101028D/none/0"] ["virtual_eth_adapters" {72/1/1/704,706,744,714,715,700/1/0/ETHERNET0//all/none} "73/0/199//0/0/ETHERNET0//all/none" "74/0/714//0/0/ETHERNET0//all/none"] []]

Ну и так далее, дальше можно внутри разобрать по слешикам если надо.

loz ★★★★★
()
Последнее исправление: loz (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.