通过解析纯文本文件生成数据结构

Ale*_*lex 7 c++ parsing fileparsing

我为我正在编写的游戏编写了一个文件解析器,以便我自己更改游戏的各个方面(比如角色/舞台/碰撞数据).例如,我可能有这样的字符类:

class Character
{
public:
    int x, y; // Character's location
    Character* teammate;
}
Run Code Online (Sandbox Code Playgroud)

我设置我的解析器从文件读入数据结构,语法类似于C++

Character Sidekick
{
    X = 12
    Y = 0
}

Character AwesomeDude
{
    X = 10
    Y = 50
    Teammate = Sidekick
}
Run Code Online (Sandbox Code Playgroud)

这将创建两个数据结构并将它们放在一个映射中<std::string, Character*>,其中键字符串是我给它的任何名称(在本例中为Sidekick和AwesomeDude).当我的解析器看到一个指向类的指针时,就像队友指针一样,它足够聪明,可以在地图中查找指向该数据结构的指针.问题是我不能宣布Sidekick的队友是AwesomeDude,因为它还没有被放入角色地图.

我正在尝试找到解决此问题的最佳方法,以便我可以将我的数据结构引用尚未添加到地图中的对象.我能想到的两个最简单的解决方案是:(a)添加转发声明数据结构的能力,或者(b)让解析器读取文件两次,一次用指针填充空数据结构,第二次到经过并填写他们.

(a)的问题是我也可以决定在类上调用哪个构造函数,如果我转发声明的东西,我必须让构造函数与其余数据分开,这可能会令人困惑.(b)的问题是我可能想在自己的文件中声明Sidekick和AwesomeDude.我必须让我的解析器能够读取一个文件列表而不是一次只读一个(我猜这不是很糟糕,虽然有时候我可能想得到一个文件列表来读取文件).(b)还有一个缺点,即无法使用构造函数本身后面声明的数据结构,但我认为这不是一个大问题.

哪种方式听起来更好?有没有第三种选择我没有想过?似乎应该有一些聪明的解决方案,使用指针引用或绑定或其他......: - /我认为这有点主观,基于我想给自己的功能,但任何输入都是受欢迎的.

Wil*_*ung 13

当您第一次遇到引用时,只需将其存储为引用.然后,您可以将字符,引用或其他内容放在"稍后需要解析的引用"列表中.

文件完成后,运行那些有引用并解决它们的文件.


Mar*_*ith 5

好吧,你问了第三种选择.您不必使用XML,但如果您遵循以下结构,则使用SAX解析器来构建数据结构将非常简单.

无论如何,每个角色都不是引用队友,而是引用一个团队(在这种情况下是蓝队).这将解耦循环引用问题.只需确保在角色前列出团队.

<team>Blue</team>

<character>
    <name>Sidekick</name>
    <X>12</X>
    <Y>0</Y>
    <teamref>Blue</teamref>
</character>

<character>
    <name>Sidekick</name>
    <X>10</X>
    <Y>50</Y>
    <teamref>Blue</teamref>
</character>
Run Code Online (Sandbox Code Playgroud)