Ich schreibe momentan einen Übersetzer. Quellsprache soll eine Art Programmiersprache sein, die Zielsprache maschinenunabhängig.
Der Lexer soll verschiedene Zeichensätze und Iteratorrepräsentationen (s. STL) unterstützen. Daher sieht meine bisherige Umsetzung etwa so aus:
Man denke sich die Vorwärtsdeklaration von
lexer und die daraus resultierenden Änderungen.
Code:
template <typename char_type, typename char_traits = std::char_traits <char_type>>
struct token {
enum class token_type;
typedef std::basic_string <char_type, char_traits> string_type;
token (token_type type, const string_type & lexeme);
};
template <
typename iterator_type,
typename char_type = typename std::iterator_traits <iterator_type>::value_type,
typename char_traits = typename std::char_traits <char_type>
>
struct token_iterator {
typedef lexer <iterator_type, char_type, char_traits> lexer_type;
typedef typename lexer_type::token_type token_type;
};
template <
typename iterator_type,
typename char_type = typename std::iterator_traits <iterator_type>::value_type,
typename char_traits = typename std::char_traits <char_type>
>
class lexer {
public:
typedef token <char_type, char_traits> token_type;
typedef token_iterator <iterator_type, char_type, char_traits> token_iterator;
lexer (iterator_type begin, iterator_type end, const std::locale & used_locale = std::locale::classic ());
token_type get ();
token_iterator begin ();
token_iterator end ();
struct token_error;
};
Sollte
token bereits den tatsächlichen Wert speichern, oder nur Lexem und Tokentyp und Funktionen zum Umwandeln in eine Zahl?
Geht das alles vielleicht auch besser?
Von obigem Aussehen ausgehend würde eine Parserklasse etwa so aussehen:
Code:
template <typename iterator_type>
class parser {
// ...
};
Damit wäre der Parser von
token_iterator<iterator,char_t,char_traits> abhängig und wäre für jeden Lexer ein anderer, also für jeden Zeichensatz und jede Iteratordarstellung. Da stellt sich natürlich die Frage, was denn der Parser mit dem Lexer zu tun hat. Den Parser geht ja nur der Typ der Token (
enum class token::token_type) etwas an. Das Problem ist dann aber die Symboltabelle. Dafür könnte der Parser mit einer Basisklasse von
token_iterator und einer von
token arbeiten, welche dann Methoden zum Vergleichen anbieten.
Was mache ich aber, wenn verschiedene Zeichensätze gleichzeitig unterstützt werden sollen, z. B. eine Quelldatei eine andere mit einem anderen Zeichensatz einbindet, und dann erwartet, Symbole aus dieser anderen Quelldatei verwenden zu können? Alles in UCS-2 (oder UTF-8 oder UTF-16) konvertieren?