/* * Copyright (C) 2014 Patrick Mours * SPDX-License-Identifier: BSD-3-Clause */ #pragma once #include "effect_token.hpp" namespace reshadefx { /// /// A lexical analyzer for C-like languages. /// class lexer { public: explicit lexer( std::string input, bool ignore_comments = true, bool ignore_whitespace = true, bool ignore_pp_directives = true, bool ignore_line_directives = false, bool ignore_keywords = false, bool escape_string_literals = true, const location &start_location = location()) : _input(std::move(input)), _cur_location(start_location), _ignore_comments(ignore_comments), _ignore_whitespace(ignore_whitespace), _ignore_pp_directives(ignore_pp_directives), _ignore_line_directives(ignore_line_directives), _ignore_keywords(ignore_keywords), _escape_string_literals(escape_string_literals) { _cur = _input.data(); _end = _cur + _input.size(); } lexer(const lexer &lexer) { operator=(lexer); } lexer &operator=(const lexer &lexer) { _input = lexer._input; _cur_location = lexer._cur_location; reset_to_offset(lexer._cur - lexer._input.data()); _end = _input.data() + _input.size(); _ignore_comments = lexer._ignore_comments; _ignore_whitespace = lexer._ignore_whitespace; _ignore_pp_directives = lexer._ignore_pp_directives; _ignore_keywords = lexer._ignore_keywords; _escape_string_literals = lexer._escape_string_literals; _ignore_line_directives = lexer._ignore_line_directives; return *this; } /// /// Gets the current position in the input string. /// size_t input_offset() const { return _cur - _input.data(); } /// /// Gets the input string this lexical analyzer works on. /// /// Constant reference to the input string. const std::string &input_string() const { return _input; } /// /// Performs lexical analysis on the input string and return the next token in sequence. /// /// Next token from the input string. token lex(); /// /// Advances to the next token that is not whitespace. /// void skip_space(); /// /// Advances to the next new line, ignoring all tokens. /// void skip_to_next_line(); /// /// Resets position to the specified . /// /// Offset in characters from the start of the input string. void reset_to_offset(size_t offset); private: /// /// Skips an arbitrary amount of characters in the input string. /// /// Number of input characters to skip. void skip(size_t length); void parse_identifier(token &tok) const; bool parse_pp_directive(token &tok); void parse_string_literal(token &tok, bool escape); void parse_numeric_literal(token &tok) const; std::string _input; location _cur_location; const std::string::value_type *_cur, *_end; bool _ignore_comments; bool _ignore_whitespace; bool _ignore_pp_directives; bool _ignore_line_directives; bool _ignore_keywords; bool _escape_string_literals; }; }