【问题标题】:Extensible parser design可扩展的解析器设计
【发布时间】:2010-12-01 17:55:19
【问题描述】:

我有一个 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 的子类简单地扩展已知的文件类型,以正确的方式扩展enum,请参阅Base enum class inheritance 了解我是如何做到的。我不想修改上面的代码,而只是一般地扩展目标一半。可能需要 C++0X,非常受欢迎。

谢谢!

更新:在尝试在这里解释它并发布一些简化的类声明时,我意识到我的设计被破坏了,我试图将 fileType 的专业化推到我的类结构中太深。我只想在一个地方存储所有已知类型的完整列表,但在尝试这样做时,我不小心强制设计一次在两个地方访问该列表。我现在意识到所有文件类型的列表应该是关键字 SOURCE、HEADER 等被读取的位置,并从那里*一般地处理。我会将完整列表存储在一个地方,稍后通过“巨大”enum 访问该列表。 std::map<fileType, std::set<std::string> > 在这里作为一个合乎逻辑的选择突然出现在我的脑海中,而不是为每个特定的 fileType 单独命名为 set。不过,感谢您在回复中的聪明才智!仍然欢迎任何想法。

【问题讨论】:

  • 您是否介意添加更多代码。我不确定你想做什么......

标签: c++ parsing


【解决方案1】:

我相信这通常不是正确的方法,但这是我的信念。我会以不同的方式做到这一点。 退后一步,我们想要实现什么,我们希望根据传入的(输入参数)值来控制行为。 假设我们有类: 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);

【讨论】:

  • 嗯,这实际上是我最终通过std::map<Target::fileType, std::set<std::string> > 实现的,它比我之前想象的灵活得多。谢谢! (我不需要 fileType 注册,并且总是让所有这些都可用,如果它还没有出现,std::map::operator[] 也会创建一个元素,这对我来说只是一个奖励!)
【解决方案2】:

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

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

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

您的目标类可以实现一个虚拟方法 retrieveAllKnownFileTypes(),子类将扩展该方法,并且您的其余代码可以对其进行评估。

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

...等等。

【讨论】:

    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-08
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多