CommonParser.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: Peter Soetens  Thu Jul 15 11:21:07 CEST 2004  CommonParser.cxx
00003 
00004                         CommonParser.cxx -  description
00005                            -------------------
00006     begin                : Thu July 15 2004
00007     copyright            : (C) 2004 Peter Soetens
00008     email                : peter.soetens at mech.kuleuven.ac.be
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
00035  *                                                                         *
00036  ***************************************************************************/
00037 #include <boost/bind.hpp>
00038 
00039 #include "parse_exception.hpp"
00040 #include "parser-debug.hpp"
00041 #include "CommonParser.hpp"
00042 
00043 namespace RTT {
00044     using boost::bind;
00045     using namespace detail;
00046 
00047     namespace {
00048         boost::spirit::classic::assertion<std::string> expect_eos("End of statement expected. Use a newline or ';' to separate statements.");
00049     }
00050 
00051     CommonParser::~CommonParser() {}
00052 
00053     CommonParser::CommonParser()
00054         : identchar( "a-zA-Z_0-9" ), skipeol(true),
00055           skipper( eol_skip_functor(skipeol) )
00056     {
00057         // we reserve a few words
00058         keywordstable =
00059             "do",
00060             "until",
00061             "done",
00062             "or",
00063             "and",
00064             "not",
00065             "include",
00066             "if",
00067             "define",
00068             "then",
00069             "else",
00070             "for",
00071             "foreach",
00072             "while",
00073             "true",
00074             "false",
00075             "const",
00076             "nothing", // do not exclude 'do nothing' !
00077             "yield",
00078             "var",
00079             "set",
00080             "alias",
00081             "send",
00082             "collect",
00083             "collectIfDone",
00084             "return",
00085             "call",
00086             "try",
00087             "catch";
00088 
00089         BOOST_SPIRIT_DEBUG_RULE( idr );
00090         BOOST_SPIRIT_DEBUG_RULE( idlr );
00091         BOOST_SPIRIT_DEBUG_RULE( eos );
00092         BOOST_SPIRIT_DEBUG_RULE( notassertingeos );
00093         BOOST_SPIRIT_DEBUG_RULE( leos );
00094         BOOST_SPIRIT_DEBUG_RULE( endofkeyword );
00095         BOOST_SPIRIT_DEBUG_RULE( keywords );
00096         BOOST_SPIRIT_DEBUG_RULE( keyword );
00097         BOOST_SPIRIT_DEBUG_RULE( identifier );
00098         BOOST_SPIRIT_DEBUG_RULE( templ );
00099         BOOST_SPIRIT_DEBUG_RULE( tidentifier );
00100         BOOST_SPIRIT_DEBUG_RULE( identchar );
00101         BOOST_SPIRIT_DEBUG_RULE( notassertingidentifier );
00102         BOOST_SPIRIT_DEBUG_RULE( lexeme_identifier );
00103         BOOST_SPIRIT_DEBUG_RULE( lexeme_notassertingidentifier );
00104         BOOST_SPIRIT_DEBUG_RULE( type_name );
00105         BOOST_SPIRIT_DEBUG_RULE( skipper );
00106 
00107         // an identifier is a word which can be used to identify a
00108         // label, or be the name of an object or method.  it is required
00109         // to start with a letter, followed by any number of letters,
00110         // numbers, dashes, underscores or letters.  The keywords we
00111         // reserved above are excluded..
00112         keywords = keywordstable;
00113         endofkeyword = (~identchar) | eol_p | end_p;
00114         keyword = lexeme_d[keywords >> eps_p(endofkeyword)];
00115 
00116         idlr = lexeme_d[alpha_p >> *identchar][assign( lastparsedident )];
00117 
00118         // silently parses every identifier except keywords
00119         notassertingidentifier = (idlr >> !str_p("[]")) - keyword;
00120         // loudly asserts when a keyword comes in
00121         identifier = keyword[bind( &CommonParser::seenillegalidentifier, this, _1, _2 )] | (idlr >> !str_p("[]") );
00122 
00123         // this is a recursive rule. 't' stands for 'template' and 'terminal' (followed by a '(')
00124         templ = ch_p('<') >> identifier >> *templ >> '>';
00125         tidentifier = identifier >> *templ; // >> eps_p( ch_p('(') ); // This is a hack: we expect always the form A<B<C>>(...)
00126 
00127         // end of statement is on a newline or a ';'
00128         //eos = lexeme_d[ *(space_p - eol_p) >> (eol_p | ch_p(';')) ];
00129         eos = expect_eos( notassertingeos ); // detect } as eos, but do not consume.
00130         notassertingeos = eol_p | ch_p(';') | eps_p(ch_p('}')); // detect } as eos, but do not consume.
00131         leos = *(space_p - eol_p) >> (eol_p | ch_p(';') | eps_p(ch_p('}')));
00132 
00133         chset<> t_identchar( "a-zA-Z-_0-9/<>." );
00134         type_name = lexeme_d[ alpha_p >> *t_identchar ] - keyword;
00135     }
00136 
00137     void CommonParser::seenillegalidentifier(iter_t begin, iter_t end )
00138     {
00139         std::string ident(begin, end);
00140         throw parse_exception_illegal_identifier( ident );
00141     }
00142 
00143 }


rtt
Author(s): RTT Developers
autogenerated on Wed Aug 26 2015 16:15:46