\newcommand for bmatrix of features using pgffor throws missing \endgroup error

Enrico Gregorio has already explained the reason in his comment: \foreach puts the body of its loop in a group. That conflicts with the cell grouping of the matrix environment. Another problem, if there is something after the line end that is not expandable (end of group, \relax, ...), then a new (empty) line is created.

The following uses the loop to define \MatrixBody that contains the lines of the matrix. The chain of \expandafter expands \entry once. Otherwise the macro \MatrixBody would contain \entry in each matrix line, undefined after the loop.

Global assignments are only used because of \g@addto@macro from LaTeX's kernel that allows to add stuff to a macro. (Local variants are defined by packages, such as ltxcmds).

\documentclass{article}

\usepackage{pgffor}
\usepackage{amsmath}

\makeatletter
\newcommand*{\Features}[1]{%
  \global\let\MatrixBody\@empty
  \foreach \entry in {#1} {%
    \expandafter\g@addto@macro\expandafter\MatrixBody
    \expandafter{%
      \expandafter\text\expandafter{\entry}\\%
    }%
  }%
  \(%
    \begin{bmatrix}%
      \MatrixBody
    \end{bmatrix}%
  \)%
}
\makeatother

\begin{document}

\Features{--ACC, +PL}

\end{document}

Result


The problem is that \foreach executes each cycle in a group. So in your case you're basically doing

\(
\begin{bmatrix}
\begingroup\text{--ACC}\\\endgroup
\begingroup\text{+PL}\\\endgroup
\end{bmatrix}
\)

which indeed stops with

! Missing \endgroup inserted.
<inserted text> 
                \endgroup 

You have to build the contents of the matrix beforehand. Also using a cycle process that doesn't group is a lost battle anyway, because also table cells are evaluated in a group and \\ ends it.

Here's an expl3 based macro.

\documentclass{article}

\usepackage{amsmath}
\usepackage{xparse}

\ExplSyntaxOn
% the user level command
\NewDocumentCommand{\Features}{ m }
 {
  \adam_features:n { #1 }
 }
% a variable
\seq_new:N \l_adam_items_seq
% the programmer level function
\cs_new_protected:Npn \adam_features:n #1
 {
  % clear the sequence
  \seq_clear:N \l_adam_items_seq
  % do a mapping on the comma list separated input
  % adding the item between \mathrm{ and }
  \clist_map_inline:nn { #1 }
   {
    \seq_put_right:Nn \l_adam_items_seq { \mathrm { ##1 } }
   }
  \(
  \begin{bmatrix}
  % deliver the items separated by \\
  \seq_use:Nn \l_adam_items_seq { \\ }
  \end{bmatrix}
  \)
}
\ExplSyntaxOff

\begin{document}

\Features{-ACC, +PL}

\end{document}

Note that I use \mathrm rather than \text; but it's personal choice.

enter image description here