mono/mono · error
%s: e - line %d of "%s", unterminated action
Error message
%s: e - line %d of "%s", unterminated action
What it means
Emitted by unterminated_action() in mcs/jay/error.c:231, reached from copy_action() (reader.c:1189) when an action block `{ ... }` reaches end-of-file (get_line() returns NULL) before its closing brace. jay tracks brace depth while copying the embedded C# action; an unbalanced brace means the action never terminates, so generation aborts via done(1) after printing the offending position.
Source
Thrown at mcs/jay/error.c:231
void
terminal_lhs (int s_lineno)
{
fprintf(stderr, "%s: e - line %d of \"%s\", a token appears on the lhs \
of a production\n", myname, s_lineno, input_file_name);
done(1);
}
void
prec_redeclared (void)
{
fprintf(stderr, "%s: w - line %d of \"%s\", conflicting %%prec \
specifiers\n", myname, lineno, input_file_name);
}
void
unterminated_action (int a_lineno, const char *a_line, const char *a_cptr)
{
fprintf(stderr, "%s: e - line %d of \"%s\", unterminated action\n",
myname, a_lineno, input_file_name);
print_pos(a_line, a_cptr);
done(1);
}
void
dollar_warning (int a_lineno, int i)
{
fprintf(stderr, "%s: w - line %d of \"%s\", $%d references beyond the \
end of the current rule\n", myname, a_lineno, input_file_name, i);
}
void
dollar_error (int a_lineno, const char *a_line, char *a_cptr)
{
fprintf(stderr, "%s: e - line %d of \"%s\", illegal $-name\n",
myname, a_lineno, input_file_name);
print_pos(a_line, a_cptr);View on GitHub (pinned to 0f53e9e151)
Solutions
- Add the missing `}` to close every action block, matching `{` count.
- Escape or restructure braces that appear inside string/char literals within actions so jay's depth tracking stays balanced.
- Ensure the file ends with a newline after the last action's closing brace.
Example fix
// before
expr : expr '+' expr { yylval = $1 + $3; /* no closing brace -> unterminated_action */
// after
expr : expr '+' expr { yylval = $1 + $3; } Defensive patterns
Strategy: validation
Validate before calling
# Brace balance across action blocks: open and close counts in the rules section must match.
sec=$(awk 'f&&/^%%/{exit} /^%%/{f=1;next} f' grammar.jay)
opens=$(printf '%s' "$sec" | tr -cd '{' | wc -c)
closes=$(printf '%s' "$sec" | tr -cd '}' | wc -c)
[ "$opens" -eq "$closes" ] || { echo "unbalanced braces in actions: $opens open vs $closes close"; exit 1; } Try / catch
jay -c -o Parser.cs grammar.jay || { echo "jay aborted; check for an unterminated action (missing closing brace)"; exit 1; } Prevention
- Close every action block on the same rule; match each `{` with a `}`.
- Escape or restructure braces inside C# string/char literals in actions.
- Run a brace-balance lint over the rules section before invoking jay.
When it happens
Trigger: An action `{ ... ` with no matching `}`; a brace opened in a string or comment that confuses depth counting; a rule action that continues past the last line of the file.
Common situations: Forgetting the closing brace of an action; brace inside a C# string literal or char literal that throws off jay's simple brace counter; trailing action on the file's final rule with no newline/brace.
Related errors
- %s: w - line %d of "%s", $%d references beyond the end of th
- %s: e - line %d of "%s", illegal $-name
- %s: w - line %d of "%s", $$ is untyped
- %s: w - line %d of "%s", $%d (%s) is untyped
- %s: e - line %d of "%s", $%d is untyped
AI-assisted analysis of mono/mono@0f53e9e151 (2026-08-13).
Data as JSON: /api/errors/d91f4e8d82174866.
Report an issue: GitHub.