Skip to content

Example: Binary Number

Ronald Franco edited this page Dec 21, 2018 · 2 revisions

The following example exhibits a parser that may make use of different starting nonterminals to accept the language of all binary numbers. The example also uses a custom lexical analyzer BinaryTokenizer to tokenize each bit in the binary number. The use of semantic actions calculates the decimal value of the accepted binary number and stores the result into flow variable z.

#include <iostream>

#include "parser.h"
#include "parsetree.h"
#include "parserprinter.h"
#include "flextokenizer.h"
#include <fstream>

class BinaryTokenizer : public Tokenizer
{
  public:
    BinaryTokenizer(std::string str)
    {
      for (unsigned int i = 0; i < str.length(); i++)
        if (str[i] == '0')
          emplace_back('0',"0",1,0,0);
        else if (str[i] == '1')
          emplace_back('1',"1",1,0,0);
        else
          break;
    }
};

int main()
{
  /* Binary Number Parser */

  // declare nonterminals and flow variables
  Parser<int> REC_NUM, IT_NUM, BIT, GETBIT;
  int x = 0, y = 0, b = 0, z = 0;

  /* AFG */
  // tail recursive starting nonterminal
  REC_NUM(x)>>z = GETBIT(x)>>y & REC_NUM(y)>>z 
    | GETBIT(x)>>z;

  // iterative starting nonterminal
  IT_NUM>>z = [&]{ z = 0; } & +( BIT>>b & [&]{ z = 2 * z + b; } );

  GETBIT(x)>>z = BIT>>b & [&]{ z = 2 * x + b; };
  
  BIT>>b = Token('0') & [&]{ b = 0; }
	  | Token('1') & [&]{ b = 1; };

  /* Prepare Input */
  // input string
  const char text[] = "101011";

  // use the FlexTokenizer class to tokenize input string
  BinaryTokenizer tokens(text);

  /* Begin Parsing */
  // parse with REC_NUM
  if (REC_NUM.parse(&tokens))
  {
    std::cout << "Success! " << text << " is " << z << std::endl;
  }

  ParserPrinter p;
  ParseTree t;

  size_t pos = 0;

  p.name(&IT_NUM,"IT_NUM");
  p.name(&BIT,"BIT");

  p.name(&x,"x");
  p.name(&y,"y");
  p.name(&b,"b");
  p.name(&z,"z");

  // parse with IT_NUM
  if (IT_NUM.parse(&tokens, &pos, &t))
  {
    std::cout << "Success! " << text << " is " << z << std::endl;
  }

  std::ofstream ofile("treetmp.dot");

  ofile << p.graphviz(&t);

  ofile.close();

  return 0;
}
Clone this wiki locally