From 45515f936be181c28e56c710e546668e64d063f7 Mon Sep 17 00:00:00 2001 From: Eelke Klein Date: Sun, 10 Sep 2017 10:13:58 +0200 Subject: [PATCH] First step at detecting dollar quoted strings. Dollar quotes are now recognized by the lexical analyzer. Plan is to let the parser decide how to handle the content. --- src/core/SqlLexer.cpp | 43 +++++++++++++++++++++++++++++- src/core/SqlLexer.h | 5 ++-- src/pglab/SqlSyntaxHighlighter.cpp | 8 +++++- src/pglab/SqlSyntaxHighlighter.h | 1 + 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/src/core/SqlLexer.cpp b/src/core/SqlLexer.cpp index bbc8deb..f28eedb 100644 --- a/src/core/SqlLexer.cpp +++ b/src/core/SqlLexer.cpp @@ -29,7 +29,8 @@ QChar SqlLexer::peekChar() * @param ofs * @param start * @param length - * @return false when input seems invalid, it will return what it did recognize but something wasn't right, parser should try to recover + * @return false when input seems invalid, it will return what it did recognize but something + * wasn't right, parser should try to recover */ bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokentype, QString &out) { @@ -117,6 +118,46 @@ bool SqlLexer::nextBasicToken(int &startpos, int &length, BasicTokenType &tokent else if (c == QChar::Null) { break; } + else if (c == '$') { + c = nextChar(); + if (c.isDigit()) { + for (;;) { + c = peekChar(); + if (c.isDigit()) + nextChar(); + else + break; + } + tokentype = BasicTokenType::Parameter; + length = m_pos - startpos; + QStringRef sr(&m_block, startpos, length); + out = sr.toString(); + return true; + } + else if (c.isLetter()) { + // is this a dollar quote? + while (true) { + c = nextChar(); + if (c == '$') { + // Found valid dollar quote + tokentype = BasicTokenType::DollarQuote; + length = m_pos - startpos; + QStringRef sr(&m_block, startpos, length); + out = sr.toString(); + return true; + } + else if (!c.isLetter()) { + // ERROR, unallowed character + tokentype = BasicTokenType::None; + length = m_pos - startpos; + QStringRef sr(&m_block, startpos, length); + out = sr.toString(); + return false; + } + } + } + + } else { // Undetermined symbol for (;;) { diff --git a/src/core/SqlLexer.h b/src/core/SqlLexer.h index c3e51f8..2ad3405 100644 --- a/src/core/SqlLexer.h +++ b/src/core/SqlLexer.h @@ -11,8 +11,9 @@ enum class BasicTokenType { BlockComment, OpenBlockComment, // Busy with a block comment end not detected before end of current input QuotedString, - DollarQuotedString, - QuotedIdentifier + DollarQuote, // Return the dollar quote tag, do not consume the entire string (potentially long) + QuotedIdentifier, + Parameter }; enum class LexerState { diff --git a/src/pglab/SqlSyntaxHighlighter.cpp b/src/pglab/SqlSyntaxHighlighter.cpp index 8367a80..451ce45 100644 --- a/src/pglab/SqlSyntaxHighlighter.cpp +++ b/src/pglab/SqlSyntaxHighlighter.cpp @@ -117,6 +117,9 @@ SqlSyntaxHighlighter::SqlSyntaxHighlighter(QTextDocument *parent) m_typeFormat.setForeground(QColor(32, 192, 32)); m_typeFormat.setFontWeight(QFont::Bold); + + m_parameterFormat.setForeground(QColor(192, 32, 32)); + m_parameterFormat.setFontWeight(QFont::Bold); } SqlSyntaxHighlighter::~SqlSyntaxHighlighter() @@ -144,7 +147,7 @@ void SqlSyntaxHighlighter::highlightBlock(const QString &text) switch (tokentype) { case BasicTokenType::None: case BasicTokenType::End: // End of input - case BasicTokenType::DollarQuotedString: + case BasicTokenType::DollarQuote: break; case BasicTokenType::Symbol: // can be many things, keyword, object name, operator, .. if (g_Keywords.count(s.toLower()) > 0) { @@ -166,6 +169,9 @@ void SqlSyntaxHighlighter::highlightBlock(const QString &text) case BasicTokenType::QuotedIdentifier: setFormat(startpos, length, m_quotedIdentifierFormat); break; + case BasicTokenType::Parameter: + setFormat(startpos, length, m_parameterFormat); + break; } } } diff --git a/src/pglab/SqlSyntaxHighlighter.h b/src/pglab/SqlSyntaxHighlighter.h index 877a8b8..e75fd2a 100644 --- a/src/pglab/SqlSyntaxHighlighter.h +++ b/src/pglab/SqlSyntaxHighlighter.h @@ -28,6 +28,7 @@ private: QTextCharFormat m_quotedStringFormat; QTextCharFormat m_typeFormat; QTextCharFormat m_quotedIdentifierFormat; + QTextCharFormat m_parameterFormat; t_SymbolSet m_typeNames; };