First work on Backends en the BackendManager
This commit is contained in:
		
							parent
							
								
									83b982015a
								
							
						
					
					
						commit
						a9067c019e
					
				|  | @ -2,9 +2,80 @@ | ||||||
| #ifndef PARSODUS_BACKEND_H | #ifndef PARSODUS_BACKEND_H | ||||||
| #define PARSODUS_BACKEND_H | #define PARSODUS_BACKEND_H | ||||||
| 
 | 
 | ||||||
|  | #include "Parsodus/config.h" | ||||||
|  | #include "Parsodus/template.h" | ||||||
|  | #include "Parsodus/util/parserType.h" | ||||||
|  | 
 | ||||||
|  | #include <functional> | ||||||
|  | #include <memory> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
| namespace pds { | namespace pds { | ||||||
|     class Backend; |     class Backend { | ||||||
|     class LRBackend; | 		public: | ||||||
|  |             /**
 | ||||||
|  |              * Constructor | ||||||
|  |              */ | ||||||
|  |             Backend(); | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Destructor | ||||||
|  |              */ | ||||||
|  |             virtual ~Backend(); | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Report a name for the backend | ||||||
|  |              * used in resolving template paths | ||||||
|  |              * | ||||||
|  |              * @return std::string A name for the backend | ||||||
|  |              */ | ||||||
|  |             virtual std::string getName() = 0; | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Can this backend process the language with given description? | ||||||
|  |              * | ||||||
|  |              * @param lang A description for a language (eg. "c++", "cxx", "cpp") | ||||||
|  |              * @return Can this backend process it | ||||||
|  |              */ | ||||||
|  |             virtual bool canProcessLang(std::string lang); | ||||||
|  | 
 | ||||||
|  |             /**
 | ||||||
|  |              * Can this backend generate a parser for the given description? | ||||||
|  |              * | ||||||
|  |              * @param parserType A type of parser that could be generated by this backend | ||||||
|  |              * @return Can this backend generate this type of parser | ||||||
|  |              */ | ||||||
|  |              | ||||||
|  |             virtual bool canGenerateParser(util::ParserType parserType); | ||||||
|  |              | ||||||
|  |             /**
 | ||||||
|  |              * The function that gets called to generate the actual parser | ||||||
|  |              * | ||||||
|  |              * @param getOstreamForFileName A function that takes a filename and returns a std::ostream that the backend can write to for that filename | ||||||
|  |              * @param parserName The name that should be given to the parser | ||||||
|  |              * @param config The Config-object containing the grammar | ||||||
|  |              */ | ||||||
|  |             virtual void generateParser(std::function<std::unique_ptr<std::ostream>(std::string)> getOstreamForFileName, std::string parserName, const Config& config) = 0; | ||||||
|  | 
 | ||||||
|  |         protected: | ||||||
|  |             /**
 | ||||||
|  |              * Render a template (with given (file)name) to the given ostream with the information provided | ||||||
|  |              * | ||||||
|  |              * @param out The ostream to write the rendered template to | ||||||
|  |              * @param templateName An identifier for the template, is combined with `getName()` to construct the actual path | ||||||
|  |              * @param context The information that should be provided to the template when rendering | ||||||
|  |              */ | ||||||
|  |             void doTemplate(std::ostream& out, std::string templateName, templ::TemplateContext context); | ||||||
|  | 
 | ||||||
|  |         private: | ||||||
|  |             /**
 | ||||||
|  |              * Find the template with given name | ||||||
|  |              * | ||||||
|  |              * @param templateName the template name, gets combined with `getName()` | ||||||
|  |              */ | ||||||
|  |             std::string findTemplate(std::string templateName); | ||||||
|  |   | ||||||
|  |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #endif //PARSODUS_BACKEND_H
 | #endif //PARSODUS_BACKEND_H
 | ||||||
|  |  | ||||||
|  | @ -7,6 +7,10 @@ | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| #include "Parsodus/backend.h" | #include "Parsodus/backend.h" | ||||||
|  | #include "Parsodus/lrtables/generator.h" | ||||||
|  | #include "Parsodus/lrtables/LR0Itemset.h" | ||||||
|  | #include "Parsodus/lrtables/SLR1Itemset.h" | ||||||
|  | #include "Parsodus/util/parserType.h" | ||||||
| 
 | 
 | ||||||
| namespace pds { | namespace pds { | ||||||
|     /**
 |     /**
 | ||||||
|  | @ -22,19 +26,21 @@ namespace pds { | ||||||
|              */ |              */ | ||||||
|             void registerBackend(std::unique_ptr<Backend> backend); |             void registerBackend(std::unique_ptr<Backend> backend); | ||||||
| 
 | 
 | ||||||
|             /**
 |             template<template<class > class T> | ||||||
|              * Register an *LR type backend |             void registerLR() { | ||||||
|              */ |                 registerBackend(std::make_unique<T<lr::Generator<lr::LR0Itemset>>>(util::ParserType::LR_0));  | ||||||
|             void registerLRBackend(std::unique_ptr<LRBackend> b); |                 registerBackend(std::make_unique<T<lr::Generator<lr::SLR1Itemset>>>(util::ParserType::SLR_1));  | ||||||
|  |             } | ||||||
|              |              | ||||||
|             /**
 |             /**
 | ||||||
|              * Get a backend that can process the given language |              * Get a backend that can process the given language | ||||||
|              * The manager retains ownership of the returned pointer |              * The manager retains ownership of the returned pointer | ||||||
|              * |              * | ||||||
|              * @param lang The language the backend should be able to process |              * @param lang The language the backend should be able to process | ||||||
|  |              * @param parserType the type of parser it should be able to produce (e.g. LALR_1, LR_0, etc..) | ||||||
|              * @returns A pointer to a Backend if it can find one, nullptr otherwise |              * @returns A pointer to a Backend if it can find one, nullptr otherwise | ||||||
|              */ |              */ | ||||||
|             Backend* findBackend(std::string lang, std::string parserType); |             Backend* findBackend(std::string lang, util::ParserType parserType); | ||||||
| 
 | 
 | ||||||
|         private: |         private: | ||||||
|             std::vector<std::unique_ptr<Backend> > m_backends; ///< The list of registered backends
 |             std::vector<std::unique_ptr<Backend> > m_backends; ///< The list of registered backends
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,42 @@ | ||||||
|  | #pragma once | ||||||
|  | #ifndef PARSODUS_BACKENDS_CPP_H | ||||||
|  | #define PARSODUS_BACKENDS_CPP_H | ||||||
|  | 
 | ||||||
|  | #include "Parsodus/backend.h" | ||||||
|  | 
 | ||||||
|  | namespace pds { | ||||||
|  | namespace backends { | ||||||
|  | 	 | ||||||
|  | 	/**
 | ||||||
|  | 	 * A backend that emits c++ code | ||||||
|  | 	 */ | ||||||
|  | 	template<typename T> | ||||||
|  | 	class CppLRBackend : public Backend { | ||||||
|  | 		public: | ||||||
|  | 			CppLRBackend(util::ParserType parserType): Backend(), m_parserType(parserType) {} | ||||||
|  | 
 | ||||||
|  | 			~CppLRBackend() {} | ||||||
|  | 
 | ||||||
|  | 			std::string getName() { | ||||||
|  |                 return "c++"; | ||||||
|  |             } | ||||||
|  | 			bool canProcessLang(std::string lang) { | ||||||
|  |                 for (char& c : lang) | ||||||
|  |                     c = std::tolower(c); | ||||||
|  |                 return lang == "c++" || lang == "cpp" || lang == "cxx"; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             bool canGenerateParser(util::ParserType parserType) { | ||||||
|  |                 return parserType == m_parserType; | ||||||
|  |             } | ||||||
|  |              | ||||||
|  | 			void generateParser(std::function<std::unique_ptr<std::ostream>(std::string)> getOstreamForFileName, std::string parserName, const Config& config) { | ||||||
|  |                 //TODO
 | ||||||
|  |             } | ||||||
|  |         private: | ||||||
|  |             util::ParserType m_parserType; | ||||||
|  |     }; | ||||||
|  | } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #endif //PARSODUS_BACKENDS_CPP_H
 | ||||||
|  | @ -0,0 +1,28 @@ | ||||||
|  | #include "Parsodus/backend.h" | ||||||
|  | #include "config.h" | ||||||
|  | 
 | ||||||
|  | namespace pds { | ||||||
|  |     Backend::Backend() | ||||||
|  |     {} | ||||||
|  | 
 | ||||||
|  |     Backend::~Backend() | ||||||
|  |     {} | ||||||
|  | 
 | ||||||
|  |     bool Backend::canProcessLang(std::string /*lang*/) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     bool Backend::canGenerateParser(util::ParserType /*parserType*/) { | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     void Backend::doTemplate(std::ostream& out, std::string templateName, templ::TemplateContext context) { | ||||||
|  |         templ::Template tpl(findTemplate(templateName)); | ||||||
|  |         tpl.render(out, context); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     std::string Backend::findTemplate(std::string templateName) { | ||||||
|  |         return DATADIR "templates/" + templateName; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -0,0 +1,15 @@ | ||||||
|  | #include "Parsodus/backendmanager.h" | ||||||
|  | #include "Parsodus/backend.h" | ||||||
|  | 
 | ||||||
|  | namespace pds { | ||||||
|  |     void BackendManager::registerBackend(std::unique_ptr<Backend> backend) { | ||||||
|  |         m_backends.push_back(std::move(backend)); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     Backend* BackendManager::findBackend(std::string lang, util::ParserType parserType) { | ||||||
|  |         for(std::unique_ptr<Backend> &backend: m_backends) { | ||||||
|  |             if(backend->canProcessLang(lang) && backend->canGenerateParser(parserType)) return backend.get(); | ||||||
|  |         } | ||||||
|  |         return nullptr; | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue