Add helper functions for making shared pointers to rules

- start work on item set class
This commit is contained in:
Max Brunsfeld 2013-11-10 14:24:25 -08:00
parent ec8b7ccf20
commit 11e3980319
33 changed files with 486 additions and 150 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
.idea
spec/run.out*
TreeSitter.xcodeproj/project.xcworkspace
TreeSitter.xcodeproj/xcuserdata

View file

@ -13,8 +13,17 @@
12130611182C3A1100FCF928 /* blank.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1213060F182C3A1100FCF928 /* blank.cpp */; };
12130614182C3A1700FCF928 /* seq.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12130612182C3A1700FCF928 /* seq.cpp */; };
12130617182C3D2900FCF928 /* string.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12130615182C3D2900FCF928 /* string.cpp */; };
1213061B182C84DF00FCF928 /* item.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12130619182C84DF00FCF928 /* item.cpp */; };
1213061F182C857100FCF928 /* item_set_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1213061D182C857100FCF928 /* item_set_spec.cpp */; };
12130622182C85D300FCF928 /* item_set.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12130620182C85D300FCF928 /* item_set.cpp */; };
1214930E181E200B008E9BDA /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 121492E9181E200B008E9BDA /* main.cpp */; };
1214930F181E200B008E9BDA /* rules_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 121492EA181E200B008E9BDA /* rules_spec.cpp */; };
12512093182F307C00C9B56A /* parse_table_spec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12512092182F307C00C9B56A /* parse_table_spec.cpp */; };
1251209B1830145300C9B56A /* rule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1251209A1830145300C9B56A /* rule.cpp */; };
1251209D18303CFB00C9B56A /* rules.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1251209C18303CFB00C9B56A /* rules.cpp */; };
12F9A64E182DD5FD00FAF50C /* spec_helper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */; };
12F9A651182DD6BC00FAF50C /* grammar.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 12F9A64F182DD6BC00FAF50C /* grammar.cpp */; };
27A343CA69E17E0F9EBEDF1C /* Pattern.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 27A340F3EEB184C040521323 /* Pattern.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -30,7 +39,6 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
121306011829FAED00FCF928 /* spec_helper.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = spec_helper.h; sourceTree = SOURCE_ROOT; };
12130603182C348F00FCF928 /* char.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = char.cpp; sourceTree = "<group>"; };
12130604182C348F00FCF928 /* char.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = char.h; sourceTree = "<group>"; };
12130607182C374800FCF928 /* rule.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rule.h; sourceTree = "<group>"; };
@ -44,6 +52,11 @@
12130613182C3A1700FCF928 /* seq.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = seq.h; sourceTree = "<group>"; };
12130615182C3D2900FCF928 /* string.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string.cpp; sourceTree = "<group>"; };
12130616182C3D2900FCF928 /* string.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string.h; sourceTree = "<group>"; };
12130619182C84DF00FCF928 /* item.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = item.cpp; sourceTree = "<group>"; };
1213061A182C84DF00FCF928 /* item.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = item.h; sourceTree = "<group>"; };
1213061D182C857100FCF928 /* item_set_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = item_set_spec.cpp; path = spec/lr/item_set_spec.cpp; sourceTree = SOURCE_ROOT; };
12130620182C85D300FCF928 /* item_set.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = item_set.cpp; sourceTree = "<group>"; };
12130621182C85D300FCF928 /* item_set.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = item_set.h; sourceTree = "<group>"; };
12149265181E200B008E9BDA /* igloo-tests_CXX_prefix.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = "igloo-tests_CXX_prefix.hxx"; sourceTree = "<group>"; };
12149266181E200B008E9BDA /* igloo-tests_CXX_prefix.hxx.gch */ = {isa = PBXFileReference; lastKnownFileType = file; path = "igloo-tests_CXX_prefix.hxx.gch"; sourceTree = "<group>"; };
12149267181E200B008E9BDA /* snowhouse-tests_CXX_prefix.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = "snowhouse-tests_CXX_prefix.hxx"; sourceTree = "<group>"; };
@ -117,9 +130,18 @@
121492C6181E200B008E9BDA /* igloo_framework.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = igloo_framework.h; sourceTree = "<group>"; };
121492E9181E200B008E9BDA /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = spec/main.cpp; sourceTree = SOURCE_ROOT; };
121492EA181E200B008E9BDA /* rules_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = rules_spec.cpp; path = spec/rules_spec.cpp; sourceTree = SOURCE_ROOT; };
12512092182F307C00C9B56A /* parse_table_spec.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = parse_table_spec.cpp; path = spec/lr/parse_table_spec.cpp; sourceTree = SOURCE_ROOT; };
1251209A1830145300C9B56A /* rule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rule.cpp; sourceTree = "<group>"; };
1251209C18303CFB00C9B56A /* rules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = rules.cpp; sourceTree = "<group>"; };
12C344421822F27700B07BE3 /* transition_map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = transition_map.h; sourceTree = "<group>"; };
12E71794181D02A80051A649 /* specs */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = specs; sourceTree = BUILT_PRODUCTS_DIR; };
12E71852181D081C0051A649 /* rules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rules.h; sourceTree = "<group>"; };
12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = spec_helper.cpp; path = spec/spec_helper.cpp; sourceTree = SOURCE_ROOT; };
12F9A64D182DD5FD00FAF50C /* spec_helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = spec_helper.h; path = spec/spec_helper.h; sourceTree = SOURCE_ROOT; };
12F9A64F182DD6BC00FAF50C /* grammar.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = grammar.cpp; sourceTree = "<group>"; };
12F9A650182DD6BC00FAF50C /* grammar.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = grammar.h; sourceTree = "<group>"; };
27A340F3EEB184C040521323 /* Pattern.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Pattern.cpp; sourceTree = "<group>"; };
27A3438C4FA59A3882E8493B /* Pattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pattern.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -142,17 +164,41 @@
12130604182C348F00FCF928 /* char.h */,
1213060C182C398300FCF928 /* choice.cpp */,
1213060D182C398300FCF928 /* choice.h */,
27A340F3EEB184C040521323 /* Pattern.cpp */,
27A3438C4FA59A3882E8493B /* Pattern.h */,
12130607182C374800FCF928 /* rule.h */,
12130612182C3A1700FCF928 /* seq.cpp */,
12130613182C3A1700FCF928 /* seq.h */,
12130609182C389100FCF928 /* symbol.cpp */,
1213060A182C389100FCF928 /* symbol.h */,
12130615182C3D2900FCF928 /* string.cpp */,
12130616182C3D2900FCF928 /* string.h */,
12130609182C389100FCF928 /* symbol.cpp */,
1213060A182C389100FCF928 /* symbol.h */,
1251209A1830145300C9B56A /* rule.cpp */,
);
path = rules;
sourceTree = "<group>";
};
12130618182C84B700FCF928 /* lr */ = {
isa = PBXGroup;
children = (
12130619182C84DF00FCF928 /* item.cpp */,
1213061A182C84DF00FCF928 /* item.h */,
12130620182C85D300FCF928 /* item_set.cpp */,
12130621182C85D300FCF928 /* item_set.h */,
);
path = lr;
sourceTree = "<group>";
};
1213061C182C854F00FCF928 /* lr */ = {
isa = PBXGroup;
children = (
1213061D182C857100FCF928 /* item_set_spec.cpp */,
12512092182F307C00C9B56A /* parse_table_spec.cpp */,
);
name = lr;
path = spec/lr;
sourceTree = "<group>";
};
1214925C181E200B008E9BDA /* externals */ = {
isa = PBXGroup;
children = (
@ -364,7 +410,11 @@
12E71701181D01890051A649 /* src */ = {
isa = PBXGroup;
children = (
12F9A64F182DD6BC00FAF50C /* grammar.cpp */,
12F9A650182DD6BC00FAF50C /* grammar.h */,
12130618182C84B700FCF928 /* lr */,
12130602182C344400FCF928 /* rules */,
1251209C18303CFB00C9B56A /* rules.cpp */,
12E71852181D081C0051A649 /* rules.h */,
12C344421822F27700B07BE3 /* transition_map.h */,
);
@ -383,9 +433,11 @@
isa = PBXGroup;
children = (
1214925C181E200B008E9BDA /* externals */,
1213061C182C854F00FCF928 /* lr */,
121492E9181E200B008E9BDA /* main.cpp */,
121492EA181E200B008E9BDA /* rules_spec.cpp */,
121306011829FAED00FCF928 /* spec_helper.h */,
12F9A64C182DD5FD00FAF50C /* spec_helper.cpp */,
12F9A64D182DD5FD00FAF50C /* spec_helper.h */,
);
name = spec;
path = Specs;
@ -443,12 +495,21 @@
files = (
12130614182C3A1700FCF928 /* seq.cpp in Sources */,
1214930F181E200B008E9BDA /* rules_spec.cpp in Sources */,
1213061B182C84DF00FCF928 /* item.cpp in Sources */,
1251209D18303CFB00C9B56A /* rules.cpp in Sources */,
12130617182C3D2900FCF928 /* string.cpp in Sources */,
12130611182C3A1100FCF928 /* blank.cpp in Sources */,
1213060E182C398300FCF928 /* choice.cpp in Sources */,
12F9A64E182DD5FD00FAF50C /* spec_helper.cpp in Sources */,
1214930E181E200B008E9BDA /* main.cpp in Sources */,
12F9A651182DD6BC00FAF50C /* grammar.cpp in Sources */,
12512093182F307C00C9B56A /* parse_table_spec.cpp in Sources */,
1213061F182C857100FCF928 /* item_set_spec.cpp in Sources */,
12130622182C85D300FCF928 /* item_set.cpp in Sources */,
12130605182C348F00FCF928 /* char.cpp in Sources */,
1213060B182C389100FCF928 /* symbol.cpp in Sources */,
1251209B1830145300C9B56A /* rule.cpp in Sources */,
27A343CA69E17E0F9EBEDF1C /* Pattern.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -458,12 +519,14 @@
12E716FE181D010E0051A649 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_VERSION = "";
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
spec/externals/igloo,
src/externals/boost,
);
STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic;
USER_HEADER_SEARCH_PATHS = "src/externals/boost spec/externals/igloo";
};
name = Debug;
@ -471,12 +534,14 @@
12E716FF181D010E0051A649 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_VERSION = "";
HEADER_SEARCH_PATHS = (
"$(inherited)",
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
spec/externals/igloo,
src/externals/boost,
);
STANDARD_C_PLUS_PLUS_LIBRARY_TYPE = dynamic;
USER_HEADER_SEARCH_PATHS = "src/externals/boost spec/externals/igloo";
};
name = Release;
@ -485,7 +550,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
@ -529,7 +594,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LANGUAGE_STANDARD = "c++11";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;

21
spec/lr/item_set_spec.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "spec_helper.h"
Describe(item_sets) {
Describe(transitions) {
Grammar grammar = Grammar({
"one",
"two"
}, {
rules::sym("one"),
rules::sym("two")
});
rules::rule_ptr rule = grammar.rules[string("one")];
lr::Item item = lr::Item(string("one"), rule, 0);
It(works) {
lr::ItemSet item_set = lr::ItemSet(item, grammar);
item_set.transitions();
}
};
};

View file

@ -0,0 +1,43 @@
#include "spec_helper.h"
Describe(parse_table_construction) {
Grammar grammar = Grammar(
{
"expression",
"term",
"factor",
"number",
"variable",
"plus",
"times",
"left_paren",
"right_paren"
}, {
rules::choice({
rules::seq({
rules::sym("term"),
rules::sym("plus"),
rules::sym("term") }),
rules::sym("term") }),
rules::choice({
rules::seq({
rules::sym("factor"),
rules::sym("times"),
rules::sym("factor") }),
rules::sym("factor") }),
rules::choice({
rules::sym("variable"),
rules::sym("number"),
rules::seq({
rules::sym("left_paren"),
rules::sym("expression"),
rules::sym("right_paren") }) }),
rules::pattern("\\d+"),
rules::pattern("\\w+"),
rules::str("+"),
rules::str("*"),
rules::str("("),
rules::str(")")
}
);
};

View file

@ -3,78 +3,94 @@
#include "transition_map.h"
Describe(Rules) {
Describe(construction) {
rules::rule_ptr symbol1 = rules::sym("1");
rules::rule_ptr symbol2 = rules::sym("2");
rules::rule_ptr symbol3 = rules::sym("3");
It(constructs_binary_trees) {
AssertThat(
rules::seq({ symbol1, symbol2, symbol3 })->to_string(),
Equals(std::string("(seq 1 (seq 2 3))")));
AssertThat(
rules::choice({ symbol1, symbol2, symbol3 })->to_string(),
Equals(std::string("(choice 1 (choice 2 3))")));
}
};
Describe(transitions) {
rules::Symbol symbol1 = rules::Symbol(1);
rules::Symbol symbol2 = rules::Symbol(2);
rules::Symbol symbol3 = rules::Symbol(3);
rules::Symbol symbol4 = rules::Symbol(3);
rules::rule_ptr symbol1 = rules::sym("1");
rules::rule_ptr symbol2 = rules::sym("2");
rules::rule_ptr symbol3 = rules::sym("3");
rules::rule_ptr symbol4 = rules::sym("3");
rules::rule_ptr char1 = rules::character('a');
It(handles_symbols) {
AssertThat(
symbol1.transitions(),
symbol1->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ symbol1.copy() },
{ new rules::Blank() }
{ symbol1 },
{ rules::blank() }
)));
}
It(handles_characters) {
rules::Char char1 = rules::Char('a');
AssertThat(
char1.transitions(),
char1->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ char1.copy() },
{ new rules::Blank() }
{ char1 },
{ rules::blank() }
)));
}
It(handles_choices) {
AssertThat(
rules::Choice(symbol1, symbol2).transitions(),
rules::choice({ symbol1, symbol2 })->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ symbol1.copy(), symbol2.copy() },
{ new rules::Blank(), new rules::Blank() }
{ symbol1, symbol2 },
{ rules::blank(), rules::blank() }
)));
}
It(handles_sequences) {
AssertThat(
rules::Seq(symbol1, symbol2).transitions(),
rules::seq({ symbol1, symbol2 })->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ symbol1.copy() },
{ symbol2.copy() }
{ symbol1 },
{ symbol2 }
)));
}
It(handles_long_sequences) {
AssertThat(
rules::Seq(
rules::Seq(symbol1, symbol2),
rules::Seq(symbol3, symbol4)).transitions(),
rules::seq({
rules::seq({ symbol1, symbol2 }),
rules::seq({ symbol3, symbol4 }) })->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ symbol1.copy() },
{ new rules::Seq(symbol2, rules::Seq(symbol3, symbol4)) }
{ symbol1 },
{ rules::seq({ symbol2, symbol3, symbol4 }) }
)));
}
It(handles_choices_with_common_starting_symbols) {
AssertThat(
rules::Choice(
rules::Seq(symbol1, symbol2),
rules::Seq(symbol1, symbol3)).transitions(),
rules::choice({
rules::seq({ symbol1, symbol2 }),
rules::seq({ symbol1, symbol3 }) })->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ symbol1.copy() },
{ new rules::Choice(symbol2, symbol3) }
{ symbol1 },
{ rules::choice({ symbol2, symbol3 }) }
)));
}
It(handles_strings) {
AssertThat(
rules::String("bad").transitions(),
rules::str("bad")->transitions(),
EqualsTransitionMap(TransitionMap<rules::Rule>(
{ new rules::Char('b') },
{ new rules::Seq(rules::Char('a'), rules::Char('d')) }
{ rules::character('b') },
{ rules::seq({ rules::character('a'), rules::character('d') }) }
)));
}
};
};
};

5
spec/spec_helper.cpp Normal file
View file

@ -0,0 +1,5 @@
#include "spec_helper.h"
EqualsContainerConstraint<rule_tmap, rule_tmap_comparator> EqualsTransitionMap(const rule_tmap &expected) {
return EqualsContainer(expected, rule_tmap::elements_equal);
}

20
spec/spec_helper.h Normal file
View file

@ -0,0 +1,20 @@
#ifndef TreeSitter_SpecHelper_h
#define TreeSitter_SpecHelper_h
#include "igloo/igloo_alt.h"
#include "transition_map.h"
#include "rule.h"
#include "item.h"
#include "item_set.h"
#include "grammar.h"
using namespace igloo;
using namespace tree_sitter;
using namespace std;
// Assertion helpers for transition maps
typedef TransitionMap<rules::Rule> rule_tmap;
typedef bool (* rule_tmap_comparator)(const rule_tmap::pair_type &, const rule_tmap::pair_type &);
EqualsContainerConstraint<rule_tmap, rule_tmap_comparator> EqualsTransitionMap(const rule_tmap &expected);
#endif

View file

@ -1,32 +0,0 @@
#ifndef TreeSitter_SpecHelper_h
#define TreeSitter_SpecHelper_h
#include "igloo/igloo_alt.h"
#include "transition_map.h"
#include "rules.h"
using namespace igloo;
using namespace tree_sitter;
// Assertion helpers for transition maps
namespace snowhouse {
template<>
std::string Stringize(const tree_sitter::TransitionMap<tree_sitter::rules::Rule> &map) {
std::string result("[");
bool started = false;
for (auto pair : map) {
if (started) result += ", ";
result += (pair.first->to_string() + " => " + pair.second->to_string());
started = true;
}
return result + "]";
}
}
typedef TransitionMap<rules::Rule> tmap;
typedef bool (* tmap_comparator)(const tmap::pair_type &, const tmap::pair_type &);
EqualsContainerConstraint<tmap, tmap_comparator> EqualsTransitionMap(const tmap &expected) {
return EqualsContainer(expected, tmap::elements_equal);
}
#endif

20
src/grammar.cpp Normal file
View file

@ -0,0 +1,20 @@
#include "grammar.h"
using namespace std;
namespace tree_sitter {
Grammar::Grammar(const rule_map &rules, const std::string &start_rule_name) :
rules(rules),
start_rule_name(start_rule_name) {};
Grammar::Grammar(const initializer_list<string> &rule_names,
const initializer_list<rules::rule_ptr> &rule_vals) {
rules = rule_map();
auto rule_name_i = rule_names.begin();
auto rule_i = rule_vals.begin();
start_rule_name = *rule_name_i;
for (; rule_i != rule_vals.end(); rule_i++ && rule_name_i++) {
rules[*rule_name_i] = *rule_i;
}
}
}

19
src/grammar.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef __TreeSitter__grammar__
#define __TreeSitter__grammar__
#include <unordered_map>
#include "rules.h"
namespace tree_sitter {
class Grammar {
typedef std::unordered_map<std::string, rules::rule_ptr> rule_map;
public:
Grammar(const rule_map &rules, const std::string &start_rule_name);
Grammar(const std::initializer_list<std::string> &rule_names,
const std::initializer_list<rules::rule_ptr> &rules);
rule_map rules;
std::string start_rule_name;
};
}
#endif

16
src/lr/item.cpp Normal file
View file

@ -0,0 +1,16 @@
#include "item.h"
namespace tree_sitter {
namespace lr {
Item::Item(const std::string &rule_name, rules::rule_ptr rule, int consumed_sym_count) :
rule_name(rule_name),
rule(rule),
consumed_sym_count(consumed_sym_count) {};
TransitionMap<Item> Item::transitions() const {
return rule->transitions().map<Item>([&](rules::rule_ptr to_rule) {
return item_ptr(new Item(rule_name, to_rule, consumed_sym_count + 1));
});
};
}
}

24
src/lr/item.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef __TreeSitter__item__
#define __TreeSitter__item__
#include <string>
#include "rule.h"
#include "transition_map.h"
namespace tree_sitter {
namespace lr {
class Item {
public:
Item(const std::string &rule_name, rules::rule_ptr rule, int consumed_sym_count);
TransitionMap<Item> transitions() const;
private:
std::string rule_name;
rules::rule_ptr rule;
int consumed_sym_count;
};
typedef std::shared_ptr<Item> item_ptr;
}
}
#endif

13
src/lr/item_set.cpp Normal file
View file

@ -0,0 +1,13 @@
#include "item_set.h"
namespace tree_sitter {
namespace lr {
ItemSet::ItemSet(const Item &item, const Grammar &grammar) {
}
TransitionMap<ItemSet> ItemSet::transitions() const {
return TransitionMap<ItemSet>();
}
}
}

17
src/lr/item_set.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef __TreeSitter__item_set__
#define __TreeSitter__item_set__
#include "item.h"
#include "grammar.h"
namespace tree_sitter {
namespace lr {
class ItemSet {
public:
ItemSet(const Item &item, const Grammar &grammar);
TransitionMap<ItemSet> transitions() const;
};
}
}
#endif

48
src/rules.cpp Normal file
View file

@ -0,0 +1,48 @@
#include "rules.h"
#include "blank.h"
#include "symbol.h"
#include "choice.h"
#include "seq.h"
#include "string.h"
#include "pattern.h"
#include "char.h"
namespace tree_sitter {
namespace rules {
rule_ptr blank() {
return rule_ptr(new Blank());
}
rule_ptr sym(const std::string &name) {
return rule_ptr(new Symbol(name));
}
rule_ptr character(char value) {
return rule_ptr(new Char(value));
}
rule_ptr str(const std::string &value) {
return rule_ptr(new String(value));
}
rule_ptr pattern(const std::string &value) {
return rule_ptr(new Pattern(value));
}
template <typename RuleClass>
rule_ptr build_binary_tree(const std::initializer_list<rule_ptr> &rules) {
rule_ptr result(nullptr);
for (auto it = rules.end() - 1; it >= rules.begin(); --it)
result = result.get() ? rule_ptr(new RuleClass(*it, result)) : *it;
return result;
}
rule_ptr seq(const std::initializer_list<rule_ptr> &rules) {
return build_binary_tree<Seq>(rules);
}
rule_ptr choice(const std::initializer_list<rule_ptr> &rules) {
return build_binary_tree<Choice>(rules);
}
}
}

View file

@ -2,11 +2,17 @@
#define __TreeSitter__rules__
#include "rules/rule.h"
#include "rules/blank.h"
#include "rules/char.h"
#include "rules/symbol.h"
#include "rules/choice.h"
#include "rules/seq.h"
#include "rules/string.h"
namespace tree_sitter {
namespace rules {
rule_ptr blank();
rule_ptr sym(const std::string &name);
rule_ptr character(char value);
rule_ptr str(const std::string &value);
rule_ptr pattern(const std::string &value);
rule_ptr seq(const std::initializer_list<rule_ptr> &rules);
rule_ptr choice(const std::initializer_list<rule_ptr> &rules);
}
}
#endif

21
src/rules/Pattern.cpp Normal file
View file

@ -0,0 +1,21 @@
#include "Pattern.h"
#include "transition_map.h"
namespace tree_sitter {
namespace rules {
Pattern::Pattern(const std::string &string) : value(string) {};
Pattern::Pattern(const char *string) : value(string) {};
TransitionMap<Rule> Pattern::transitions() const {
return tree_sitter::TransitionMap<Rule>();
}
bool Pattern::operator ==(tree_sitter::rules::Rule const &other) const {
return false;
}
std::string Pattern::to_string() const {
return value;
}
}
}

22
src/rules/Pattern.h Normal file
View file

@ -0,0 +1,22 @@
#ifndef __tree_sitter_pattern_h_
#define __tree_sitter_pattern_h_
#include "rule.h"
namespace tree_sitter {
namespace rules {
class Pattern : public Rule {
public:
Pattern(const char *string);
Pattern(const std::string &string);
TransitionMap<Rule> transitions() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
private:
std::string value;
};
}
}
#endif

View file

@ -13,10 +13,6 @@ namespace tree_sitter {
return dynamic_cast<const Blank *>(&rule) != NULL;
}
Blank * Blank::copy() const {
return new Blank();
}
std::string Blank::to_string() const {
return "blank";
}

View file

@ -9,7 +9,6 @@ namespace tree_sitter {
public:
Blank();
TransitionMap<Rule> transitions() const;
Blank * copy() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
};

View file

@ -1,4 +1,5 @@
#include "char.h"
#include "blank.h"
#include "transition_map.h"
using namespace std;
@ -6,22 +7,18 @@ using namespace std;
namespace tree_sitter {
namespace rules {
Char::Char(char value) : value(value) {};
TransitionMap<Rule> Char::transitions() const {
return TransitionMap<Rule>({ copy() }, { new Blank() });
return TransitionMap<Rule>({ rule_ptr(new Char(value)) }, { rule_ptr(new Blank()) });
}
bool Char::operator==(const Rule &rule) const {
const Char *other = dynamic_cast<const Char *>(&rule);
return (other != NULL) && (other->value == value);
return (other != nullptr) && (other->value == value);
}
Char * Char::copy() const {
return new Char(value);
}
string Char::to_string() const {
return std::string("'") + &value + "'";
}
}
}
}

View file

@ -9,13 +9,12 @@ namespace tree_sitter {
public:
Char(char value);
TransitionMap<Rule> transitions() const;
Char * copy() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
private:
char value;
};
};
}
}
#endif
#endif

View file

@ -3,7 +3,6 @@
namespace tree_sitter {
namespace rules {
Choice::Choice(const Rule &left, const Rule &right) : left(left.copy()), right(right.copy()) {};
Choice::Choice(rule_ptr left, rule_ptr right) : left(left), right(right) {};
TransitionMap<Rule> Choice::transitions() const {
@ -19,10 +18,6 @@ namespace tree_sitter {
return (other != NULL) && (*other->left == *left) && (*other->right == *right);
}
Choice * Choice::copy() const {
return new Choice(left, right);
}
std::string Choice::to_string() const {
return std::string("(choice ") + left->to_string() + " " + right->to_string() + ")";
}

View file

@ -3,14 +3,12 @@
#include "rule.h"
namespace tree_sitter {
namespace tree_sitter {
namespace rules {
class Choice : public Rule {
public:
Choice(const Rule &left, const Rule &right);
Choice(std::shared_ptr<const Rule> left, std::shared_ptr<const Rule> right);
Choice(rule_ptr left, rule_ptr right);
TransitionMap<Rule> transitions() const;
Choice * copy() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
private:

7
src/rules/rule.cpp Normal file
View file

@ -0,0 +1,7 @@
#include "rule.h"
std::ostream& operator<<(std::ostream& stream, const tree_sitter::rules::Rule &rule)
{
stream << rule.to_string();
return stream;
}

View file

@ -10,7 +10,6 @@ namespace tree_sitter {
class Rule {
public:
virtual TransitionMap<Rule> transitions() const = 0;
virtual Rule * copy() const = 0;
virtual bool operator==(const Rule& other) const = 0;
virtual std::string to_string() const = 0;
};
@ -19,4 +18,6 @@ namespace tree_sitter {
}
}
std::ostream& operator<<(std::ostream& stream, const tree_sitter::rules::Rule &rule);
#endif

View file

@ -2,13 +2,12 @@
#include "blank.h"
#include "transition_map.h"
namespace tree_sitter {
namespace tree_sitter {
namespace rules {
Seq::Seq(const Rule &left, const Rule &right) : left(left.copy()), right(right.copy()) {};
Seq::Seq(rule_ptr left, rule_ptr right) : left(left), right(right) {};
TransitionMap<Rule> Seq::transitions() const {
return left->transitions().map([&](rule_ptr left_rule) -> rule_ptr {
return left->transitions().map<Rule>([&](rule_ptr left_rule) -> rule_ptr {
if (typeid(*left_rule) == typeid(Blank))
return right;
else
@ -21,12 +20,8 @@ namespace tree_sitter {
return (other != NULL) && (*other->left == *left) && (*other->right == *right);
}
Seq * Seq::copy() const {
return new Seq(left, right);
}
std::string Seq::to_string() const {
return std::string("(seq ") + left->to_string() + " " + right->to_string() + ")";
}
}
}
}

View file

@ -7,10 +7,8 @@ namespace tree_sitter {
namespace rules {
class Seq : public Rule {
public:
Seq(const Rule &left, const Rule &right);
Seq(std::shared_ptr<const Rule> left, std::shared_ptr<const Rule> right);
Seq(rule_ptr left, rule_ptr right);
TransitionMap<Rule> transitions() const;
Seq * copy() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
private:
@ -20,4 +18,4 @@ namespace tree_sitter {
}
}
#endif
#endif

View file

@ -8,10 +8,9 @@ namespace tree_sitter {
String::String(std::string value) : value(value) {};
TransitionMap<Rule> String::transitions() const {
rule_ptr result = rule_ptr(new Char(value[0]));
for (int i = 1; i < value.length(); i++) {
auto result = rule_ptr(new Char(value[0]));
for (int i = 1; i < value.length(); i++)
result = rule_ptr(new Seq(result, rule_ptr(new Char(value[i]))));
}
return result->transitions();
}

View file

@ -18,4 +18,4 @@ namespace tree_sitter {
}
}
#endif
#endif

View file

@ -1,25 +1,23 @@
#include "symbol.h"
#include "blank.h"
#include "transition_map.h"
namespace tree_sitter {
namespace rules {
Symbol::Symbol(int id) : id(id) {};
Symbol::Symbol(const std::string &name) : name(name) {};
Symbol::Symbol(const char *name) : name(name) {};
TransitionMap<Rule> Symbol::transitions() const {
return TransitionMap<Rule>({ copy() }, { new Blank() });
return TransitionMap<Rule>({ rule_ptr(new Symbol(name)) }, { rule_ptr(new Blank()) });
}
bool Symbol::operator==(const Rule &rule) const {
const Symbol *other = dynamic_cast<const Symbol *>(&rule);
return (other != NULL) && (other->id == id);
}
Symbol * Symbol::copy() const {
return new Symbol(id);
return (other != NULL) && (other->name == name);
}
std::string Symbol::to_string() const {
return std::to_string(id);
}
return name;
}
}
}

View file

@ -7,13 +7,14 @@ namespace tree_sitter {
namespace rules {
class Symbol : public Rule {
public:
Symbol(int id);
Symbol(const std::string &name);
Symbol(const char *name);
TransitionMap<Rule> transitions() const;
Symbol * copy() const;
bool operator==(const Rule& other) const;
std::string to_string() const;
private:
int id;
std::string name;
};
}
}

View file

@ -3,6 +3,7 @@
#include <vector>
#include <functional>
#include <initializer_list>
#include "rules.h"
namespace tree_sitter {
@ -13,14 +14,14 @@ namespace tree_sitter {
typedef std::shared_ptr<const MappedType> mapped_ptr;
typedef std::pair<rule_ptr, mapped_ptr> pair_type;
typedef std::vector<pair_type> contents_type;
static bool elements_equal(const pair_type &left, const pair_type &right) {
return (*left.first == *right.first) && (*left.second == *right.second);
}
TransitionMap() : contents(contents_type()) {};
TransitionMap(std::initializer_list<rules::Rule *> keys, std::initializer_list<MappedType *> values) : TransitionMap() {
TransitionMap(std::initializer_list<rule_ptr> keys, std::initializer_list<mapped_ptr> values) : TransitionMap() {
auto value_iter(values.begin());
for (auto key_iter(keys.begin()); key_iter != keys.end(); ++key_iter) {
add(*key_iter, *value_iter);
@ -36,23 +37,15 @@ namespace tree_sitter {
const_iterator begin() const { return contents.begin(); }
const_iterator end() const { return contents.end(); }
void add(const rules::Rule *on_rule, const MappedType *to_value) {
rule_ptr key(on_rule);
mapped_ptr value(to_value);
contents.push_back(pair_type(key, value));
}
void add(rule_ptr on_rule, mapped_ptr to_value) {
rule_ptr key(on_rule);
mapped_ptr value(to_value);
contents.push_back(pair_type(key, value));
void add(const rule_ptr on_rule, const mapped_ptr to_value) {
contents.push_back(pair_type(on_rule, to_value));
}
size_t size() const {
return contents.size();
}
mapped_ptr operator[](rules::Rule const &on_rule) const {
mapped_ptr operator[](rules::Rule const &on_rule) {
pair_type *pair = pair_for_key(on_rule);
if (pair)
return pair->second;
@ -73,8 +66,9 @@ namespace tree_sitter {
}
}
TransitionMap<MappedType> map(std::function<mapped_ptr(mapped_ptr)> map_fn) {
TransitionMap<MappedType> result;
template<typename NewMappedType>
TransitionMap<NewMappedType> map(std::function<std::shared_ptr<const NewMappedType>(mapped_ptr)> map_fn) {
TransitionMap<NewMappedType> result;
for (pair_type pair : *this)
result.add(pair.first, map_fn(pair.second));
return result;
@ -91,6 +85,20 @@ namespace tree_sitter {
contents_type contents;
};
template<typename MappedType>
std::ostream& operator<<(std::ostream &stream, const TransitionMap<MappedType> &map) {
stream << std::string("[");
bool started = false;
for (auto pair : map) {
if (started) stream << std::string(", ");
stream << (pair.first->to_string() + " => " + pair.second->to_string());
started = true;
}
stream << std::string("]");
return stream;
}
}
#endif
#endif