Boost logo

Boost :

Subject: Re: [boost] compile time parser generator
From: Martin Bidlingmaier (Martin.Bidlingmaier_at_[hidden])
Date: 2012-01-07 08:50:43


I'm not sure it's possible to get a string literal in a
template< char ... >
class string;
'Literals transformation is redefined into two distinct phases: raw and cooked. A raw literal is a sequence of characters of some specific type, while the cooked literal is of a separate type. The C++ literal 1234, as a raw literal, is this sequence of characters '1', '2', '3', '4'. As a cooked literal, it is the integer 1234. The C++ literal 0xA in raw form is '0', 'x', 'A', while in cooked form it is the integer 10.

Literals can be extended in both raw and cooked forms, with the exception of string literals, which can only be processed in cooked form. This exception is due to the fact that strings have prefixes that affect the specific meaning and type of the characters in question.' - source: wikipedia - http://en.wikipedia.org/wiki/C%2B%2B11#User-defined_literals .

Parsing string literals with constexpr is described in this article:
http://akrzemi1.wordpress.com/2011/05/11/parsing-strings-at-compile-time-part-i/
For building the parser generator I used compile time polymorphism. Each symbol in EBNF would be represented as a class.
The interface each symbol defines looks like this:

struct symbol
{
    constexpr symbol( const_string str , unsigned int begin = 0 );
    //for an implementation of const_string see the article I linked
    constexpr bool valid();
    constexpr unsigned int end();
};

For example, a symbol that parses a single character 'a' looks like this:
struct sym_a
{
    constexpr sym_a( const_string str , unsigned int begin = 0 )
        : m_end
        (
            begin >= str.size() ?
                0u - 1 : //invalid index
                str[ begin ] == 'a' ?
                    begin + 1 :
                    0u - 1
        )
    {
    }
    constexpr bool valid()
    {
        return m_end != 0u - 1;
    }
    constexpr unsigned int end()
    {
        return m_end;
    }
    unsigned int m_end;
};

constexpr sym_a s1( "a" );
constexpr sym_a s2( "b" );
static_assert( s1.valid() , "" );
static_assert( !s2.valid() , "" );

The source for my current version of the parser generator is appended.
I've also created a simple calculator that can handle + and * (and will accept any digit sequence as number, including "00000").
Notice, that currently only char strings are completely supported, defining terminals and the opt< T > operator won't work with other literals. (I know I can improve this for terminals, but I'm not sure about opt< T >.)
The source compiles with gcc 4.6 and c++11 turned on without errors.

-- 
NEU: FreePhone - 0ct/min Handyspartarif mit Geld-zurück-Garantie!		
Jetzt informieren: http://www.gmx.net/de/go/freephone























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