Skip to content

Example: Comma Separated Doubles

Ronald Franco edited this page Dec 21, 2018 · 1 revision

The following example creates a parser that accepts strings that contain some number of comma separated doubles. This example employs its own custom Tokenizer class, called doubleTokenizer, to handle the scanning. Since this example repeatedly prompts the user for the input, until the user enters a ‘q’ or ‘Q’ to halt, it would have been easier to use the FlexTokenizer class to handle the scanning. However, this example is meant to illustrate how one would use the Tokenizer class to employ a custom scanning method as well as to act as a comparison to the Boost Spirit example given in Section 8.2. As a result, some code in this example comes from the comma separated double list example provided by Boost Spirit’s documentation.

Driver Program:

#include <cstring>
#include <sstream>
#include "parser.h"
#include "tokenizer.h"

#define DOUBLE_TOK_CODE -1

/* custom tokenizer class */
class doubleTokenizer : public Tokenizer
{
  public:
  doubleTokenizer(std::string str)
  {
    /* make copy of input string */
    char * input = nullptr;
    input = strdup(str.c_str());

    /* get token */
    char * tok = std::strtok(input,", ");
    
    /* check if token was found */
    while (tok != NULL)
    {
      /* Check to see if token is a double */
      double dummy = 0;
      if (!sscanf(tok, "%lf", &dummy))
        break;

      /* token is a double, add token */
      emplace_back(DOUBLE_TOK_CODE,tok,strlen(tok),0,0);

      /* get next token */ 
      tok = std::strtok(NULL,", ");
    }
  }
};

int main()
{
  /* comma separated doubles example */

  /* declare nonterminal start and terminal double_ */
  Parser<> start, double_(DOUBLE_TOK_CODE);

  /* AFG */
  start = double_ & *(Token(',') & double_);

  while (true)
  {
    /* user prompt */
    std::cout << "==============================================================";
    std::cout << "\nA comma separated list parser...\n";
    std::cout << "==============================================================";

    std::cout << "\nGive me a comma separated list of numbers.";
    std::cout << "\nType [q or Q] to quit: ";

    /* check input */
    std::string str;
    getline(std::cin, str);
    if (str.empty() || str[0] == 'q' || str[0] == 'Q')
      break;

    /* tokenize input */
    doubleTokenizer tokens(str);

    /* begin parsing */
    if (start.parse(&tokens))
    {
      std::cout << "Parsing succeeded" << std::endl;
    }
    else
    {
      std::cout << "Parsing failed" << std::endl;
    }
  }

  return 0;
}
Clone this wiki locally