[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-core-devel
Subject: Re: Looking for (KDE) lib/class to perform calculations
From: Rik Hemsley <rik () kde ! org>
Date: 2002-03-25 10:43:24
[Download RAW message or body]
#if Rik Hemsley
> #if Rob Kaper
>
> > Is there a class/method/lib in KDE/Qt to perform calculations?
> >
> > Something like KCalculator::calculate(const QString expression) or
> > something that let's me do int result = calculate( "(3*%1)+40" ).(30)
> > which will return 130..
>
> Have a look at 'spirit'. It allows you to write a parser in (very
> few lines of) pure C++.
>
> The examples include a calculator which seems to be almost exactly
> what you're looking for.
And just to illustrate how good this thing is to anyone else
reading, here's the source of the example.
#include <iostream>
#include <string>
#include <Spirit.h>
/////////////////////////////////////////////////////////////////////////////////////////
using std::cout;
using std::cin;
using std::endl;
using std::string;
using Spirit::Rule;
using Spirit::Scanner;
using Spirit::Action;
using Spirit::Lexeme;
using Spirit::ch_p;
using Spirit::digit;
using Spirit::space;
namespace {
void doInt(char const* str, char const* end)
{
string s(str, end);
cout << s << endl;
}
void doAdd(char const*, char const*) { cout << "ADD\n"; }
void doSubt(char const*, char const*) { cout << "SUBT\n"; }
void doMult(char const*, char const*) { cout << "MULT\n"; }
void doDiv(char const*, char const*) { cout << "DIV\n"; }
}
/////////////////////////////////////////////////////////////////////////////////////////
static void
Parse(Rule<> const& rule, char const* expr)
{
cout << "/////////////////////////////////////////////////////////\n\n";
Scanner<> scan(expr, space);
if (rule.Parse(scan) && !*scan)
{
cout << "\t\t" << expr << " Parses OK\n\n\n";
}
else
{
cout << "\t\t" << expr << " Fails Parsing\n";
cout << "\t\t";
for (int i = 0; i < (&*scan - expr); i++)
cout << " ";
cout << "^--Here\n\n\n";
}
}
/////////////////////////////////////////////////////////////////////////////////////////
int
main()
{
cout << "/////////////////////////////////////////////////////////\n\n";
cout << "\t\tInterpreter Test For Spirit...\n\n";
cout << "/////////////////////////////////////////////////////////\n\n";
// Start grammar definition
Rule<> expr;
Rule<> integer = Lexeme[ (!(ch_p('+') | '-') >> +digit)[&doInt] ];
Rule<> group = '(' >> expr >> ')';
Rule<> expr1 = integer | group;
Rule<> expr2 = expr1 >> *(('*' >> expr1)[&doMult] | ('/' >>
expr1)[&doDiv]);
expr = expr2 >> *(('+' >> expr2)[&doAdd] | ('-' >> expr2)[&doSubt]);
// End grammar definition
cout << "=================================================\n";
cout << "The following expressions should fail to parse...\n";
cout << "=================================================\n\n";
Parse(expr, "- ");
Parse(expr, "1 2 3 4 5");
Parse(expr, "- 1234");
Parse(expr, "1 ++ 1");
Parse(expr, "1 ^ 1");
Parse(expr, "(1 + 1) * 3)");
Parse(expr, "(1 + 1) * 3 4");
Parse(expr, "(1 + (2 + (3 + (4 + 5)))");
Parse(expr, ")1 + 1)");
cout << "=================================================\n";
cout << "The following expressions should parse OK...\n";
cout << "=================================================\n\n";
Parse(expr, "12345");
Parse(expr, "-12345");
Parse(expr, "+12345");
Parse(expr, "1 + 2");
Parse(expr, "1 * 2");
Parse(expr, "1/2 + 3/4");
Parse(expr, "1 + 2 + 3 + 4");
Parse(expr, "1 * 2 * 3 * 4");
Parse(expr, "(1 + 2) * (3 + 4)");
Parse(expr, "(-1 + 2) * (3 + -4)");
Parse(expr, "1 + ((6 * 200) - 20) / 6");
Parse(expr, "(1 + (2 + (3 + (4 + 5))))");
return 0;
}
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic