Support block comments

This commit is contained in:
Jean Pierre Cimalando 2020-04-20 19:47:28 +02:00
parent 1dc83d3a94
commit 748e3668a8
3 changed files with 70 additions and 14 deletions

View file

@ -113,7 +113,7 @@ void Parser::processTopLevel()
while (!_included.empty()) {
Reader& reader = *_included.back();
while (reader.skipChars(" \t\r\n") || skipComment(reader));
while (reader.skipChars(" \t\r\n") || skipComment());
switch (reader.peekChar()) {
case Reader::kEof:
@ -348,32 +348,70 @@ void Parser::flushCurrentHeader()
_currentOpcodes.clear();
}
bool Parser::hasComment(Reader& reader)
int Parser::hasComment(Reader& reader)
{
if (reader.peekChar() != '/')
return false;
reader.getChar();
if (reader.peekChar() != '/') {
reader.putBackChar('/');
return false;
int ret = 0;
switch (reader.peekChar()) {
case '/':
ret = 1;
break;
case '*':
ret = 2;
break;
}
return true;
reader.putBackChar('/');
return ret;
}
size_t Parser::skipComment(Reader& reader)
size_t Parser::skipComment()
{
if (!hasComment(reader))
Reader& reader = *_included.back();
int commentType = hasComment(reader);
if (!commentType)
return 0;
SourceLocation start = reader.location();
size_t count = 2;
reader.getChar();
reader.getChar();
int c;
while ((c = reader.getChar()) != Reader::kEof && c != '\r' && c != '\n')
++count;
bool terminated = false;
switch (commentType) {
case 1: // line comment
{
int c;
while ((c = reader.getChar()) != Reader::kEof && c != '\r' && c != '\n')
++count;
terminated = true;
}
break;
case 2: // block comment
{
int c1 = 0;
int c2 = reader.getChar();
while (!terminated && c2 != Reader::kEof) {
c1 = c2;
c2 = reader.getChar();
terminated = c1 == '*' && c2 == '/';
}
}
break;
}
if (!terminated) {
SourceLocation end = reader.location();
emitError({ start, end }, "Unterminated block comment.");
}
return count;
}
@ -387,7 +425,14 @@ void Parser::trimRight(std::string& text)
size_t Parser::extractToEol(Reader& reader, std::string* dst)
{
return reader.extractWhile(dst, [&reader](char c) {
return c != '\r' && c != '\n' && !(c == '/' && reader.peekChar() == '/');
if (c == '\r' || c == '\n')
return false;
if (c == '/') {
int c2 = reader.peekChar();
if (c2 == '/' || c2 == '*') // stop at comment
return false;
}
return true;
});
}

View file

@ -84,8 +84,8 @@ private:
void flushCurrentHeader();
// helpers
static bool hasComment(Reader& reader);
static size_t skipComment(Reader& reader);
static int hasComment(Reader& reader); // 0=None 1=Line 2=Block
size_t skipComment();
static void trimRight(std::string& text);
static size_t extractToEol(Reader& reader, std::string* dst); // ignores comment
std::string expandDollarVars(const SourceRange& range, absl::string_view src);

View file

@ -38,6 +38,11 @@ static const char defaultSfzText[] = R"SFZ(
// This is a SFZ test file with many problems. //
//----------------------------------------------------------------------------//
/*
* This is a block comment. Not all the SFZ players accept it.
* It can span over multiple lines.
*/
// opcode without header
not_in_header=on // warning
@ -75,6 +80,12 @@ abcdef=$tata
// opcode name which expands to invalid identifier
$titi=1
volume=10 /*
block comments at the end of line
*/
/* unterminated block comment
)SFZ";
void Application::init()