#pragma once #include "minicc.h" #include "bnf.h" #include #include #include namespace Lex { class Lexer { // constructor input const BNF& m_bnf; const std::string& m_top; // Graph size_t states{}; // start, ... std::unordered_map>> transitions; // transitions: state -> {state,character}, ...; empty transition is marked by \0 std::unordered_map m_state_types; // only necessary for 2nd level symbol names size_t m_startState; // Graph manipulation size_t newState(); bool isEndState(size_t state); void addTransition(size_t state0, size_t state1, char c); void removeTransition(size_t state0, size_t state1, char c); std::vector> getSuccessorsViaEmpty(size_t state); std::vector> getSuccessors(size_t state); // Build up automaton, recursively void addPath(size_t state0, size_t state1, std::string s); void addPathOrTransition(size_t state0, size_t state1, std::string symbol); void addRule(const std::vector& list, size_t list_index_from, size_t list_index_to, size_t state0, size_t state1, const std::string& rule_symbol); Token getToken(const std::string& s, Location& location); void skipWhitespace(const std::string& s, Location& location); void replaceEmptyTransitions(); void removeEmptyTransitions(); public: Lexer(const BNF& bnf, const std::string& top); std::vector Lex(const std::string& s); }; } // namespace Lex