【问题标题】:How good is this representation of a context free grammar for a parser? [closed]对于解析器来说,上下文无关语法的这种表示有多好? [关闭]
【发布时间】:2009-10-08 15:08:22
【问题描述】:

我已共享包含用于解析器的上下文无关语法的类定义的头文件。你能评论一下这个设计吗? 此代码用于我的实验室作业。 也许我们可以从这段代码中得到一些好的编程技巧。类层次结构好还是太复杂。

#ifndef CFG_H
#define CFG_H

#include <iostream>
#include <set>
#include <list>

using namespace std;



class Terminal;


class CfgSymbol
{
protected:
    char ch;
    set<Terminal*> first;
    set<Terminal*> follow;

public:
    CfgSymbol()
    {
        ch = '\0';
    }

    CfgSymbol(char c) : ch(c)
    {
    }

    virtual void computeFirst() = 0;
};


class Terminal: public CfgSymbol
{
private:

public:
    Terminal(): CfgSymbol()
    {
    }

    Terminal(char c) : CfgSymbol(c)
    {
        computeFirst();
    }

    virtual void computeFirst()
    {
        first->insert(this);
    }

};

class NonTerminal: public CfgSymbol
{
private:

public:
    virtual void computeFirst();
    virtual void computeFollow();
};

class SymbolString
{
public:
    CfgProduction* prd;
    list<CfgSymbol*> symstr;

    void computeFirst();
    void computeFollow();
};

class CfgProduction
{
private:
    NonTerminal lhs;
    SymbolString rhs;
public:
    int add_terminal(char t);
    int add_nonterminal(char n);
    int set_lhs(char c);
};

class Cfg
{
public:
    vector<CfgProduction*> prdList;

    void addProduction(const CfgProduction& cfg);
    void computeFirst();
    void computeFollow();
    void computeFirstFollow();

};

#endif

【问题讨论】:

  • 有人请更正代码标签。
  • 您需要将整个代码缩进 4 个空格(而不是制表符)。顺便说一句,除非有必要(即模板),否则将实现放在标题中是一个坏主意。并且将using namespace 放在标题中是恕我直言总是一个坏主意。
  • 好的,但是上下文无关语法的类层次结构呢。
  • 这看起来像复合设计模式吗? en.wikipedia.org/wiki/Composite_pattern

标签: c++ parsing


【解决方案1】:

Spirit's documentation 应该给你一个很好的介绍 grammar 实现(带有模板)。不知道你的水平,可能太简单了,不过挺有意思的:

随着语法变得复杂,它 将零件分组为一个好主意 逻辑模块。例如,当 写一门语言,这可能是明智的 将表达式和语句放入 单独的语法胶囊。语法 利用封装 C++ 类的属性。这 类的声明性使其 完美契合 语法。因为语法什么都不是 不仅仅是一个类声明,我们可以 方便地在标题中发布 文件。这个想法是,一旦写 并经过充分测试,语法可以 在许多情况下重复使用。我们现在有 语法库的概念。

【讨论】:

  • 很高兴能学到新东西
【解决方案2】:

没有 cmets 整个事情都是没有意义的。

应该有一些关于如何使用对象实例以及在什么上下文中使用它的冗长描述。

另一方面,我通常在类定义之前从 BNF 语法定义开始(至少在 cmets 中)。然后围绕语法设计类。

【讨论】:

    【解决方案3】:

    您不应在标头中编写除模板之外的实现。标头必须仅包含您的类和函数以及您的成员的签名。

    惯例是每个文件只放置一个类。最好编译:Multiple classes in a header file vs. a single header file per class。 但我认为如果类的长度少于 10 行,将多个类放在同一个标​​题中是正确的。

    【讨论】:

    • 首先,由于它没有回答问题,我认为这属于评论。
    • 我认为根据类的长度将类(或不类)分组在一个文件中不是一个好主意。如果A) 它们是一组完整的相关且相当小的类,或者B) 其中一个是主类,而其他类是一组相当小的助手和卫星,则 IMO 几个类属于同一个标题。
    • 我同意你的看法。在我看来,重新组合小班课程包括您的条件。
    猜你喜欢
    • 2018-07-13
    • 2013-10-17
    • 1970-01-01
    • 2014-09-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 2014-06-07
    相关资源
    最近更新 更多