dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005-2007 Roman Schindlauer 00003 * Copyright (C) 2006-2015 Thomas Krennwallner 00004 * Copyright (C) 2009-2016 Peter Schüller 00005 * Copyright (C) 2011-2016 Christoph Redl 00006 * Copyright (C) 2015-2016 Tobias Kaminski 00007 * Copyright (C) 2015-2016 Antonius Weinzierl 00008 * 00009 * This file is part of dlvhex. 00010 * 00011 * dlvhex is free software; you can redistribute it and/or modify it 00012 * under the terms of the GNU Lesser General Public License as 00013 * published by the Free Software Foundation; either version 2.1 of 00014 * the License, or (at your option) any later version. 00015 * 00016 * dlvhex is distributed in the hope that it will be useful, but 00017 * WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00019 * Lesser General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Lesser General Public 00022 * License along with dlvhex; if not, write to the Free Software 00023 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00024 * 02110-1301 USA. 00025 */ 00026 00042 #ifndef DLVHEX_HEX_GRAMMAR_H_INCLUDED 00043 #define DLVHEX_HEX_GRAMMAR_H_INCLUDED 00044 00045 #include <boost/spirit/include/qi.hpp> 00046 //#include <boost/spirit/include/qi_rule.hpp> 00047 //#include <boost/spirit/include/qi_grammar.hpp> 00048 //#include <boost/spirit/include/qi_symbols.hpp> 00049 00050 #include <boost/mpl/assert.hpp> 00051 #include <boost/mpl/and.hpp> 00052 #include <boost/mpl/logical.hpp> 00053 #include <boost/type_traits.hpp> 00054 #include <boost/version.hpp> 00055 00056 #include "dlvhex2/PlatformDefinitions.h" 00057 #include "dlvhex2/fwd.h" 00058 #include "dlvhex2/ID.h" 00059 00060 #if BOOST_VERSION == 104700 00061 // workaround for spirit 1.47 issue with optional< optional<T> > 00062 namespace boost 00063 { 00064 namespace spirit 00065 { 00066 namespace traits 00067 { 00068 template <typename T> 00069 struct build_optional<boost::optional<T> > 00070 { 00071 typedef boost::optional<T> type; 00072 }; 00073 } 00074 } 00075 } 00076 #endif 00077 00078 DLVHEX_NAMESPACE_BEGIN 00079 00080 /* 00081 * Structure of this Header 00082 * 00083 * HexParserSkipperGrammar 00084 * * skip parser for HEX 00085 * * shared by all parsers and parser modules 00086 * 00087 * HexGrammarSemantics 00088 * * semantic evaluation functionality class 00089 * * holds registry and program ctx and store parsed stuff there 00090 * * required to be passed to all modules and grammars 00091 * * intended to be called/reused by parser modules 00092 * * TODO will likely also be extended by parser modules 00093 * * TODO probably should be moved into separate header 00094 * 00095 * HexGrammarBase 00096 * * template, source in HexGrammar.tcc, instantiated via HexGrammar 00097 * * reusable by parser modules 00098 * 00099 * HexGrammar 00100 * * concrete grammar used for parsing HEX 00101 * * instantiated in HexGrammar.cpp and in parser modules 00102 * 00103 * HexParserIterator 00104 * * concrete iterator type used for parsing HEX 00105 * * used to instantiate grammar and parser modules 00106 * 00107 * HexParserModuleGrammar 00108 * * non-template base class for grammars of parser modules in shared libraries 00109 * * has fixed attribute type to communicate with HexGrammar 00110 * * uses fixed HexParserSkipper 00111 * * uses fixed HexParserIterator 00112 */ 00113 00115 template<typename Iterator> 00116 struct HexParserSkipperGrammar: 00117 boost::spirit::qi::grammar<Iterator> 00118 { 00120 HexParserSkipperGrammar(); 00121 boost::spirit::qi::rule<Iterator> ws; 00122 }; 00123 00125 typedef std::string::iterator HexParserIterator; 00126 00128 typedef HexParserSkipperGrammar<HexParserIterator> HexParserSkipper; 00129 00131 typedef boost::spirit::qi::grammar< 00132 HexParserIterator, ID(), HexParserSkipper> 00133 HexParserModuleGrammar; 00134 typedef boost::shared_ptr<HexParserModuleGrammar> 00135 HexParserModuleGrammarPtr; 00136 00140 template<typename Tag> 00141 struct sem 00142 { 00143 template<typename Mgr, typename Source, typename Target> 00144 void operator()(Mgr& mgr, const Source& source, Target& target) 00145 { BOOST_MPL_ASSERT(( boost::is_same< Source, void > )); } 00146 }; 00147 00151 template<typename ManagerClass, typename TargetAttribute, typename Tag> 00152 struct SemanticActionBase 00153 { 00154 typedef SemanticActionBase<ManagerClass, TargetAttribute, Tag> base_type; 00155 00156 ManagerClass& mgr; 00158 SemanticActionBase(ManagerClass& mgr): mgr(mgr) {} 00159 00160 template<typename SourceAttributes, typename Ctx> 00161 void operator()(const SourceAttributes& source, Ctx& ctx, boost::spirit::qi::unused_type) const 00162 { 00163 TargetAttribute& target = boost::fusion::at_c<0>(ctx.attributes); 00164 sem<Tag>()(mgr, source, target); 00165 } 00166 }; 00167 00169 class DLVHEX_EXPORT HexGrammarSemantics 00170 { 00171 public: 00173 ProgramCtx& ctx; 00175 std::string currentModuleName; 00177 int mlpMode; 00181 void markExternalPropertyIfExternalBody(RegistryPtr registry, Rule& r); 00185 void markModulePropertyIfModuleBody(RegistryPtr registry, Rule& r); 00186 00187 public: 00190 HexGrammarSemantics(ProgramCtx& ctx); 00191 00192 // the classes defined here act as tags to resolve semantic actions 00193 // in a global template which is partially specialized using these tags 00194 #define DLVHEX_DEFINE_SEMANTIC_ACTION(name, targettype) \ 00195 struct name: \ 00196 SemanticActionBase<HexGrammarSemantics, targettype, name> \ 00197 { \ 00198 name(HexGrammarSemantics& mgr): name ::base_type(mgr) {} \ 00199 }; 00200 00201 DLVHEX_DEFINE_SEMANTIC_ACTION(termId, ID); 00202 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromCIdent, ID); 00203 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromFunctionTerm, ID); 00204 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromRange, ID); 00205 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromInteger, ID); 00206 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromString, ID); 00207 DLVHEX_DEFINE_SEMANTIC_ACTION(termFromVariable, ID); 00208 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromPredDecl, ID); 00209 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromNameOnly, ID); 00210 DLVHEX_DEFINE_SEMANTIC_ACTION(predFromString, ID); 00211 DLVHEX_DEFINE_SEMANTIC_ACTION(classicalAtomFromPrefix, ID); 00212 DLVHEX_DEFINE_SEMANTIC_ACTION(classicalAtomFromTuple, ID); 00213 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinTernaryInfix, ID); 00214 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinBinaryInfix, ID); 00215 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinUnaryPrefix, ID); 00216 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinBinaryPrefix, ID); 00217 DLVHEX_DEFINE_SEMANTIC_ACTION(builtinTernaryPrefix, ID); 00218 DLVHEX_DEFINE_SEMANTIC_ACTION(aggregateAtom, ID); 00219 DLVHEX_DEFINE_SEMANTIC_ACTION(externalAtom, ID); 00220 DLVHEX_DEFINE_SEMANTIC_ACTION(extSourceProperty, std::vector<std::string>); 00221 DLVHEX_DEFINE_SEMANTIC_ACTION(mlpModuleAtom, ID); 00222 DLVHEX_DEFINE_SEMANTIC_ACTION(bodyLiteral, ID); 00223 DLVHEX_DEFINE_SEMANTIC_ACTION(rule, ID); 00224 DLVHEX_DEFINE_SEMANTIC_ACTION(ruleVariableDisjunction, ID); 00225 DLVHEX_DEFINE_SEMANTIC_ACTION(constraint, ID); 00226 DLVHEX_DEFINE_SEMANTIC_ACTION(weakconstraint, ID); 00227 DLVHEX_DEFINE_SEMANTIC_ACTION(weakconstraintaspcore2, ID); 00228 DLVHEX_DEFINE_SEMANTIC_ACTION(add, const boost::spirit::unused_type); 00229 DLVHEX_DEFINE_SEMANTIC_ACTION(addMLPModuleName, std::string); 00230 DLVHEX_DEFINE_SEMANTIC_ACTION(addMLPModuleHeader, const boost::spirit::unused_type); 00231 DLVHEX_DEFINE_SEMANTIC_ACTION(ignoreAndWarnIfNotFail, const boost::spirit::unused_type); 00232 DLVHEX_DEFINE_SEMANTIC_ACTION(maxint, const boost::spirit::unused_type); 00233 00234 #undef DLVHEX_DEFINE_SEMANTIC_ACTION 00235 }; 00236 00238 template<typename Iterator, typename Skipper> 00239 struct DLVHEX_EXPORT HexGrammarBase 00240 { 00242 HexGrammarSemantics& sem; 00245 HexGrammarBase(HexGrammarSemantics& g); 00246 00251 void registerToplevelModule(HexParserModuleGrammarPtr module); 00252 00257 void registerBodyAtomModule(HexParserModuleGrammarPtr module); 00258 00263 void registerHeadAtomModule(HexParserModuleGrammarPtr module); 00264 00269 void registerTermModule(HexParserModuleGrammarPtr module); 00270 00275 template<typename Attrib=void, typename Dummy=void> 00276 struct Rule 00277 { 00278 typedef boost::spirit::qi::rule<Iterator, Attrib(), Skipper> type; 00279 }; 00280 template<typename Dummy> 00281 struct Rule<void, Dummy> 00282 { 00283 typedef boost::spirit::qi::rule<Iterator, Skipper> type; 00284 // BEWARE: this is _not_ the same (!) as 00285 // typedef boost::spirit::qi::rule<Iterator, boost::spirit::unused_type, Skipper> type; 00286 }; 00287 00288 // core grammar rules (parser modules can derive from this class and reuse these rules!) 00289 typename Rule<>::type 00290 start, toplevel, toplevelBuiltin, mlpModuleHeader; 00291 typename Rule<std::string>::type 00292 cident, string, variable, externalAtomPropertyString, mlpModuleName; 00293 typename Rule<uint32_t>::type 00294 posinteger; 00295 typename Rule<ID>::type 00296 term, primitiveTerm, pred, externalAtom, externalAtomPredicate, 00297 mlpModuleAtom, mlpModuleAtomPredicate, predDecl, 00298 classicalAtomPredicate, classicalAtom, builtinAtom, aggregateAtom, 00299 bodyAtom, bodyLiteral, headAtom, rule, constraint, weakconstraint, weakconstraintaspcore2; 00300 typename Rule<std::vector<ID> >::type 00301 terms, preds, predList; 00302 typename Rule<boost::fusion::vector2<std::vector<ID>, boost::optional<std::vector<ID> > > >::type 00303 symbolicSet; 00304 typename Rule<boost::fusion::vector2<ID, std::vector<boost::fusion::vector2<std::vector<ID>, boost::optional<std::vector<ID> > > > > >::type 00305 aggregateTerm; 00306 // rules that are extended by modules 00307 typename Rule<ID>::type 00308 toplevelExt, bodyAtomExt, headAtomExt, termExt; 00309 typename Rule<std::vector<std::vector<std::string> > >::type 00310 externalAtomProperties; 00311 typename Rule<std::vector<std::string> >::type 00312 externalAtomProperty; 00313 // symbol tables 00314 boost::spirit::qi::symbols<char, ID> 00315 builtinOpsUnary, builtinOpsBinary, builtinOpsTernary, builtinOpsAgg; 00316 protected: 00317 std::vector<HexParserModuleGrammarPtr> modules; 00318 }; 00319 00321 template<typename Iterator, typename Skipper> 00322 struct HexGrammar: 00323 HexGrammarBase<Iterator, Skipper>, 00324 boost::spirit::qi::grammar<Iterator, Skipper> 00325 { 00326 typedef HexGrammarBase<Iterator, Skipper> GrammarBase; 00327 typedef boost::spirit::qi::grammar<Iterator, Skipper> QiBase; 00328 00331 HexGrammar(HexGrammarSemantics& sem): 00332 GrammarBase(sem), 00333 QiBase(GrammarBase::start) { 00334 } 00335 }; 00336 00337 DLVHEX_NAMESPACE_END 00338 #endif // DLVHEX_HEX_GRAMMAR_H_INCLUDED 00339 00340 00341 // vim:expandtab:ts=4:sw=4: 00342 // mode: C++ 00343 // End: