Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > b9ba69a436161613d8fb030c8c726a8e > files > 648

spirit-1.5.1-2mdk.noarch.rpm

//
//  A very simple parser grammar .
//  This parser parses a simple polynomial expression ( of the form
//  aX^2 + bX^3 + ...  ) .
//
// Written by: Andy Elvey
// Slightly modified by Dan Nuffer
//
//    This software is provided 'as-is', without any express or implied
//    warranty. In no event will the copyright holder be held liable for
//    any damages arising from the use of this software.
//
//    Permission is granted to anyone to use this software for any purpose,
//    including commercial applications, and to alter it and redistribute
//    it freely, subject to the following restrictions:
//
//    1.  The origin of this software must not be misrepresented; you must
//        not claim that you wrote the original software. If you use this
//        software in a product, an acknowledgment in the product documentation
//        would be appreciated but is not required.
//
//    2.  Altered source versions must be plainly marked as such, and must
//        not be misrepresented as being the original software.
//
//    3.  This notice may not be removed or altered from any source
//        distribution.
//
// Uses:  The Spirit parser framework, which was written by
//  Joel de Guzman isis-tech.n3.net
//

//#define SPIRIT_DEBUG  ///$$$ DEFINE THIS WHEN DEBUGGING $$$///

#include <boost/spirit/core.hpp>
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

///////////////////////////////////////////////////////////////////////////////
using namespace spirit;
using namespace std;

///////////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//  Start grammar definition
//----------------------------------------------------------------------------

struct polynomial_grammar :
    public grammar<polynomial_grammar>
{
    template <typename ScannerT>
    struct definition
    {
        typedef rule<ScannerT> rule_t;

        rule_t program, stmts, term, constant, sign, var, caret;
        rule_t IDENT, STRING_LITERAL, VAR;

        definition(polynomial_grammar const&)
        {
            //-----------------------------------------------------------------
            // OPERATORS
            //-----------------------------------------------------------------
            chlit<>     PLUS('+');
            chlit<>     MINUS('-');
            chlit<>     CARET('^');

            //-----------------------------------------------------------------
            // TOKENS
            //-----------------------------------------------------------------


            IDENT =
                nocase_d
                [
                    lexeme_d
                    [
                        (alpha_p >> *(alnum_p | '_'))
                    ]
                ]
            ;

            STRING_LITERAL =
                lexeme_d
                [
                    ch_p('\'')
                    >>  +(
                            str_p("\'\'")
                            | anychar_p - ch_p('\'')
                         )
                    >> ch_p('\'')
                ]
            ;

            VAR = nocase_d[ lexeme_d[ alpha_p ] ] ;


            //-----------------------------------------------------------------
            // RULES
            //-----------------------------------------------------------------

            //  Now - the actual BNF grammar for the parser

            program =
                +(stmts)
            ;

            stmts =
                ( term | constant )
            ;

            term =
                +(
                    !(sign)
                    >> !(uint_p)
                    >> VAR
                    >> !(CARET)
                    >> !(uint_p)
                 )
            ;   //  e.g. 3x^2

            constant =
                !(sign) >> +(uint_p)
            ;

            sign =
                ( PLUS | MINUS )
            ;

            var =
                VAR
            ;

            caret =
                CARET
            ;

        }

        rule_t const& start() const
        {
            return program;
        }
    };
};


int
main(int /*argc*/, char* /*argv[]*/)
{
    cout << "/////////////////////////////////////////////////////////\n\n";
    cout << "\t\t A polynomial parser...\n\n";
    cout << "/////////////////////////////////////////////////////////\n\n";
    cout << "Type a polynomial (e.g. 3a^4 + 7a^5 - 8a^3 - 4a - 5) or\n"
        << "[q or Q] to quit\n\n";


    polynomial_grammar g;

    while (true)
    {
        string str;
        getline(cin, str);
        if (str[0] == 'q' || str[0] == 'Q')
            break;

        if (parse(str.c_str(), g, space_p).full)
        {
            cout << "parsing succeeded\n";
        }
        else
        {
            cout << "parsing failed\n";
        }
    }

    cout << "Bye... :-) \n\n";
    return 0;
}