From 94843c8a8facdc621058b00100129331da67e66a Mon Sep 17 00:00:00 2001 From: slavek-kucera <53339291+slavek-kucera@users.noreply.github.com> Date: Wed, 18 Aug 2021 13:08:34 +0200 Subject: [PATCH] fix: Apostrophe parsing in model statements (fixes eclipse/che-che4z-lsp-for-hlasm#163) (#164) --- .../parsing/grammar/model_operand_rules.g4 | 8 +-- .../test/parsing/parser_model_test.cpp | 52 ++++++++++++++++--- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/parser_library/src/parsing/grammar/model_operand_rules.g4 b/parser_library/src/parsing/grammar/model_operand_rules.g4 index 7d9ea711a..4823a0504 100644 --- a/parser_library/src/parsing/grammar/model_operand_rules.g4 +++ b/parser_library/src/parsing/grammar/model_operand_rules.g4 @@ -143,12 +143,12 @@ string_v_actual returns [concat_chain chain] }; model_string_v returns [concat_chain chain] - : ap1=(APOSTROPHE|ATTR) string_ch_v_c ap2=(APOSTROPHE|ATTR) + : ap1=(APOSTROPHE|ATTR) model_string_ch_v_c ap2=(APOSTROPHE|ATTR) { $chain.push_back(std::make_unique("'", provider.get_range($ap1))); - $chain.insert($chain.end(), - std::make_move_iterator($string_ch_v_c.chain.begin()), - std::make_move_iterator($string_ch_v_c.chain.end()) + $chain.insert($chain.end(), + std::make_move_iterator($model_string_ch_v_c.chain.begin()), + std::make_move_iterator($model_string_ch_v_c.chain.end()) ); $chain.push_back(std::make_unique("'", provider.get_range($ap2))); collector.add_hl_symbol(token_info(provider.get_range($ap1,$ap2),hl_scopes::string)); diff --git a/parser_library/test/parsing/parser_model_test.cpp b/parser_library/test/parsing/parser_model_test.cpp index d6854011e..1fab167bd 100644 --- a/parser_library/test/parsing/parser_model_test.cpp +++ b/parser_library/test/parsing/parser_model_test.cpp @@ -12,6 +12,8 @@ * Broadcom, Inc. - initial API and implementation */ +#include + #include "gtest/gtest.h" #include "../common_testing.h" @@ -24,15 +26,17 @@ auto parse_model(std::string s, range r, bool after_substitution = false, diagnostic_op_consumer* diag_consumer = nullptr, - processing_form form = processing_form::MACH) + processing_form form = processing_form::MACH, + hlasm_context* context = nullptr) { - hlasm_context context; + hlasm_context fallback_context; diagnostic_op_consumer_container fallback_container; - return statement_fields_parser(&context).parse_operand_field(std::move(s), - after_substitution, - range_provider(r, adjusting_state::NONE), - std::make_pair(processing_format(processing_kind::ORDINARY, form), op_code()), - diag_consumer ? *diag_consumer : fallback_container); + return statement_fields_parser(context ? context : &fallback_context) + .parse_operand_field(std::move(s), + after_substitution, + range_provider(r, adjusting_state::NONE), + std::make_pair(processing_format(processing_kind::ORDINARY, form), op_code()), + diag_consumer ? *diag_consumer : fallback_container); } TEST(parser, parse_model) @@ -202,3 +206,37 @@ TEST(parser, invalid_macro_param_alternative) range expected_range = { { 1, 16 }, { 1, 16 } }; EXPECT_EQ(diags[0].diag_range, expected_range); } + +TEST(parser, parse_single_apostrophe_string) +{ + diagnostic_op_consumer_container diag_container; + hlasm_context context; + + range r(position(0, 10), position(0, 20)); + auto [op, rem] = parse_model("&VAR,C''''", r, false, &diag_container, processing::processing_form::MACH, &context); + + EXPECT_TRUE(diag_container.diags.empty()); + + ASSERT_EQ(op.value.size(), 1); + auto* model = op.value[0]->access_model(); + ASSERT_TRUE(model); + auto cc = concatenation_point::to_string(model->chain); + EXPECT_EQ(std::count(cc.begin(), cc.end(), '\''), 4); +} + +TEST(parser, parse_single_apostrophe_literal) +{ + diagnostic_op_consumer_container diag_container; + hlasm_context context; + + range r(position(0, 10), position(0, 21)); + auto [op, rem] = parse_model("&VAR,=C''''", r, false, &diag_container, processing::processing_form::MACH, &context); + + EXPECT_TRUE(diag_container.diags.empty()); + + ASSERT_EQ(op.value.size(), 1); + auto* model = op.value[0]->access_model(); + ASSERT_TRUE(model); + auto cc = concatenation_point::to_string(model->chain); + EXPECT_EQ(std::count(cc.begin(), cc.end(), '\''), 4); +}