C++如何自己动手解析json

golden平常心 2018-04-20 08:43:41
怎么用C++写一个简易的Json解析工具?求指导,求思路?修改
简单一点的方法,想两天搞定的
...全文
1575 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
Steps-of-time 2018-04-29
  • 打赏
  • 举报
回复
可以网上下载一个acl库,里面有相应的解析方法,都是一些很成熟的东西,之后自己可以封装相应的方法,从而达到自己的需求。具体的编译方式,库中有相应介绍方法。
小小蔷薇 2018-04-28
  • 打赏
  • 举报
回复
自己写麻烦,用jsoncpp比较方便
www_adintr_com 2018-04-28
  • 打赏
  • 举报
回复
在已经有词法分析器的基础上, 要解析 json 其实是非常简单的, 代码不超过 200 行, 下面这个就是我手动写的:

JsonItem* ParseJSArray(CLex& lex);
JsonItem* ParseJSObject(CLex& lex);

static JsonItem* ParseJSItem(CLex& lex)
{
	CToken tk = lex.get_token_no_lfeed();
	if (tk.is_number())
	{
		return new JsonItemInt((int)tk.get_number());
	}
	else if (tk.is_float())
	{
		return new JsonItemDouble(tk.get_double());
	}
	else if (tk.is_string())
	{
		return new JsonItemString(tk.get_string());
	}
	else if (tk.is_operator(CTokenType::OpBracketLeft))
	{
		return ParseJSArray(lex);
	}
	else if (tk.is_operator(CTokenType::OpBraceLeft))
	{
		return ParseJSObject(lex);
	}
	else if (tk.is_identifier())
	{
		if (tk.get_string() == L"true" || tk.get_string() == L"false")
		{
			return new JsonItemBool(tk.get_string() == L"true");
		}
		else if (tk.get_string() == L"null")
		{
			return new JsonItem();
		}
	}

	return nullptr;
}

JsonItem* ParseJSArray(CLex& lex)
{
	JsonItemArray* array = new JsonItemArray;
	CToken tk = lex.get_token_no_lfeed();
	
	while (!tk.is_operator(CTokenType::OpBracketRight))
	{
		lex.put_back(tk);
		JsonItem* item = ParseJSItem(lex);
		if (item == nullptr)
		{
			delete array;
			return nullptr;
		}

		array->push(item);

		tk = lex.get_token_no_lfeed();

		if (tk.is_operator(CTokenType::OpBracketRight))
		{
			return array;
		}

		if (!tk.is_operator(CTokenType::OpComma))
		{
			delete array;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
	}

	return array;
}

JsonItem* ParseJSObject(CLex& lex)
{
	JsonItemObject* dict = new JsonItemObject;
	CToken tk = lex.get_token_no_lfeed();

	while (!tk.is_operator(CTokenType::OpBraceRight))
	{
		std::wstring name;

		if (tk.is_identifier() || tk.is_string())
		{
			name = tk.get_string();
		}
		else
		{
			delete dict;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
		if (!tk.is_operator(CTokenType::OpColon))
		{
			delete dict;
			return nullptr;
		}

		JsonItem* item = ParseJSItem(lex);
		if (item == nullptr)
		{
			delete dict;
			return nullptr;
		}

		dict->add_child(name, item);
		tk = lex.get_token_no_lfeed();
		if (tk.is_operator(CTokenType::OpBraceRight))
		{
			return dict;
		}

		if (!tk.is_operator(CTokenType::OpComma))
		{
			delete dict;
			return nullptr;
		}

		tk = lex.get_token_no_lfeed();
	}

	return dict;
}

JsonItemPtr ParseJSCode(const std::wstring& json)
{
	if (json.empty())
	{
		return nullptr;
	}

	CLex lex;
	if (!lex.load_data(json))
	{
		return nullptr;
	}

	return JsonItemPtr(ParseJSItem(lex));
}
Marcelxx 2018-04-28
  • 打赏
  • 举报
回复
libjson了解一下?
赵4老师 2018-04-27
  • 打赏
  • 举报
回复
引用 13 楼 iloveyou418 的回复:
[quote=引用 3 楼 zhao4zhong1 的回复:] http://www.json.org
+1 看看学学抄抄~ok了 [/quote]
eeeeelin 2018-04-27
  • 打赏
  • 举报
回复
看cJSON源码,自己用C++封装一下
CT8100 2018-04-27
  • 打赏
  • 举报
回复
引用 3 楼 zhao4zhong1 的回复:
http://www.json.org
+1 看看学学抄抄~ok了
Really_want 2018-04-26
  • 打赏
  • 举报
回复
引用 5 楼 hefashion0190 的回复:
[quote=引用 4 楼 housecarl 的回复:] 非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
+1[/quote] +1
mLee79 2018-04-25
  • 打赏
  • 举报
回复
JSON 这么规范的, 带个栈的正规文法就可以描述, 用不着BNF, 正则就可以了 ..
剑文文 2018-04-25
  • 打赏
  • 举报
回复
jsoncpp 好用,我一直用这个
mxway 2018-04-24
  • 打赏
  • 举报
回复
cjson几百行代码
starytx 2018-04-24
  • 打赏
  • 举报
回复
如果你只是要使用json,这个轮子造的没有一点性价比,可以使用的json库多得很,自己造太累,如果你是做研究,祝你成功
FoolCarpe 2018-04-24
  • 打赏
  • 举报
回复
引用 4 楼 housecarl 的回复:
非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
+1
zilaishuichina 2018-04-24
  • 打赏
  • 举报
回复
EBNF范式 boost的spirit库
轻箬笠 2018-04-24
  • 打赏
  • 举报
回复
非常理解楼主的想法。因为一开始我也是这么想的,然后发现太麻烦了,就用了公共库。 推荐楼主使用rapidjson或者jsoncpp
ztenv 版主 2018-04-24
  • 打赏
  • 举报
回复
jsoncpp
赵4老师 2018-04-21
  • 打赏
  • 举报
回复
幻夢之葉 2018-04-20
  • 打赏
  • 举报
回复
找个开源的简易解析Json的源代码
srhouyu 2018-04-20
  • 打赏
  • 举报
回复
你要是从没有搞过解析器,那么这并不是简单事,两天恐怕不行。 想简单的,看看这个问答: https://www.zhihu.com/question/24640264 想系统的,看看《编程语言实现模式》。

64,670

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧