32 using Ts::operator()...;
50 typename T::ValueType;
51 typename T::UserDataType;
66 template<IGrammar G, ctll::fixed_
string regex,
typename SemanticType>
72 template<IGrammar G,
typename SemanticType>
135 std::vector<ProductionRule<G>>
rules;
139 this->rules.push_back(rule);
157 return this->location.
end - this->location.
begin;
170 template<
typename GValueType,
typename GUserDataType = Dummy>
171 requires std::constructible_from<GValueType>
233 virtual std::optional<Token<G>>
Lex(std::string_view input)
const
246 template<IGrammar G, ctll::fixed_
string regex,
typename SemanticType =
void>
252 if constexpr(std::variant_size<typename G::ValueType>::value != 0)
254 if(!std::holds_alternative<SemanticType>(value))
256 throw std::runtime_error(
"failed to convert type");
259 return std::move(std::get<SemanticType>(value));
263 return std::move(
reinterpret_cast<SemanticType>(value));
267 std::optional<Token<G>>
Lex(std::string_view input)
const override
269 auto match = ctre::starts_with<regex>(input);
329 template<IGrammar G,
typename SemanticValue =
void>
335 if constexpr(std::variant_size<typename G::ValueType>::value != 0)
337 if(!std::holds_alternative<SemanticValue>(value))
339 throw std::runtime_error(
"failed to convert type");
342 return std::move(std::get<SemanticValue>(value));
383 this->sequence_.push_back(&
rhs);
390 this->sequence_.push_back(&
rhs);
413 if(this->sequence_.size() !=
other.
sequence_.size())
return false;
423 std::optional<typename G::ValueType>
Transduce(std::vector<typename G::ValueType> &
args)
const
425 if(this->transductor_)
454 std::unique_ptr<Terminal<G>>
EOS;
459 std::map<NonTerminal<G>*, std::set<Terminal<G>*>>
first_;
460 std::map<NonTerminal<G>*, std::set<Terminal<G>*>>
follow_;
475 return this->follow_.at(&
non_terminal).contains(&terminal);
480 return this->first_.at(&
non_terminal).contains(&terminal);
496 if(rule.sequence_.empty())
continue;
530 this->follow_[&
root] = { this->EOS.get() };
542 if(std::holds_alternative<
Terminal<G>*>(rule.sequence_[
i]))
continue;
545 auto symbol = std::get<NonTerminal<G>*>(rule.sequence_[
i]);
594 this->production_rules_.push_back({
nonterminal, rule});
596 for(
auto &
symbol : rule.sequence_)
602 this->terminals_.insert(terminal);
624 this->terminals_.insert(this->EOS.get());
680 return this->position >= this->rule->
sequence_.size();
685 return LRItem(this->rule, this->position + 1);
695 return *this->rule == *
other.rule && this->position ==
other.position;
749 if(
item.Complete())
continue;
764 if(this->kernel_items.size() !=
other.kernel_items.size())
return false;
766 for(
int i = 0;
i < this->kernel_items.size();
i++)
768 if(this->kernel_items[
i] !=
other.kernel_items[
i])
return false;
776 for(
auto const &rule :
start->rules_)
778 this->kernel_items.emplace_back(&rule);
820 virtual std::expected<typename G::ValueType, Error>
Parse(std::string_view input, std::vector<
Token<G>> *tokens) = 0;
834 std::map<lrstate_id_t, std::map<Terminal<G>*,
LRAction<G>>> action_;
835 std::map<lrstate_id_t, std::map<NonTerminal<G>*,
lrstate_id_t>> goto_;
837 struct ParseStackItem
849 std::string_view input;
850 std::size_t index = 0;
852 std::vector<Token<G>> *tokens;
862 for(
auto terminal : this->parser.grammar_.terminals_)
864 auto token = terminal->Lex(this->input.substr(
this->index));
867 token->location.begin += this->index;
868 token->location.end += this->index;
879 for(
auto terminal : this->parser.action_.at(state) | std::views::keys)
881 auto token = terminal->Lex(this->input.substr(
this->index));
884 token->location.begin += this->index;
885 token->location.end += this->index;
897 this->index +=
token.Size();
900 tokens->push_back(
token);
904 Tokenizer(
SLRParser<G> const &parser, std::string_view input, std::vector<
Token<G>> *tokens =
nullptr) : parser(parser), input(input), tokens(tokens) {}
931 std::optional<Error> BuildParsingTables()
933 std::vector<LRState<G>>
states;
937 states.emplace_back(&this->grammar_.root);
955 this->action_[
i][terminal] = {
1035 this->action_[0][this->grammar_.EOS.get()] = {
1039 return std::nullopt;
1054 return this->grammar_;
1057 std::expected<typename G::ValueType, Error>
Parse(std::string_view input, std::vector<
Token<G>> *tokens =
nullptr)
override
1059 Tokenizer
tokenizer(*
this, input, tokens);
1086 return std::unexpected(
Error{
"Unexpected Token!"});
1099 std::optional<typename G::ValueType> value = std::move(
lookahead->terminal->Reason(*
lookahead));
1151 auto error = parser.BuildParsingTables();
1154 return std::unexpected(*
error);
1157 return std::move(parser);
bf::GrammarDefinition< double > G
DefineNonTerminal(ProductionRuleList< G > const &rule_list)
SemanticValue operator()(typename G::ValueType &value)
DefineNonTerminal(ProductionRule< G > const &rule)
DefineNonTerminal()=delete
constexpr DefineTerminal(typename G::UserDataType user_data)
constexpr DefineTerminal(Associativity assoc=bf::None, typename G::UserDataType user_data={}, typename Terminal< G >::ReasonerType reasoner=nullptr)
SemanticType operator()(typename G::ValueType &value)
constexpr DefineTerminal(Associativity assoc, typename Terminal< G >::ReasonerType reasoner)
constexpr DefineTerminal(typename G::UserDataType user_data, typename Terminal< G >::ReasonerType reasoner)
std::optional< Token< G > > Lex(std::string_view input) const override
constexpr DefineTerminal(typename Terminal< G >::ReasonerType reasoner)
GUserDataType UserDataType
std::map< NonTerminal< G > *, std::set< Terminal< G > * > > follow_
std::unique_ptr< Terminal< G > > EOS
bool NonTerminalHasFollow(NonTerminal< G > &non_terminal, Terminal< G > &terminal) const
bool HasNonTerminal(NonTerminal< G > &non_terminal) const
std::set< NonTerminal< G > * > nonterminals_
Grammar(NonTerminal< G > &start)
std::vector< std::pair< NonTerminal< G > *, ProductionRule< G > > > production_rules_
List of all production rules along with their respective NonTerminal.
bool NonTerminalHasFirst(NonTerminal< G > &non_terminal, Terminal< G > &terminal) const
std::set< Terminal< G > * > terminals_
std::map< NonTerminal< G > *, std::set< Terminal< G > * > > first_
void RegisterSymbols(NonTerminal< G > *nonterminal)
std::vector< ProductionRule< G > > rules_
NonTerminal(NonTerminal &)=delete
NonTerminal(ProductionRule< G > const &rule)
NonTerminal(ProductionRuleList< G > const &rule_list)
typename G::ValueType(*)(std::vector< typename G::ValueType > &) TransductorType
NonTerminal(NonTerminal &&)=delete
virtual ~Parser()=default
virtual std::expected< typename G::ValueType, Error > Parse(std::string_view input, std::vector< Token< G > > *tokens)=0
ProductionRule & operator<=>(typename NonTerminal< G >::TransductorType tranductor)
std::optional< typename G::ValueType > Transduce(std::vector< typename G::ValueType > &args) const
ProductionRule & operator+(NonTerminal< G > &rhs)
NonTerminal< G >::TransductorType transductor_
ProductionRule & operator+(Terminal< G > &rhs)
bool operator==(ProductionRule< G > const &other) const
ProductionRule(Terminal< G > &terminal)
std::vector< Symbol< G > > sequence_
NonTerminal< G > * non_terminal_
Grammar< G > const & GetGrammar() const
static std::expected< SLRParser, Error > Build(NonTerminal< G > &start)
SLRParser(NonTerminal< G > &start)
std::expected< typename G::ValueType, Error > Parse(std::string_view input, std::vector< Token< G > > *tokens=nullptr) override
Associativity associativity
virtual std::optional< Token< G > > Lex(std::string_view input) const
Terminal(Terminal< G > const &)=delete
Terminal(Terminal< G > &&)=delete
G::UserDataType user_data
static std::size_t counter
std::optional< typename G::ValueType > Reason(Token< G > const &token) const
typename G::ValueType(*)(Token< G > const &) ReasonerType
constexpr bool always_false_v
ProductionRuleList< G > operator|(ProductionRule< G > const &lhs, ProductionRule< G > const &rhs)
std::variant< Terminal< G > *, NonTerminal< G > * > Symbol
ProductionRule< G > operator+(Terminal< G > &lhs, Terminal< G > &rhs)
Error(std::string message)
GrammarDefinitionError(std::string message)
ProductionRule< G > const * rule
Symbol< G > NextSymbol() const
LRItem(ProductionRule< G > const *rule, int position=0)
ProductionRule< G > const * rule
bool operator==(LRItem const &other) const
LRState(NonTerminal< G > const *start)
bool operator==(LRState const &other) const
std::vector< LRItem< G > > GenerateClosure() const
std::vector< LRItem< G > > kernel_items
std::map< Symbol< G >, LRState< G > > GenerateTransitions() const
std::string SnippetString(std::size_t padding=10)
ParsingError(Location location, std::string message)
ProductionRuleList & operator|(ProductionRule< G > const &rule)
std::vector< ProductionRule< G > > rules
constexpr void operator()(T) const