Some architectural design and task delegation

This commit is contained in:
Robin Jadoul 2016-11-09 13:04:56 +01:00
parent 99a9707448
commit 5792b5474e
15 changed files with 2633 additions and 0 deletions

1
.gitignore vendored
View File

@ -254,3 +254,4 @@ Makefile
cmake_install.cmake cmake_install.cmake
install_manifest.txt install_manifest.txt
CTestTestfile.cmake CTestTestfile.cmake
build

58
CMakeLists.txt Normal file
View File

@ -0,0 +1,58 @@
cmake_minimum_required(VERSION 3.2.2)
project(Parsodus VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED 11)
include(ExternalProject)
find_package(mstch QUIET)
if (NOT mstch_FOUND)
ExternalProject_Add(ext-mstch
GIT_REPOSITORY https://github.com/no1msd/mstch
GIT_TAG 1.0.2
#The following line is a dirty hack
#to prevent cmake from needlessly clone any submodule
#inspect `ext-mstch-prefix/tmp/ext-mstch-gitclone.cmake` for more info
GIT_SUBMODULES "NONE\ COMMAND\ true\ ERROR_QUIET"
CMAKE_ARGS -DWITH_UNIT_TESTS=NO
INSTALL_COMMAND ""
)
add_library(mstch::mstch IMPORTED STATIC GLOBAL)
add_dependencies(mstch::mstch ext-mstch)
ExternalProject_Get_Property(ext-mstch source_dir binary_dir)
set_target_properties(mstch::mstch PROPERTIES "IMPORTED_LOCATION" "${binary_dir}/src/${CMAKE_STATIC_LIBRARY_PREFIX}mstch${CMAKE_STATIC_LIBRARY_SUFFIX}")
include_directories(${source_dir}/include)
endif()
ExternalProject_Add(ext-optparse
GIT_REPOSITORY https://github.com/myint/optparse
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
)
ExternalProject_Get_Property(ext-optparse source_dir)
include_directories(${source_dir})
##########################################
find_package(Doxygen)
if(DOXYGEN_FOUND)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
add_custom_target(doc ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} COMMENT "Generating API documentation" VERBATIM)
endif(DOXYGEN_FOUND)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}")
include_directories(include)
add_subdirectory(src)
add_dependencies(Parsodus ext-optparse)
install(DIRECTORY templates
DESTINATION share/Parsodus
)
# add_subdirectory(examples)

2384
Doxyfile.in Normal file

File diff suppressed because it is too large Load Diff

23
TODO Normal file
View File

@ -0,0 +1,23 @@
(-) common infrastructure (grammar structure)
(2) backend plug per parser type (not LALR/SLR, but *LR)
(3) simple first config file parser (only grammar?)
(4) complete config file grammar
(-) lexer
(6) driver (resolution of parser type + backend, input/output files)
(7) main (option parsing, calling driver)
(8) backend (LR, c++)
(9) table (LALR(1))
(10) unit tests
ROBIN: 8, 9, 10
THOMAS: 2, 3, 6, 10
KOBE: 4, 7, 10
extras:
-> bash completion
-> more tables/backends
-> update lexesis parser
-> man pages
-> README

View File

@ -0,0 +1,10 @@
#pragma once
#ifndef PARSODUS_BACKEND_H
#define PARSODUS_BACKEND_H
namespace pds {
class Backend;
class LRBackend;
}
#endif //PARSODUS_BACKEND_H

View File

@ -0,0 +1,45 @@
#pragma once
#ifndef PARSODUS_BACKENDMANAGER_H
#define PARSODUS_BACKENDMANAGER_H
#include <memory>
#include <string>
#include <vector>
#include "Parsodus/backend.h"
namespace pds {
/**
* A manager for backends
* Aggregates and allow to search for backends that can process a specific language
*/
class BackendManager {
public:
/**
* Add a backend to the list of registered backends
*
* @param backend The backend to register
*/
void registerBackend(std::unique_ptr<Backend> backend);
/**
* Register an *LR type backend
*/
void registerLRBackend(std::unique_ptr<LRBackend> b);
/**
* Get a backend that can process the given language
* The manager retains ownership of the returned pointer
*
* @param lang The language the backend should be able to process
* @returns A pointer to a Backend if it can find one, nullptr otherwise
*/
Backend* findBackend(std::string lang, std::string parserType);
private:
std::vector<std::unique_ptr<Backend> > m_backends; ///< The list of registered backends
};
}
#endif //PARSODUS_BACKENDMANAGER_H

View File

@ -0,0 +1,30 @@
#pragma once
#ifndef PARSODUS_GRAMMAR_H
#include <map>
#include <set>
#include <string>
#include <vector>
namespace pds {
/**
* Represents a grammar rule
* head -> tail[0] tail[1] ... tail[tail.size() - 1]
*/
struct Rule {
std::string head; ///< The replaced variable
std::vector<std::string> tail; ///< The replacement rule
};
/**
* A context free grammar
* Keeps track of variables, terminals and replacement rules
*/
struct Grammar {
std::set<std::string> variables; ///< the variables
std::set<std::string> terminals; ///< the terminals
std::map<std::string, std::set<Rule> > rules; ///< the replacement rules
};
}
#endif //PARSODUS_GRAMMAR_H

18
parser.example.pds Normal file
View File

@ -0,0 +1,18 @@
parser: lalr(1)
precedence: #optional
left 5 PLUS
right 6 TIMES
nonassoc 2 LT
lexesis: lexer.lxs
# of
terminals:
TERMINAL
...
start: start
grammar:
start -> a
| b
;
a → TERMINAL;
b -> a;

27
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,27 @@
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
add_library(Parsodus-backends
backends/cpp.cpp
)
add_library(pds
driver.cpp
)
add_executable(Parsodus
main.cpp
)
target_link_libraries(Parsodus Parsodus-backends pds mstch::mstch)
if (CMAKE_BUILD_TYPE MATCHES Debug)
add_executable(Parsodus-test
test.cpp
)
target_link_libraries(Parsodus-test Parsodus-backends pds mstch::mstch)
endif()
install(TARGETS Parsodus
RUNTIME DESTINATION bin
)

0
src/backends/cpp.cpp Normal file
View File

7
src/config.h.in Normal file
View File

@ -0,0 +1,7 @@
#ifndef CONFIG_H
#define CONFIG_H
#define DATADIR "@CMAKE_INSTALL_PREFIX@/share/Parsodus/"
#endif //CONFIG_H

2
src/driver.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "Parsodus/grammar.h"

18
src/inputparser.lxs Normal file
View File

@ -0,0 +1,18 @@
PARSER = parser
PRECEDENCE = precedence
LEXESIS = lexesis
TERMINALS = terminals
START = start
GRAMMAR = grammar
PARSERTYPE = [_a-zA-Z]+(\([1-9][0-9]*\))?
LEFT = left
RIGHT = right
NONASSOC = nonassoc
NUM = [1-9][0-9]*
LEXESISNAME = [_a-zA-Z]+\.lxs
TERMINAL = [_A-Z]+
VARIABLE = [_a-z]+
ARROW = ->|→
SEMICOLON = ;
COLON = :
PIPE = \|

5
src/main.cpp Normal file
View File

@ -0,0 +1,5 @@
#include <iostream>
int main() {
std::cout << "Parsodus to the rescue" << std::endl;
}

5
src/test.cpp Normal file
View File

@ -0,0 +1,5 @@
#include <iostream>
int main() {
std::cout << "Parsodus to the rescue" << std::endl;
}