как проще всего распарсить на с++?
От: wl. Россия  
Дата: 22.05.23 18:59
Оценка:
есть некие файлы, подобного формата:

  Скрытый текст
astver = 2.0
ast = {
    block_00000 = {
        {"bg", file="black", path=":bg/"},
        {"user", mode="manual"},
        {"selback", file="b999"},
        {"msg", no=1},
        {"excall", file="b999"},
        {"text"},
        line = 15,
    },
    label = {
        top = { block="block_00000", label=1 },
    },
}

немного похожи на json. Чем подобное парсят?
Отредактировано 22.05.2023 19:00 wl. . Предыдущая версия . Еще …
Отредактировано 22.05.2023 19:00 wl. . Предыдущая версия .
Re: как проще всего распарсить на с++?
От: LuciferSaratov Россия  
Дата: 22.05.23 19:45
Оценка:
Здравствуйте, wl., Вы писали:

wl.>немного похожи на json. Чем подобное парсят?


Я бы, наверное, взял antlr4 и сделал бы парсер на нём.
Re: как проще всего распарсить на с++?
От: kov_serg Россия  
Дата: 22.05.23 20:16
Оценка: +2
wl.>есть некие файлы, подобного формата:


wl.>немного похожи на json. Чем подобное парсят?


это очень похоже на lua код
Re: как проще всего распарсить на с++?
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 22.05.23 20:39
Оценка:
Здравствуйте, wl., Вы писали:

wl.>немного похожи на json. Чем подобное парсят?

Емнип, boost::Qi, Spirit2, вроде hana из последнего. Описываешь грамматику и оно само всё парсит. Но придётся вспоминать базу.
Sic luceat lux!
Re: как проще всего распарсить на с++?
От: CreatorCray  
Дата: 23.05.23 02:24
Оценка:
Здравствуйте, wl., Вы писали:

wl.>есть некие файлы, подобного формата:

Если уже есть примитивный токенайзер то на страничку текста парсер будет.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: как проще всего распарсить на с++?
От: so5team https://stiffstream.com
Дата: 23.05.23 08:01
Оценка: +1
Здравствуйте, wl., Вы писали:

wl.>немного похожи на json. Чем подобное парсят?


Сейчас я бы смотрел сперва на lexy.
Если хочется поупарываться C++ными шаблонами, то есть еще PEGTL и Boost.Spirit.

Если не хочется выписывать DSL прямо в C++, а проще подключить внешний инструмент, то можно глянуть на Ragel, Coco/R или упоминавшийся выше Antlr4.
Re: как проще всего распарсить на с++?
От: Wawan Россия http://www.wawan.ru/resume
Дата: 23.05.23 10:05
Оценка:
это lua, почему бы ей не распарсить
Re[2]: как проще всего распарсить на с++?
От: kov_serg Россия  
Дата: 23.05.23 10:25
Оценка:
Здравствуйте, Wawan, Вы писали:

W>это lua, почему бы ей не распарсить

Тем более что синтаксис элементарный
https://www.lua.org/manual/5.3/manual.html#9
https://www.boost.org/doc/libs/1_68_0/libs/spirit/doc/x3/html/spirit_x3/introduction.html
Re: как проще всего распарсить на с++?
От: B0FEE664  
Дата: 23.05.23 12:32
Оценка: +1
Здравствуйте, wl., Вы писали:

wl.> Чем подобное парсят?

Как ни странно, но, действительно, используют boost::spirit:
    ParseBlockResults parseBlock(std::string_view view, bool registerPositions)
    {
        ParseBlockResults res{view};
        if (view.empty())
            return res;

        auto f = view.begin();
        const auto l = view.end();
        if (registerPositions)
        {
            const auto parser = boost::spirit::x3::with<lac::pos::position_tag>(std::ref(res.positions))[chunkRule()];
            const auto skipper = boost::spirit::x3::with<lac::pos::position_tag>(std::ref(res.positions))[skipperRule()];
            res.parsed = boost::spirit::x3::phrase_parse(f, l, parser, skipper, res.block) && f == l;
        }
        else
        {
            res.parsed = boost::spirit::x3::phrase_parse(f, l, chunkRule(), skipperRule(), res.block) && f == l;
        }

        res.lastParsedPosition = f - view.begin();
        return res;
    }


Парсер из этого проекта: https://github.com/cguebert/LuaAutoComplete
И каждый день — без права на ошибку...
Re[2]: как проще всего распарсить на с++?
От: wl. Россия  
Дата: 23.05.23 18:32
Оценка: +1
Здравствуйте, Wawan, Вы писали:

W>это lua, почему бы ей не распарсить


начну с этого, раз уж это валидная структура lua.

Спасибо всем за ответы
Re[3]: как проще всего распарсить на с++?
От: kov_serg Россия  
Дата: 25.05.23 22:15
Оценка: 3 (1)
Здравствуйте, wl., Вы писали:

wl.>начну с этого, раз уж это валидная структура lua.


  example.c
// gcc -o example example.c -llua -lm -ldl && ./example

#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

static void inspect_table(lua_State *L,int lev) {
    const char *k, *v, *t; int i;
    luaL_checktype(L,-1,LUA_TTABLE);
    lua_pushnil(L);
    while(lua_next(L,-2)) {
        k=luaL_tolstring(L,-2,0);
        v=luaL_tolstring(L,-2,0);
        for(i=0;i<lev;i++) printf("  ");
        if (lua_istable(L,-3)) {
            printf("[%s]={\n",k);
            lua_pop(L,2);
            lua_pushvalue(L,-1);
            inspect_table(L,lev+1);
            lua_pop(L,1);
            for(i=0;i<lev;i++) printf("  "); printf("}\n");
        } else {
            t=luaL_typename(L,-3);
            printf("[%s]='%s':%s\n",k,v,t);
            lua_pop(L,3);
        }
    }
    lua_pop(L,1);
}

int main(int argc, char const *argv[]) {
    lua_State *L;

    L=luaL_newstate();
    luaL_openlibs(L);
    luaL_dofile(L,"load_data.lua");

    lua_getglobal(L,"data");
    inspect_table(L,0);

    lua_close(L);
    return 0;
}
  load_data.lua
local function load_data(name)
    local res,fn,err={},loadfile(name)
    if err then error(err,2) end
    setmetatable(_G,{__newindex=function(t,n,v) res[n]=v end})
    local ok,err=pcall(fn)
    setmetatable(_G,nil)
    if err then error(err) end
    return res
end

data=load_data "data.lua"
  data.lua
astver = 2.0
ast = {
    block_00000 = {
        {"bg", file="black", path=":bg/"},
        {"user", mode="manual"},
        {"selback", file="b999"},
        {"msg", no=1},
        {"excall", file="b999"},
        {"text"},
        line = 15,
    },
    label = {
        top = { block="block_00000", label=1 },
    },
}
  output:
[astver]='2.0':number
[ast]={
  [block_00000]={
    [1]={
      [1]='bg':string
      [file]='black':string
      [path]=':bg/':string
    }
    [2]={
      [1]='user':string
      [mode]='manual':string
    }
    [3]={
      [1]='selback':string
      [file]='b999':string
    }
    [4]={
      [1]='msg':string
      [no]='1':number
    }
    [5]={
      [1]='excall':string
      [file]='b999':string
    }
    [6]={
      [1]='text':string
    }
    [line]='15':number
  }
  [label]={
    [top]={
      [label]='1':number
      [block]='block_00000':string
    }
  }
}
Re[2]: как проще всего распарсить на с++?
От: sts  
Дата: 29.05.23 22:21
Оценка:
Здравствуйте, so5team, Вы писали:

S>Здравствуйте, wl., Вы писали:


wl.>>немного похожи на json. Чем подобное парсят?


S>Сейчас я бы смотрел сперва на lexy.

S>Если хочется поупарываться C++ными шаблонами, то есть еще PEGTL и Boost.Spirit.

S>Если не хочется выписывать DSL прямо в C++, а проще подключить внешний инструмент, то можно глянуть на Ragel, Coco/R или упоминавшийся выше Antlr4.


да, какой-нибудь peg типа spirit на раз-два
Отредактировано 29.05.2023 22:23 sts . Предыдущая версия .
Re: как проще всего распарсить на с++?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 29.05.23 22:30
Оценка:
Здравствуйте, wl., Вы писали:

wl.>немного похожи на json. Чем подобное парсят?


Кроме символа '=' вместо символа ':' — не заметил отличий от json. Но, может, проглядел. Я бы взял какой-нибудь готовый json парсер, например nlohman, и, если он искаропки не поддерживает замену разделителя ключ-значение, то нашел бы, где он там явно задаётся, и заменил бы его
Маньяк Робокряк колесит по городу
Re[2]: как проще всего распарсить на с++?
От: Sm0ke Россия ksi
Дата: 31.05.23 07:28
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте, wl., Вы писали:


wl.>>немного похожи на json. Чем подобное парсят?


M>Кроме символа '=' вместо символа ':' — не заметил отличий от json. Но, может, проглядел. Я бы взял какой-нибудь готовый json парсер, например nlohman, и, если он искаропки не поддерживает замену разделителя ключ-значение, то нашел бы, где он там явно задаётся, и заменил бы его


В json текстовые ключи в кавычки надо заключать ещё.
Re[3]: как проще всего распарсить на с++?
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 31.05.23 09:06
Оценка:
Здравствуйте, Sm0ke, Вы писали:

M>>Кроме символа '=' вместо символа ':' — не заметил отличий от json. Но, может, проглядел. Я бы взял какой-нибудь готовый json парсер, например nlohman, и, если он искаропки не поддерживает замену разделителя ключ-значение, то нашел бы, где он там явно задаётся, и заменил бы его


S>В json текстовые ключи в кавычки надо заключать ещё.


А, да. Но, имхо, так тоже скушает
Маньяк Робокряк колесит по городу
Re[2]: как проще всего распарсить на с++?
От: CRT  
Дата: 06.07.23 10:35
Оценка:
Здравствуйте, Marty, Вы писали:


M>Кроме символа '=' вместо символа ':' — не заметил отличий от json. Но, может, проглядел.


проглядел. В json такая конструкция {{ невозможна.
Не может новый объект начинаться сразу после {

такая {"bg", file="black", path=":bg/"} тоже,
даже если заменить = на :
(у "bg" нет имени или значения),
Отредактировано 06.07.2023 13:46 CRT . Предыдущая версия . Еще …
Отредактировано 06.07.2023 10:38 CRT . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.