diff --git a/src/search/parser/abstract_syntax_tree.cc b/src/search/parser/abstract_syntax_tree.cc index 280174b645..49c1635a93 100644 --- a/src/search/parser/abstract_syntax_tree.cc +++ b/src/search/parser/abstract_syntax_tree.cc @@ -420,6 +420,8 @@ DecoratedASTNodePtr LiteralNode::decorate(DecorateContext &context) const { switch (value.type) { case TokenType::BOOLEAN: return utils::make_unique_ptr(value.content); + case TokenType::STRING: + return utils::make_unique_ptr(value.content); case TokenType::INTEGER: return utils::make_unique_ptr(value.content); case TokenType::FLOAT: @@ -441,6 +443,8 @@ const plugins::Type &LiteralNode::get_type(DecorateContext &context) const { switch (value.type) { case TokenType::BOOLEAN: return plugins::TypeRegistry::instance()->get_type(); + case TokenType::STRING: + return plugins::TypeRegistry::instance()->get_type(); case TokenType::INTEGER: return plugins::TypeRegistry::instance()->get_type(); case TokenType::FLOAT: diff --git a/src/search/parser/decorated_abstract_syntax_tree.cc b/src/search/parser/decorated_abstract_syntax_tree.cc index 3a401d9e7f..51576f20b8 100644 --- a/src/search/parser/decorated_abstract_syntax_tree.cc +++ b/src/search/parser/decorated_abstract_syntax_tree.cc @@ -218,6 +218,19 @@ void BoolLiteralNode::dump(string indent) const { cout << indent << "BOOL: " << value << endl; } +StringLiteralNode::StringLiteralNode(const string &value) + : value(value) { +} + +plugins::Any StringLiteralNode::construct(ConstructContext &context) const { + utils::TraceBlock block(context, "Constructing string value from '" + value + "'"); + return value; +} + +void StringLiteralNode::dump(string indent) const { + cout << indent << "STRING: " << value << endl; +} + IntLiteralNode::IntLiteralNode(const string &value) : value(value) { } @@ -473,6 +486,18 @@ shared_ptr BoolLiteralNode::clone_shared() const { return make_shared(*this); } +StringLiteralNode::StringLiteralNode(const StringLiteralNode &other) + : value(other.value) { +} + +unique_ptr StringLiteralNode::clone() const { + return utils::make_unique_ptr(*this); +} + +shared_ptr StringLiteralNode::clone_shared() const { + return make_shared(*this); +} + IntLiteralNode::IntLiteralNode(const IntLiteralNode &other) : value(other.value) { } diff --git a/src/search/parser/decorated_abstract_syntax_tree.h b/src/search/parser/decorated_abstract_syntax_tree.h index 0094f8874b..105f77bf13 100644 --- a/src/search/parser/decorated_abstract_syntax_tree.h +++ b/src/search/parser/decorated_abstract_syntax_tree.h @@ -157,6 +157,20 @@ class BoolLiteralNode : public DecoratedASTNode { BoolLiteralNode(const BoolLiteralNode &other); }; +class StringLiteralNode : public DecoratedASTNode { + std::string value; +public: + StringLiteralNode(const std::string &value); + + plugins::Any construct(ConstructContext &context) const override; + void dump(std::string indent) const override; + + // TODO: once we get rid of lazy construction, this should no longer be necessary. + virtual std::unique_ptr clone() const override; + virtual std::shared_ptr clone_shared() const override; + StringLiteralNode(const StringLiteralNode &other); +}; + class IntLiteralNode : public DecoratedASTNode { std::string value; public: diff --git a/src/search/parser/lexical_analyzer.cc b/src/search/parser/lexical_analyzer.cc index 9a37360809..94bd594cad 100644 --- a/src/search/parser/lexical_analyzer.cc +++ b/src/search/parser/lexical_analyzer.cc @@ -29,6 +29,8 @@ static vector> construct_token_type_expressions() { {TokenType::INTEGER, R"([+-]?(infinity|\d+([kmg]\b)?))"}, {TokenType::BOOLEAN, R"(true|false)"}, + // TODO: support quoted strings. + {TokenType::STRING, R"("([^"]*)\")"}, {TokenType::LET, R"(let)"}, {TokenType::IDENTIFIER, R"([a-zA-Z_]\w*)"} }; @@ -59,7 +61,13 @@ TokenStream split_tokens(const string &text) { TokenType token_type = type_and_expression.first; const regex &expression = type_and_expression.second; if (regex_search(start, end, match, expression, regex_constants::match_continuous)) { - tokens.push_back({utils::tolower(match[1]), token_type}); + string value; + if (token_type == TokenType::STRING) { + value = match[2]; + } else { + value = utils::tolower(match[1]); + } + tokens.push_back({value, token_type}); start += match[0].length(); has_match = true; break; diff --git a/src/search/parser/syntax_analyzer.cc b/src/search/parser/syntax_analyzer.cc index ffcafbfa4e..ae4b616d03 100644 --- a/src/search/parser/syntax_analyzer.cc +++ b/src/search/parser/syntax_analyzer.cc @@ -162,6 +162,7 @@ static unordered_set literal_tokens { TokenType::FLOAT, TokenType::INTEGER, TokenType::BOOLEAN, + TokenType::STRING, TokenType::IDENTIFIER }; @@ -193,7 +194,8 @@ static ASTNodePtr parse_list(TokenStream &tokens, SyntaxAnalyzerContext &context static vector PARSE_NODE_TOKEN_TYPES = { TokenType::LET, TokenType::IDENTIFIER, TokenType::BOOLEAN, - TokenType::INTEGER, TokenType::FLOAT, TokenType::OPENING_BRACKET}; + TokenType::STRING, TokenType::INTEGER, TokenType::FLOAT, + TokenType::OPENING_BRACKET}; static ASTNodePtr parse_node(TokenStream &tokens, SyntaxAnalyzerContext &context) { @@ -220,6 +222,7 @@ static ASTNodePtr parse_node(TokenStream &tokens, return parse_literal(tokens, context); } case TokenType::BOOLEAN: + case TokenType::STRING: case TokenType::INTEGER: case TokenType::FLOAT: return parse_literal(tokens, context); diff --git a/src/search/parser/token_stream.cc b/src/search/parser/token_stream.cc index c6d689cf1b..c8ff79f2ca 100644 --- a/src/search/parser/token_stream.cc +++ b/src/search/parser/token_stream.cc @@ -96,6 +96,8 @@ string token_type_name(TokenType token_type) { return "Float"; case TokenType::BOOLEAN: return "Boolean"; + case TokenType::STRING: + return "String"; case TokenType::IDENTIFIER: return "Identifier"; case TokenType::LET: diff --git a/src/search/parser/token_stream.h b/src/search/parser/token_stream.h index 832cdafc75..027946b2d7 100644 --- a/src/search/parser/token_stream.h +++ b/src/search/parser/token_stream.h @@ -19,6 +19,7 @@ enum class TokenType { INTEGER, FLOAT, BOOLEAN, + STRING, IDENTIFIER, LET }; diff --git a/src/search/plugins/types.cc b/src/search/plugins/types.cc index 117c139b53..c1ca2c372b 100644 --- a/src/search/plugins/types.cc +++ b/src/search/plugins/types.cc @@ -292,6 +292,7 @@ BasicType TypeRegistry::NO_TYPE = BasicType(typeid(void), ""); TypeRegistry::TypeRegistry() { insert_basic_type(); + insert_basic_type(); insert_basic_type(); insert_basic_type(); }