J'ai commencé mon parser en C++, et je commence par le lexer : j'ai créé un lexer générique qui peut s'utiliser avec un autre langage qu'Acid, mais je n'ai pas encore commencé à rédiger le code propre à Acid. Pour l'instant, je n'ai pas créé de dépôt sur Github, je le ferai dès que j'ai le temps.
En attendant, je poste le code ici si quelqu'un veut l'utiliser. A moi d'utiliser ma magie noire (non, je rigole rien de compliqué là dedans) ! Bref, trève de parlote :
Lexer.hpp :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include <map> #include <regex> #include <functional> // TODO : WRITE DOC !!! template<typename TokenTraits> class Lexer { public: explicit Lexer(std::istream& is) : m_is(is) , associations{} { } Lexer(Lexer const&) = delete; Lexer& operator=(Lexer const&) = delete; Lexer(Lexer&&) = delete; Lexer& operator=(Lexer&&) = delete; virtual ~Lexer() { } public: using Tokens = TokenTraits::Tokens; using Token = Tokens; public: Token popToken(); Token getCurrentToken() const { return m_currentToken; } public: // Todo : find a better name for this. std::map<std::regex, Token> associations; private: virtual Token handleSpecialLexem() { } private: std::istream& m_is; Token m_currentToken; }; |
Lexer.inl :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | // TODO : WRITE DOC !!! #include "Lexer.hpp" #include <string> Lexer::Token Lexer::popToken() { auto popped = getCurrentToken(); std::string word{}; if(!(m_is >> word)) { if(is.eof()) { m_currentToken = Tokens::EndOfFile; } return popped; } for(auto const& element : associations) { if(std::regex_match(word, element.first) { m_currentToken = element.second; return popped; } } m_currentToken = handleSpecialLexem(); return popped; } |
un exemple de TokenTraits :
1 2 3 4 5 6 7 8 9 10 11 | struct TokenTraits { enum class Tokens { Lambda, ..., EndOfFile, Other, Unknown } } |
Si vous voulez des explications, n'hésitez pas à demander !
P.S : Avec un peu de chance, peut-être que ce message attirera des amateurs de C++ sur le sujet D'ailleurs, peux-tu ajouter le tag C++ dans le sujet ?
EDIT : nohar a montré de trucs cool en python, il fallait bien que je défende de mon mieux C++
EDIT 2 : J'ai renommé le paramètre template en TokenTraits, car c'est plus une classe de traits qu'une classe de politiques