Skip to content

Commit 6589ec5

Browse files
authored
v1.5 (#21)
* rename files * add extension * add extension test * refactor peg grammar program * update parser extension test * update deps * update travis * update Glue * v1.5
1 parent 3e90a90 commit 6589ec5

22 files changed

+286
-87
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ before_install:
3939
- sudo sh cmake.sh --skip-license --exclude-subdir --prefix=/usr/local
4040

4141
install:
42-
- cmake -H. -Bbuild
42+
- cmake -H. -Bbuild -DBUILD_LARS_PARSER_GLUE_EXTENSION=On
4343
- cmake --build build
4444
- sudo cmake --build build --target install
4545

CMakeLists.txt

+35-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ endif()
77
# ---- Project ----
88

99
project(LarsParser
10-
VERSION 1.4
10+
VERSION 1.5
1111
LANGUAGES CXX
1212
)
1313

@@ -19,6 +19,7 @@ endif()
1919

2020
option(BUILD_LARS_PARSER_EXAMPLES "Enable examples" OFF)
2121
option(ENABLE_LARS_PARSER_TESTS "Enable tests" OFF)
22+
option(BUILD_LARS_PARSER_GLUE_EXTENSION "Build LarsParser Glue extension" OFF)
2223

2324
# ---- Dependencies ----
2425

@@ -27,9 +28,17 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CPM.cmake)
2728
CPMAddPackage(
2829
NAME LHC
2930
GIT_REPOSITORY https://github.com/TheLartians/LHC.git
30-
VERSION 0.3
31+
VERSION 0.4
3132
)
3233

34+
if(BUILD_LARS_PARSER_GLUE_EXTENSION)
35+
CPMAddPackage(
36+
NAME Glue
37+
GIT_REPOSITORY https://github.com/TheLartians/Glue.git
38+
VERSION 0.3
39+
)
40+
endif()
41+
3342
# ---- Minimum CXX ----
3443

3544
if(NOT CMAKE_CXX_STANDARD GREATER 17)
@@ -38,12 +47,34 @@ endif()
3847

3948
# ---- Create library ----
4049

41-
FILE(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/include/lars/*.h")
42-
FILE(GLOB sources "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
50+
SET(headers
51+
"${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/grammar.h"
52+
"${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/parser.h"
53+
"${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/interpreter.h"
54+
"${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/generator.h"
55+
"${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/peg.h"
56+
)
57+
58+
SET(sources
59+
"${CMAKE_CURRENT_SOURCE_DIR}/source/grammar.cpp"
60+
"${CMAKE_CURRENT_SOURCE_DIR}/source/parser.cpp"
61+
"${CMAKE_CURRENT_SOURCE_DIR}/source/interpreter.cpp"
62+
"${CMAKE_CURRENT_SOURCE_DIR}/source/peg.cpp"
63+
)
64+
65+
if(BUILD_LARS_PARSER_GLUE_EXTENSION)
66+
LIST(APPEND headers "${CMAKE_CURRENT_SOURCE_DIR}/include/lars/parser/extension.h")
67+
LIST(APPEND sources "${CMAKE_CURRENT_SOURCE_DIR}/source/extension.cpp")
68+
endif()
69+
4370
add_library(LarsParser ${sources} ${headers})
4471

4572
target_link_libraries(LarsParser PRIVATE LHC)
4673

74+
if(BUILD_LARS_PARSER_GLUE_EXTENSION)
75+
target_link_libraries(LarsParser PUBLIC Glue)
76+
endif()
77+
4778
target_include_directories(LarsParser
4879
PUBLIC
4980
$<INSTALL_INTERFACE:include>
@@ -58,7 +89,6 @@ write_basic_package_version_file(
5889
COMPATIBILITY AnyNewerVersion
5990
)
6091

61-
6292
# ---- Install ----
6393

6494
install(

cmake/CPM.cmake

+6-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ set(_CPM_Dir "${CMAKE_CURRENT_LIST_DIR}")
22

33
include(CMakeParseArguments)
44
include(${_CPM_Dir}/DownloadProject.cmake)
5-
6-
function(CPMHasPackage)
75

8-
endfunction()
6+
option(CPM_OFFLINE "CPM offline mode" OFF)
7+
8+
if(NOT ${CPM_OFFLINE})
9+
set(CPM_PACKAGES "" CACHE INTERNAL "CPM Packages")
10+
endif()
911

1012
function(CPMAddPackage)
1113
set(options QUIET)
@@ -16,6 +18,7 @@ function(CPMAddPackage)
1618
VERSION
1719
GIT_TAG
1820
BINARY_DIR
21+
UPDATE_DISCONNECTED
1922
)
2023

2124
set(multiValueArgs "")

cmake/CPMProject.CMakeLists.cmake.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ else()
1717
PROJ @CPM_ARGS_NAME@
1818
GIT_REPOSITORY @CPM_ARGS_GIT_REPOSITORY@
1919
GIT_TAG @CPM_ARGS_GIT_TAG@
20-
UPDATE_DISCONNECTED 1
20+
UPDATE_DISCONNECTED @CPM_OFFLINE@
2121
GIT_SHALLOW 1
2222
PREFIX @CPM_ARGS_BINARY_DIR@/dl
2323
QUIET

cmake/LarsParserConfig.cmake.in

+5
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
@PACKAGE_INIT@
22

33
include(CMakeFindDependencyMacro)
4+
45
find_dependency(LHC)
56

7+
if(@BUILD_LARS_PARSER_GLUE_EXTENSION@)
8+
find_dependency(Glue)
9+
endif()
10+
611
include("${CMAKE_CURRENT_LIST_DIR}/LarsParserTargets.cmake")
712
check_required_components("@PROJECT_NAME@")
813

examples/calculator.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
#include <unordered_map>
1212
#include <cmath>
1313

14-
#include <lars/parser_generator.h>
14+
#include <lars/parser/generator.h>
1515

1616
int main() {
1717
using namespace std;

examples/calculator_sequental.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#include <cmath>
88
#include <numeric>
99

10-
#include <lars/parser_generator.h>
10+
#include <lars/parser/generator.h>
1111

1212
int main() {
1313
using namespace std;

examples/type_checker.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <iostream>
1414
#include <unordered_set>
1515

16-
#include <lars/parser_generator.h>
16+
#include <lars/parser/generator.h>
1717

1818
int main() {
1919
using namespace std;

include/lars/parser/extension.h

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#pragma once
2+
3+
#include <lars/glue.h>
4+
5+
namespace lars{
6+
namespace extensions{
7+
std::shared_ptr<Extension> parser();
8+
}
9+
}

include/lars/parser_generator.h include/lars/parser/generator.h

+10-8
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,13 @@ namespace lars {
66

77
template <class R = void, typename ... Args> class ParserGenerator: public Program<R, Args ...> {
88
private:
9-
Program<peg::GrammarNode::Shared> grammarProgram;
9+
peg::GrammarProgram grammarProgram;
1010
std::unordered_map<std::string, std::shared_ptr<peg::Rule>> rules;
1111
peg::GrammarNode::Shared separatorRule;
12-
1312
public:
1413

1514
ParserGenerator(){
16-
grammarProgram = peg::createGrammarProgram([this](const std::string_view &name){
17-
return getRuleNode(std::string(name));
18-
});
15+
grammarProgram = peg::createGrammarProgram();
1916
}
2017

2118
std::shared_ptr<peg::Rule> getRule(const std::string &name) {
@@ -45,8 +42,13 @@ namespace lars {
4542
return rule;
4643
}
4744

45+
peg::GrammarNode::Shared parseRule(const std::string_view &grammar){
46+
peg::RuleGetter rg = [this](const auto &name){ return getRuleNode(std::string(name)); };
47+
return grammarProgram.run(grammar, rg);
48+
}
49+
4850
std::shared_ptr<peg::Rule> setRule(const std::string &name, const std::string_view &grammar, const typename Interpreter<R, Args ...>::Callback &callback = typename Interpreter<R, Args ...>::Callback()){
49-
return setRule(name, grammarProgram.run(grammar), callback);
51+
return setRule(name, parseRule(grammar), callback);
5052
}
5153

5254
template <class R2, typename ... Args2> std::shared_ptr<peg::Rule> setProgramRule(const std::string &name, Program<R2, Args2 ...> subprogram, std::function<R(typename Interpreter<R2, Args2 ...>::Expression,Args...)> callback = [](auto e, Args...){ return e.evaluate(); }){
@@ -59,7 +61,7 @@ namespace lars {
5961
}
6062

6163
std::shared_ptr<peg::Rule> setFilteredRule(const std::string &name, const std::string_view &grammar, const peg::GrammarNode::FilterCallback &filter, const typename Interpreter<R, Args ...>::Callback &callback = typename Interpreter<R, Args ...>::Callback()){
62-
return setRule(name, peg::GrammarNode::Sequence({grammarProgram.run(grammar), peg::GrammarNode::Filter(filter)}), callback);
64+
return setRule(name, peg::GrammarNode::Sequence({parseRule(grammar), peg::GrammarNode::Filter(filter)}), callback);
6365
}
6466

6567
void setSeparator(const std::shared_ptr<peg::Rule> &rule){
@@ -74,7 +76,7 @@ namespace lars {
7476
}
7577

7678
std::shared_ptr<peg::Rule> setSeparatorRule(const std::string &name, const std::string_view &grammar){
77-
return setSeparatorRule(name, grammarProgram.run(grammar));
79+
return setSeparatorRule(name, parseRule(grammar));
7880
}
7981

8082
void setStart(const std::shared_ptr<peg::Rule> &rule){
File renamed without changes.

include/lars/interpreter.h include/lars/parser/interpreter.h

+1
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ namespace lars {
118118
const char * what()const noexcept override;
119119
};
120120

121+
121122
template <class R, typename ... Args> struct Program {
122123
using Expression = typename Interpreter<R, Args...>::Expression;
123124

File renamed without changes.

include/lars/peg.h include/lars/parser/peg.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ namespace lars {
1212
std::function<char(char)> defaultEscapeCodeCallback();
1313
Program<char> createCharacterProgram(const std::function<char(char)> escapeCodeCallback = defaultEscapeCodeCallback());
1414
Program<std::string> createStringProgram(const std::string &open, const std::string &close);
15-
Program<peg::GrammarNode::Shared> createGrammarProgram(const std::function<GrammarNode::Shared(const std::string_view &)> &getRule);
15+
16+
using RuleGetter = const std::function<GrammarNode::Shared(const std::string_view &)> &;
17+
using GrammarProgram = Program<peg::GrammarNode::Shared, RuleGetter &>;
18+
GrammarProgram createGrammarProgram();
1619
}
1720

1821
}

source/extension.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
#include <lars/parser/extension.h>
2+
#include <lars/parser/generator.h>
3+
#include <stdexcept>
4+
#include <lars/log.h>
5+
6+
std::shared_ptr<lars::Extension> lars::extensions::parser(){
7+
using namespace lars;
8+
9+
using ParserGenerator = lars::ParserGenerator<Any,Any&>;
10+
using Expression = ParserGenerator::Expression;
11+
12+
auto expressionExtension = std::make_shared<Extension>();
13+
expressionExtension->set_class<ParserGenerator::Expression>();
14+
15+
expressionExtension->add_function("evaluate", [](Expression &e,Any &d){
16+
return e.evaluate(d);
17+
});
18+
19+
expressionExtension->add_function("size", [](Expression &e)->unsigned{
20+
return e.size();
21+
});
22+
23+
expressionExtension->add_function("get", [](Expression &e, unsigned i){
24+
if (i < e.size()) {
25+
return e[i];
26+
} else {
27+
throw std::runtime_error("invalid expression index");
28+
}
29+
});
30+
31+
expressionExtension->add_function("string", [](Expression &e){
32+
return e.string();
33+
});
34+
35+
expressionExtension->add_function("position", [](Expression &e){
36+
return e.position();
37+
});
38+
39+
expressionExtension->add_function("length", [](Expression &e){
40+
return e.length();
41+
});
42+
43+
auto parserGeneratorExtension = std::make_shared<Extension>();
44+
parserGeneratorExtension->set_class<ParserGenerator>();
45+
parserGeneratorExtension->add_function("create", [](){ return ParserGenerator(); });
46+
47+
parserGeneratorExtension->add_function("run", [](ParserGenerator &g, const std::string &str, Any& arg){
48+
return g.run(str, arg);
49+
});
50+
51+
parserGeneratorExtension->add_function("setRule",[](ParserGenerator &g, const std::string &name, const std::string &grammar){
52+
return g.setRule(name, grammar);
53+
});
54+
55+
parserGeneratorExtension->add_function("setRuleWithCallback",[](ParserGenerator &g, const std::string &name, const std::string &grammar, AnyFunction callback){
56+
return g.setRule(name, grammar, [callback](auto e, Any v){
57+
return callback(e, v);
58+
});
59+
});
60+
61+
parserGeneratorExtension->add_function("setStartRule", [](ParserGenerator &g, const std::string &name){
62+
g.setStart(g.getRule(name));
63+
});
64+
65+
parserGeneratorExtension->add_function("setSeparatorRule", [](ParserGenerator &g, const std::string &name){
66+
g.setSeparator(g.getRule(name));
67+
});
68+
69+
auto extension = std::make_shared<Extension>();
70+
extension->add_extension("Program", parserGeneratorExtension);
71+
extension->add_extension("Expression", expressionExtension);
72+
73+
return extension;
74+
}

source/grammar.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
#include <lars/grammar.h>
1+
#include <lars/parser/grammar.h>
2+
#include <lars/parser/interpreter.h>
23
#include <lars/iterators.h>
3-
#include <lars/interpreter.h>
44

55
using namespace lars::peg;
66

source/interpreter.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#include <lars/interpreter.h>
1+
#include <lars/parser/interpreter.h>
22
#include <lars/to_string.h>
33
#include <lars/iterators.h>
44
#include <string>

source/parser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11

2-
#include <lars/parser.h>
2+
#include <lars/parser/parser.h>
33
#include <lars/to_string.h>
44
#include <lars/iterators.h>
55
#include <lars/hashers.h>

0 commit comments

Comments
 (0)