oracle/graal · error · RuleParseError

Extra tokens following match pattern: ${peek(null)}

Error message

Extra tokens following match pattern: ${peek(null)}

What it means

Thrown by RuleParser.parseExpression when the first token of what should be a parenthesized expression is not '('. After the two arity checks, a well-formed expression must begin with '('; reaching the final throw means the caller asked for an expression where a bare token (a node type or name outside parentheses) appeared.

Source

Thrown at compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/core/match/processor/MatchProcessor.java:178

                for (int n = 0; n < descriptor.nodeType.inputs.size(); n++) {
                    if (peek("(").equals("(")) {
                        descriptor.inputs[n] = parseExpression();
                    } else {
                        descriptor.inputs[n] = parseType(false);
                    }
                }
                for (int n = 0; n < descriptor.nodeType.inputs.size(); n++) {
                    if (descriptor.inputs[n] == null) {
                        throw new RuleParseError("not enough inputs for " + descriptor.name);
                    }
                }
                if (peek(")").equals(")")) {
                    next();
                    return descriptor;
                }
                throw new RuleParseError("Too many arguments to " + descriptor.nodeType.nodeClass);
            }
            throw new RuleParseError("Extra tokens following match pattern: " + peek(null));
        }

        private MatchDescriptor parseType(boolean forExpression) {
            TypeDescriptor type = null;
            String name = null;
            if (Character.isUpperCase(peek("node type or name").charAt(0))) {
                String token = next();
                type = knownTypes.get(token);
                if (type == null) {
                    throw new RuleParseError("Unknown node type: " + token);
                }
                if (peek("=").equals("=")) {
                    next();
                    name = next();
                }
                originatingElements.addAll(type.originatingElements);
            } else if (Character.isLowerCase(peek("name").charAt(0))) {
                name = next();

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Wrap the node and its inputs in parentheses: 'NodeType(input, ...)'.
  2. Check the token quoted after 'Extra tokens following match pattern:' — it is the one that must be inside a parenthesized expression.
  3. Model new rules on existing ones in the same package for correct shape.

Example fix

// before
@MatchRule("Add x y")

// after
@MatchRule("Add(x, y)")
Defensive patterns

Strategy: try-catch

Try / catch

Compile-time error from the annotation processor; no runtime catch exists. CI should fail on any RuleParseError diagnostic.

Prevention

When it happens

Trigger: A @MatchRule value that starts with or contains a bare type/name where the grammar requires a nested parenthesized expression, e.g. "Add x y" or using parseExpression on a top-level bare identifier. The message shows the offending token via peek(null).

Common situations: Omitting parentheses entirely when composing a rule; treating the DSL as infix rather than S-expressions; editing a rule down to a single node without wrapping context.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/59650c28bf7aae0c. Report an issue: GitHub.