[gcc r16-5751] a68: parser: pragmats infrastructure

Jose E. Marchesi jemarch@gcc.gnu.org
Sun Nov 30 01:01:38 GMT 2025


https://gcc.gnu.org/g:1730426b8a5a0afca50f09157bbd97799a95e980

commit r16-5751-g1730426b8a5a0afca50f09157bbd97799a95e980
Author: Jose E. Marchesi <jose.marchesi@oracle.com>
Date:   Sat Nov 22 02:19:52 2025 +0100

    a68: parser: pragmats infrastructure
    
    This patch adds the infrastructure for adding handlers for pragmats,
    along with some intial support for the "access Module" pragmat.
    
    Signed-off-by: Jose E. Marchesi <jemarch@gnu.org>
    
    gcc/ChangeLog
    
            * algol68/a68-parser-pragmat.cc: New file.

Diff:
---
 gcc/algol68/a68-parser-pragmat.cc | 202 ++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)

diff --git a/gcc/algol68/a68-parser-pragmat.cc b/gcc/algol68/a68-parser-pragmat.cc
new file mode 100644
index 000000000000..2407eaa1b721
--- /dev/null
+++ b/gcc/algol68/a68-parser-pragmat.cc
@@ -0,0 +1,202 @@
+/* Handling of compiler pragmats.
+   Copyright (C) 2025 Jose E. Marchesi.
+
+   Written by 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"
+#include "system.h"
+#include "coretypes.h"
+
+#include "a68.h"
+
+/* Utility macros useful for parsing pragmat contents.  */
+
+#define SKIP_WHITESPACES(P)			\
+  while (ISSPACE (*(P))) (P)++
+
+#define PARSE_WORD(P,W)					\
+  do							\
+    {							\
+      (W) = (char *) alloca (strlen ((P)));		\
+      size_t i = 0;					\
+      while (ISALPHA (*(P)))				\
+	(W)[i++] = *((P)++);				\
+      (W)[i] = '\0';					\
+    } while (0)
+
+/* Parse a string denotation and return its value in an allocated buffer in
+   *STR.  It is up to the caller to dispose of the allocated memory.
+
+   This function returns a pointer to the character following the string
+   denotation in P, or P in case of parse error.
+
+   In case of parse error *STR is also set to NULL.  */
+
+const char *
+parse_string_denotation (const char *p, char **str)
+{
+  const char *orig = p;
+  size_t i = 0;
+  char *s = (char *) xmalloc (2 * strlen (p));
+
+  if (*(p++) != '\"')
+    goto error;
+  while (*p != '\0' && *p != '\"')
+    {
+      if (*p == '\'' && *(p + 1) == '\"')
+	{
+	  s[i++] = '\"';
+	  p += 2;
+	}
+      else
+	{
+	  s[i++] = *p;
+	  p++;
+	}
+    }
+  if (*p != '\"')
+    goto error;
+
+  *str = s;
+  return p + 1;
+ error:
+  free (s);
+  *str = NULL;
+  return orig;
+}
+
+/* PR access MODULE in "filename" PR  */
+
+const char *
+handle_access_in_pragmat (NODE_T *p, const char *pragmat, size_t pos)
+{
+  const char *beginning = pragmat;
+
+  SKIP_WHITESPACES (pragmat);
+  /* Parse module name.  */
+  char *module;
+  PARSE_WORD (pragmat, module);
+  if (*module == '\0')
+    {
+      a68_error (p, "invalid pragmat: expected module name after %<access%>");
+      return NULL;
+    }
+  SKIP_WHITESPACES (pragmat);
+  /* Parse "in " */
+  if (strncmp (pragmat, "in ", 3) != 0)
+    {
+      a68_error (p, "invalid pragmat: expected %<in%> after module name");
+      return NULL;
+    }
+  pragmat += 3;
+  SKIP_WHITESPACES (pragmat);
+  /* Parse a string denotation.  */
+  char *filename;
+  pragmat = parse_string_denotation (pragmat, &filename);
+  if (filename == NULL)
+    {
+      size_t off = pos + pragmat - beginning;
+      char *found;
+      PARSE_WORD (pragmat, found);
+      a68_error_in_pragmat (p, off,
+			    "in %<access%> pragmat, expected string, found Z",
+			    found);
+      return NULL;
+    }
+  /* Add entry in the module files map.  */
+  const char **pmodule = A68_MODULE_FILES->get (module);
+  if (pmodule != NULL)
+    {
+      a68_error_in_pragmat (p, pos + pragmat - beginning,
+			    "module Z cannot appear in multiple %<access%> pragmats",
+			    module);
+      return NULL;
+    }
+
+  SKIP_WHITESPACES (pragmat);
+  /* Skip closing PR or PRAGMAT.  */
+  if (NPRAGMAT_TYPE (p) == STYLE_I_PRAGMAT_SYMBOL)
+    pragmat += 2;
+  else
+    pragmat += 7;
+
+  A68_MODULE_FILES->put (ggc_strdup (module), ggc_strdup (filename));
+  free (filename);
+  return pragmat;
+}
+
+/* Parse and action on a pragmat.  */
+
+void
+handle_pragmat (NODE_T *p)
+{
+  const char *pragmat = NPRAGMAT (p);
+  if (pragmat != NULL
+      && (NPRAGMAT_TYPE (p) == STYLE_I_PRAGMAT_SYMBOL
+	  || NPRAGMAT_TYPE (p) == BOLD_PRAGMAT_SYMBOL))
+    {
+      /* Process pragmat commands.  */
+      do
+	{
+	  SKIP_WHITESPACES (pragmat);
+	  /* Skip PR or PRAGMAT.  */
+	  if (NPRAGMAT_TYPE (p) == STYLE_I_PRAGMAT_SYMBOL)
+	    pragmat += 2;
+	  else
+	    pragmat += 7;
+	  SKIP_WHITESPACES (pragmat);
+	  /* Get first word in pragmat and dispatch.  */
+	  SKIP_WHITESPACES (pragmat);
+	  char *word = (char *) alloca (strlen (pragmat));
+	  size_t i = 0;
+	  while (ISALPHA (*pragmat) || *pragmat == '\n')
+	    word[i++] = *(pragmat++);
+	  word[i] = '\0';
+
+	  if (strcmp (word, "access") == 0)
+	    {
+	      pragmat
+		= handle_access_in_pragmat (p, pragmat, pragmat - NPRAGMAT (p));
+	      if (pragmat == NULL)
+		break;
+	    }
+	  else if (strcmp (word, "include") == 0)
+	    /* Include pragmats are handled in the scanner.  */
+	    return;
+	  else
+	    {
+	      a68_error_in_pragmat (p, pragmat - NPRAGMAT (p),
+				    "unrecognized pragmat Z", word);
+	      break;
+	    }
+	}
+      while (*pragmat != '\0');
+    }
+}
+
+/* Entry point: handle all pragmats in the given parse tree.  */
+
+void
+a68_handle_pragmats (NODE_T *p)
+{
+  for (; p != NO_NODE; FORWARD (p))
+    {
+      a68_handle_pragmats (SUB (p));
+      handle_pragmat (p);
+    }
+}


More information about the Gcc-cvs mailing list