解析与char c ++相关的整数

时间:2016-02-02 04:50:54

标签: c++ parsing

我正在做一个项目,从公式中读取一些字符串反应,例如:(5A + 3B = c + 10D)作为输入。我需要对字符串反应进行解析,以便我可以在char旁边提取&(拆分)整数值并将它们放入一个向量中,即与此处反应相关的向量是:[5 3 1 10]。 我考虑过std::strtok函数,但我认为它不能分离整数值!  谁能帮我 ?? 我试试这里:

int main()
{
  std::string input;
  std::getline(std::cin, input);
  std::stringstream stream(input);
  while(1) {
      int n;
      stream >> n;
      char * pch;

      pch = strtok (input," ");
      while (pch != NULL)
        {
          printf ("%s\n",pch);
          pch = strtok (NULL, " ,.");
        }
      return 0;
  }
}

1 个答案:

答案 0 :(得分:1)

要做一些严肃的解析工作,你需要学习一些语言理论。幸运的是,这并不困难。

我们将在这里讨论的方法是我们称之为自上而下的递归解析。

这个源代码的完整列表对于本论坛来说太长了,相反,我将为它提供一些伪代码。

您需要做的第一件事就是定义您的语法。什么被认为是有效的,什么不是,你代表这样的语法:

formula := term 
        := term + formula
        := term - formula
term    := variable
        := coefficient variable

所以公式C + 2D可以表示为

formula
        term
             variable
                      C
        +
        formula
                term
                     coefficient
                                 2
                     variable
                              D

考虑到这一点,我们首先解决一个更简单的问题,输入字符串只需要几种类型的东西

+
-
coefficient
variable

只有这四件事是有效的输入,你可能想跳过空格。将输入字符串拆分为这4种类型的东西称为词法分析。我们通常会实施一个所谓的扫描仪来执行此操作。

扫描仪通常看起来像这样

class Scanner
{
public:
    Scanner(const char* text);
    Token GetToken(); // The current token
    void Scan(); // read the next token
}

接下来,您需要将这些令牌分组到树中,就像我在上面显示的那样。我们通常将此逻辑称为解析,并将其实现为解析器。您可以通过多种方式实现解析器,这是使用自顶向下预测解析器执行此操作的一种方法

class Parser
{
public:

private:
    bool ParseVariable()
    {
        if (s.GetToken() is variable) { s.Scan(); return true; }
    }
    bool ParseTerm()
    {
        if (s.GetToken() is variable) { s.Scan(); return true; }
        if (s.GetToken() is coefficient) { s.Scan(); return this->ParseVariable(); }
    }
    Scanner s;
}

类似的代码继续下去。显然,可以扩展那些Parse()方法的返回类型,以返回对其调用者有用的东西,并为您的目的组合所需的表示。

出于个人目的,我为不同语言编写了一些解析器。您可以将它们看作样本。

这是Python中的一个示例。 https://github.com/cshung/MiscLab/blob/master/GreatestCommonDivisor/polynomial_module.py

这是C ++中的一个带有小扭曲的示例,我向后解析字符串以避免左递归' https://github.com/cshung/Competition/blob/master/Competition/LEET_BASIC_CALCULATOR.cpp

要在真实产品中查看自上而下的解析器,请参阅ChakraCore中的这个示例,我很自豪地在之前工作过。 https://github.com/Microsoft/ChakraCore/blob/master/lib/Parser/Parse.cpp