@Test public void oneLevelOneTree() { Assert.assertEquals( parse("a(b)", Function.identity()), TreeNode.of("a").attach("b") ); }
static <B> TreeNode<B> parse( final String value, final Function<? super String, ? extends B> mapper ) { requireNonNull(value); requireNonNull(mapper); final TreeNode<B> root = TreeNode.of(); final Deque<TreeNode<B>> parents = new ArrayDeque<>(); TreeNode<B> current = root; for (Token token : tokenize(value.trim())) { switch (token.seq) { case "(": if (current == null) { throw new IllegalArgumentException(format( "Illegal parentheses tree string: '%s'.", value )); } final TreeNode<B> tn1 = TreeNode.of(); current.attach(tn1); parents.push(current); current = tn1; break; case ",": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Expect '(' at position %d.", token.pos )); } final TreeNode<B> tn2 = TreeNode.of(); assert parents.peek() != null; parents.peek().attach(tn2); current = tn2; break; case ")": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Unbalanced parentheses at position %d.", token.pos )); } current = parents.pop(); if (parents.isEmpty()) { current = null; } break; default: if (current == null) { throw new IllegalArgumentException(format( "More than one root element at pos %d: '%s'.", token.pos, value )); } if (current.value() == null) { current.value(mapper.apply(token.seq)); } break; } } if (!parents.isEmpty()) { throw new IllegalArgumentException( "Unbalanced parentheses: " + value ); } return root; }
ParenthesesTreeParser { static <B> TreeNode<B> parse( final String value, final Function<? super String, ? extends B> mapper ) { requireNonNull(value); requireNonNull(mapper); final TreeNode<B> root = TreeNode.of(); final Deque<TreeNode<B>> parents = new ArrayDeque<>(); TreeNode<B> current = root; for (Token token : tokenize(value.trim())) { switch (token.seq) { case "(": if (current == null) { throw new IllegalArgumentException(format( "Illegal parentheses tree string: '%s'.", value )); } final TreeNode<B> tn1 = TreeNode.of(); current.attach(tn1); parents.push(current); current = tn1; break; case ",": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Expect '(' at position %d.", token.pos )); } final TreeNode<B> tn2 = TreeNode.of(); assert parents.peek() != null; parents.peek().attach(tn2); current = tn2; break; case ")": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Unbalanced parentheses at position %d.", token.pos )); } current = parents.pop(); if (parents.isEmpty()) { current = null; } break; default: if (current == null) { throw new IllegalArgumentException(format( "More than one root element at pos %d: '%s'.", token.pos, value )); } if (current.value() == null) { current.value(mapper.apply(token.seq)); } break; } } if (!parents.isEmpty()) { throw new IllegalArgumentException( "Unbalanced parentheses: " + value ); } return root; } }
ParenthesesTreeParser { static <B> TreeNode<B> parse( final String value, final Function<? super String, ? extends B> mapper ) { requireNonNull(value); requireNonNull(mapper); final TreeNode<B> root = TreeNode.of(); final Deque<TreeNode<B>> parents = new ArrayDeque<>(); TreeNode<B> current = root; for (Token token : tokenize(value.trim())) { switch (token.seq) { case "(": if (current == null) { throw new IllegalArgumentException(format( "Illegal parentheses tree string: '%s'.", value )); } final TreeNode<B> tn1 = TreeNode.of(); current.attach(tn1); parents.push(current); current = tn1; break; case ",": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Expect '(' at position %d.", token.pos )); } final TreeNode<B> tn2 = TreeNode.of(); assert parents.peek() != null; parents.peek().attach(tn2); current = tn2; break; case ")": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Unbalanced parentheses at position %d.", token.pos )); } current = parents.pop(); if (parents.isEmpty()) { current = null; } break; default: if (current == null) { throw new IllegalArgumentException(format( "More than one root element at pos %d: '%s'.", token.pos, value )); } if (current.value() == null) { current.value(mapper.apply(token.seq)); } break; } } if (!parents.isEmpty()) { throw new IllegalArgumentException( "Unbalanced parentheses: " + value ); } return root; } private  ParenthesesTreeParser(); }
ParenthesesTreeParser { static <B> TreeNode<B> parse( final String value, final Function<? super String, ? extends B> mapper ) { requireNonNull(value); requireNonNull(mapper); final TreeNode<B> root = TreeNode.of(); final Deque<TreeNode<B>> parents = new ArrayDeque<>(); TreeNode<B> current = root; for (Token token : tokenize(value.trim())) { switch (token.seq) { case "(": if (current == null) { throw new IllegalArgumentException(format( "Illegal parentheses tree string: '%s'.", value )); } final TreeNode<B> tn1 = TreeNode.of(); current.attach(tn1); parents.push(current); current = tn1; break; case ",": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Expect '(' at position %d.", token.pos )); } final TreeNode<B> tn2 = TreeNode.of(); assert parents.peek() != null; parents.peek().attach(tn2); current = tn2; break; case ")": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Unbalanced parentheses at position %d.", token.pos )); } current = parents.pop(); if (parents.isEmpty()) { current = null; } break; default: if (current == null) { throw new IllegalArgumentException(format( "More than one root element at pos %d: '%s'.", token.pos, value )); } if (current.value() == null) { current.value(mapper.apply(token.seq)); } break; } } if (!parents.isEmpty()) { throw new IllegalArgumentException( "Unbalanced parentheses: " + value ); } return root; } private  ParenthesesTreeParser();  }
ParenthesesTreeParser { static <B> TreeNode<B> parse( final String value, final Function<? super String, ? extends B> mapper ) { requireNonNull(value); requireNonNull(mapper); final TreeNode<B> root = TreeNode.of(); final Deque<TreeNode<B>> parents = new ArrayDeque<>(); TreeNode<B> current = root; for (Token token : tokenize(value.trim())) { switch (token.seq) { case "(": if (current == null) { throw new IllegalArgumentException(format( "Illegal parentheses tree string: '%s'.", value )); } final TreeNode<B> tn1 = TreeNode.of(); current.attach(tn1); parents.push(current); current = tn1; break; case ",": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Expect '(' at position %d.", token.pos )); } final TreeNode<B> tn2 = TreeNode.of(); assert parents.peek() != null; parents.peek().attach(tn2); current = tn2; break; case ")": if (parents.isEmpty()) { throw new IllegalArgumentException(format( "Unbalanced parentheses at position %d.", token.pos )); } current = parents.pop(); if (parents.isEmpty()) { current = null; } break; default: if (current == null) { throw new IllegalArgumentException(format( "More than one root element at pos %d: '%s'.", token.pos, value )); } if (current.value() == null) { current.value(mapper.apply(token.seq)); } break; } } if (!parents.isEmpty()) { throw new IllegalArgumentException( "Unbalanced parentheses: " + value ); } return root; } private  ParenthesesTreeParser();   }