Orocos Real-Time Toolkit
2.5.0
|
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 "async", 00076 "time", 00077 "const", 00078 "nothing", // do not exclude 'do nothing' ! 00079 "yield", 00080 "var", 00081 "set", 00082 "alias", 00083 "sync", 00084 "send", 00085 "call", 00086 "collect", 00087 "collectIfDone", 00088 "return", 00089 "call", 00090 "try", 00091 "catch"; 00092 00093 BOOST_SPIRIT_DEBUG_RULE( idr ); 00094 BOOST_SPIRIT_DEBUG_RULE( idlr ); 00095 BOOST_SPIRIT_DEBUG_RULE( eos ); 00096 BOOST_SPIRIT_DEBUG_RULE( notassertingeos ); 00097 BOOST_SPIRIT_DEBUG_RULE( leos ); 00098 BOOST_SPIRIT_DEBUG_RULE( endofkeyword ); 00099 BOOST_SPIRIT_DEBUG_RULE( keywords ); 00100 BOOST_SPIRIT_DEBUG_RULE( keyword ); 00101 BOOST_SPIRIT_DEBUG_RULE( identifier ); 00102 BOOST_SPIRIT_DEBUG_RULE( templ ); 00103 BOOST_SPIRIT_DEBUG_RULE( tidentifier ); 00104 BOOST_SPIRIT_DEBUG_RULE( identchar ); 00105 BOOST_SPIRIT_DEBUG_RULE( notassertingidentifier ); 00106 BOOST_SPIRIT_DEBUG_RULE( lexeme_identifier ); 00107 BOOST_SPIRIT_DEBUG_RULE( lexeme_notassertingidentifier ); 00108 BOOST_SPIRIT_DEBUG_RULE( type_name ); 00109 BOOST_SPIRIT_DEBUG_RULE( skipper ); 00110 00111 // an identifier is a word which can be used to identify a 00112 // label, or be the name of an object or method. it is required 00113 // to start with a letter, followed by any number of letters, 00114 // numbers, dashes, underscores or letters. The keywords we 00115 // reserved above are excluded.. 00116 keywords = keywordstable; 00117 endofkeyword = (~identchar) | eol_p | end_p; 00118 keyword = lexeme_d[keywords >> eps_p(endofkeyword)]; 00119 00120 // if a rule is going to be used inside a lexeme_d, then it 00121 // needs to be of a different type.. Since identifier is used 00122 // both inside and outside of lexeme_d, we need two versions of 00123 // it. Those are provided here: lexeme_identifier and 00124 // identifier.. 00125 idr = lexeme_d[ alpha_p >> *identchar ][assign( lastparsedident )] - keyword; 00126 idlr = lexeme_d[ alpha_p >> *identchar ][assign( lastparsedident )] - keyword; 00127 // #warning " Rule on stack ?? " 00128 //RULE( identifier_base, lexeme_d[ alpha_p >> *identchar ][assign( lastparsedident )] - as_lower_d[keywords] ); 00129 //BOOST_SPIRIT_DEBUG_RULE( identifier_base ); 00130 lexeme_identifier = idlr | keyword[bind( &CommonParser::seenillegalidentifier, this )]; 00131 lexeme_notassertingidentifier = idlr; 00132 00133 notassertingidentifier = idr >> !str_p("[]"); 00134 identifier = (idr >> !str_p("[]")) | keyword[bind( &CommonParser::seenillegalidentifier, this )]; 00135 00136 // this is a recursive rule. 't' stands for 'template' and 'terminal' (followed by a '(') 00137 templ = ch_p('<') >> identifier >> *templ >> '>'; 00138 tidentifier = identifier >> *templ; // >> eps_p( ch_p('(') ); // This is a hack: we expect always the form A<B<C>>(...) 00139 00140 // end of statement is on a newline or a ';' 00141 //eos = lexeme_d[ *(space_p - eol_p) >> (eol_p | ch_p(';')) ]; 00142 eos = expect_eos( notassertingeos ); // detect } as eos, but do not consume. 00143 notassertingeos = eol_p | ch_p(';') | eps_p(ch_p('}')); // detect } as eos, but do not consume. 00144 leos = *(space_p - eol_p) >> (eol_p | ch_p(';') | eps_p(ch_p('}'))); 00145 00146 chset<> t_identchar( "a-zA-Z-_0-9/<>." ); 00147 type_name = lexeme_d[ alpha_p >> *t_identchar ] - keyword; 00148 } 00149 00150 void CommonParser::seenillegalidentifier() 00151 { 00152 throw parse_exception_illegal_identifier( lastparsedident ); 00153 } 00154 00155 }