Skip to content

Commit

Permalink
fix: Apostrophe parsing in model statements (fixes #163) (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
slavek-kucera authored Aug 18, 2021
1 parent d8545fe commit 94843c8
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 11 deletions.
8 changes: 4 additions & 4 deletions parser_library/src/parsing/grammar/model_operand_rules.g4
Original file line number Diff line number Diff line change
Expand Up @@ -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<char_str_conc>("'", 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<char_str_conc>("'", provider.get_range($ap2)));
collector.add_hl_symbol(token_info(provider.get_range($ap1,$ap2),hl_scopes::string));
Expand Down
52 changes: 45 additions & 7 deletions parser_library/test/parsing/parser_model_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
* Broadcom, Inc. - initial API and implementation
*/

#include <numeric>

#include "gtest/gtest.h"

#include "../common_testing.h"
Expand All @@ -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)
Expand Down Expand Up @@ -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);
}

0 comments on commit 94843c8

Please sign in to comment.