|
dlvhex
2.1.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer 00003 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner 00004 * Copyright (C) 2009, 2010 Peter Schüller 00005 * 00006 * This file is part of dlvhex. 00007 * 00008 * dlvhex is free software; you can redistribute it and/or modify it 00009 * under the terms of the GNU Lesser General Public License as 00010 * published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * dlvhex is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with dlvhex; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00021 * 02110-1301 USA. 00022 */ 00023 00024 00040 #ifndef DLVHEX_HEX_GRAMMAR_H_INCLUDED 00041 #define DLVHEX_HEX_GRAMMAR_H_INCLUDED 00042 00043 #include <boost/spirit/include/qi.hpp> 00044 //#include <boost/spirit/include/qi_rule.hpp> 00045 //#include <boost/spirit/include/qi_grammar.hpp> 00046 //#include <boost/spirit/include/qi_symbols.hpp> 00047 00048 #include <boost/mpl/assert.hpp> 00049 #include <boost/mpl/and.hpp> 00050 #include <boost/mpl/logical.hpp> 00051 #include <boost/type_traits.hpp> 00052 #include <boost/version.hpp> 00053 00054 #include "dlvhex2/PlatformDefinitions.h" 00055 #include "dlvhex2/fwd.h" 00056 #include "dlvhex2/ID.h" 00057 #include "dlvhex2/ExtSourceProperties.h" 00058 00059 #if BOOST_VERSION == 104700 00060 // workaround for spirit 1.47 issue with optional< optional<T> > 00061 namespace boost { namespace spirit { namespace traits 00062 { 00063 template <typename T> 00064 struct build_optional<boost::optional<T> > 00065 { 00066 typedef boost::optional<T> type; 00067 }; 00068 }}} 00069 #endif 00070 00071 DLVHEX_NAMESPACE_BEGIN 00072 00073 /* 00074 * Structure of this Header 00075 * 00076 * HexParserSkipperGrammar 00077 * * skip parser for HEX 00078 * * shared by all parsers and parser modules 00079 * 00080 * HexGrammarSemantics 00081 * * semantic evaluation functionality class 00082 * * holds registry and program ctx and store parsed stuff there 00083 * * required to be passed to all modules and grammars 00084 * * intended to be called/reused by parser modules 00085 * * TODO will likely also be extended by parser modules 00086 * * TODO probably should be moved into separate header 00087 * 00088 * HexGrammarBase 00089 * * template, source in HexGrammar.tcc, instantiated via HexGrammar 00090 * * reusable by parser modules 00091 * 00092 * HexGrammar 00093 * * concrete grammar used for parsing HEX 00094 * * instantiated in HexGrammar.cpp and in parser modules 00095 * 00096 * HexParserIterator 00097 * * concrete iterator type used for parsing HEX 00098 * * used to instantiate grammar and parser modules 00099 * 00100 * HexParserModuleGrammar 00101 * * non-template base class for grammars of parser modules in shared libraries 00102 * * has fixed attribute type to communicate with HexGrammar 00103 * * uses fixed HexParserSkipper 00104 * * uses fixed HexParserIterator 00105 */ 00106 00108 template<typename Iterator> 00109 struct HexParserSkipperGrammar: 00110 boost::spirit::qi::grammar<Iterator> 00111 { 00112 HexParserSkipperGrammar(); 00113 boost::spirit::qi::rule<Iterator> ws; 00114 }; 00115 00117 typedef std::string::iterator HexParserIterator; 00118 00120 typedef HexParserSkipperGrammar<HexParserIterator> HexParserSkipper; 00121 00123 typedef boost::spirit::qi::grammar< 00124 HexParserIterator, ID(), HexParserSkipper> 00125 HexParserModuleGrammar; 00126 typedef boost::shared_ptr<HexParserModuleGrammar> 00127 HexParserModuleGrammarPtr; 00128 00129 // generic semantic action processor which creates useful compile-time error messages 00130 // (if the grammar compiles, this class is never used, this means we have a handler for each action) 00131 template<typename Tag> 00132 struct sem 00133 { 00134 template<typename Mgr, typename Source, typename Target> 00135 void operator()(Mgr& mgr, const Source& source, Target& target) 00136 { BOOST_MPL_ASSERT(( boost::is_same< Source, void > )); } 00137 }; 00138 00139 // base class for semantic actions 00140 // this class delegates to sem<Tag>::operator() where all the true processing happens (hidden in compilation unit) 00141 template<typename ManagerClass, typename TargetAttribute, typename Tag> 00142 struct SemanticActionBase 00143 { 00144 typedef SemanticActionBase<ManagerClass, TargetAttribute, Tag> base_type; 00145 00146 ManagerClass& mgr; 00147 SemanticActionBase(ManagerClass& mgr): mgr(mgr) {} 00148 00149 template<typename SourceAttributes, typename Ctx> 00150 void operator()(const SourceAttributes& source, Ctx& ctx, boost::spirit::qi::unused_type) const 00151 { 00152 TargetAttribute& target = boost::fusion::at_c<0>(ctx.attributes); 00153 sem<Tag>()(mgr, source, target); 00154 } 00155 }; 00156 00158 class HexGrammarSemantics 00159 { 00160 public: 00161 ProgramCtx& ctx; 00162 std::string currentModuleName; // store module name to prefix pred_decl 00163 int mlpMode; 00164 void markExternalPropertyIfExternalBody(RegistryPtr registry, Rule& r); 00165 void markModulePropertyIfModuleBody(RegistryPtr registry, Rule& r); 00166 00167 public: 00168 HexGrammarSemantics(ProgramCtx& ctx); 00169 00170 // the classes defined here act as tags to resolve semantic actions 00171 // in a global template which is partially specialized using these tags 00172 #define DLVHEX_DEFINE_SEMANTIC_ACTION(name, targettype) \ 00173 struct name: \ 00174 SemanticActionBase<HexGrammarSemantics, targettype, name> \ 00175 { \ 00176 name(HexGrammarSemantics& mgr): name ::base_type(mgr) {} \ 00177 }; 00178 00179 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromCIdent, ID); 00180 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromInteger, ID); 00181 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromString, ID); 00182 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromVariable, ID); 00183 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromPredDecl, ID); 00184 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromNameOnly, ID); 00185 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromString, ID); 00186 DLVHEX_DEFINE_SEMANTIC_ACTION(classicalAtomFromPrefix, ID); 00187 DLVHEX_DEFINE_SEMANTIC_ACTION(classicalAtomFromTuple, ID); 00188 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinTernaryInfix, ID); 00189 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinBinaryInfix, ID); 00190 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinUnaryPrefix, ID); 00191 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinBinaryPrefix, ID); 00192 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinTernaryPrefix, ID); 00193 DLVHEX_DEFINE_SEMANTIC_ACTION(aggregateAtom, ID); 00194 DLVHEX_DEFINE_SEMANTIC_ACTION(externalAtom, ID); 00195 DLVHEX_DEFINE_SEMANTIC_ACTION(extSourceProperty, ExtSourceProperty); 00196 DLVHEX_DEFINE_SEMANTIC_ACTION(mlpModuleAtom, ID); 00197 DLVHEX_DEFINE_SEMANTIC_ACTION(bodyLiteral, ID); 00198 DLVHEX_DEFINE_SEMANTIC_ACTION(rule, ID); 00199 DLVHEX_DEFINE_SEMANTIC_ACTION(constraint, ID); 00200 DLVHEX_DEFINE_SEMANTIC_ACTION(weakconstraint, ID); 00201 DLVHEX_DEFINE_SEMANTIC_ACTION(add, const boost::spirit::unused_type); 00202 DLVHEX_DEFINE_SEMANTIC_ACTION(addMLPModuleName, std::string); 00203 DLVHEX_DEFINE_SEMANTIC_ACTION(addMLPModuleHeader, const boost::spirit::unused_type); 00204 DLVHEX_DEFINE_SEMANTIC_ACTION(ignoreAndWarnIfNotFail, const boost::spirit::unused_type); 00205 DLVHEX_DEFINE_SEMANTIC_ACTION(maxint, const boost::spirit::unused_type); 00206 00207 #undef DLVHEX_DEFINE_SEMANTIC_ACTION 00208 }; 00209 00211 template<typename Iterator, typename Skipper> 00212 struct HexGrammarBase 00213 { 00214 HexGrammarSemantics& sem; 00215 HexGrammarBase(HexGrammarSemantics&); 00216 00219 void registerToplevelModule(HexParserModuleGrammarPtr module); 00220 00223 void registerBodyAtomModule(HexParserModuleGrammarPtr module); 00224 00227 void registerHeadAtomModule(HexParserModuleGrammarPtr module); 00228 00231 void registerTermModule(HexParserModuleGrammarPtr module); 00232 00233 // helper struct for creating rule types 00234 // wrt Dummy see http://stackoverflow.com/questions/6301966/c-nested-template-classes-error-explicit-specialization-in-non-namespace-scop 00235 template<typename Attrib=void, typename Dummy=void> 00236 struct Rule 00237 { 00238 typedef boost::spirit::qi::rule<Iterator, Attrib(), Skipper> type; 00239 }; 00240 template<typename Dummy> 00241 struct Rule<void, Dummy> 00242 { 00243 typedef boost::spirit::qi::rule<Iterator, Skipper> type; 00244 // BEWARE: this is _not_ the same (!) as 00245 // typedef boost::spirit::qi::rule<Iterator, boost::spirit::unused_type, Skipper> type; 00246 }; 00247 00248 // core grammar rules (parser modules can derive from this class and reuse these rules!) 00249 typename Rule<>::type 00250 start, toplevel, toplevelBuiltin, mlpModuleHeader; 00251 typename Rule<std::string>::type 00252 cident, string, variable, mlpModuleName; 00253 typename Rule<uint32_t>::type 00254 posinteger; 00255 typename Rule<ID>::type 00256 term, pred, externalAtom, externalAtomPredicate, 00257 mlpModuleAtom, mlpModuleAtomPredicate, predDecl, 00258 classicalAtomPredicate, classicalAtom, builtinAtom, aggregateAtom, 00259 bodyAtom, bodyLiteral, headAtom, rule, constraint, weakconstraint; 00260 typename Rule<std::vector<ID> >::type 00261 terms, preds, predList; 00262 typename Rule<boost::fusion::vector3<ID, std::vector<ID>, std::vector<ID> > >::type 00263 aggregateTerm; 00264 // rules that are extended by modules 00265 typename Rule<ID>::type 00266 toplevelExt, bodyAtomExt, headAtomExt, termExt; 00267 typename Rule<std::vector<ExtSourceProperty> >::type 00268 externalAtomProperties; 00269 typename Rule<ExtSourceProperty>::type 00270 externalAtomProperty; 00271 // symbol tables 00272 boost::spirit::qi::symbols<char, ID> 00273 builtinOpsUnary, builtinOpsBinary, builtinOpsTernary, builtinOpsAgg; 00274 protected: 00275 std::vector<HexParserModuleGrammarPtr> modules; 00276 }; 00277 00278 template<typename Iterator, typename Skipper> 00279 struct HexGrammar: 00280 HexGrammarBase<Iterator, Skipper>, 00281 boost::spirit::qi::grammar<Iterator, Skipper> 00282 { 00283 typedef HexGrammarBase<Iterator, Skipper> GrammarBase; 00284 typedef boost::spirit::qi::grammar<Iterator, Skipper> QiBase; 00285 00286 HexGrammar(HexGrammarSemantics& sem): 00287 GrammarBase(sem), 00288 QiBase(GrammarBase::start) 00289 { 00290 } 00291 }; 00292 00293 DLVHEX_NAMESPACE_END 00294 00295 #endif // DLVHEX_HEX_GRAMMAR_H_INCLUDED 00296 00297 // Local Variables: 00298 // mode: C++ 00299 // End: