Sample

Schnappinger/aoi/nik777.xlate.StringEditor

Human rating uses the original dataset scale.

Human2.99
Lines311

Scores

MethodScoreScaleDataset rank
(0–100)
Posnett00–1; higher is more readable
36.5Δ 12.4
Scalabrino0.8670–1; higher is more readable
80.5Δ 56.4
Dorn0.0540–1; higher is more readable
29.4Δ 5.3
Mi0.5410–1; higher is more readable
39.6Δ 15.5
LLOC99Logical lines; fewer is more readable
25.2Δ 1.2
DeepSeek V4 Pro110–20; mean of three runs
12.0Δ 12.0
GPT-6.1 Sol130–20; mean of three runs
9.4Δ 14.7
BTTF0.4070–1; higher is more readable
35.0Δ 10.9
Human2.991–4; original rating
24.1

Views

Source code

/* StringEditor.java */ package nik777.xlate; /* * StringEditor: apply stored edit commands to strings. * * Copyright (C) 2000-2006, Nik Trevallyn-Jones, Sydney Australia * * Author: Nik Trevallyn-Jones, nik777@users.sourceforge.net * $Id: Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See version 2 of the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * with this program. If not, version 2 of the license is available * from the GNU project, at http://www.gnu.org. */ import java.util.*; import java.util.regex.*; /** * the string editor class. * * Provides efficient, repeated editing functions specified by * commands which can include regular expressions. * * The editing command syntax is based loosely on the 'sed' commands, and uses * the java.util.regex regular expression handler in * {@link java.util.regex#Pattern} - see {@link #compile(String)} for details. * * To invoke the editor, see * {@link #edit(java.lang.String)}. */ public class StringEditor { protected Pattern pattern; protected String value; protected char op; protected boolean global; protected StringEditor next; public static final StringEditor EMPTY = new StringEditor() { public String edit(String str) { return str; } public void compile() { next = null; } }; public StringEditor() { next = null; } public StringEditor(String cmd) { next = null; compile(cmd); } /** * return the number of edit rules in this editor */ public int size() { int result = (pattern != null ? 1 : 0); for (StringEditor nx = next; nx != null; nx = nx.next) result++; return result; } /** * edit a string. * * @return the result of applying this editor to <i>str</i>. */ public String edit(String str) { if (pattern == null) return str; String result = ""; int pos=0, group=0, max; StringBuffer sb; Matcher matcher = pattern.matcher(str); switch (op) { case 's': case 'S': case 'd': case 'D': // s,d - replace matched text with value or null if (global) result = matcher.replaceAll(value); else result = matcher.replaceFirst(value); break; case 'a': case 'A': case 'i': case 'I': // a,i append/insert value sb = new StringBuffer(str.length()*2); while (matcher.find()) { matcher.appendReplacement(sb, value); if (!global) break; } matcher.appendTail(sb); result = sb.toString(); break; case 'p': case 'P': // p return the specified matched group sb = (global ? new StringBuffer(str.length()) : null); // get the group number max = value.length(); while (pos < max && Character.isDigit(value.charAt(pos++))) group = (group*10) + Character.digit(value.charAt(pos), 10); while (matcher.find()) { result = matcher.group(group); if (!global) break; sb.append(result); } if (global) result = sb.toString(); } return (next != null ? next.edit(result) : result); } /** * add an editor to this editor. The added editor will be invoked by * this.edit() <i>after</i> all this editor's edits have been applied. */ public void add(StringEditor editor) { if (next != null) next.add(editor); else next = editor; } /** * add the specified editing commands to this editor. * * The command(s) will be compiled and then executed <i>after</i> this * editor's edits (if any) have been applied. */ public void add(String cmd) { if (pattern == null) compile(cmd); else add(new StringEditor(cmd)); } /** * compile an edit command. * * Causes any previous editing command to be replaced with the * newly compiled command. * *<br>The format of an editing command is: *<br>[qual] op delim pattern [delim arg] [delim cmd] * *<br>Eg: gs/(dog|hound)/canine/s;cat;feline * *<br>Where: *<br>qual is a qualifier. The only qualifier currently is <i>g</i> which * causes the associated operation to be applied to <i>all</i> matches. *<br>op is an editing operation, and is one of * *<ul> *<li> s - switch; replace matched text with <i>arg</i> *<li> a - append; append <i>arg</i> to the matched text *<li> i - insert; insert <i>arg</i> to the matched text *<li> d - delete; delete the matched text *<li> p - print; return the <i>arg</i>th match group (0 => all) *</ul> * *<br>delim is a single character (ie the character immediately following * the <i>op</i>). * *<br>pattern is a regular expression for matching substrings in the text * For an explanation of the valid regular expressions see * {@link java.util.regex.Pattern}. * *<br>arg is an argument for the operation. *<br>Note also that the 's,a,i' commands allows <i>arg</i> to contain * references to sequences of the matched data * (see {@link java.util.regex.Matcher#appendReplacement()}). * In particular the token '$0' will be replaced with the entire matched * text. Hence a literal '$' char will need to be escaped as in '\$'. *</ul> * *<br>As can be seen, multiple commands can be concatenated, each * separated by the current delimiter char. In addition, the delimiter can * be different for each command. By definition, the delimiter for each * commmand is the character <i>immediately following</i> the editing op. * *<br>So from this, the example command(s) above replace <i>all</i> * occurences of 'dog' or 'hound' with 'canine, and then the first * occurence of 'cat' with 'feline'. (In this example, the delimiter for * the first op is '/', and for the second op is ';', although the one * delimiter could just as easily be used for all commands). * *<br>Changes are applied in the same order as the commands, so * if an earlier edit inserts a pieces of text which can match a later * edit's pattern, then that newly added text may be modified by the * later command. * * @param cmd the editing command string. */ public void compile(String cmd) throws PatternSyntaxException { cmd = cmd.trim(); int len = (cmd != null ? cmd.length() : 0); char qual = cmd.charAt(0); if (qual == 'g' || qual == 'G') { global = true; cmd = cmd.substring(1); len--; } if (len == 2) return; int cut, cut2; char delim; op = cmd.charAt(0); delim = cmd.charAt(1); // get the edit pattern cut = cmd.indexOf(delim, 2); if (cut < 0) pattern = Pattern.compile(cmd.substring(2)); else pattern = Pattern.compile(cmd.substring(2, cut)); switch (op) { case 's': case 'S': case 'a': case 'A': case 'i': case 'I': case 'p': case 'P': if (cut > 0) { cut++; // find the replacement string cut2 = cmd.indexOf(delim, cut); if (cut2 > cut) value = cmd.substring(cut, cut2); else value = cmd.substring(cut); // null string if (value.length() == 1 && value.charAt(0) == delim) value = ""; cut = cut2; // advance cut } else value = ""; // for insert/append, include the matched string (group-0) switch ("aAiI".indexOf(op)) { case 0: case 1: value = "$0" + value; break; case 2: case 3: value = value + "$0"; break; } break; case 'd': case 'D': value = ""; break; default: throw new PatternSyntaxException("Unrecognised cmd: " + op, cmd, 0); } // if there is more, chain to next editor if (cut > 0 && cut+2 < len) next = new StringEditor(cmd.substring(cut+1)); else next = null; } }

Loading feature diagnosis…

Source regions

Feature contributions

Feature contributions

FeatureValueContribution
(log-odds)
Halstead volumeHow much symbolic information the code contains. It combines the total number of operators and values with the number of distinct ones.5981.017−197.374
Source linesThe number of non-empty source lines.311+124.4
Byte entropyHow varied the bytes in the source text are. Repeated bytes give a lower value; a more even mixture gives a higher value.4.831−7.246

Intercept 8.87 + feature contributions = -71.35 (log-odds).
Score = sigmoid(-71.35) = 0.

Score0.867

Feature contributions

FeatureValueContribution
(log-odds)
Comment layout frequencyHow frequently the layout switches between lines containing only comments or whitespace and lines containing code.312−10.011
Indentation frequencyHow rapidly indentation changes from line to line.198+6.111
Number layout frequencyHow rapidly the number of numeric values per line changes through the code.198−4.123
Identifier layout (vertical)How rapidly the visual pattern of identifier characters changes from top to bottom.310.825+3.935
Comment layout (horizontal)How rapidly the visual pattern of comment characters changes from left to right.77.683+0.449
Operator visual areaThe share of the code’s visual area occupied by operators such as +, =, and *.0.058+0.375
Identifier layout (horizontal)How rapidly the visual pattern of identifier characters changes from left to right. It measures spatial frequency, not the meaning of the names.78.971+0.32

Intercept 0.07 + feature contributions = -2.873 (log-odds).
Score = sigmoid(-2.873) = 0.054.

Score0.541
Score99
Run 1

The code has reasonable structure (clear fields, constructor, size/edit/add/compile methods) and good Javadoc, but the core methods suffer from deep nesting and unclear flow. The `edit` method uses a large switch inside conditionals with multiple break statements and variable reassignments, making its logic hard to follow. Some branches (e.g., case 'p') have confusing group parsing with off-by-one character indexing. `compile` is a long method with nested conditionals, magic numbers, and variable reuse (`cut`, `cut2`) that obscures intent. Action granularity is mixed: some operations are compact while others pack multiple actions per line. The regex parsing is terse and relies on implicit delimiter semantics. Overall, it is maintainable by an experienced Java developer but not immediately readable. The score would improve with smaller helper methods, fewer mutable variables reused across branches, and simpler control flow (e.g., early returns or state objects).

Run 2

The code shows dated style with several readability issues. Structure is somewhat organized (clear separation of methods, Javadoc present) but the core edit/compile logic is tangled. Nesting is moderate but switch cases contain lengthy inline logic. Intent is documented but actual code is ambiguous in places: magic numbers, single-letter variables (op, cut, cut2), and unclear control flow reduce clarity. Code length is excessive for what it does, especially compile() and edit(). Action granularity is poor—multiple actions are packed into lines (e.g., group digit accumulation, switch-based value concatenation). Reading flow is disjointed: constants like EMPTY use anonymous subclass with odd indentation; while loops have non-obvious termination; conditional branches lack braces. The code works but requires careful study to understand, and doesn't meet modern readability expectations.

Run 3

The code is generally structured but has several readability issues. The main edit() method uses a large switch with inconsistent braces and indentation, and one case ('p') is missing its break, relying on fall-through. Variable names like sb, pos, group, cut, cut2 are terse and ambiguous. The compile() method mixes parsing, validation, and chaining logic in one long method, making intent harder to follow. Nesting is moderate but uneven; some blocks are flat while others have nested switches inside switch cases. Action granularity is mixed: some lines pack multiple operations (e.g., matcher.appendReplacement in loops), while others are clear. Reading flow suffers from the dense Javadoc and inconsistent formatting. Positive aspects include a clear class purpose, logical field grouping, and helpful comments. Overall, it is understandable but requires effort to parse the editing logic.

Run 1

Code Structure: Methods separate editing, compilation, and rule chaining logically, but compile combines parsing, operation configuration, and chain construction. Nesting: Mostly moderate, with nested switches and conditionals making compilation harder to follow. Clarity of intent: Extensive documentation and operation comments explain the purpose, but abbreviated names such as op, qual, cut, nx, and sb obscure details. Character-coded operations and index manipulation require careful interpretation. Code length: Implementation is reasonably compact, although lengthy documentation and duplicated uppercase/lowercase cases add bulk. Action granularity: Most statements perform one action, but inline loop bodies, combined declarations, and increments embedded in character access complicate tracing. Reading flow: Method organization is sensible, but inconsistent indentation, compressed formatting, shared mutable fields, and recursive chaining interrupt readability. Overall, understandable with effort, especially in the command parser.

Run 2

Code Structure: Methods logically separate editing, compilation, and rule chaining, but compile and edit each combine several responsibilities. Nesting: Generally moderate, although nested switches and conditionals make command parsing harder to follow. Clarity of intent: Class documentation and operation comments explain the purpose well; terse identifiers such as op, cut, cut2, nx, and sb obscure implementation details, especially delimiter handling and group parsing. Code length: The implementation is reasonably compact, but extensive, sometimes repetitive documentation interrupts navigation. Action granularity: Most statements perform one action, though inline conditionals, combined declarations, and an increment embedded in a condition increase cognitive load. Reading flow: Method organization and switch-based dispatch are natural, but inconsistent spacing, compressed method bodies, omitted braces, and character-to-index dispatch reduce smoothness. Overall, understandable with careful reading, but parsing logic and formatting prevent high readability.

Run 3

1. Code Structure: Methods separate editing, compilation, and chaining logically, but compile() mixes parsing, validation, and state mutation. 2. Nesting: Mostly shallow, although nested switches and conditionals in compile() require extra attention. 3. Clarity of intent: Extensive documentation explains command syntax and purpose; terse names such as op, cut, cut2, and nx, plus character-based dispatch, obscure implementation details. 4. Code length: Generally compact, but lengthy documentation and duplicated uppercase/lowercase cases add bulk; parsing could benefit from helper methods. 5. Action granularity: Most statements perform one action, but inline conditionals, combined declarations, and pos++ inside a condition make some lines harder to interpret. 6. Reading flow: Method ordering and comments support navigation, while inconsistent spacing, indentation, omitted braces, and dense substring/index arithmetic interrupt the flow.