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