{"record":{"id":"c0d4e85f906c49e5","repo":"oracle/graal","slug":"unexpected-tokens-rule-substring-m-end-m-reg","errorCode":null,"errorMessage":"Unexpected tokens :${rule.substring(m.end(), m.regionEnd())}","messagePattern":"Unexpected tokens :(.+?)","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":126,"sourceCode":"        private int current;\n\n        private MatchDescriptor matchDescriptor;\n\n        private final Set<Element> originatingElements = new LinkedHashSet<>();\n\n        private Set<String> requiredPackages = new LinkedHashSet<>();\n\n        RuleParser(String rule) {\n            Matcher m = tokenizer.matcher(rule);\n            List<String> list = new ArrayList<>();\n            int end = 0;\n            while (m.lookingAt()) {\n                list.add(m.group(1));\n                end = m.end();\n                m.region(m.end(), m.regionEnd());\n            }\n            if (end != m.regionEnd()) {\n                throw new RuleParseError(\"Unexpected tokens :\" + rule.substring(m.end(), m.regionEnd()));\n            }\n            tokens = list.toArray(new String[0]);\n\n            matchDescriptor = parseExpression();\n            if (!done()) {\n                throw new RuleParseError(\"didn't consume all tokens\");\n            }\n            capturedNames.add(0, \"root\");\n            capturedTypes.add(0, matchDescriptor.nodeType);\n        }\n\n        String next() {\n            return tokens[current++];\n        }\n\n        String peek(String name) {\n            if (current >= tokens.length) {\n                if (name == null) {","sourceCodeStart":108,"sourceCodeEnd":144,"githubUrl":"https://github.com/oracle/graal/blob/a66e9ccd1d7bf2552883939aa0788dfd0e294aab/compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/core/match/processor/MatchProcessor.java#L108-L144","documentation":"Thrown by the RuleParser inside MatchProcessor (the annotation processor for @MatchRule) when tokenizing a match rule leaves a suffix the tokenizer regex cannot consume. Match rules are written as S-expression-like patterns (e.g. 'Add(x, y)'), and after repeatedly applying the token regex the parser verifies it reached the end of the string; leftover characters mean illegal syntax at that position.","triggerScenarios":"Writing @MatchRule(\"Add(x, y) #\") or any rule containing characters outside the tokenizer's token set (stray punctuation, comments, unquoted operators) so that after the last matched token the region end exceeds the tokenizer end. The message echoes the unconsumed substring so you can locate it.","commonSituations":"Hand-editing a @MatchRule string and leaving trailing junk; attempting to write a condition or predicate syntax the match DSL does not support; merge artifacts or stray characters inside the annotation value.","solutions":["Look at the substring after 'Unexpected tokens :' in the message and delete/fix exactly that part of the @MatchRule value.","Compare against a known-good rule in the same file for the accepted S-expression grammar (identifiers, parentheses, '=' for captured names).","Move complex conditions that the DSL cannot express into the generated match method body instead of the pattern string."],"exampleFix":"// before\n@MatchRule(\"Add(x, y) #\")\n\n// after\n@MatchRule(\"Add(x, y)\")","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"RuleParseError and its siblings are compile-time annotation-processing failures; there is no runtime catch site. Wrap javac/mx output parsing in CI to fail fast and echo the offending @MatchRule string.","preventionTips":["Keep @MatchRule strings on one line; run a build after every rule edit.","Model new rules on existing working ones in the same package.","Cover rule syntax with a small compile-only test module so CI catches bad rules early."],"tags":["graalvm","match-rules","annotation-processing","compile-time"],"backgroundTag":null,"analyzedSha":"a66e9ccd1d7bf2552883939aa0788dfd0e294aab","analyzedAt":"2026-08-14T13:58:47.161Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}