Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

word_count.cpp


SourceForge.net Logo     CTTL on    
    SourceForge    
    Download    
    Latest    
    Documentation    
    Index    
    Library    
    News    
    CVS    
    Repository    
   Other    
   Links    

This sample demonstrates semantic action functions organized within a base parser class.

// sample code: word_count.cpp
// demonstrates stateful parser and lexer implementation.

//#define NDEBUG    // must appear before assert.h is included to stop assertions from being compiled 
//#define CTTL_TRACE_EVERYTHING

#include <iostream>
#include "cttl/cttl.h"

using namespace cttl;

template< typename UniverseT >
struct base_parser {
    // parser defines two kinds of universes:
    typedef UniverseT universe_T;
    typedef typename UniverseT::strict_edge_T strict_universe_T;

    // semantic actions:
    size_t count_words( strict_universe_T& ) const
    {
        return 0;
    }

    size_t replace_words( strict_universe_T& ) const
    {
        return 0;
    }
};

template< typename UniverseT >
struct parser : public base_parser< UniverseT > {

    // parser defines two kinds of universes:
    typedef UniverseT universe_T;
    typedef typename UniverseT::strict_edge_T strict_universe_T;

    int count;

    parser( int count_ )
        :
        count( count_ )
    {
    }

    // semantic actions:
    size_t count_words( strict_universe_T& universe_ )
    {
        ++count;
        return universe_.second.offset();
    }

    /*
    size_t replace_words( strict_universe_T& universe_ )
    {
        universe_ = "<WORD/>";
        return universe_.second.offset();
    }
    */
};

template< typename ParserT >
struct lexer : public ParserT {

    // lexer defines two kinds of universes:
    typedef typename ParserT::universe_T universe_T;
    typedef typename universe_T::strict_edge_T strict_universe_T;

    // lexer static data:
    std::set< std::string > keywords;

    lexer( int count_ = 0 )
        :   ParserT( count_ )
    {
        // populate list of keywords:
        keywords.insert( "abc" );
        keywords.insert( "xyz" );
    }

    // grammar rule definitions
    size_t start( universe_T& universe_ )
    {
        return (
            // at least one word should be present
            +(
                // invoke grammar rule
                rule( *this, &lexer< ParserT >::word )
                &
                // invoke semantic action
                rule( *this, &ParserT::count_words )
                &
                // invoke another semantic action
                rule( *this, &ParserT::replace_words )
            )

        ).match( universe_ )
        ;
    }

    size_t word( universe_T& universe_ ) const
    {
        // a word can anything made of alphabetic
        // characters, but not a keyword:
        return (

            isalpha
            -
            begin( keywords )

        ).match( universe_ );
    }
};


int main(int argc, char* argv[])
{
    if ( argc == 1 ) {
        std::cout
            << "Usage: on command the line, enter some words to count, for example,"
            << std::endl
            << '\t'
            << argv[ 0 ]
            << " abc def ghi"
            << std::endl
            ;

        return 1;
    }

    // construct input string from the command line arguments:
    input<> inp( &argv[ 1 ], ' ' );

    // construct universe to be parsed:
    typedef const_edge< policy_space<> > universe_T;

    universe_T universe( new_edge( inp ) );

    // construct the parser:
    lexer< parser< universe_T > > word_parser;

    // count words:
    if ( word_parser.start( universe ) != std::string::npos ) {
        std::cout << "Word count: " << word_parser.count << std::endl;

    } else {
        std::cout << "*** parser failed ***" << std::endl;
        return 1;
    }

    std::cout << "Input: " << inp.text() << std::endl;
    return 0;
}

Providing that the user specifies command arguments "one two three", the program generates the following output:

Word count: 3
Input: one two three



Copyright © 1997-2006 Igor Kholodov mailto:cttl@users.sourceforge.net.

Permission to copy, use, modify, sell and distribute this document is granted provided this copyright notice appears in all copies. This document is provided "as is" without express or implied warranty, and with no claim as to its suitability for any purpose.


Generated on Thu Nov 2 17:44:56 2006 for Common Text Transformation Library by  doxygen 1.3.9.1