Boost logo

Boost :

From: joel de guzman (djowel_at_[hidden])
Date: 2002-01-17 14:31:34


----- Original Message -----
From: "Vladimir Prus" :

> > > I think you'll agree that concerns about code size, speed, and dependency
> > > on other libraries are in general reasonable. It would help a lot, if
> > > instead of one person expressing such concerns and another person stating
> > > that there's no need to worry, you'll provide us with a table of grammars
> > > and code sizes on various compilers.
> >
> > And compare it against what?
>
> With hand-written code, which you yourlself use as a basis of comparison in
> some other message.

Ok here's a quick shot at it:
Borland 5.5.1

///////////////////////////////////////////////////////////////////////////////
Hand coded {based on Gennadiy's code}:
181K {includes main driver code}

bool
parse_complex(char const* in, double& r, double& i)
{
    // parses complex numbers of the form r or (r) or (r,i)

    tokenizer<> tok(in, in+strlen(in));
    tokenizer<>::iterator iter=tok.begin();

    r = lexical_cast<double>(*iter++);
    i = lexical_cast<double>(*iter);
}

Note: This code allows improper syntax such as "(((1,,,()(2)((("
Needless to say, adding more code to conform to the
grammar will increase the code size.

///////////////////////////////////////////////////////////////////////////////
Spirit {Based on Dan's code}
146K {includes main driver code}

bool
parse_complex(char const* in, double& r, double& i)
{
    // parses complex numbers of the form r or (r) or (r,i)

    return parse(in,
                real_p[ref(r)]
            | '(' >> real_p[ref(r)] >> !( ',' >> real_p[ref(i)]) >> ')'
        , space).full;
}

Here's the common driver code:

///////////////////////////////////////////////////////////////////////////////
int
main()
{

    while (true)
    {
        double r = 0;
        double i = 0;
        char str[256];

        cin.getline(str, 256);
        if (str[0] == 'q' || str[0] == 'Q')
            break;

        r = 0;
        i = 0;

        if (parse_complex(str, r, i))
            cout << "(" << r << ", " << i << ") parses OK\n";
        else
            cout << " parsing failed\n";
    }

    return 0;
}

///////////////////////////////////////////////////////////////////////////////
So the numbers don't lie. In terms of code size,
Spirit outperforms Gennadiy's code hand written code.
146K vs 180K in this trivial example.

> Ok, so you think that performance or code size do not matter. Can you still
> provide some measurements to those who feel the other way?

Don't get me wrong. Performance matters and code size matters.
But it should be balanced against other factors such as robustness,
extensibility, flexibility, ease-of-use etc. In the case of C vs. Assembler
for example, Assembler will leave C behind in terms of code size
and speed, but then C is a magnitude more easier to use and a
magnitude more powerful. I assert that EBNF is a magnitude
more powerful and extensible than any other home-brew config
file I/O protocol.

Cheers,
--Joel


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk