// file : build2/token -*- C++ -*- // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef BUILD2_TOKEN #define BUILD2_TOKEN #include #include #include namespace build2 { // Extendable/inheritable enum-like class. // // A line consists of a sequence of words separated by separators and // terminated with the newline. If whitespace is a separator, then it is // ignored. // struct token_type { enum { // NOTE: remember to update token_printer()! eos, newline, word, pair_separator, colon, lcbrace, // { rcbrace, // } lsbrace, // [ rsbrace, // ] assign, // = prepend, // =+ append, // += equal, // == not_equal, // != less, // < greater, // > less_equal, // <= greater_equal, // >= dollar, // $ lparen, // ( rparen, // ) value_next }; using value_type = uint16_t; token_type (value_type v = eos): v_ (v) {} operator value_type () const {return v_;} value_type v_; }; class token; void token_printer (ostream&, const token&, bool); class token { public: using printer_type = void (ostream&, const token&, bool diag); token_type type; bool separated; // Whitespace-separated from the previous token. bool quoted; // Word (or some part of it) was quoted. string value; // Only valid for word. uint64_t line; uint64_t column; printer_type* printer; public: token () : token (token_type::eos, false, 0, 0, token_printer) {} token (token_type t, bool s, uint64_t l, uint64_t c, printer_type* p) : type (t), separated (s), quoted (false), line (l), column (c), printer (p) {} token (string v, bool s, bool q, uint64_t l, uint64_t c) : type (token_type::word), separated (s), quoted (q), value (move (v)), line (l), column (c), printer (&token_printer) {} }; // Output the token value in a format suitable for diagnostics. // inline ostream& operator<< (ostream& o, const token& t) {t.printer (o, t, true); return o;} // Extendable/inheritable enum-like class. // struct lexer_mode_base { enum { value_next }; using value_type = uint16_t; lexer_mode_base (value_type v = value_next): v_ (v) {} operator value_type () const {return v_;} value_type v_; }; struct replay_token { build2::token token; const path* file; lexer_mode_base mode; char pair_separator; using location_type = build2::location; location_type location () const {return location_type (file, token.line, token.column);} }; using replay_tokens = vector; // Diagnostics plumbing. We assume that any diag stream for which we can use // token as location has its aux data pointing to pointer to path. // inline location get_location (const token& t, const path& p) { return location (&p, t.line, t.column); } inline location get_location (const token& t, const void* data) { assert (data != nullptr); // E.g., must be &parser::path_. const path* p (*static_cast (data)); return get_location (t, *p); } } #endif // BUILD2_TOKEN