https://gcc.gnu.org/g:b95636bf3e0b5c3f5d37dd238d4cc2f4c765b40b
commit r16-5748-gb95636bf3e0b5c3f5d37dd238d4cc2f4c765b40b Author: Jose E. Marchesi <[email protected]> Date: Sat Oct 11 19:50:12 2025 +0200 a68: parser: debug facilities Signed-off-by: Jose E. Marchesi <[email protected]> gcc/ChangeLog * algol68/a68-parser-debug.cc: New file. Diff: --- gcc/algol68/a68-parser-debug.cc | 255 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) diff --git a/gcc/algol68/a68-parser-debug.cc b/gcc/algol68/a68-parser-debug.cc new file mode 100644 index 000000000000..28646b3f31ad --- /dev/null +++ b/gcc/algol68/a68-parser-debug.cc @@ -0,0 +1,255 @@ +/* Debug facilities for the Algol 68 parser. + Copyright (C) 2025 Jose E. Marchesi. + + GCC is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. + + GCC is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with GCC; see the file COPYING3. If not see + <http://www.gnu.org/licenses/>. */ + +#define INCLUDE_MEMORY +#include "config.h" +#define INCLUDE_VECTOR +#include "system.h" +#include "coretypes.h" +#include "tree.h" +#include "diagnostic.h" +#include "text-art/types.h" +#include "text-art/dump.h" +#include "text-art/dump-widget-info.h" +#include "text-art/canvas.h" +#include "text-art/theme.h" +#include "text-art/tree-widget.h" + +#include "a68.h" + +/* Write a printable representation of the parse tree with top node P to the + standard output. */ + +static void +a68_dump_parse_tree_1 (NODE_T *p, const text_art::dump_widget_info &dwi, + text_art::tree_widget &widget, bool tables, bool levels) +{ + for (; p != NO_NODE; FORWARD (p)) + { + char *symbol; + if (ATTRIBUTE (p) == IDENTIFIER + || ATTRIBUTE (p) == DEFINING_IDENTIFIER + || ATTRIBUTE (p) == DEFINING_OPERATOR + || ATTRIBUTE (p) == BOLD_TAG) + symbol = xasprintf (" %s", NSYMBOL (p)); + else + symbol = xstrdup (""); + + char *tableinfo; + if (tables && TABLE (p) != NO_TABLE) + tableinfo = xasprintf (" table=%p prev=%p", + (void *) TABLE (p), + (void *) PREVIOUS (TABLE (p))); + else + tableinfo = xstrdup (""); + + char *levelsinfo; + if (levels && TABLE (p) != NO_TABLE) + levelsinfo = xasprintf (" level=%d", LEVEL (TABLE (p))); + else + levelsinfo = xstrdup (""); + + char mode[BUFFER_SIZE]; + mode[0] = '\0'; + if (MOID (p) != NO_MOID) + { + MOID_T *moid = MOID (p); + mode[0] = '\0'; + + a68_bufcat (mode, " (", 2); + if (IS (moid, SERIES_MODE)) + { + if (PACK (moid) != NO_PACK && NEXT (PACK (moid)) == NO_PACK) + a68_bufcat (mode, a68_moid_to_string (MOID (PACK (moid)), MOID_ERROR_WIDTH, p), + BUFFER_SIZE); + else + a68_bufcat (mode, a68_moid_to_string (moid, MOID_ERROR_WIDTH, p), BUFFER_SIZE); + } + else + a68_bufcat (mode, a68_moid_to_string (moid, MOID_ERROR_WIDTH, p), BUFFER_SIZE); + a68_bufcat (mode, ")", 2); + } + + location_t loc = a68_get_node_location (p); + std::unique_ptr<text_art::tree_widget> cwidget + = text_art::tree_widget::from_fmt (dwi, nullptr, + "%s:%d:%d [%d] %s%s%s%s%s", + LOCATION_FILE (loc), + LOCATION_LINE (loc), + LOCATION_COLUMN (loc), + NUMBER (p), + a68_attribute_name (ATTRIBUTE (p)), + symbol, + mode, + tableinfo, + levelsinfo); + free (symbol); + free (tableinfo); + free (levelsinfo); + + a68_dump_parse_tree_1 (SUB (p), dwi, *cwidget, tables, levels); + widget.add_child (std::move (cwidget)); + } +} + +void +a68_dump_parse_tree (NODE_T *p, bool tables, bool levels) +{ + text_art::style_manager sm; + text_art::style::id_t default_style_id (sm.get_or_create_id (text_art::style ())); + text_art::ascii_theme theme; + text_art::dump_widget_info dwi (sm, theme, default_style_id); + std::unique_ptr<text_art::tree_widget> widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "Parse Tree"); + + a68_dump_parse_tree_1 (p, dwi, *widget, tables, levels); + + text_art::canvas c (widget->to_canvas (sm)); + pretty_printer *const pp = global_dc->get_reference_printer (); + pp_clear_output_area (pp); + c.print_to_pp (pp); + printf ("%s", pp_formatted_text (pp)); +} + +/* Dump the modes in the list MOID. */ + +void +a68_dump_modes (MOID_T *moid) +{ + for (; moid != NO_MOID; FORWARD (moid)) + { + printf ("%p %s\n", (void *) moid, + a68_moid_to_string (moid, MOID_ERROR_WIDTH, NODE (moid), + true /* indicant_value */)); + } +} + +/* Dump a given MOIF. */ + +void +a68_dump_moif (MOIF_T *moif) +{ + text_art::style_manager sm; + text_art::style::id_t default_style_id (sm.get_or_create_id (text_art::style ())); + text_art::ascii_theme theme; + text_art::dump_widget_info dwi (sm, theme, default_style_id); + std::unique_ptr<text_art::tree_widget> widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "module interface: %s", NAME (moif)); + + std::unique_ptr<text_art::tree_widget> prelude_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "prelude: %s", PRELUDE (moif)); + widget->add_child (std::move (prelude_widget)); + + std::unique_ptr<text_art::tree_widget> postlude_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "postlude: %s", POSTLUDE (moif)); + widget->add_child (std::move (postlude_widget)); + + /* Mode table. */ + std::unique_ptr<text_art::tree_widget> modes_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "modes"); + for (MOID_T *mode : MODES (moif)) + { + const char *asm_label = ASM_LABEL (mode); + if (asm_label == NULL) + asm_label = a68_moid_to_string (mode, 80, NO_NODE, false); + std::unique_ptr<text_art::tree_widget> mode_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "mode: %s: %s", + asm_label, + a68_moid_to_string (mode, 80, NO_NODE, true)); + modes_widget->add_child (std::move (mode_widget)); + } + widget->add_child (std::move (modes_widget)); + + /* Module extracts. */ + std::unique_ptr<text_art::tree_widget> mod_extracts_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "module extracts"); + for (EXTRACT_T *e : MODULES (moif)) + { + std::unique_ptr<text_art::tree_widget> mod_extract_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "module extract: %s", EXTRACT_SYMBOL (e)); + mod_extracts_widget->add_child (std::move (mod_extract_widget)); + } + widget->add_child (std::move (mod_extracts_widget)); + + /* Mode extracts. */ + std::unique_ptr<text_art::tree_widget> mode_extracts_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "mode extracts"); + for (EXTRACT_T *e : INDICANTS (moif)) + { + const char *asm_label = ASM_LABEL (EXTRACT_MODE (e)); + if (asm_label == NULL) + asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false); + std::unique_ptr<text_art::tree_widget> mode_extract_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "mode extract: %s [%s]", + EXTRACT_SYMBOL (e), asm_label); + mode_extracts_widget->add_child (std::move (mode_extract_widget)); + } + widget->add_child (std::move (mode_extracts_widget)); + + /* Priority extracts. */ + std::unique_ptr<text_art::tree_widget> prio_extracts_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "prio extracts"); + for (EXTRACT_T *e : PRIOS (moif)) + { + std::unique_ptr<text_art::tree_widget> prio_extract_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "prio extract: %s [prio: %d]", + EXTRACT_SYMBOL (e), EXTRACT_PRIO (e)); + prio_extracts_widget->add_child (std::move (prio_extract_widget)); + } + widget->add_child (std::move (prio_extracts_widget)); + + /* Identifier extracts. */ + std::unique_ptr<text_art::tree_widget> id_extracts_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "identifier extracts"); + for (EXTRACT_T *e : IDENTIFIERS (moif)) + { + const char *asm_label = ASM_LABEL (EXTRACT_MODE (e)); + if (asm_label == NULL) + asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false); + std::unique_ptr<text_art::tree_widget> id_extract_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "iden extract: %s [%s] variable=%d inproc=%d", + EXTRACT_SYMBOL (e), asm_label, + EXTRACT_VARIABLE (e), + EXTRACT_IN_PROC (e)); + id_extracts_widget->add_child (std::move (id_extract_widget)); + } + widget->add_child (std::move (id_extracts_widget)); + + /* Operator extracts. */ + std::unique_ptr<text_art::tree_widget> op_extracts_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "operator extracts"); + for (EXTRACT_T *e : OPERATORS (moif)) + { + const char *asm_label = ASM_LABEL (EXTRACT_MODE (e)); + if (asm_label == NULL) + asm_label = a68_moid_to_string (EXTRACT_MODE (e), 80, NO_NODE, false); + + std::unique_ptr<text_art::tree_widget> op_extract_widget + = text_art::tree_widget::from_fmt (dwi, nullptr, "op extract: %s [%s] variable=%d inproc=%d", + EXTRACT_SYMBOL (e), asm_label, + EXTRACT_VARIABLE (e), + EXTRACT_IN_PROC (e)); + op_extracts_widget->add_child (std::move (op_extract_widget)); + } + widget->add_child (std::move (op_extracts_widget)); + + text_art::canvas c (widget->to_canvas (sm)); + pretty_printer *const pp = global_dc->get_reference_printer (); + pp_clear_output_area (pp); + c.print_to_pp (pp); + printf ("%s", pp_formatted_text (pp)); +}
