diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 21fc3461ec3..5475cf629f3 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -1735,7 +1735,7 @@ amd64_dtrace_disable_probe (struct gdbarch *gdbarch, CORE_ADDR addr)
 
 static void
 amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch,
-				   struct parser_state *pstate,
+				   struct expr_builder *builder,
 				   int narg)
 {
   struct stoken str;
@@ -1758,11 +1758,11 @@ amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch,
       int regno = arg_reg_map[narg];
       const char *regname = user_reg_map_regnum_to_name (gdbarch, regno);
 
-      write_exp_elt_opcode (pstate, OP_REGISTER);
+      write_exp_elt_opcode (builder, OP_REGISTER);
       str.ptr = regname;
       str.length = strlen (regname);
-      write_exp_string (pstate, str);
-      write_exp_elt_opcode (pstate, OP_REGISTER);
+      write_exp_string (builder, str);
+      write_exp_elt_opcode (builder, OP_REGISTER);
     }
   else
     {
@@ -1770,27 +1770,27 @@ amd64_dtrace_parse_probe_argument (struct gdbarch *gdbarch,
       const char *regname = user_reg_map_regnum_to_name (gdbarch, AMD64_RSP_REGNUM);
 
       /* Displacement.  */
-      write_exp_elt_opcode (pstate, OP_LONG);
-      write_exp_elt_type (pstate, builtin_type (gdbarch)->builtin_long);
-      write_exp_elt_longcst (pstate, narg - 6);
-      write_exp_elt_opcode (pstate, OP_LONG);
+      write_exp_elt_opcode (builder, OP_LONG);
+      write_exp_elt_type (builder, builtin_type (gdbarch)->builtin_long);
+      write_exp_elt_longcst (builder, narg - 6);
+      write_exp_elt_opcode (builder, OP_LONG);
 
       /* Register: SP.  */
-      write_exp_elt_opcode (pstate, OP_REGISTER);
+      write_exp_elt_opcode (builder, OP_REGISTER);
       str.ptr = regname;
       str.length = strlen (regname);
-      write_exp_string (pstate, str);
-      write_exp_elt_opcode (pstate, OP_REGISTER);
+      write_exp_string (builder, str);
+      write_exp_elt_opcode (builder, OP_REGISTER);
 
-      write_exp_elt_opcode (pstate, BINOP_ADD);
+      write_exp_elt_opcode (builder, BINOP_ADD);
 
       /* Cast to long. */
-      write_exp_elt_opcode (pstate, UNOP_CAST);
-      write_exp_elt_type (pstate,
+      write_exp_elt_opcode (builder, UNOP_CAST);
+      write_exp_elt_type (builder,
 			  lookup_pointer_type (builtin_type (gdbarch)->builtin_long));
-      write_exp_elt_opcode (pstate, UNOP_CAST);
+      write_exp_elt_opcode (builder, UNOP_CAST);
 
-      write_exp_elt_opcode (pstate, UNOP_IND);
+      write_exp_elt_opcode (builder, UNOP_IND);
     }
 }
 
diff --git a/gdb/dtrace-probe.c b/gdb/dtrace-probe.c
index f80db713813..bd5cddcf804 100644
--- a/gdb/dtrace-probe.c
+++ b/gdb/dtrace-probe.c
@@ -624,26 +624,25 @@ dtrace_probe::build_arg_exprs (struct gdbarch *gdbarch)
      value of the argument when executed at the PC of the probe.  */
   for (dtrace_probe_arg &arg : m_args)
     {
-      /* Initialize the expression buffer in the parser state.  The
-	 language does not matter, since we are using our own
-	 parser.  */
-      parser_state pstate (current_language, gdbarch);
+      /* Initialize the expression builder.  The language does not
+	 matter, since we are using our own parser.  */
+      expr_builder builder (current_language, gdbarch);
 
       /* The argument value, which is ABI dependent and casted to
 	 `long int'.  */
-      gdbarch_dtrace_parse_probe_argument (gdbarch, &pstate, argc);
+      gdbarch_dtrace_parse_probe_argument (gdbarch, &builder, argc);
 
       /* Casting to the expected type, but only if the type was
 	 recognized at probe load time.  Otherwise the argument will
 	 be evaluated as the long integer passed to the probe.  */
       if (arg.type != NULL)
 	{
-	  write_exp_elt_opcode (&pstate, UNOP_CAST);
-	  write_exp_elt_type (&pstate, arg.type);
-	  write_exp_elt_opcode (&pstate, UNOP_CAST);
+	  write_exp_elt_opcode (&builder, UNOP_CAST);
+	  write_exp_elt_type (&builder, arg.type);
+	  write_exp_elt_opcode (&builder, UNOP_CAST);
 	}
 
-      arg.expr = pstate.release ();
+      arg.expr = builder.release ();
       prefixify_expression (arg.expr.get ());
       ++argc;
     }
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 210defffea3..a0c169d74d4 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -4523,13 +4523,13 @@ gdbarch_dtrace_parse_probe_argument_p (struct gdbarch *gdbarch)
 }
 
 void
-gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, struct parser_state *pstate, int narg)
+gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, struct expr_builder *builder, int narg)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->dtrace_parse_probe_argument != NULL);
   if (gdbarch_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_dtrace_parse_probe_argument called\n");
-  gdbarch->dtrace_parse_probe_argument (gdbarch, pstate, narg);
+  gdbarch->dtrace_parse_probe_argument (gdbarch, builder, narg);
 }
 
 void
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 7e185241872..7ebd365a31e 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -60,7 +60,7 @@ struct syscall;
 struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
-struct parser_state;
+struct expr_builder;
 struct ravenscar_arch_ops;
 struct mem_range;
 struct syscalls_info;
@@ -1356,8 +1356,8 @@ extern void set_gdbarch_stap_parse_special_token (struct gdbarch *gdbarch, gdbar
 
 extern int gdbarch_dtrace_parse_probe_argument_p (struct gdbarch *gdbarch);
 
-typedef void (gdbarch_dtrace_parse_probe_argument_ftype) (struct gdbarch *gdbarch, struct parser_state *pstate, int narg);
-extern void gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, struct parser_state *pstate, int narg);
+typedef void (gdbarch_dtrace_parse_probe_argument_ftype) (struct gdbarch *gdbarch, struct expr_builder *builder, int narg);
+extern void gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, struct expr_builder *builder, int narg);
 extern void set_gdbarch_dtrace_parse_probe_argument (struct gdbarch *gdbarch, gdbarch_dtrace_parse_probe_argument_ftype *dtrace_parse_probe_argument);
 
 /* True if the given ADDR does not contain the instruction sequence
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 5e3e4346a4e..59493d8c215 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1034,7 +1034,7 @@ M;int;stap_parse_special_token;struct stap_parse_info *p;p
 
 # The expression to compute the NARTGth+1 argument to a DTrace USDT probe.
 # NARG must be >= 0.
-M;void;dtrace_parse_probe_argument;struct parser_state *pstate, int narg;pstate, narg
+M;void;dtrace_parse_probe_argument;struct expr_builder *builder, int narg;builder, narg
 
 # True if the given ADDR does not contain the instruction sequence
 # corresponding to a disabled DTrace is-enabled probe.
@@ -1305,7 +1305,7 @@ struct syscall;
 struct agent_expr;
 struct axs_value;
 struct stap_parse_info;
-struct parser_state;
+struct expr_builder;
 struct ravenscar_arch_ops;
 struct mem_range;
 struct syscalls_info;
diff --git a/gdb/parse.c b/gdb/parse.c
index e2d01e9dd97..c4c35176915 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -119,7 +119,7 @@ static expression_up parse_exp_in_context (const char **, CORE_ADDR,
 					   int, int *,
 					   innermost_block_tracker_types);
 
-static void increase_expout_size (struct parser_state *ps, size_t lenelt);
+static void increase_expout_size (struct expr_builder *ps, size_t lenelt);
 
 
 /* Documented at it's declaration.  */
@@ -165,7 +165,7 @@ end_arglist (void)
 
 /* See definition in parser-defs.h.  */
 
-parser_state::parser_state (const struct language_defn *lang,
+expr_builder::expr_builder (const struct language_defn *lang,
 			    struct gdbarch *gdbarch)
   : expout_size (10),
     expout (XNEWVAR (expression,
@@ -178,7 +178,7 @@ parser_state::parser_state (const struct language_defn *lang,
 }
 
 expression_up
-parser_state::release ()
+expr_builder::release ()
 {
   /* Record the actual number of expression elements, and then
      reallocate the expression memory so that we free up any
@@ -201,7 +201,7 @@ parser_state::release ()
    a register through here.  */
 
 static void
-write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
+write_exp_elt (struct expr_builder *ps, const union exp_element *expelt)
 {
   if (ps->expout_ptr >= ps->expout_size)
     {
@@ -214,7 +214,7 @@ write_exp_elt (struct parser_state *ps, const union exp_element *expelt)
 }
 
 void
-write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
+write_exp_elt_opcode (struct expr_builder *ps, enum exp_opcode expelt)
 {
   union exp_element tmp;
 
@@ -224,7 +224,7 @@ write_exp_elt_opcode (struct parser_state *ps, enum exp_opcode expelt)
 }
 
 void
-write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
+write_exp_elt_sym (struct expr_builder *ps, struct symbol *expelt)
 {
   union exp_element tmp;
 
@@ -234,7 +234,7 @@ write_exp_elt_sym (struct parser_state *ps, struct symbol *expelt)
 }
 
 void
-write_exp_elt_msym (struct parser_state *ps, minimal_symbol *expelt)
+write_exp_elt_msym (struct expr_builder *ps, minimal_symbol *expelt)
 {
   union exp_element tmp;
 
@@ -244,7 +244,7 @@ write_exp_elt_msym (struct parser_state *ps, minimal_symbol *expelt)
 }
 
 void
-write_exp_elt_block (struct parser_state *ps, const struct block *b)
+write_exp_elt_block (struct expr_builder *ps, const struct block *b)
 {
   union exp_element tmp;
 
@@ -254,7 +254,7 @@ write_exp_elt_block (struct parser_state *ps, const struct block *b)
 }
 
 void
-write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
+write_exp_elt_objfile (struct expr_builder *ps, struct objfile *objfile)
 {
   union exp_element tmp;
 
@@ -264,7 +264,7 @@ write_exp_elt_objfile (struct parser_state *ps, struct objfile *objfile)
 }
 
 void
-write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
+write_exp_elt_longcst (struct expr_builder *ps, LONGEST expelt)
 {
   union exp_element tmp;
 
@@ -274,7 +274,7 @@ write_exp_elt_longcst (struct parser_state *ps, LONGEST expelt)
 }
 
 void
-write_exp_elt_floatcst (struct parser_state *ps, const gdb_byte expelt[16])
+write_exp_elt_floatcst (struct expr_builder *ps, const gdb_byte expelt[16])
 {
   union exp_element tmp;
   int index;
@@ -286,7 +286,7 @@ write_exp_elt_floatcst (struct parser_state *ps, const gdb_byte expelt[16])
 }
 
 void
-write_exp_elt_type (struct parser_state *ps, struct type *expelt)
+write_exp_elt_type (struct expr_builder *ps, struct type *expelt)
 {
   union exp_element tmp;
 
@@ -296,7 +296,7 @@ write_exp_elt_type (struct parser_state *ps, struct type *expelt)
 }
 
 void
-write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
+write_exp_elt_intern (struct expr_builder *ps, struct internalvar *expelt)
 {
   union exp_element tmp;
 
@@ -327,7 +327,7 @@ write_exp_elt_intern (struct parser_state *ps, struct internalvar *expelt)
 
 
 void
-write_exp_string (struct parser_state *ps, struct stoken str)
+write_exp_string (struct expr_builder *ps, struct stoken str)
 {
   int len = str.length;
   size_t lenelt;
@@ -369,7 +369,7 @@ write_exp_string (struct parser_state *ps, struct stoken str)
    long constant, followed by the contents of the string.  */
 
 void
-write_exp_string_vector (struct parser_state *ps, int type,
+write_exp_string_vector (struct expr_builder *ps, int type,
 			 struct stoken_vector *vec)
 {
   int i, len;
@@ -422,7 +422,7 @@ write_exp_string_vector (struct parser_state *ps, int type,
    either end of the bitstring.  */
 
 void
-write_exp_bitstring (struct parser_state *ps, struct stoken str)
+write_exp_bitstring (struct expr_builder *ps, struct stoken str)
 {
   int bits = str.length;	/* length in bits */
   int len = (bits + HOST_CHAR_BIT - 1) / HOST_CHAR_BIT;
@@ -532,7 +532,7 @@ find_minsym_type_and_address (minimal_symbol *msymbol,
    the expression.  */
 
 void
-write_exp_msymbol (struct parser_state *ps,
+write_exp_msymbol (struct expr_builder *ps,
 		   struct bound_minimal_symbol bound_msym)
 {
   write_exp_elt_opcode (ps, OP_VAR_MSYM_VALUE);
@@ -545,7 +545,7 @@ write_exp_msymbol (struct parser_state *ps,
    expression.  This is used when completing on field names.  */
 
 void
-mark_struct_expression (struct parser_state *ps)
+mark_struct_expression (struct expr_builder *ps)
 {
   gdb_assert (parse_completion
 	      && expout_tag_completion_type == TYPE_CODE_UNDEF);
@@ -593,7 +593,7 @@ mark_completion_tag (enum type_code tag, const char *ptr, int length)
    value in the value history, I.e. $$1  */
 
 void
-write_dollar_variable (struct parser_state *ps, struct stoken str)
+write_dollar_variable (struct expr_builder *ps, struct stoken str)
 {
   struct block_symbol sym;
   struct bound_minimal_symbol msym;
@@ -1405,7 +1405,7 @@ push_type_int (int n)
    item.  */
 
 void
-insert_type_address_space (struct parser_state *pstate, char *string)
+insert_type_address_space (struct expr_builder *pstate, char *string)
 {
   union type_stack_elt element;
   int slot;
@@ -1829,7 +1829,7 @@ exp_uses_objfile (struct expression *exp, struct objfile *objfile)
    there is enough room for the elements.  */
 
 static void
-increase_expout_size (struct parser_state *ps, size_t lenelt)
+increase_expout_size (struct expr_builder *ps, size_t lenelt)
 {
   if ((ps->expout_ptr + lenelt) >= ps->expout_size)
     {
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index 8fcbca36bb1..5bc9d253d48 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -32,15 +32,17 @@ struct internalvar;
 
 extern int parser_debug;
 
-struct parser_state
+/* A class that can be used to build a "struct expression".  */
+
+struct expr_builder
 {
   /* Constructor.  LANG is the language used to parse the expression.
      And GDBARCH is the gdbarch to use during parsing.  */
 
-  parser_state (const struct language_defn *lang,
+  expr_builder (const struct language_defn *lang,
 		struct gdbarch *gdbarch);
 
-  DISABLE_COPY_AND_ASSIGN (parser_state);
+  DISABLE_COPY_AND_ASSIGN (expr_builder);
 
   /* Resize the allocated expression to the correct size, and return
      it as an expression_up -- passing ownership to the caller.  */
@@ -74,6 +76,24 @@ struct parser_state
   size_t expout_ptr;
 };
 
+/* An instance of this type is instantiated during expression parsing,
+   and passed to the appropriate parser.  It holds both inputs to the
+   parser, and result.  */
+
+struct parser_state : public expr_builder
+{
+  /* Constructor.  LANG is the language used to parse the expression.
+     And GDBARCH is the gdbarch to use during parsing.  */
+
+  parser_state (const struct language_defn *lang,
+		struct gdbarch *gdbarch)
+    : expr_builder (lang, gdbarch)
+  {
+  }
+
+  DISABLE_COPY_AND_ASSIGN (parser_state);
+};
+
 /* If this is nonzero, this block is used as the lexical context
    for symbol names.  */
 
@@ -236,36 +256,36 @@ struct type_stack
 
 extern int prefixify_expression (struct expression *expr);
 
-extern void write_exp_elt_opcode (struct parser_state *, enum exp_opcode);
+extern void write_exp_elt_opcode (struct expr_builder *, enum exp_opcode);
 
-extern void write_exp_elt_sym (struct parser_state *, struct symbol *);
+extern void write_exp_elt_sym (struct expr_builder *, struct symbol *);
 
-extern void write_exp_elt_longcst (struct parser_state *, LONGEST);
+extern void write_exp_elt_longcst (struct expr_builder *, LONGEST);
 
-extern void write_exp_elt_floatcst (struct parser_state *, const gdb_byte *);
+extern void write_exp_elt_floatcst (struct expr_builder *, const gdb_byte *);
 
-extern void write_exp_elt_type (struct parser_state *, struct type *);
+extern void write_exp_elt_type (struct expr_builder *, struct type *);
 
-extern void write_exp_elt_intern (struct parser_state *, struct internalvar *);
+extern void write_exp_elt_intern (struct expr_builder *, struct internalvar *);
 
-extern void write_exp_string (struct parser_state *, struct stoken);
+extern void write_exp_string (struct expr_builder *, struct stoken);
 
-void write_exp_string_vector (struct parser_state *, int type,
+void write_exp_string_vector (struct expr_builder *, int type,
 			      struct stoken_vector *vec);
 
-extern void write_exp_bitstring (struct parser_state *, struct stoken);
+extern void write_exp_bitstring (struct expr_builder *, struct stoken);
 
-extern void write_exp_elt_block (struct parser_state *, const struct block *);
+extern void write_exp_elt_block (struct expr_builder *, const struct block *);
 
-extern void write_exp_elt_objfile (struct parser_state *,
+extern void write_exp_elt_objfile (struct expr_builder *,
 				   struct objfile *objfile);
 
-extern void write_exp_msymbol (struct parser_state *,
+extern void write_exp_msymbol (struct expr_builder *,
 			       struct bound_minimal_symbol);
 
-extern void write_dollar_variable (struct parser_state *, struct stoken str);
+extern void write_dollar_variable (struct expr_builder *, struct stoken str);
 
-extern void mark_struct_expression (struct parser_state *);
+extern void mark_struct_expression (struct expr_builder *);
 
 extern const char *find_template_name_end (const char *);
 
@@ -281,7 +301,7 @@ extern void push_type (enum type_pieces);
 
 extern void push_type_int (int);
 
-extern void insert_type_address_space (struct parser_state *, char *);
+extern void insert_type_address_space (struct expr_builder *, char *);
 
 extern enum type_pieces pop_type (void);
 
diff --git a/gdb/stap-probe.h b/gdb/stap-probe.h
index 6c56904aeb3..d5199d9a245 100644
--- a/gdb/stap-probe.h
+++ b/gdb/stap-probe.h
@@ -20,7 +20,6 @@
 #if !defined (STAP_PROBE_H)
 #define STAP_PROBE_H 1
 
-/* For `struct parser_state'.  */
 #include "parser-defs.h"
 
 /* Structure which holds information about the parsing process of one probe's
@@ -46,7 +45,7 @@ struct stap_parse_info
   const char *arg;
 
   /* The parser state to be used when generating the expression.  */
-  struct parser_state pstate;
+  struct expr_builder pstate;
 
   /* A pointer to the full chain of arguments.  This is useful for printing
      error messages.  The parser functions should not modify this argument
