{"record":{"id":"59650c28bf7aae0c","repo":"oracle/graal","slug":"extra-tokens-following-match-pattern-peek-null","errorCode":null,"errorMessage":"Extra tokens following match pattern: ${peek(null)}","messagePattern":"Extra tokens following match pattern: (.+?)","errorType":"validation","errorClass":"RuleParseError","httpStatus":null,"severity":"error","filePath":"compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/core/match/processor/MatchProcessor.java","lineNumber":178,"sourceCode":"                for (int n = 0; n < descriptor.nodeType.inputs.size(); n++) {\n                    if (peek(\"(\").equals(\"(\")) {\n                        descriptor.inputs[n] = parseExpression();\n                    } else {\n                        descriptor.inputs[n] = parseType(false);\n                    }\n                }\n                for (int n = 0; n < descriptor.nodeType.inputs.size(); n++) {\n                    if (descriptor.inputs[n] == null) {\n                        throw new RuleParseError(\"not enough inputs for \" + descriptor.name);\n                    }\n                }\n                if (peek(\")\").equals(\")\")) {\n                    next();\n                    return descriptor;\n                }\n                throw new RuleParseError(\"Too many arguments to \" + descriptor.nodeType.nodeClass);\n            }\n            throw new RuleParseError(\"Extra tokens following match pattern: \" + peek(null));\n        }\n\n        private MatchDescriptor parseType(boolean forExpression) {\n            TypeDescriptor type = null;\n            String name = null;\n            if (Character.isUpperCase(peek(\"node type or name\").charAt(0))) {\n                String token = next();\n                type = knownTypes.get(token);\n                if (type == null) {\n                    throw new RuleParseError(\"Unknown node type: \" + token);\n                }\n                if (peek(\"=\").equals(\"=\")) {\n                    next();\n                    name = next();\n                }\n                originatingElements.addAll(type.originatingElements);\n            } else if (Character.isLowerCase(peek(\"name\").charAt(0))) {\n                name = next();","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/core/match/processor/MatchProcessor.java#L160-L196","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Wrap the node and its inputs in parentheses: 'NodeType(input, ...)'.","Check the token quoted after 'Extra tokens following match pattern:' — it is the one that must be inside a parenthesized expression.","Model new rules on existing ones in the same package for correct shape."],"exampleFix":"// before\n@MatchRule(\"Add x y\")\n\n// after\n@MatchRule(\"Add(x, y)\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Compile-time error from the annotation processor; no runtime catch exists. CI should fail on any RuleParseError diagnostic.","preventionTips":["Remember the grammar is S-expressions: every expression is '( Type inputs... )'.","Wrap node applications in parentheses even for single-input nodes.","Copy the shape of existing rules rather than inventing infix syntax."],"tags":["graalvm","match-rules","annotation-processing","syntax","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}