可扩展的解析器设计

时间:2010-12-01 17:55:19

标签: c++ parsing

我有一个类Target,其中包含一个“fileType”enum,它包含我的解析器需要知道的各种文件(目前是SOURCE,HEADER,RESOURCE)。我希望我的Parsing函数能够执行以下通用操作:

if( token == some_known_fileType )
    put_nextToken_in_the_list_for_that_fileType();
else
    return an_error();

但是有一个问题:我希望能够简单地扩展已知的Target子类的fileTypes,以正确的方式扩展enum,请参阅Base enum class inheritance我是怎么做到的我不想修改上面的代码,但只是一般地扩展了目标的一半。可能需要C ++ 0X,非常受欢迎。

谢谢!

更新:在尝试在此处解释并发布一些简化的类声明时,我意识到我的设计已经破了,我试图在我的类结构中推动fileType的特化。我只想要一个地方存储所有已知类型的完整列表,但在尝试这样做时,我不小心强迫设计一次只能在两个地方访问该列表。我现在意识到所有文件类型的列表应该是读取关键字SOURCE,HEADER等的地方,并且从那里一般地处理*。我将在一个地方存储完整列表,然后通过“巨大的”enum访问该列表。 std::map<fileType, std::set<std::string> >弹出我的脑袋作为逻辑选择,而不是为每个特定的set分别命名为fileType。感谢您的回复中的braincandy!任何想法仍然受欢迎。

3 个答案:

答案 0 :(得分:2)

我认为这通常不是正确的方法,但这是我的信念。我会以不同的方式做到这一点。 退后一步,我们想要实现的目标,我们希望根据传入(输入参数)值来控制行为。 让我们说我们有类:FileA FileB ... file_type包含文件类型。 使用工厂来控制可用的文件列表(可以根据不同文件的注册进行更改)。

class FileA {
    void register_type();  // register itself to the factory.
};

class FileB..
//main code
class FileFactoryDelegator {
    ...
    delegateControl (FileType file_type) {
        //validate file_type.
        file_types[file_type]->performFileOperation (..);
    }
};

而不是if-else循环。

file_factory.delegateControl (token);

答案 1 :(得分:0)

这很难回答,因为很大程度上取决于您对令牌,文件类型值和目标实例的确切做法。但是,我认为这里的基本主题是你需要用虚方法调用替换if()语句。例如,您的代码片段可能最终成为

if (tokenLists.supportsFileType(token))
    tokenLists.getListForType(token).put_nextToken_into_this_list();
else
    return an_error();

上面的tokenLists示例可以概括为TargetSpecificLogic实例的注册表,它结合了各种特定于文件类型的方法。

您的Target类可以实现一个虚方法retrieveAllKnownFileTypes(),子类将扩展该方法,以及其余代码可以评估的方法。

您的目标类可以实现虚拟方法bool isFileTypeKnown(filetype),返回truefalse

......等等。

答案 2 :(得分:-1)

不要写你的解析器。使用boost::spirit