2

我正在用 C++ 编写一个项目,我正在寻找一种方法以人类可读/可写的形式放入一个文本文件 ( usergrammar.txt ),这是一种定义对象的用户定义语法。

完成此操作后,我希望能够在代码中实例化其中一些对象,并将创建的实例保存在另一个文件 (instances.txt) 中,始终以人类可访问的格式。这第二个文件显然依赖于第一个被正确读取。

我遇到的问题是如何定义语法并解析它们。我一直在研究 Boost::Spirit,但是虽然它在读取第一个文件时会做得很好(因为它的规则是预定义的),但我认为它不适用于第二个文件,因为 Spirit 语法只是定义的一个编译时间,不能在运行时加载(至少我是这么理解的)。

现在我正在阅读 ENBF 表单,但我也有一个问题,即我不仅有语言规则,而且每个对象每次包含在另一个对象中时都有一个特定且不同的名称/描述/选项(例如,如果我有对象颜色,则其中的整数将称为红色、蓝色、黄色,而如果对象是标尺,则其整数将称为 length ),所以我也有办法将这些信息包含到文件中,并让它们与相应的值正确关联。

对于这样的项目,你有什么建议吗?提前致谢。

4

2 回答 2

1

请参阅使用从运行时提供的语法中提取的事实来解析上下文无关语言的Earley 解析器。

另一种方法是利用几乎所有 C++ 编译器系统都提供可以分叉进程的库这一事实。您可以使用它来创建一个 shell 脚本,以根据任何相应的语法形式运行您喜欢的任何解析器生成器方案(包括 Boost:Spirit,要求您从脚本中调用 C++ 编译器,但这并不难),然后拥有该脚本调用生成的解析器。如果您要处理大型文档,这可能比 Earley 解析器更有效。实施起来肯定会容易得多。

于 2012-04-25T21:43:01.663 回答
0

如果您愿意对文件格式有一些限制,您可以考虑使用 XML 或 JSON 来描述您的语法。

你可以有一个看起来像的语法文件

{
    "ObjectTypes" : {
        "ruler" : { "properties" : [ "length" ] },
        "color" : { "properties" : [ "red", "green", "blue" ] }
    }
}

读入此文件后(很可能使用一些预先存在的库),然后您可以读入另一个包含实际对象的文件。它可能看起来像这样:

{
    "Objects" : [
        { name : "object1", "type" : "ruler", "length" : 5 },
        { name : "object2", "type" : "color", "red" : 5, "blue" : 127, "green" : 150, }
    ]
}

等等。此处给出了 JSON 的更具描述性的概述,其中包括几个处理 JSON 的 C++ 库的链接(我个人最喜欢的是JsonCpp)。

于 2012-04-25T18:21:59.123 回答