mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-05-13 10:51:35 +00:00
Make use of std::string_view when parsing
There may very well be more places it can be used, but this updates the easiest to identify cases that could be switched over with minimal restructuring. Change-Id: I5100f398731cc4e031c82548ac826d713d0a4cda Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/76640 Reviewed-by: Ben Clayton <bclayton@google.com> Commit-Queue: Brandon Jones <bajones@chromium.org> Kokoro: Kokoro <noreply+kokoro@google.com>
This commit is contained in:
parent
1c02eb8cb0
commit
b9d1540b31
@ -750,6 +750,7 @@ if(TINT_BUILD_TESTS)
|
|||||||
sem/type_manager_test.cc
|
sem/type_manager_test.cc
|
||||||
sem/u32_type_test.cc
|
sem/u32_type_test.cc
|
||||||
sem/vector_type_test.cc
|
sem/vector_type_test.cc
|
||||||
|
source_test.cc
|
||||||
symbol_table_test.cc
|
symbol_table_test.cc
|
||||||
symbol_test.cc
|
symbol_test.cc
|
||||||
test_main.cc
|
test_main.cc
|
||||||
|
@ -138,10 +138,10 @@ bool Lexer::is_hex(char ch) const {
|
|||||||
return std::isxdigit(ch);
|
return std::isxdigit(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Lexer::matches(size_t pos, const std::string& substr) {
|
bool Lexer::matches(size_t pos, std::string_view substr) {
|
||||||
if (pos >= len_)
|
if (pos >= len_)
|
||||||
return false;
|
return false;
|
||||||
return content_->data.substr(pos, substr.size()) == substr;
|
return content_->data_view.substr(pos, substr.size()) == substr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Token Lexer::skip_whitespace_and_comments() {
|
Token Lexer::skip_whitespace_and_comments() {
|
||||||
@ -763,7 +763,7 @@ Token Lexer::try_ident() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto str = content_->data.substr(s, pos_ - s);
|
auto str = content_->data_view.substr(s, pos_ - s);
|
||||||
end_source(source);
|
end_source(source);
|
||||||
|
|
||||||
auto t = check_keyword(source, str);
|
auto t = check_keyword(source, str);
|
||||||
@ -771,7 +771,7 @@ Token Lexer::try_ident() {
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {Token::Type::kIdentifier, source, str};
|
return {Token::Type::kIdentifier, source, std::string(str)};
|
||||||
}
|
}
|
||||||
|
|
||||||
Token Lexer::try_punctuation() {
|
Token Lexer::try_punctuation() {
|
||||||
@ -937,7 +937,7 @@ Token Lexer::try_punctuation() {
|
|||||||
return {type, source};
|
return {type, source};
|
||||||
}
|
}
|
||||||
|
|
||||||
Token Lexer::check_keyword(const Source& source, const std::string& str) {
|
Token Lexer::check_keyword(const Source& source, std::string_view str) {
|
||||||
if (str == "array")
|
if (str == "array")
|
||||||
return {Token::Type::kArray, source, "array"};
|
return {Token::Type::kArray, source, "array"};
|
||||||
if (str == "atomic")
|
if (str == "atomic")
|
||||||
|
@ -51,7 +51,7 @@ class Lexer {
|
|||||||
size_t start,
|
size_t start,
|
||||||
size_t end,
|
size_t end,
|
||||||
int32_t base);
|
int32_t base);
|
||||||
Token check_keyword(const Source&, const std::string&);
|
Token check_keyword(const Source&, std::string_view);
|
||||||
|
|
||||||
/// The try_* methods have the following in common:
|
/// The try_* methods have the following in common:
|
||||||
/// - They assume there is at least one character to be consumed,
|
/// - They assume there is at least one character to be consumed,
|
||||||
@ -89,7 +89,7 @@ class Lexer {
|
|||||||
/// @returns true if 'ch' is a digit, an alphabetic character,
|
/// @returns true if 'ch' is a digit, an alphabetic character,
|
||||||
/// or an underscore.
|
/// or an underscore.
|
||||||
bool is_alphanum_underscore(char ch) const;
|
bool is_alphanum_underscore(char ch) const;
|
||||||
bool matches(size_t pos, const std::string& substr);
|
bool matches(size_t pos, std::string_view substr);
|
||||||
|
|
||||||
/// The source file path
|
/// The source file path
|
||||||
std::string const file_path_;
|
std::string const file_path_;
|
||||||
|
@ -70,7 +70,7 @@ const char kReadAccess[] = "read";
|
|||||||
const char kWriteAccess[] = "write";
|
const char kWriteAccess[] = "write";
|
||||||
const char kReadWriteAccess[] = "read_write";
|
const char kReadWriteAccess[] = "read_write";
|
||||||
|
|
||||||
ast::Builtin ident_to_builtin(const std::string& str) {
|
ast::Builtin ident_to_builtin(std::string_view str) {
|
||||||
if (str == "position") {
|
if (str == "position") {
|
||||||
return ast::Builtin::kPosition;
|
return ast::Builtin::kPosition;
|
||||||
}
|
}
|
||||||
@ -266,8 +266,8 @@ ParserImpl::ParserImpl(Source::File const* file)
|
|||||||
ParserImpl::~ParserImpl() = default;
|
ParserImpl::~ParserImpl() = default;
|
||||||
|
|
||||||
ParserImpl::Failure::Errored ParserImpl::add_error(const Source& source,
|
ParserImpl::Failure::Errored ParserImpl::add_error(const Source& source,
|
||||||
const std::string& err,
|
std::string_view err,
|
||||||
const std::string& use) {
|
std::string_view use) {
|
||||||
std::stringstream msg;
|
std::stringstream msg;
|
||||||
msg << err;
|
msg << err;
|
||||||
if (!use.empty()) {
|
if (!use.empty()) {
|
||||||
@ -759,8 +759,7 @@ Maybe<const ast::Type*> ParserImpl::depth_texture_type() {
|
|||||||
// | 'rgba32uint'
|
// | 'rgba32uint'
|
||||||
// | 'rgba32sint'
|
// | 'rgba32sint'
|
||||||
// | 'rgba32float'
|
// | 'rgba32float'
|
||||||
Expect<ast::TexelFormat> ParserImpl::expect_texel_format(
|
Expect<ast::TexelFormat> ParserImpl::expect_texel_format(std::string_view use) {
|
||||||
const std::string& use) {
|
|
||||||
auto tok = next();
|
auto tok = next();
|
||||||
if (tok.IsIdentifier()) {
|
if (tok.IsIdentifier()) {
|
||||||
auto s = tok.to_str();
|
auto s = tok.to_str();
|
||||||
@ -819,7 +818,7 @@ Expect<ast::TexelFormat> ParserImpl::expect_texel_format(
|
|||||||
// variable_ident_decl
|
// variable_ident_decl
|
||||||
// : IDENT COLON variable_decoration_list* type_decl
|
// : IDENT COLON variable_decoration_list* type_decl
|
||||||
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
||||||
const std::string& use,
|
std::string_view use,
|
||||||
bool allow_inferred) {
|
bool allow_inferred) {
|
||||||
auto ident = expect_ident(use);
|
auto ident = expect_ident(use);
|
||||||
if (ident.errored)
|
if (ident.errored)
|
||||||
@ -849,7 +848,7 @@ Expect<ParserImpl::TypedIdentifier> ParserImpl::expect_variable_ident_decl(
|
|||||||
return TypedIdentifier{type.value, ident.value, ident.source};
|
return TypedIdentifier{type.value, ident.value, ident.source};
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<ast::Access> ParserImpl::expect_access(const std::string& use) {
|
Expect<ast::Access> ParserImpl::expect_access(std::string_view use) {
|
||||||
auto ident = expect_ident(use);
|
auto ident = expect_ident(use);
|
||||||
if (ident.errored)
|
if (ident.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1016,7 +1015,7 @@ Maybe<const ast::Type*> ParserImpl::type_decl(ast::DecorationList& decos) {
|
|||||||
return Failure::kNoMatch;
|
return Failure::kNoMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<const ast::Type*> ParserImpl::expect_type(const std::string& use) {
|
Expect<const ast::Type*> ParserImpl::expect_type(std::string_view use) {
|
||||||
auto type = type_decl();
|
auto type = type_decl();
|
||||||
if (type.errored)
|
if (type.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -1170,7 +1169,7 @@ Expect<const ast::Type*> ParserImpl::expect_type_decl_matrix(Token t) {
|
|||||||
// | PRIVATE
|
// | PRIVATE
|
||||||
// | FUNCTION
|
// | FUNCTION
|
||||||
Expect<ast::StorageClass> ParserImpl::expect_storage_class(
|
Expect<ast::StorageClass> ParserImpl::expect_storage_class(
|
||||||
const std::string& use) {
|
std::string_view use) {
|
||||||
auto source = peek().source();
|
auto source = peek().source();
|
||||||
|
|
||||||
if (match(Token::Type::kUniform))
|
if (match(Token::Type::kUniform))
|
||||||
@ -2228,7 +2227,7 @@ Maybe<const ast::Expression*> ParserImpl::singular_expression() {
|
|||||||
// : PAREN_LEFT ((logical_or_expression COMMA)* logical_or_expression COMMA?)?
|
// : PAREN_LEFT ((logical_or_expression COMMA)* logical_or_expression COMMA?)?
|
||||||
// PAREN_RIGHT
|
// PAREN_RIGHT
|
||||||
Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list(
|
Expect<ast::ExpressionList> ParserImpl::expect_argument_expression_list(
|
||||||
const std::string& use) {
|
std::string_view use) {
|
||||||
return expect_paren_block(use, [&]() -> Expect<ast::ExpressionList> {
|
return expect_paren_block(use, [&]() -> Expect<ast::ExpressionList> {
|
||||||
ast::ExpressionList ret;
|
ast::ExpressionList ret;
|
||||||
while (continue_parsing()) {
|
while (continue_parsing()) {
|
||||||
@ -2296,8 +2295,8 @@ Maybe<const ast::Expression*> ParserImpl::unary_expression() {
|
|||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
}
|
}
|
||||||
if (!expr.matched) {
|
if (!expr.matched) {
|
||||||
return add_error(
|
return add_error(peek(), "unable to parse right side of " +
|
||||||
peek(), "unable to parse right side of " + t.to_name() + " expression");
|
std::string(t.to_name()) + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
return create<ast::UnaryOpExpression>(t.source(), op, expr.value);
|
return create<ast::UnaryOpExpression>(t.source(), op, expr.value);
|
||||||
@ -2329,8 +2328,8 @@ Expect<const ast::Expression*> ParserImpl::expect_multiplicative_expr(
|
|||||||
if (rhs.errored)
|
if (rhs.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!rhs.matched) {
|
if (!rhs.matched) {
|
||||||
return add_error(peek(),
|
return add_error(peek(), "unable to parse right side of " +
|
||||||
"unable to parse right side of " + name + " expression");
|
std::string(name) + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
@ -2466,8 +2465,8 @@ Expect<const ast::Expression*> ParserImpl::expect_relational_expr(
|
|||||||
if (rhs.errored)
|
if (rhs.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!rhs.matched) {
|
if (!rhs.matched) {
|
||||||
return add_error(peek(),
|
return add_error(peek(), "unable to parse right side of " +
|
||||||
"unable to parse right side of " + name + " expression");
|
std::string(name) + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
@ -2510,8 +2509,8 @@ Expect<const ast::Expression*> ParserImpl::expect_equality_expr(
|
|||||||
if (rhs.errored)
|
if (rhs.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
if (!rhs.matched) {
|
if (!rhs.matched) {
|
||||||
return add_error(peek(),
|
return add_error(peek(), "unable to parse right side of " +
|
||||||
"unable to parse right side of " + name + " expression");
|
std::string(name) + " expression");
|
||||||
}
|
}
|
||||||
|
|
||||||
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
lhs = create<ast::BinaryExpression>(source, op, lhs, rhs.value);
|
||||||
@ -3147,7 +3146,7 @@ bool ParserImpl::match(Token::Type tok, Source* source /*= nullptr*/) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ParserImpl::expect(const std::string& use, Token::Type tok) {
|
bool ParserImpl::expect(std::string_view use, Token::Type tok) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (t.Is(tok)) {
|
if (t.Is(tok)) {
|
||||||
next();
|
next();
|
||||||
@ -3195,7 +3194,7 @@ bool ParserImpl::expect(const std::string& use, Token::Type tok) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<int32_t> ParserImpl::expect_sint(const std::string& use) {
|
Expect<int32_t> ParserImpl::expect_sint(std::string_view use) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (!t.Is(Token::Type::kSintLiteral))
|
if (!t.Is(Token::Type::kSintLiteral))
|
||||||
return add_error(t.source(), "expected signed integer literal", use);
|
return add_error(t.source(), "expected signed integer literal", use);
|
||||||
@ -3204,30 +3203,30 @@ Expect<int32_t> ParserImpl::expect_sint(const std::string& use) {
|
|||||||
return {t.to_i32(), t.source()};
|
return {t.to_i32(), t.source()};
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<uint32_t> ParserImpl::expect_positive_sint(const std::string& use) {
|
Expect<uint32_t> ParserImpl::expect_positive_sint(std::string_view use) {
|
||||||
auto sint = expect_sint(use);
|
auto sint = expect_sint(use);
|
||||||
if (sint.errored)
|
if (sint.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
if (sint.value < 0)
|
if (sint.value < 0)
|
||||||
return add_error(sint.source, use + " must be positive");
|
return add_error(sint.source, std::string(use) + " must be positive");
|
||||||
|
|
||||||
return {static_cast<uint32_t>(sint.value), sint.source};
|
return {static_cast<uint32_t>(sint.value), sint.source};
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<uint32_t> ParserImpl::expect_nonzero_positive_sint(
|
Expect<uint32_t> ParserImpl::expect_nonzero_positive_sint(
|
||||||
const std::string& use) {
|
std::string_view use) {
|
||||||
auto sint = expect_sint(use);
|
auto sint = expect_sint(use);
|
||||||
if (sint.errored)
|
if (sint.errored)
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
|
|
||||||
if (sint.value <= 0)
|
if (sint.value <= 0)
|
||||||
return add_error(sint.source, use + " must be greater than 0");
|
return add_error(sint.source, std::string(use) + " must be greater than 0");
|
||||||
|
|
||||||
return {static_cast<uint32_t>(sint.value), sint.source};
|
return {static_cast<uint32_t>(sint.value), sint.source};
|
||||||
}
|
}
|
||||||
|
|
||||||
Expect<std::string> ParserImpl::expect_ident(const std::string& use) {
|
Expect<std::string> ParserImpl::expect_ident(std::string_view use) {
|
||||||
auto t = peek();
|
auto t = peek();
|
||||||
if (t.IsIdentifier()) {
|
if (t.IsIdentifier()) {
|
||||||
synchronized_ = true;
|
synchronized_ = true;
|
||||||
@ -3247,7 +3246,7 @@ Expect<std::string> ParserImpl::expect_ident(const std::string& use) {
|
|||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
T ParserImpl::expect_block(Token::Type start,
|
T ParserImpl::expect_block(Token::Type start,
|
||||||
Token::Type end,
|
Token::Type end,
|
||||||
const std::string& use,
|
std::string_view use,
|
||||||
F&& body) {
|
F&& body) {
|
||||||
if (!expect(use, start)) {
|
if (!expect(use, start)) {
|
||||||
return Failure::kErrored;
|
return Failure::kErrored;
|
||||||
@ -3267,19 +3266,19 @@ T ParserImpl::expect_block(Token::Type start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
T ParserImpl::expect_paren_block(const std::string& use, F&& body) {
|
T ParserImpl::expect_paren_block(std::string_view use, F&& body) {
|
||||||
return expect_block(Token::Type::kParenLeft, Token::Type::kParenRight, use,
|
return expect_block(Token::Type::kParenLeft, Token::Type::kParenRight, use,
|
||||||
std::forward<F>(body));
|
std::forward<F>(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
T ParserImpl::expect_brace_block(const std::string& use, F&& body) {
|
T ParserImpl::expect_brace_block(std::string_view use, F&& body) {
|
||||||
return expect_block(Token::Type::kBraceLeft, Token::Type::kBraceRight, use,
|
return expect_block(Token::Type::kBraceLeft, Token::Type::kBraceRight, use,
|
||||||
std::forward<F>(body));
|
std::forward<F>(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename F, typename T>
|
template <typename F, typename T>
|
||||||
T ParserImpl::expect_lt_gt_block(const std::string& use, F&& body) {
|
T ParserImpl::expect_lt_gt_block(std::string_view use, F&& body) {
|
||||||
return expect_block(Token::Type::kLessThan, Token::Type::kGreaterThan, use,
|
return expect_block(Token::Type::kLessThan, Token::Type::kGreaterThan, use,
|
||||||
std::forward<F>(body));
|
std::forward<F>(body));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -367,8 +368,8 @@ class ParserImpl {
|
|||||||
/// @return `Failure::Errored::kError` so that you can combine an add_error()
|
/// @return `Failure::Errored::kError` so that you can combine an add_error()
|
||||||
/// call and return on the same line.
|
/// call and return on the same line.
|
||||||
Failure::Errored add_error(const Source& source,
|
Failure::Errored add_error(const Source& source,
|
||||||
const std::string& msg,
|
std::string_view msg,
|
||||||
const std::string& use);
|
std::string_view use);
|
||||||
/// Appends an error at `source` with the message `msg`
|
/// Appends an error at `source` with the message `msg`
|
||||||
/// @param source the source to associate the error with
|
/// @param source the source to associate the error with
|
||||||
/// @param msg the error message
|
/// @param msg the error message
|
||||||
@ -407,7 +408,7 @@ class ParserImpl {
|
|||||||
/// specify type
|
/// specify type
|
||||||
/// @returns the identifier and type parsed or empty otherwise
|
/// @returns the identifier and type parsed or empty otherwise
|
||||||
Expect<TypedIdentifier> expect_variable_ident_decl(
|
Expect<TypedIdentifier> expect_variable_ident_decl(
|
||||||
const std::string& use,
|
std::string_view use,
|
||||||
bool allow_inferred = false);
|
bool allow_inferred = false);
|
||||||
/// Parses a `variable_qualifier` grammar element
|
/// Parses a `variable_qualifier` grammar element
|
||||||
/// @returns the variable qualifier information
|
/// @returns the variable qualifier information
|
||||||
@ -426,7 +427,7 @@ class ParserImpl {
|
|||||||
/// Parses a `storage_class` grammar element, erroring on parse failure.
|
/// Parses a `storage_class` grammar element, erroring on parse failure.
|
||||||
/// @param use a description of what was being parsed if an error was raised.
|
/// @param use a description of what was being parsed if an error was raised.
|
||||||
/// @returns the storage class or StorageClass::kNone if none matched
|
/// @returns the storage class or StorageClass::kNone if none matched
|
||||||
Expect<ast::StorageClass> expect_storage_class(const std::string& use);
|
Expect<ast::StorageClass> expect_storage_class(std::string_view use);
|
||||||
/// Parses a `struct_decl` grammar element with the initial
|
/// Parses a `struct_decl` grammar element with the initial
|
||||||
/// `struct_decoration_decl*` provided as `decos`.
|
/// `struct_decoration_decl*` provided as `decos`.
|
||||||
/// @returns the struct type or nullptr on error
|
/// @returns the struct type or nullptr on error
|
||||||
@ -472,7 +473,7 @@ class ParserImpl {
|
|||||||
/// Parses a `texel_format` grammar element
|
/// Parses a `texel_format` grammar element
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns returns the texel format or kNone if none matched.
|
/// @returns returns the texel format or kNone if none matched.
|
||||||
Expect<ast::TexelFormat> expect_texel_format(const std::string& use);
|
Expect<ast::TexelFormat> expect_texel_format(std::string_view use);
|
||||||
/// Parses a `function_header` grammar element
|
/// Parses a `function_header` grammar element
|
||||||
/// @returns the parsed function header
|
/// @returns the parsed function header
|
||||||
Maybe<FunctionHeader> function_header();
|
Maybe<FunctionHeader> function_header();
|
||||||
@ -490,7 +491,7 @@ class ParserImpl {
|
|||||||
/// match a valid access control.
|
/// match a valid access control.
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed access control.
|
/// @returns the parsed access control.
|
||||||
Expect<ast::Access> expect_access(const std::string& use);
|
Expect<ast::Access> expect_access(std::string_view use);
|
||||||
/// Parses a builtin identifier, erroring if the next token does not match a
|
/// Parses a builtin identifier, erroring if the next token does not match a
|
||||||
/// valid builtin name.
|
/// valid builtin name.
|
||||||
/// @returns the parsed builtin.
|
/// @returns the parsed builtin.
|
||||||
@ -566,7 +567,7 @@ class ParserImpl {
|
|||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the list of arguments
|
/// @returns the list of arguments
|
||||||
Expect<ast::ExpressionList> expect_argument_expression_list(
|
Expect<ast::ExpressionList> expect_argument_expression_list(
|
||||||
const std::string& use);
|
std::string_view use);
|
||||||
/// Parses the recursive portion of the postfix_expression
|
/// Parses the recursive portion of the postfix_expression
|
||||||
/// @param prefix the left side of the expression
|
/// @param prefix the left side of the expression
|
||||||
/// @returns the parsed expression or nullptr
|
/// @returns the parsed expression or nullptr
|
||||||
@ -712,32 +713,32 @@ class ParserImpl {
|
|||||||
/// @param use a description of what was being parsed if an error was raised.
|
/// @param use a description of what was being parsed if an error was raised.
|
||||||
/// @param tok the token to test against
|
/// @param tok the token to test against
|
||||||
/// @returns true if the next token equals `tok`
|
/// @returns true if the next token equals `tok`
|
||||||
bool expect(const std::string& use, Token::Type tok);
|
bool expect(std::string_view use, Token::Type tok);
|
||||||
/// Parses a signed integer from the next token in the stream, erroring if the
|
/// Parses a signed integer from the next token in the stream, erroring if the
|
||||||
/// next token is not a signed integer.
|
/// next token is not a signed integer.
|
||||||
/// Consumes the next token on match.
|
/// Consumes the next token on match.
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed integer.
|
/// @returns the parsed integer.
|
||||||
Expect<int32_t> expect_sint(const std::string& use);
|
Expect<int32_t> expect_sint(std::string_view use);
|
||||||
/// Parses a signed integer from the next token in the stream, erroring if
|
/// Parses a signed integer from the next token in the stream, erroring if
|
||||||
/// the next token is not a signed integer or is negative.
|
/// the next token is not a signed integer or is negative.
|
||||||
/// Consumes the next token if it is a signed integer (not necessarily
|
/// Consumes the next token if it is a signed integer (not necessarily
|
||||||
/// negative).
|
/// negative).
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed integer.
|
/// @returns the parsed integer.
|
||||||
Expect<uint32_t> expect_positive_sint(const std::string& use);
|
Expect<uint32_t> expect_positive_sint(std::string_view use);
|
||||||
/// Parses a non-zero signed integer from the next token in the stream,
|
/// Parses a non-zero signed integer from the next token in the stream,
|
||||||
/// erroring if the next token is not a signed integer or is less than 1.
|
/// erroring if the next token is not a signed integer or is less than 1.
|
||||||
/// Consumes the next token if it is a signed integer (not necessarily
|
/// Consumes the next token if it is a signed integer (not necessarily
|
||||||
/// >= 1).
|
/// >= 1).
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed integer.
|
/// @returns the parsed integer.
|
||||||
Expect<uint32_t> expect_nonzero_positive_sint(const std::string& use);
|
Expect<uint32_t> expect_nonzero_positive_sint(std::string_view use);
|
||||||
/// Errors if the next token is not an identifier.
|
/// Errors if the next token is not an identifier.
|
||||||
/// Consumes the next token on match.
|
/// Consumes the next token on match.
|
||||||
/// @param use a description of what was being parsed if an error was raised
|
/// @param use a description of what was being parsed if an error was raised
|
||||||
/// @returns the parsed identifier.
|
/// @returns the parsed identifier.
|
||||||
Expect<std::string> expect_ident(const std::string& use);
|
Expect<std::string> expect_ident(std::string_view use);
|
||||||
/// Parses a lexical block starting with the token `start` and ending with
|
/// Parses a lexical block starting with the token `start` and ending with
|
||||||
/// the token `end`. `body` is called to parse the lexical block body
|
/// the token `end`. `body` is called to parse the lexical block body
|
||||||
/// between the `start` and `end` tokens. If the `start` or `end` tokens
|
/// between the `start` and `end` tokens. If the `start` or `end` tokens
|
||||||
@ -754,7 +755,7 @@ class ParserImpl {
|
|||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T expect_block(Token::Type start,
|
T expect_block(Token::Type start,
|
||||||
Token::Type end,
|
Token::Type end,
|
||||||
const std::string& use,
|
std::string_view use,
|
||||||
F&& body);
|
F&& body);
|
||||||
/// A convenience function that calls expect_block() passing
|
/// A convenience function that calls expect_block() passing
|
||||||
/// `Token::Type::kParenLeft` and `Token::Type::kParenRight` for the `start`
|
/// `Token::Type::kParenLeft` and `Token::Type::kParenRight` for the `start`
|
||||||
@ -765,7 +766,7 @@ class ParserImpl {
|
|||||||
/// @return the value returned by `body` if no errors are raised, otherwise
|
/// @return the value returned by `body` if no errors are raised, otherwise
|
||||||
/// an Expect with error state.
|
/// an Expect with error state.
|
||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T expect_paren_block(const std::string& use, F&& body);
|
T expect_paren_block(std::string_view use, F&& body);
|
||||||
/// A convenience function that calls `expect_block` passing
|
/// A convenience function that calls `expect_block` passing
|
||||||
/// `Token::Type::kBraceLeft` and `Token::Type::kBraceRight` for the `start`
|
/// `Token::Type::kBraceLeft` and `Token::Type::kBraceRight` for the `start`
|
||||||
/// and `end` arguments, respectively.
|
/// and `end` arguments, respectively.
|
||||||
@ -775,7 +776,7 @@ class ParserImpl {
|
|||||||
/// @return the value returned by `body` if no errors are raised, otherwise
|
/// @return the value returned by `body` if no errors are raised, otherwise
|
||||||
/// an Expect with error state.
|
/// an Expect with error state.
|
||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T expect_brace_block(const std::string& use, F&& body);
|
T expect_brace_block(std::string_view use, F&& body);
|
||||||
/// A convenience function that calls `expect_block` passing
|
/// A convenience function that calls `expect_block` passing
|
||||||
/// `Token::Type::kLessThan` and `Token::Type::kGreaterThan` for the `start`
|
/// `Token::Type::kLessThan` and `Token::Type::kGreaterThan` for the `start`
|
||||||
/// and `end` arguments, respectively.
|
/// and `end` arguments, respectively.
|
||||||
@ -785,7 +786,7 @@ class ParserImpl {
|
|||||||
/// @return the value returned by `body` if no errors are raised, otherwise
|
/// @return the value returned by `body` if no errors are raised, otherwise
|
||||||
/// an Expect with error state.
|
/// an Expect with error state.
|
||||||
template <typename F, typename T = ReturnType<F>>
|
template <typename F, typename T = ReturnType<F>>
|
||||||
T expect_lt_gt_block(const std::string& use, F&& body);
|
T expect_lt_gt_block(std::string_view use, F&& body);
|
||||||
|
|
||||||
/// sync() calls the function `func`, and attempts to resynchronize the
|
/// sync() calls the function `func`, and attempts to resynchronize the
|
||||||
/// parser to the next found resynchronization token if `func` fails. If the
|
/// parser to the next found resynchronization token if `func` fails. If the
|
||||||
@ -853,7 +854,7 @@ class ParserImpl {
|
|||||||
ast::DecorationList decos);
|
ast::DecorationList decos);
|
||||||
Expect<const ast::Type*> expect_type_decl_matrix(Token t);
|
Expect<const ast::Type*> expect_type_decl_matrix(Token t);
|
||||||
|
|
||||||
Expect<const ast::Type*> expect_type(const std::string& use);
|
Expect<const ast::Type*> expect_type(std::string_view use);
|
||||||
|
|
||||||
Maybe<const ast::Statement*> non_block_statement();
|
Maybe<const ast::Statement*> non_block_statement();
|
||||||
Maybe<const ast::Statement*> for_header_initializer();
|
Maybe<const ast::Statement*> for_header_initializer();
|
||||||
|
@ -19,7 +19,7 @@ namespace reader {
|
|||||||
namespace wgsl {
|
namespace wgsl {
|
||||||
|
|
||||||
// static
|
// static
|
||||||
std::string Token::TypeToName(Type type) {
|
std::string_view Token::TypeToName(Type type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case Token::Type::kError:
|
case Token::Type::kError:
|
||||||
return "kError";
|
return "kError";
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#define SRC_READER_WGSL_TOKEN_H_
|
#define SRC_READER_WGSL_TOKEN_H_
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
|
||||||
#include "src/source.h"
|
#include "src/source.h"
|
||||||
|
|
||||||
@ -260,7 +261,7 @@ class Token {
|
|||||||
/// Converts a token type to a name
|
/// Converts a token type to a name
|
||||||
/// @param type the type to convert
|
/// @param type the type to convert
|
||||||
/// @returns the token type as as string
|
/// @returns the token type as as string
|
||||||
static std::string TypeToName(Type type);
|
static std::string_view TypeToName(Type type);
|
||||||
|
|
||||||
/// Creates an uninitialized token
|
/// Creates an uninitialized token
|
||||||
Token();
|
Token();
|
||||||
@ -354,7 +355,7 @@ class Token {
|
|||||||
Source source() const { return source_; }
|
Source source() const { return source_; }
|
||||||
|
|
||||||
/// Returns the string value of the token
|
/// Returns the string value of the token
|
||||||
/// @return const std::string&
|
/// @return std::string
|
||||||
std::string to_str() const;
|
std::string to_str() const;
|
||||||
/// Returns the float value of the token. 0 is returned if the token does not
|
/// Returns the float value of the token. 0 is returned if the token does not
|
||||||
/// contain a float value.
|
/// contain a float value.
|
||||||
@ -370,7 +371,7 @@ class Token {
|
|||||||
int32_t to_i32() const;
|
int32_t to_i32() const;
|
||||||
|
|
||||||
/// @returns the token type as string
|
/// @returns the token type as string
|
||||||
std::string to_name() const { return Token::TypeToName(type_); }
|
std::string_view to_name() const { return Token::TypeToName(type_); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The Token::Type of the token
|
/// The Token::Type of the token
|
||||||
|
@ -16,23 +16,50 @@
|
|||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <string_view>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
namespace tint {
|
namespace tint {
|
||||||
namespace {
|
namespace {
|
||||||
std::vector<std::string> split_lines(const std::string& str) {
|
std::vector<std::string_view> SplitLines(std::string_view str) {
|
||||||
std::stringstream stream(str);
|
std::vector<std::string_view> lines;
|
||||||
std::string line;
|
|
||||||
std::vector<std::string> lines;
|
size_t lineStart = 0;
|
||||||
while (std::getline(stream, line, '\n')) {
|
for (size_t i = 0; i < str.size(); ++i) {
|
||||||
lines.emplace_back(std::move(line));
|
if (str[i] == '\n') {
|
||||||
|
lines.push_back(str.substr(lineStart, i - lineStart));
|
||||||
|
lineStart = i + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (lineStart < str.size()) {
|
||||||
|
lines.push_back(str.substr(lineStart));
|
||||||
|
}
|
||||||
|
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::string_view> CopyRelativeStringViews(
|
||||||
|
const std::vector<std::string_view>& src_list,
|
||||||
|
const std::string_view& src_view,
|
||||||
|
const std::string_view& dst_view) {
|
||||||
|
std::vector<std::string_view> out(src_list.size());
|
||||||
|
for (size_t i = 0; i < src_list.size(); i++) {
|
||||||
|
auto offset = static_cast<size_t>(&src_list[i].front() - &src_view.front());
|
||||||
|
auto count = src_list[i].length();
|
||||||
|
out[i] = dst_view.substr(offset, count);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Source::FileContent::FileContent(const std::string& body)
|
Source::FileContent::FileContent(const std::string& body)
|
||||||
: data(body), lines(split_lines(body)) {}
|
: data(body), data_view(data), lines(SplitLines(data_view)) {}
|
||||||
|
|
||||||
|
Source::FileContent::FileContent(const FileContent& rhs)
|
||||||
|
: data(rhs.data),
|
||||||
|
data_view(data),
|
||||||
|
lines(CopyRelativeStringViews(rhs.lines, rhs.data_view, data_view)) {}
|
||||||
|
|
||||||
Source::FileContent::~FileContent() = default;
|
Source::FileContent::~FileContent() = default;
|
||||||
|
|
||||||
|
12
src/source.h
12
src/source.h
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -33,13 +34,19 @@ class Source {
|
|||||||
/// @param data the file contents
|
/// @param data the file contents
|
||||||
explicit FileContent(const std::string& data);
|
explicit FileContent(const std::string& data);
|
||||||
|
|
||||||
|
/// Copy constructor
|
||||||
|
/// @param rhs the FileContent to copy
|
||||||
|
FileContent(const FileContent& rhs);
|
||||||
|
|
||||||
/// Destructor
|
/// Destructor
|
||||||
~FileContent();
|
~FileContent();
|
||||||
|
|
||||||
/// un-split file content
|
/// The original un-split file content
|
||||||
const std::string data;
|
const std::string data;
|
||||||
|
/// A string_view over #data
|
||||||
|
const std::string_view data_view;
|
||||||
/// #data split by lines
|
/// #data split by lines
|
||||||
const std::vector<std::string> lines;
|
const std::vector<std::string_view> lines;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// File describes a source file, including path and content.
|
/// File describes a source file, including path and content.
|
||||||
@ -51,6 +58,7 @@ class Source {
|
|||||||
inline File(const std::string& p, const std::string& c)
|
inline File(const std::string& p, const std::string& c)
|
||||||
: path(p), content(c) {}
|
: path(p), content(c) {}
|
||||||
|
|
||||||
|
/// Destructor
|
||||||
~File();
|
~File();
|
||||||
|
|
||||||
/// file path (optional)
|
/// file path (optional)
|
||||||
|
66
src/source_test.cc
Normal file
66
src/source_test.cc
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
// Copyright 2022 The Tint Authors.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
#include "src/source.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
namespace tint {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static constexpr const char* kSource = R"(line one
|
||||||
|
line two
|
||||||
|
line three)";
|
||||||
|
|
||||||
|
using SourceFileContentTest = testing::Test;
|
||||||
|
|
||||||
|
TEST_F(SourceFileContentTest, Ctor) {
|
||||||
|
Source::FileContent fc(kSource);
|
||||||
|
EXPECT_EQ(fc.data, kSource);
|
||||||
|
EXPECT_EQ(fc.data_view, kSource);
|
||||||
|
ASSERT_EQ(fc.lines.size(), 3u);
|
||||||
|
EXPECT_EQ(fc.lines[0], "line one");
|
||||||
|
EXPECT_EQ(fc.lines[1], "line two");
|
||||||
|
EXPECT_EQ(fc.lines[2], "line three");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SourceFileContentTest, CopyCtor) {
|
||||||
|
auto src = std::make_unique<Source::FileContent>(kSource);
|
||||||
|
Source::FileContent fc{*src};
|
||||||
|
src.reset();
|
||||||
|
EXPECT_EQ(fc.data, kSource);
|
||||||
|
EXPECT_EQ(fc.data_view, kSource);
|
||||||
|
ASSERT_EQ(fc.lines.size(), 3u);
|
||||||
|
EXPECT_EQ(fc.lines[0], "line one");
|
||||||
|
EXPECT_EQ(fc.lines[1], "line two");
|
||||||
|
EXPECT_EQ(fc.lines[2], "line three");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(SourceFileContentTest, MoveCtor) {
|
||||||
|
auto src = std::make_unique<Source::FileContent>(kSource);
|
||||||
|
Source::FileContent fc{std::move(*src)};
|
||||||
|
src.reset();
|
||||||
|
EXPECT_EQ(fc.data, kSource);
|
||||||
|
EXPECT_EQ(fc.data_view, kSource);
|
||||||
|
ASSERT_EQ(fc.lines.size(), 3u);
|
||||||
|
EXPECT_EQ(fc.lines[0], "line one");
|
||||||
|
EXPECT_EQ(fc.lines[1], "line two");
|
||||||
|
EXPECT_EQ(fc.lines[2], "line three");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
} // namespace tint
|
@ -699,6 +699,7 @@ tint_unittests_source_set("tint_unittests_core_src") {
|
|||||||
"../src/program_builder_test.cc",
|
"../src/program_builder_test.cc",
|
||||||
"../src/program_test.cc",
|
"../src/program_test.cc",
|
||||||
"../src/scope_stack_test.cc",
|
"../src/scope_stack_test.cc",
|
||||||
|
"../src/source_test.cc",
|
||||||
"../src/symbol_table_test.cc",
|
"../src/symbol_table_test.cc",
|
||||||
"../src/symbol_test.cc",
|
"../src/symbol_test.cc",
|
||||||
"../src/traits_test.cc",
|
"../src/traits_test.cc",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user