blob: 6e97551f5b02d8105eebf665f26b6d1eee61a3ac [file] [log] [blame]
// Copyright 2020 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
#define SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_
#include <optional>
#include <vector>
#include "src/tint/lang/wgsl/reader/parser/token.h"
namespace tint::wgsl::reader {
/// Converts the input stream into a series of Tokens
class Lexer {
public:
/// Creates a new Lexer
/// @param file the source file
explicit Lexer(const Source::File* file);
~Lexer();
/// @return the token list.
std::vector<Token> Lex();
private:
/// Returns the next token in the input stream.
/// @return Token
Token next();
/// Advances past blankspace and comments, if present at the current position.
/// @returns error token, EOF, or uninitialized
std::optional<Token> skip_blankspace_and_comments();
/// Advances past a comment at the current position, if one exists.
/// Returns an error if there was an unterminated block comment,
/// or a null character was present.
/// @returns uninitialized token on success, or error
std::optional<Token> skip_comment();
Token build_token_from_int_if_possible(Source source,
size_t start,
size_t prefix_count,
int32_t base);
std::optional<Token::Type> parse_keyword(std::string_view);
/// The try_* methods have the following in common:
/// - They assume there is at least one character to be consumed,
/// i.e. the input has not yet reached end of file.
/// - They return an initialized token when they match and consume
/// a token of the specified kind.
/// - Some can return an error token.
/// - Otherwise they return an uninitialized token when they did not
/// match a token of the specfied kind.
std::optional<Token> try_float();
std::optional<Token> try_hex_float();
std::optional<Token> try_hex_integer();
std::optional<Token> try_ident();
std::optional<Token> try_integer();
std::optional<Token> try_punctuation();
Source begin_source() const;
void end_source(Source&) const;
/// @returns view of current line
std::string_view line() const;
/// @returns position in current line
size_t pos() const;
/// @returns length of current line
size_t length() const;
/// @returns reference to character at `pos` within current line
const char& at(size_t pos) const;
/// @returns substring view at `offset` within current line of length `count`
std::string_view substr(size_t offset, size_t count);
/// advances current position by `offset` within current line
void advance(size_t offset = 1);
/// sets current position to `pos` within current line
void set_pos(size_t pos);
/// advances current position to next line
void advance_line();
/// @returns true if the end of the input has been reached.
bool is_eof() const;
/// @returns true if the end of the current line has been reached.
bool is_eol() const;
/// @returns true if there is another character on the input and
/// it is not null.
bool is_null() const;
/// @param ch a character
/// @returns true if 'ch' is a decimal digit
bool is_digit(char ch) const;
/// @param ch a character
/// @returns true if 'ch' is a hexadecimal digit
bool is_hex(char ch) const;
/// @returns true if string at `pos` matches `substr`
bool matches(size_t pos, std::string_view substr);
/// @returns true if char at `pos` matches `ch`
bool matches(size_t pos, char ch);
/// The source file content
Source::File const* const file_;
/// The current location within the input
Source::Location location_;
};
} // namespace tint::wgsl::reader
#endif // SRC_TINT_LANG_WGSL_READER_PARSER_LEXER_H_