-
Notifications
You must be signed in to change notification settings - Fork 2
Example: Calculator
Ronald Franco edited this page Dec 21, 2018
·
1 revision
This example is an expression interpreter that prompts the user for a simple mathematical expression that can contain the four basic arithmetic operations (+, -, *, and /) that can contain parenthesis. The example, uses the FlexTokenizer class to employ the following Flex specification that allows the interpreter to accept integers, doubles, and numbers expressed in scientific notation. This example illustrates the use of flow variables to extract the semantic value of the terminal num and calculate the result of the expression. The FlexTokenizer class is employed to scan from stdin.
Flex Specification:
%{
#define NUM 2
%}
num [0-9]*([0-9]|\.[0-9]|[0-9]\.)[0-9]*
%option noyywrap
%%
[-+*/=()\n] { return *yytext; }
{num} { return NUM; }
. { /* do nothing */ }
%%
Program:
#include <iostream>
#include "parser.h"
#include "flextokenizer.h"
int main()
{
/* calculator example */
/* define tokens */
Parser<> plus('+'), minus('-'), times('*'), divides('/'), num(2);
/* define nonterminals */
Parser<int> line, expr, fact, term;
/* define flow variables */
int a(0), b(0);
/* AFG */
line>>a = expr>>a & Token('\n');
expr>>a = term>>a & *( plus & term>>b & [&]{ a += b; }
| minus & term>>b & [&]{ a -= b; } );
term>>a = fact>>a & *( times & fact>>b & [&]{ a *= b; }
| divides & fact>>b & [&]{ a /= b; } );
fact>>a = Token('(') & expr>>a & Token(')') | num>>a;
/* FlexTokenizer will use stdin */
FlexTokenizer tokens;
/* maintain current position */
size_t pos = 0;
while (true)
{
/* user prompt */
std::cout << "============================================================";
std::cout << "\nA calculator that supports:";
std::cout << "\n\t- integers and doubles";
std::cout << "\n\t- +, -, *, /";
std::cout << "\n\t- parenthesis";
std::cout << "\nFormat: <arithmetic expression>";
std::cout << "\nExamples:\n\t1) 4 + 3 * 2\n\t2) (7 - 2) / 5\n";
std::cout << "============================================================";
std::cout << "\nGive me a mathematical expression.";
std::cout << "\nCtrl + C to quit: ";
/* begin parsing */
if (line.parse(&tokens,&pos))
{
std::cout << "Expression computed succesfully!\nResult: " << a << "\n" << std::endl;
}
else
{
std::cout << "Expression computation failed\n" << std::endl;
}
/* clear input */
tokens.clear();
pos = 0;
}
return 0;
}