private void insert(CharacterRange range, Node<T> parent, Node<T> newNode) {

    if (root == null) {
      root = newNode;
      countNodes++;
      return;
    }

    if (range.getStart() < parent.start) {
      if (parent.left == null) {
        addToLeft(parent, newNode);
        updateHeight(newNode);
        if (parent.parent != null) balance(parent.parent, parent);
      } else {
        insert(range, parent.left, newNode);
      }
    } else if (range.getEnd() > parent.end) {
      if (parent.right == null) {
        addToRight(parent, newNode);
        updateHeight(newNode);
        if (parent.parent != null) balance(parent.parent, parent);
      } else {
        insert(range, parent.right, newNode);
      }
    }
  }
 public static Matcher characterRangeBackwardsMatcher(CharacterRange range) {
   return (input, i) ->
       i == 0
           ? -1
           : (input.charAt(i - 1) >= range.getStart() && input.charAt(i - 1) <= range.getEnd()
               ? 1
               : -1);
 }
 public static Matcher characterRangeMatcher(CharacterRange range) {
   return (input, i) ->
       input.charAt(i) >= range.getStart() && input.charAt(i) <= range.getEnd() ? 1 : -1;
 }
 public void insert(CharacterRange range, T val) {
   insert(range, root, new Node<T>(range.getStart(), range.getEnd(), val));
 }
 public void insert(int key, T val) {
   insert(CharacterRange.in(key, key), val);
 }
  @Test
  public void test() {
    Grammar grammar =
        Grammar.builder()
            .setLayout(Nonterminal.builder("L").build())
            // $default$ ::=  {UNDEFINED,-1,NON_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("$default$").build())
                    .setLayoutStrategy(NO_LAYOUT)
                    .setRecursion(Recursion.NON_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(-1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false))
                    .build())
            // L ::= (\u0009-\\u000A | \\u000D | \u0020)*  !>>  (\u0009-\\u000A | \\u000D | \u0020)
            // {UNDEFINED,-1,NON_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("L").build())
                    .addSymbol(
                        Star.builder(
                                Alt.builder(
                                        CharacterRange.builder(9, 10).build(),
                                        CharacterRange.builder(13, 13).build(),
                                        CharacterRange.builder(32, 32).build())
                                    .build())
                            .addPostConditions(
                                set(
                                    new RegularExpressionCondition(
                                        ConditionType.NOT_FOLLOW,
                                        Alt.builder(
                                                CharacterRange.builder(9, 10).build(),
                                                CharacterRange.builder(13, 13).build(),
                                                CharacterRange.builder(32, 32).build())
                                            .build())))
                            .build())
                    .setLayoutStrategy(NO_LAYOUT)
                    .setRecursion(Recursion.NON_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(-1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false))
                    .build())
            // E ::= (i f) E (t h e n) E (e l s e) E  {UNDEFINED,1,RIGHT_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(
                                Sequence.builder(
                                        Character.builder(105).build(),
                                        Character.builder(102).build())
                                    .build())
                            .build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(
                                Sequence.builder(
                                        Character.builder(116).build(),
                                        Character.builder(104).build(),
                                        Character.builder(101).build(),
                                        Character.builder(110).build())
                                    .build())
                            .build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(
                                Sequence.builder(
                                        Character.builder(101).build(),
                                        Character.builder(108).build(),
                                        Character.builder(115).build(),
                                        Character.builder(101).build())
                                    .build())
                            .build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .setRecursion(Recursion.RIGHT_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false))
                    .build())
            // E ::= (a)  {UNDEFINED,-1,NON_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(Sequence.builder(Character.builder(97).build()).build())
                            .build())
                    .setRecursion(Recursion.NON_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(-1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, 1, true, false, false, false))
                    .build())
            // E ::= E (+) E  {LEFT,2,LEFT_RIGHT_REC} PREC(2,2)
            .addRule(
                Rule.withHead(Nonterminal.builder("E").build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(Sequence.builder(Character.builder(43).build()).build())
                            .build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .setRecursion(Recursion.LEFT_RIGHT_REC)
                    .setAssociativity(Associativity.LEFT)
                    .setPrecedence(2)
                    .setPrecedenceLevel(PrecedenceLevel.from(2, 2, -1, false, false, true, false))
                    .build())
            // S ::= E  {UNDEFINED,-1,NON_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("S").build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .setRecursion(Recursion.NON_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(-1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, false, false, false))
                    .build())
            .build();

    grammar = new EBNFToBNF().transform(grammar);

    grammar = new DesugarPrecedenceAndAssociativity().transform(grammar);
    System.out.println(grammar.toStringWithOrderByPrecedence());

    grammar = new LayoutWeaver().transform(grammar);

    Input input = Input.fromString("a + if a then a else a + a");
    GrammarGraph graph = grammar.toGrammarGraph(input, Configuration.DEFAULT);

    // Visualization.generateGrammarGraph("/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/", graph);

    GLLParser parser = ParserFactory.getParser(Configuration.DEFAULT, input, grammar);
    ParseResult result = parser.parse(input, graph, Nonterminal.withName("S"));

    Assert.assertTrue(result.isParseSuccess());

    Visualization.generateSPPFGraph(
        "/Users/anastasiaizmaylova/git/diguana/test/org/jgll/parser/datadependent/precedence/",
        result.asParseSuccess().getRoot(),
        input);

    Assert.assertTrue(result.asParseSuccess().getStatistics().getCountAmbiguousNodes() == 0);
  }