reader/wgsl: Add support for block comments

Handles nested block comments.

Allow unterminated block comments at EOF, as it is not clear whether
WGSL will allow this or not.

Bug: tint:881
Change-Id: Ieae4e0073dab69f773adb32018a9bdaf4f352116
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59180
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
This commit is contained in:
James Price 2021-07-22 14:41:37 +00:00
parent 18d7e785d3
commit eb39420ae6
3 changed files with 90 additions and 5 deletions

View File

@ -135,13 +135,43 @@ void Lexer::skip_whitespace() {
}
void Lexer::skip_comments() {
if (!matches(pos_, "//")) {
if (matches(pos_, "//")) {
// Line comment: ignore everything until the end of line.
while (!is_eof() && !matches(pos_, "\n")) {
pos_++;
location_.column++;
}
return;
}
while (!is_eof() && !matches(pos_, "\n")) {
pos_++;
location_.column++;
if (matches(pos_, "/*")) {
// Block comment: ignore everything until the closing '*/' token.
pos_ += 2;
location_.column += 2;
int depth = 1;
while (!is_eof() && depth > 0) {
if (matches(pos_, "/*")) {
// Start of block comment: increase nesting depth.
pos_ += 2;
location_.column += 2;
depth++;
} else if (matches(pos_, "*/")) {
// End of block comment: decrease nesting depth.
pos_ += 2;
location_.column += 2;
depth--;
} else if (matches(pos_, "\n")) {
// Newline: skip and update source location.
pos_++;
location_.line++;
location_.column = 1;
} else {
// Anything else: skip and update source location.
pos_++;
location_.column++;
}
}
}
}

View File

@ -48,7 +48,7 @@ TEST_F(LexerTest, Skips_Whitespace) {
EXPECT_TRUE(t.IsEof());
}
TEST_F(LexerTest, Skips_Comments) {
TEST_F(LexerTest, Skips_Comments_Line) {
Source::FileContent content(R"(//starts with comment
ident1 //ends with comment
// blank line
@ -75,6 +75,41 @@ ident1 //ends with comment
EXPECT_TRUE(t.IsEof());
}
TEST_F(LexerTest, Skips_Comments_Block) {
Source::FileContent content(R"(/* comment
text */ident)");
Lexer l("test.wgsl", &content);
auto t = l.next();
EXPECT_TRUE(t.IsIdentifier());
EXPECT_EQ(t.source().range.begin.line, 2u);
EXPECT_EQ(t.source().range.begin.column, 8u);
EXPECT_EQ(t.source().range.end.line, 2u);
EXPECT_EQ(t.source().range.end.column, 13u);
EXPECT_EQ(t.to_str(), "ident");
t = l.next();
EXPECT_TRUE(t.IsEof());
}
TEST_F(LexerTest, Skips_Comments_Block_Nested) {
Source::FileContent content(R"(/* comment
text // nested line comments are ignored /* more text
/////**/ */*/ident)");
Lexer l("test.wgsl", &content);
auto t = l.next();
EXPECT_TRUE(t.IsIdentifier());
EXPECT_EQ(t.source().range.begin.line, 3u);
EXPECT_EQ(t.source().range.begin.column, 14u);
EXPECT_EQ(t.source().range.end.line, 3u);
EXPECT_EQ(t.source().range.end.column, 19u);
EXPECT_EQ(t.to_str(), "ident");
t = l.next();
EXPECT_TRUE(t.IsEof());
}
struct FloatData {
const char* input;
float result;

View File

@ -48,6 +48,26 @@ fn main() -> { // missing return type
EXPECT_EQ(p->error(), "2:15: unable to determine function return type");
}
TEST_F(ParserImplTest, Comments) {
auto p = parser(R"(
/**
* Here is my shader.
*
* /* I can nest /**/ comments. */
* // I can nest line comments too.
**/
[[stage(fragment)]] // This is the stage
fn main(/*
no
parameters
*/) -> [[location(0)]] vec4<f32> {
return/*block_comments_delimit_tokens*/vec4<f32>(.4, .2, .3, 1);
}/* unterminated block comments are OK at EOF...)");
ASSERT_TRUE(p->Parse()) << p->error();
ASSERT_EQ(1u, p->program().AST().Functions().size());
}
TEST_F(ParserImplTest, GetRegisteredType) {
auto p = parser("");
auto* alias = create<ast::Alias>(Sym("my_alias"), ty.i32());