effect_lexer.hpp (3248B)
1 /* 2 * Copyright (C) 2014 Patrick Mours 3 * SPDX-License-Identifier: BSD-3-Clause 4 */ 5 6 #pragma once 7 8 #include "effect_token.hpp" 9 10 namespace reshadefx 11 { 12 /// <summary> 13 /// A lexical analyzer for C-like languages. 14 /// </summary> 15 class lexer 16 { 17 public: 18 explicit lexer( 19 std::string input, 20 bool ignore_comments = true, 21 bool ignore_whitespace = true, 22 bool ignore_pp_directives = true, 23 bool ignore_line_directives = false, 24 bool ignore_keywords = false, 25 bool escape_string_literals = true, 26 const location &start_location = location()) : 27 _input(std::move(input)), 28 _cur_location(start_location), 29 _ignore_comments(ignore_comments), 30 _ignore_whitespace(ignore_whitespace), 31 _ignore_pp_directives(ignore_pp_directives), 32 _ignore_line_directives(ignore_line_directives), 33 _ignore_keywords(ignore_keywords), 34 _escape_string_literals(escape_string_literals) 35 { 36 _cur = _input.data(); 37 _end = _cur + _input.size(); 38 } 39 40 lexer(const lexer &lexer) { operator=(lexer); } 41 lexer &operator=(const lexer &lexer) 42 { 43 _input = lexer._input; 44 _cur_location = lexer._cur_location; 45 reset_to_offset(lexer._cur - lexer._input.data()); 46 _end = _input.data() + _input.size(); 47 _ignore_comments = lexer._ignore_comments; 48 _ignore_whitespace = lexer._ignore_whitespace; 49 _ignore_pp_directives = lexer._ignore_pp_directives; 50 _ignore_keywords = lexer._ignore_keywords; 51 _escape_string_literals = lexer._escape_string_literals; 52 _ignore_line_directives = lexer._ignore_line_directives; 53 54 return *this; 55 } 56 57 /// <summary> 58 /// Gets the current position in the input string. 59 /// </summary> 60 size_t input_offset() const { return _cur - _input.data(); } 61 62 /// <summary> 63 /// Gets the input string this lexical analyzer works on. 64 /// </summary> 65 /// <returns>Constant reference to the input string.</returns> 66 const std::string &input_string() const { return _input; } 67 68 /// <summary> 69 /// Performs lexical analysis on the input string and return the next token in sequence. 70 /// </summary> 71 /// <returns>Next token from the input string.</returns> 72 token lex(); 73 74 /// <summary> 75 /// Advances to the next token that is not whitespace. 76 /// </summary> 77 void skip_space(); 78 /// <summary> 79 /// Advances to the next new line, ignoring all tokens. 80 /// </summary> 81 void skip_to_next_line(); 82 83 /// <summary> 84 /// Resets position to the specified <paramref name="offset"/>. 85 /// </summary> 86 /// <param name="offset">Offset in characters from the start of the input string.</param> 87 void reset_to_offset(size_t offset); 88 89 private: 90 /// <summary> 91 /// Skips an arbitrary amount of characters in the input string. 92 /// </summary> 93 /// <param name="length">Number of input characters to skip.</param> 94 void skip(size_t length); 95 96 void parse_identifier(token &tok) const; 97 bool parse_pp_directive(token &tok); 98 void parse_string_literal(token &tok, bool escape); 99 void parse_numeric_literal(token &tok) const; 100 101 std::string _input; 102 location _cur_location; 103 const std::string::value_type *_cur, *_end; 104 105 bool _ignore_comments; 106 bool _ignore_whitespace; 107 bool _ignore_pp_directives; 108 bool _ignore_line_directives; 109 bool _ignore_keywords; 110 bool _escape_string_literals; 111 }; 112 }