-
Notifications
You must be signed in to change notification settings - Fork 2
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;
}