{"record":{"id":"eeb914a6d1aa076c","repo":"stanfordnlp/CoreNLP","slug":"use-of-node-conjugation-expressions-such-as-f","errorCode":null,"errorMessage":"Use of node conjugation (expressions such as '< [foo bar]' or '< [foo & bar]') is now illegal.  The issue is that expressions such as '[foo bar] < zzz' may intuitively mean that foo < zzz, bar < zzz, zzz the same for both cases, but that is not the way the parser interpreted this expression.  Changing the functionality might break existing expressions, and anyway this can be rewritten in various ways such as 'zzz > foo > bar' or 'foo < zzz=a : bar < zzz=a'.  Offending expression: ","messagePattern":"Use of node conjugation \\(expressions such as '< \\[foo bar\\]' or '< \\[foo & bar\\]'\\) is now illegal\\.  The issue is that expressions such as '\\[foo bar\\] < zzz' may intuitively mean that foo < zzz, bar < zzz, zzz the same for both cases, but that is not the way the parser interpreted this expression\\.  Changing the functionality might break existing expressions, and anyway this can be rewritten in various ways such as 'zzz > foo > bar' or 'foo < zzz=a : bar < zzz=a'\\.  Offending expression: ","errorType":"validation","errorClass":"SemgrexParseException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/semgraph/semgrex/SemgrexParser.java","lineNumber":101,"sourceCode":"        }\n        jj_consume_token(10);\n        node = SubNode(GraphRelation.ITERATOR);\nchildren.add(node);\n      }\n      break;\n      }\n    default:\n      jj_la1[1] = jj_gen;\n      jj_consume_token(-1);\n      throw new ParseException();\n    }\nif (children.size() > 1)\n        node = new CoordinationPattern(true, children, true, true);\n      if (deprecatedAmp) {\n        {if (true) throw new SemgrexParseException(\"Use of & in semgrex patterns is now illegal.  It is equivalent to the same expression without the &.  Offending expression: \" + startToken);}\n      }\n      if (deprecatedNodeConj) {\n        {if (true) throw new SemgrexParseException(\"Use of node conjugation (expressions such as '< [foo bar]' or '< [foo & bar]') is now illegal.  The issue is that expressions such as '[foo bar] < zzz' may intuitively mean that foo < zzz, bar < zzz, zzz the same for both cases, but that is not the way the parser interpreted this expression.  Changing the functionality might break existing expressions, and anyway this can be rewritten in various ways such as 'zzz > foo > bar' or 'foo < zzz=a : bar < zzz=a'.  Offending expression: \" + startToken);}\n      }\n    switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {\n    case 11:{\n      jj_consume_token(11);\n      jj_consume_token(UNIQ);\nuniqKeys = new ArrayList<>();\n      label_2:\n      while (true) {\n        switch ((jj_ntk==-1)?jj_ntk_f():jj_ntk) {\n        case UNIQ:\n        case IDENTIFIER:{\n          ;\n          break;\n          }\n        default:\n          jj_la1[2] = jj_gen;\n          break label_2;\n        }","sourceCodeStart":83,"sourceCodeEnd":119,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/semgraph/semgrex/SemgrexParser.java#L83-L119","documentation":"SemgrexParser throws this SemgrexParseException during Root() when a pattern uses the deprecated node-conjugation syntax, i.e. applying a relation to a bracketed coordination like '< [foo bar]' or '< [foo & bar]'. The parser's interpretation of such expressions does not match developers' intuition (that each element is compared to the outside node), so the construct was removed rather than redefined, since changing semantics would silently break existing patterns.","triggerScenarios":"Calling SemgrexPattern.compile(...) with a pattern where a relation symbol ('<', '>', etc.) targets a bracketed group of node expressions, e.g. '< [foo bar]' or the deprecated '< [foo & bar]' form; the parser sets deprecatedNodeConj and throws before returning a pattern.","commonSituations":"Upgrading old Stanford Semgrex patterns written for legacy semgrex syntax; porting extraction rules or Ssurgeon scripts from older CoreNLP versions where node conjunction was legal; copy-pasting regex-like patterns that assume conjunctive comparison semantics.","solutions":["Rewrite the coordination as chained relations that compare each node to the shared target, e.g. 'zzz > foo > bar' or 'foo < zzz=a : bar < zzz=a'.","Remove the '&' inside brackets — it was already a no-op equivalent to a space, but the whole construct is now illegal.","Split the pattern into multiple compiled patterns joined with ':' branches so each relation applies to a single named node.","If the pattern comes from a config or rule file, update the rule text, not the code; the exception names the offending expression in startToken."],"exampleFix":"// before\nSemgrexPattern.compile(\"{} < [foo bar]\");\n// after\nSemgrexPattern.compile(\"{} < zzz=a : foo < zzz=a : bar < zzz=a\");","handlingStrategy":"validation","validationCode":"private static final Pattern NODE_CONJ = Pattern.compile(\"[<>]\\\\s*\\\\[[^]]*\\\\]\");\nif (NODE_CONJ.matcher(semgrex).find()) throw new IllegalArgumentException(\"Node conjugation is illegal: \" + semgrex);","typeGuard":null,"tryCatchPattern":"try { SemgrexPattern.compile(semgrex); } catch (SemgrexParseException e) { log.warn(\"Deprecated node conjugation in: {}\", semgrex); }","preventionTips":["Never put bracketed groups directly after a relation symbol; chain relations through named nodes instead","Use ':' branches to express per-node comparisons","Run a lint pass over legacy rule files when upgrading CoreNLP","Prefer 'zzz > foo > bar' style chaining from the start"],"tags":["java","parser","regex","deprecated-syntax"],"backgroundTag":"deprecated-api-usage","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}