ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

nlohmann 非侵入式代码生成(llvm-cppparser)

2022-03-25 10:33:50  阅读:165  来源: 互联网

标签:代码生成 llvm Console AppendLine nlohmann WriteLine var sb cls


nlohmann是一个用起来很方便的json c++ 库,但是还得自己写一堆代码。特别是如果原来的结构较多,得改一堆,

可以用llvm cpp parser来生成这样的代码。

主函数

static void Main(string[] args)
{

var p = @"J:\fy\inc\";
var files = new List<string>()
{
"test.h"
};
var fullfns = files.Select(x => p + x).ToList();
ParseSourceFile(fullfns);


}

具体的代码如下:

public static bool ParseSourceFile(List<string> files)
{
// Lets setup the options for parsing the file.
var parserOptions = new ParserOptions
{
LanguageVersion = LanguageVersion.CPP17,
Verbose = true
};

parserOptions.Setup();

var parserResult = ClangParser.ParseSourceFiles(files, parserOptions);

if (parserResult.Kind != ParserResultKind.Success)
{
if (parserResult.Kind == ParserResultKind.FileNotFound)
Console.Error.WriteLine("some file was not found.");

for (uint i = 0; i < parserResult.DiagnosticsCount; i++)
{
var diag = parserResult.GetDiagnostics(i);

Console.WriteLine("{0}({1},{2}): {3}: {4}",
diag.FileName, diag.LineNumber, diag.ColumnNumber,
diag.Level.ToString().ToLower(), diag.Message);
}

parserResult.Dispose();
return false;
}

var astContext = ClangParser.ConvertASTContext(parserOptions.ASTContext);
parserResult.Dispose();

foreach (var unit in astContext.TranslationUnits)
{
if (unit.IsSystemHeader)
continue;
foreach (var ns in unit.Namespaces)
{
HandleNamespace(ns, ns.LogicalName);
}
}
return true;
}

 

public static void HandleClass(Class cls, string nsname)
{
if (!nsname.StartsWith("fy::"))
{
Console.WriteLine("not fy msg:"+nsname+"::"+cls.Name);
return;
}
var rosns = nsname.Substring(4);
StringBuilder sb_fromros = new StringBuilder();
sb_fromros.AppendLine("template<>");
sb_fromros.AppendFormat("FYMSG_DECL void copy_from_ros({0}::{1} &lhs, const {2}::{1} &rhs)", nsname, cls.Name,
rosns);
sb_fromros.AppendLine("{");
foreach (var mem in cls.Fields)
{
var fldname = mem.Name;
sb_fromros.AppendFormat(" copy_from_ros(lhs.{0}, rhs.{0});\n", fldname);
}

sb_fromros.AppendLine("}");


StringBuilder sb_tojson = new StringBuilder();
sb_tojson.AppendLine("template<>");
sb_tojson.Append(
$"FYMSG_DECL void to_json(nlohmann::json &js, const {nsname}::{cls.Name} &t)\n");
sb_tojson.AppendLine("{");
foreach (var mem in cls.Fields)
{
var fldname = mem.Name;
sb_tojson.AppendFormat(" to_json(js[\"{0}\"], t.{0});\n", fldname);
}

sb_tojson.AppendLine("}");

StringBuilder sb_fromjson = new StringBuilder();
sb_fromjson.AppendLine("template<>");
sb_fromjson.Append(
$"FYMSG_DECL void from_json(const nlohmann::json &js, {nsname}::{cls.Name} &t)\n");
sb_fromjson.AppendLine("{");
foreach (var mem in cls.Fields)
{
var fldname = mem.Name;
sb_fromjson.AppendFormat(" from_json(js[\"{0}\"], t.{0});\n", fldname);
}

sb_fromjson.AppendLine("}");

Console.WriteLine(sb_fromros.ToString());
Console.WriteLine();
Console.WriteLine(sb_tojson.ToString());
Console.WriteLine();
Console.WriteLine(sb_fromjson.ToString());
}

public static void HandleNamespace(Namespace ns, string fullns)
{
var clses = ns.Classes;
foreach (var cls in clses)
HandleClass(cls, fullns);
foreach (var subns in ns.Namespaces)
{
string newfullns = fullns + "::" + subns.LogicalName;
HandleNamespace(subns, newfullns);
}
}

 

 

如果序列化不是用的这个,同理可以在里面处理,其实就是通过cpp parser 拉到他的所有field,然后生成对应的代码。

标签:代码生成,llvm,Console,AppendLine,nlohmann,WriteLine,var,sb,cls
来源: https://www.cnblogs.com/sevencatwang/p/16053443.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有