dlvhex  2.5.0
include/dlvhex2/HexGrammar.h
Go to the documentation of this file.
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: