{"record":{"id":"32e39d72a93cccd4","repo":"stanfordnlp/CoreNLP","slug":"found-a-non-empty-line-in-a-tsurgeon-section-after","errorCode":null,"errorMessage":"Found a non-empty line in a tsurgeon section after reading the operation","messagePattern":"Found a non-empty line in a tsurgeon section after reading the operation","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/trees/GenerateTrees.java","lineNumber":134,"sourceCode":"        try {\n          Section newSection = Section.valueOf(line.toUpperCase(Locale.ROOT));\n          section = newSection;\n          if (section == Section.TSURGEON) {\n            // this will tregex pattern until it has eaten a blank\n            // line, then read tsurgeon until it has eaten another\n            // blank line.\n            Pair<TregexPattern, TsurgeonPattern> operation = Tsurgeon.getOperationFromReader(bin, compiler);\n            tsurgeons.add(operation);\n          }\n          continue;\n        } catch (IllegalArgumentException e) {\n          // never mind, not an enum\n        }\n        \n        String[] pieces = line.split(\" +\");\n        switch(section) {\n        case TSURGEON: {\n          throw new RuntimeException(\"Found a non-empty line in a tsurgeon section after reading the operation\");\n        }\n        case TERMINALS: {\n          Counter<String> productions = terminals.get(pieces[0]);\n          if (productions == null) {\n            productions = new ClassicCounter<>();\n            terminals.put(pieces[0], productions);\n          }\n          for (int i = 1; i < pieces.length; ++i) {\n            productions.incrementCount(pieces[i]);\n          }\n          break;\n        }\n        case NONTERMINALS: {\n          Counter<List<String>> productions = nonTerminals.get(pieces[0]);\n          if (productions == null) {\n            productions = new ClassicCounter<>();\n            nonTerminals.put(pieces[0], productions);\n          }","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/trees/GenerateTrees.java#L116-L152","documentation":"GenerateTrees.readGrammar reads a grammar file divided into sections (TSURGEON, TERMINALS, etc.). In the TSURGEON section, exactly one operation is expected per entry; any additional non-empty line after the operation has been read means the file is malformed, so it throws with the offending line context.","triggerScenarios":"A tsurgeon section in the grammar file contains more than one operation's worth of non-empty lines — e.g. two operations without a proper section/blank-line separator, or stray text after the tsurgeon command.","commonSituations":"Hand-edited grammar files where blank-line separators between tsurgeon operations were removed; concatenating tsurgeon scripts without the expected section formatting; copy-paste artifacts leaving extra lines in the TSURGEON block.","solutions":["Edit the grammar file so each tsurgeon operation is separated properly (blank line / next section marker) and no extra non-empty lines follow an operation.","Split multiple tsurgeon operations into separate operation entries in the section.","Check for hidden characters or missing newlines around the tsurgeon block reported by the stack trace."],"exampleFix":"// before\nTSURGEON\ndelete NP-1\nmove NP > NP\n// after\nTSURGEON\ndelete NP-1\n\nTSURGEON\nmove NP > NP","handlingStrategy":"validation","validationCode":"// parse the grammar file first and assert each TSURGEON block has exactly one operation before calling readGrammar\nassertEachTsurgeonBlockHasOneOp(grammarFile);","typeGuard":null,"tryCatchPattern":"try { g.readGrammar(reader); } catch (RuntimeException e) { if (e.getMessage().contains(\"non-empty line in a tsurgeon section\")) { throw new GrammarFormatException(\"fix TSURGEON section: \" + e.getMessage(), e); } }","preventionTips":["Separate tsurgeon operations with blank lines / section markers","Lint grammar files for stray lines inside TSURGEON sections","Keep one operation per TSURGEON entry"],"tags":["java","nlp","file-parsing","grammar-format"],"backgroundTag":"invalid-argument-format","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}