From 7ebe351ef60aff0ebd99cb6444d6c23b55100fe5 Mon Sep 17 00:00:00 2001 From: Ivan Koryabkin Date: Thu, 3 Oct 2019 17:46:11 +0300 Subject: [PATCH] Fixed invalid pattern arguments detection --- .../src/main/lspl/patterns/PatternBuilder.cpp | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/core/src/main/lspl/patterns/PatternBuilder.cpp b/core/src/main/lspl/patterns/PatternBuilder.cpp index 84dc8ff6..9c960dd5 100644 --- a/core/src/main/lspl/patterns/PatternBuilder.cpp +++ b/core/src/main/lspl/patterns/PatternBuilder.cpp @@ -64,6 +64,15 @@ class ParserImpl: public PatternBuilder::Parser { return buffer[pos] == '\0'; } + /** + * Проверка на наличие конца строки / ввода + */ + bool seekEndOfLine() { + while (buffer[pos] == ' ') + ++pos; + return buffer[pos] == '\0' || buffer[pos] == '\n' || buffer[pos] == '\r'; + } + /** * Создаёт экземпляр исключения с заданным сообщением об ошибке, хранящий * информацию о текущей позиции парсера и входных данных @@ -331,13 +340,20 @@ class ParserImpl: public PatternBuilder::Parser { pos = before_pos; return nullptr; } - if (canBeBinding && alts.size() == 1) { + readStrFollows(rbrace); + + // Потенциально вложенный сопоставитель все ещё может быть параметром шаблона, если + // параметр всего один. В таком случае нужно проверить, что + // 1. внутри скобок есть только один параметр; + // 2. этот параметр не является составным; + // 3. после параметра ничего нет (кроме, возможно, шаблона извлечения). + if (canBeBinding && alts.size() == 1 && alts[0].size() == 1 + && dynamic_cast(alts[0][0].get()) == nullptr + && (seekEndOfLine() || strFollows("="))) { pos = before_pos; return nullptr; } - readStrFollows(rbrace); - if (allow && strFollows("<") && !strFollows("<<")) { readStrFollows("<"); min = readUInt();