\name{add_brackets}
\alias{add_brackets}
\title{Add Brackets to a Structure String}
\description{
Inserts curly braces into a structure string so that operators are grouped with their arguments and remaining elements are grouped by compositional rules.

The function processes \code{\{...\}} groups already present in the input recursively, then resolves operator binding and compositional grouping rules according to a priority list.
}
\usage{
add_brackets(s, type)
}
\arguments{
  \item{s}{Character string containing \code{#N} tags and optional \code{\{...\}} groups, as produced by step a of \code{\link{compose_skeleton_entry}}.}
  \item{type}{Character vector of type annotations for the children. \code{type[k]} is the type string for tag \code{#k} (e.g. \code{"S"}, \code{"V"}, \code{"Sx->V"}, \code{"xS->S"}).}
}
\details{
The function first recursively processes any \code{\{...\}} groups already present in the input. Then it applies rules from a priority list, restarting after each successful match:

\enumerate{
  \item \strong{Pipe rules:} Operators whose result type matches the first argument's base type (the type "flows through").
  \item \strong{Explicit rules:} Specific operator types bound by exact match (e.g. \code{xS->A}).
  \item \strong{General operator rules:} Any remaining operators that match their argument types.
  \item \strong{Compositional grouping:} Adjacent elements are grouped by type: S+A, S,S (comma), S+Vt, S+S, S+Vi, S+V, SEN+SEN.
}

If operators cannot find matching arguments, an error is returned.
}
\value{
A list with two elements:
\describe{
  \item{string}{The structure string with all brackets inserted.}
  \item{type}{The resulting type of the outermost group (\code{"S"}, \code{"V"}, \code{"SEN"}, or \code{"ERROR"}).}
}
}
\examples{
x <- "mec3-ki-aj2-ga-ce-er"
x <- as.cuneiform(x)
x

meaning <- rbind( c("S",      "a man who relies on his own strength"),
                  c("S",      "place {earth}"),
                  c("Sx->A",  ", whose allocated resource is S"),
                  c("xS->A",   ", whose sustenance is S"),
                  c("S",      "grain"),
                  c("Sx->S",  "lamented S"))

df <- data.frame(
    type  = meaning[,1],
    translation = meaning[,2],
    expr  = split_sumerian(x)$signs)

s <- x
for(i in 1:nrow(df)){
 s <- sub(df$expr[i], paste0("#", i), s)
}
s

(s_bracketed  <- sumer:::add_brackets(s,df$type))
apply_translation_rules(s_bracketed$string, df$type, df$translation)
}

\seealso{
\code{\link{apply_translation_rules}} for the next step (translating the bracketed string),
\code{\link{compose_skeleton_entry}} which calls this function
}
\keyword{internal}
