Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Syntax errors reported in bilingual macros #152

1 change: 1 addition & 0 deletions parser_library/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ target_sources(parser_library PRIVATE
analyzing_context.h
compiler_options.h
diagnosable.h
diagnosable_ctx.cpp
diagnosable_ctx.h
diagnosable_impl.h
diagnostic.cpp
Expand Down
2 changes: 1 addition & 1 deletion parser_library/src/checking/diagnostic_collector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void diagnostic_collector::operator()(diagnostic_op diagnostic) const
{
if (!diagnoser_)
return;
diagnoser_->add_diagnostic_inner(std::move(diagnostic), get_location_stack());
diagnoser_->diagnosable_impl::add_diagnostic(add_stack_details(std::move(diagnostic), get_location_stack()));
}

context::processing_stack_t diagnostic_collector::get_location_stack() const
Expand Down
10 changes: 9 additions & 1 deletion parser_library/src/context/hlasm_statement.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,19 @@
#define CONTEXT_HLASM_STATEMENT_H

#include <memory>
#include <utility>
#include <vector>

#include "range.h"

namespace hlasm_plugin::parser_library {
struct diagnostic_op;
} // namespace hlasm_plugin::parser_library
namespace hlasm_plugin::parser_library::semantics {
struct deferred_statement;
} // namespace hlasm_plugin::parser_library::semantics
namespace hlasm_plugin::parser_library::processing {
class error_statement;
struct resolved_statement;
} // namespace hlasm_plugin::parser_library::processing

Expand All @@ -38,7 +43,8 @@ using statement_block = std::vector<shared_stmt_ptr>;
enum class statement_kind
{
RESOLVED,
DEFERRED
DEFERRED,
ERROR,
};

// abstract structure representing general HLASM statement
Expand All @@ -54,6 +60,8 @@ struct hlasm_statement

virtual position statement_position() const = 0;

virtual std::pair<const diagnostic_op*, const diagnostic_op*> diagnostics() const = 0;

virtual ~hlasm_statement() = default;

protected:
Expand Down
9 changes: 7 additions & 2 deletions parser_library/src/debugging/debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,16 @@ class debugger::impl final : public processing::statement_analyzer
// lookahead and copy/macro definitions)
if (proc_kind != processing::processing_kind::ORDINARY)
return;

const auto* resolved_stmt = statement.access_resolved();
if (!resolved_stmt)
return;

// Continue only for non-empty statements
if (statement.access_resolved()->opcode_ref().value == context::id_storage::empty_id)
if (resolved_stmt->opcode_ref().value == context::id_storage::empty_id)
return;

range stmt_range = statement.access_resolved()->stmt_range_ref();
range stmt_range = resolved_stmt->stmt_range_ref();

bool breakpoint_hit = false;

Expand Down
49 changes: 49 additions & 0 deletions parser_library/src/diagnosable_ctx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2021 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*/

#include "diagnosable_ctx.h"

namespace hlasm_plugin::parser_library {

void diagnosable_ctx::add_diagnostic(diagnostic_s diagnostic) const
{
diagnosable_impl::add_diagnostic(add_stack_details(
diagnostic_op(
diagnostic.severity, std::move(diagnostic.code), std::move(diagnostic.message), diagnostic.diag_range),
ctx_.processing_stack()));
}

void diagnosable_ctx::add_diagnostic(diagnostic_op diagnostic) const
{
diagnosable_impl::add_diagnostic(add_stack_details(std::move(diagnostic), ctx_.processing_stack()));
}

diagnostic_s add_stack_details(diagnostic_op diagnostic, context::processing_stack_t stack)
{
diagnostic_s diag(std::move(stack.back().proc_location.file), std::move(diagnostic));

diag.related.reserve(stack.size() - 1);
for (auto frame = ++stack.rbegin(); frame != stack.rend(); ++frame)
{
auto& file_name = frame->proc_location.file;
auto message = "While compiling " + file_name + '(' + std::to_string(frame->proc_location.pos.line + 1) + ")";
diag.related.emplace_back(
range_uri_s(std::move(file_name), range(frame->proc_location.pos, frame->proc_location.pos)),
std::move(message));
}

return diag;
}

} // namespace hlasm_plugin::parser_library
34 changes: 5 additions & 29 deletions parser_library/src/diagnosable_ctx.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,45 +28,21 @@ class diagnosable_ctx : public diagnosable_impl, public diagnostic_op_consumer
context::hlasm_context& ctx_;

public:
void add_diagnostic(diagnostic_s diagnostic) const override
{
add_diagnostic_inner(
diagnostic_op(
diagnostic.severity, std::move(diagnostic.code), std::move(diagnostic.message), diagnostic.diag_range),
ctx_.processing_stack());
}

void add_diagnostic(diagnostic_op diagnostic) const override
{
add_diagnostic_inner(std::move(diagnostic), ctx_.processing_stack());
}
void add_diagnostic(diagnostic_s diagnostic) const override;
void add_diagnostic(diagnostic_op diagnostic) const override;

protected:
diagnosable_ctx(context::hlasm_context& ctx)
: ctx_(ctx)
{}

virtual ~diagnosable_ctx() {};

private:
void add_diagnostic_inner(diagnostic_op diagnostic, const context::processing_stack_t& stack) const
{
diagnostic_s diag(stack.back().proc_location.file, diagnostic);

for (auto frame = ++stack.rbegin(); frame != stack.rend(); ++frame)
{
auto& file_name = frame->proc_location.file;
range r = range(frame->proc_location.pos, frame->proc_location.pos);
diagnostic_related_info_s s = diagnostic_related_info_s(range_uri_s(file_name, r),
"While compiling " + file_name + '(' + std::to_string(frame->proc_location.pos.line + 1) + ")");
diag.related.push_back(std::move(s));
}
diagnosable_impl::add_diagnostic(std::move(diag));
}
virtual ~diagnosable_ctx() = default;

friend diagnostic_collector;
};

diagnostic_s add_stack_details(diagnostic_op diagnostic, context::processing_stack_t stack);

} // namespace hlasm_plugin::parser_library


Expand Down
39 changes: 22 additions & 17 deletions parser_library/src/diagnostic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1676,6 +1676,26 @@ diagnostic_op diagnostic_op::error_E043(const range& range)
return diagnostic_op(diagnostic_severity::error, "E043", "Invalid name of variable in macro prototype", range);
}

diagnostic_op diagnostic_op::error_E044(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E044", "Illegal name field in macro prototype, discarded", range);
}

diagnostic_op diagnostic_op::error_E045(const std::string& message, const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E045", "Sequence symbol already defined - " + message, range);
}

diagnostic_op diagnostic_op::error_E046(const std::string& message, const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E046", "Missing MEND in " + message, range);
}

diagnostic_op diagnostic_op::error_E047(const std::string& message, const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E047", "Lookahead failed, symbol not found - " + message, range);
}

diagnostic_op diagnostic_op::error_E048(const std::string& message, const range& range)
{
return diagnostic_op(
Expand Down Expand Up @@ -1798,24 +1818,9 @@ diagnostic_op diagnostic_op::error_E070(const range& range)
diagnostic_severity::error, "E070", "Invalid AREAD operand. Use AREAD [NOSTMT|NOPRINT|CLOCKB|CLOCKD].", range);
}

diagnostic_op diagnostic_op::error_E044(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E044", "Illegal name field in macro prototype, discarded", range);
}

diagnostic_op diagnostic_op::error_E045(const std::string& message, const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E045", "Sequence symbol already defined - " + message, range);
}

diagnostic_op diagnostic_op::error_E046(const std::string& message, const range& range)
diagnostic_op diagnostic_op::error_E071(const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E046", "Missing MEND in " + message, range);
}

diagnostic_op diagnostic_op::error_E047(const std::string& message, const range& range)
{
return diagnostic_op(diagnostic_severity::error, "E047", "Lookahead failed, symbol not found - " + message, range);
return diagnostic_op(diagnostic_severity::error, "E071", "Macro prototype expected.", range);
}

diagnostic_op diagnostic_op::warning_W010(const std::string& message, const range& range)
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/diagnostic.h
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ struct diagnostic_op

static diagnostic_op error_E070(const range& range);

static diagnostic_op error_E071(const range& range);

static diagnostic_op warning_W010(const std::string& message, const range& range);

static diagnostic_op warning_W011(const range& range);
Expand Down
4 changes: 2 additions & 2 deletions parser_library/src/parsing/parser_impl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,14 +149,14 @@ void parser_impl::resolve_expression(expressions::ca_expr_ptr& expr) const
else if (opcode.value == hlasm_ctx->ids().well_known.SETB)
{
if (!expr->is_compatible(ca_expression_compatibility::setb))
expr->diags().push_back(diagnostic_op::error_CE016_logical_expression_parenthesis(expr->expr_range));
expr->add_diagnostic(diagnostic_op::error_CE016_logical_expression_parenthesis(expr->expr_range));

resolve_expression(expr, context::SET_t_enum::B_TYPE);
}
else if (opcode.value == hlasm_ctx->ids().well_known.AIF)
{
if (!expr->is_compatible(ca_expression_compatibility::aif))
expr->diags().push_back(diagnostic_op::error_CE016_logical_expression_parenthesis(expr->expr_range));
expr->add_diagnostic(diagnostic_op::error_CE016_logical_expression_parenthesis(expr->expr_range));

resolve_expression(expr, context::SET_t_enum::B_TYPE);
}
Expand Down
6 changes: 6 additions & 0 deletions parser_library/src/parsing/parser_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class parser_impl : public antlr4::Parser
processing::processing_status proc_stat,
diagnostic_op_consumer* diagnoser);

void set_diagnoser(diagnostic_op_consumer* diagnoser)
{
diagnoser_ = diagnoser;
err_listener_.diagnoser = diagnoser;
}

semantics::collector& get_collector() { return collector; }

protected:
Expand Down
2 changes: 2 additions & 0 deletions parser_library/src/processing/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ target_sources(parser_library PRIVATE
context_manager.cpp
context_manager.h
db2_preprocessor.cpp
error_statement.cpp
error_statement.h
op_code.h
opencode_provider.cpp
opencode_provider.h
Expand Down
28 changes: 28 additions & 0 deletions parser_library/src/processing/error_statement.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright (c) 2021 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*/

#include "error_statement.h"


namespace hlasm_plugin::parser_library::processing {


position error_statement::statement_position() const { return m_range.start; }

std::pair<const diagnostic_op*, const diagnostic_op*> error_statement::diagnostics() const
{
return { m_errors.data(), m_errors.data() + m_errors.size() };
}

} // namespace hlasm_plugin::parser_library::processing
42 changes: 42 additions & 0 deletions parser_library/src/processing/error_statement.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2021 Broadcom.
* The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Broadcom, Inc. - initial API and implementation
*/

#ifndef HLASMPARSER_PARSERLIBRARY_PROCESSING_ERROR_STATEMENT_H
#define HLASMPARSER_PARSERLIBRARY_PROCESSING_ERROR_STATEMENT_H

#include "context/hlasm_statement.h"
#include "diagnostic.h"

namespace hlasm_plugin::parser_library::processing {

class error_statement : public context::hlasm_statement
{
std::vector<diagnostic_op> m_errors;
range m_range;

public:
error_statement(range r, std::vector<diagnostic_op>&& diags)
: hlasm_statement(context::statement_kind::ERROR)
, m_errors(std::make_move_iterator(diags.begin()), std::make_move_iterator(diags.end()))
, m_range(r)
{}

position statement_position() const override;

std::pair<const diagnostic_op*, const diagnostic_op*> diagnostics() const override;
};

} // namespace hlasm_plugin::parser_library::processing

#endif // HLASMPARSER_PARSERLIBRARY_PROCESSING_ERROR_STATEMENT_H
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ asm_processor::asm_processor(analyzing_context ctx,
, open_code_(&open_code)
{}

void asm_processor::process(context::shared_stmt_ptr stmt)
void asm_processor::process(std::shared_ptr<const processing::resolved_statement> stmt)
{
auto rebuilt_stmt = preprocess(stmt);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class asm_processor : public low_language_processor
statement_fields_parser& parser,
opencode_provider& open_code);

void process(context::shared_stmt_ptr stmt) override;
void process(std::shared_ptr<const processing::resolved_statement> stmt) override;

static bool process_copy(const semantics::complete_statement& stmt,
analyzing_context ctx,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,10 @@ ca_processor::ca_processor(analyzing_context ctx,
, open_code_(&open_code)
{}

void ca_processor::process(context::shared_stmt_ptr stmt)
void ca_processor::process(std::shared_ptr<const processing::resolved_statement> stmt)
{
auto res = stmt->access_resolved();
auto& func = table_.at(res->opcode_ref().value);
func(*res);
auto& func = table_.at(stmt->opcode_ref().value);
func(*stmt);
}

ca_processor::process_table_t ca_processor::create_table(context::hlasm_context& h_ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class ca_processor : public instruction_processor
processing_state_listener& listener,
opencode_provider& open_code);

void process(context::shared_stmt_ptr stmt) override;
void process(std::shared_ptr<const processing::resolved_statement> stmt) override;

private:
opencode_provider* open_code_;
Expand Down
Loading