Exemple #1
0
  @Before
  public void init() {

    Nonterminal S = Nonterminal.withName("S");

    Nonterminal E = Nonterminal.builder("E").addParameters("l", "r").build();

    Character z = Character.from('z');
    Character w = Character.from('w');

    Rule r0 =
        Rule.withHead(S)
            .addSymbol(Nonterminal.builder(E).apply(integer(0), integer(0)).build())
            .build();

    Rule r1_1 =
        Rule.withHead(E)
            .addSymbol(
                Nonterminal.builder(E)
                    .apply(integer(5), var("r"))
                    .addPreCondition(predicate(greaterEq(integer(5), var("r"))))
                    .build())
            .addSymbol(z)
            .build();

    Rule r1_2 =
        Rule.withHead(E)
            .addSymbol(
                Character.builder('x')
                    .addPreCondition(predicate(greaterEq(integer(4), var("l"))))
                    .build())
            .addSymbol(Nonterminal.builder(E).apply(var("l"), integer(4)).build())
            .build();

    Rule r1_3 =
        Rule.withHead(E)
            .addSymbol(
                Nonterminal.builder(E)
                    .apply(integer(3), integer(0))
                    .addPreCondition(predicate(greaterEq(integer(3), var("r"))))
                    .build())
            .addSymbol(w)
            .build();

    Rule r1_4 =
        Rule.withHead(E)
            .addSymbol(
                Character.builder('y')
                    .addPreCondition(predicate(greaterEq(integer(2), var("l"))))
                    .build())
            .addSymbol(Nonterminal.builder(E).apply(integer(0), integer(0)).build())
            .build();

    Rule r1_5 = Rule.withHead(E).addSymbol(Character.from('a')).build();

    grammar = Grammar.builder().addRules(r0, r1_1, r1_2, r1_3, r1_4, r1_5).build();
  }
Exemple #2
0
  @Test
  public void test() {
    Grammar grammar =
        Grammar.builder()

            // $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())
            // E ::= ('-') E  {UNDEFINED,1,RIGHT_REC} PREC(1,1)
            .addRule(
                Rule.withHead(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(Sequence.builder(Character.builder(45).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(94).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())
            // E ::= E ('*') E  {UNDEFINED,3,LEFT_RIGHT_REC} PREC(3,3)
            .addRule(
                Rule.withHead(Nonterminal.builder("E").build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .addSymbol(
                        Terminal.builder(Sequence.builder(Character.builder(42).build()).build())
                            .build())
                    .addSymbol(Nonterminal.builder("E").build())
                    .setRecursion(Recursion.LEFT_RIGHT_REC)
                    .setAssociativity(Associativity.UNDEFINED)
                    .setPrecedence(3)
                    .setPrecedenceLevel(PrecedenceLevel.from(3, 3, 3, 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);
    System.out.println(grammar);

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

    Input input = Input.fromString("a*-a^a");
    GrammarGraph graph = GrammarGraph.from(grammar, input, Configuration.DEFAULT);

    // Visualization.generateGrammarGraph("test/org/iguana/parser/datadependent/precedence/",
    // graph);

    ParseResult result = Iguana.parse(input, graph, Nonterminal.withName("S"));

    Assert.assertTrue(result.isParseSuccess());

    // Visualization.generateSPPFGraph("test/org/iguana/parser/datadependent/precedence/",
    //                   result.asParseSuccess().getSPPFNode(), input);

    Assert.assertEquals(0, result.asParseSuccess().getStatistics().getCountAmbiguousNodes());
  }
Exemple #3
0
/** E ::= E '*' E | E '+' E | 'a' */
public class Test19 {

  static Nonterminal E = Nonterminal.withName("E");
  static org.iguana.grammar.symbol.Character a = Character.from('a');
  static Character plus = Character.from('+');
  static Character star = Character.from('*');

  static Rule r1 = Rule.withHead(E).addSymbols(E, star, E).build();
  static Rule r2 = Rule.withHead(E).addSymbols(E, plus, E).build();
  static Rule r3 = Rule.withHead(E).addSymbols(a).build();

  public static Grammar grammar = Grammar.builder().addRules(r1, r2, r3).build();
  private static Nonterminal startSymbol = E;

  private static Input input1 = Input.fromString("a+a");
  private static Input input2 = Input.fromString("a+a*a");
  private static Input input3 = Input.fromString("a+a*a+a*a");

  @Test
  public void testParser1() {
    GrammarGraph graph = GrammarGraph.from(grammar, input1);
    ParseResult result = Iguana.parse(input1, graph, startSymbol);
    assertTrue(result.isParseSuccess());
    assertEquals(getParseResult1(graph), result);
    assertEquals(getTree1(), result.asParseSuccess().getTree());
  }

  @Test
  public void testParser2() {
    GrammarGraph graph = GrammarGraph.from(grammar, input2);
    ParseResult result = Iguana.parse(input2, graph, startSymbol);
    assertTrue(result.isParseSuccess());
    assertEquals(getParseResult2(graph), result);
    assertEquals(getTree2(), result.asParseSuccess().getTree());
  }

  @Test
  public void testParser3() {
    GrammarGraph graph = GrammarGraph.from(grammar, input3, Configuration.DEFAULT);
    ParseResult result = Iguana.parse(input3, graph, startSymbol);
    assertTrue(result.isParseSuccess());
    assertEquals(getParseResult3(graph), result);
    assertEquals(getTree3(), result.asParseSuccess().getTree());
  }

  private ParseSuccess getParseResult1(GrammarGraph registry) {
    ParseStatistics statistics =
        ParseStatistics.builder()
            .setDescriptorsCount(8)
            .setGSSNodesCount(2)
            .setGSSEdgesCount(5)
            .setNonterminalNodesCount(3)
            .setTerminalNodesCount(3)
            .setIntermediateNodesCount(2)
            .setPackedNodesCount(5)
            .setAmbiguousNodesCount(0)
            .build();
    return new ParseSuccess(expectedSPPF1(registry), statistics, input1);
  }

  private NonterminalNode expectedSPPF1(GrammarGraph registry) {
    TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input1);
    NonterminalNode node1 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input1);
    TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input1);
    IntermediateNode node3 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2);
    TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input1);
    NonterminalNode node5 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input1);
    IntermediateNode node6 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5);
    NonterminalNode node7 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node6, input1);
    return node7;
  }

  private Tree getTree1() {
    Tree t0 = createTerminal(0, 1, input1);
    Tree t1 = createRule(r3, list(t0), input1);
    Tree t2 = createTerminal(1, 2, input1);
    Tree t3 = createTerminal(2, 3, input1);
    Tree t4 = createRule(r3, list(t3), input1);
    Tree t5 = createRule(r2, list(t1, t2, t4), input1);
    return t5;
  }

  private ParseSuccess getParseResult2(GrammarGraph registry) {
    ParseStatistics statistics =
        ParseStatistics.builder()
            .setDescriptorsCount(16)
            .setGSSNodesCount(3)
            .setGSSEdgesCount(9)
            .setNonterminalNodesCount(6)
            .setTerminalNodesCount(5)
            .setIntermediateNodesCount(7)
            .setPackedNodesCount(14)
            .setAmbiguousNodesCount(1)
            .build();
    return new ParseSuccess(expectedSPPF2(registry), statistics, input1);
  }

  private NonterminalNode expectedSPPF2(GrammarGraph registry) {
    TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input2);
    NonterminalNode node1 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input2);
    TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input2);
    IntermediateNode node3 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2);
    TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input2);
    NonterminalNode node5 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input2);
    TerminalNode node6 = createTerminalNode(registry.getSlot("*"), 3, 4, input2);
    IntermediateNode node7 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node5, node6);
    TerminalNode node8 = createTerminalNode(registry.getSlot("a"), 4, 5, input2);
    NonterminalNode node9 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node8, input2);
    IntermediateNode node10 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node9);
    NonterminalNode node11 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node10, input2);
    IntermediateNode node12 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node11);
    IntermediateNode node13 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5);
    NonterminalNode node14 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node13, input2);
    IntermediateNode node15 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node14, node6);
    IntermediateNode node16 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node15, node9);
    NonterminalNode node17 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node12, input2);
    node17.addPackedNode(registry.getSlot("E ::= E * E ."), node16);
    return node17;
  }

  private Tree getTree2() {
    Tree t0 = createTerminal(0, 1, input2);
    Tree t1 = createRule(r3, list(t0), input2);
    Tree t2 = createTerminal(1, 2, input2);
    Tree t3 = createTerminal(2, 3, input2);
    Tree t4 = createRule(r3, list(t3), input2);
    Tree t5 = createRule(r2, list(t1, t2, t4), input2);
    Tree t6 = createTerminal(3, 4, input2);
    Tree t7 = createTerminal(4, 5, input2);
    Tree t8 = createRule(r3, list(t7), input2);
    Tree t9 = createRule(r1, list(t4, t6, t8), input2);
    Tree t10 = createAmbiguity(set(createBranch(list(t5, t6, t8)), createBranch(list(t1, t2, t9))));
    return t10;
  }

  private ParseSuccess getParseResult3(GrammarGraph registry) {
    ParseStatistics statistics =
        ParseStatistics.builder()
            .setDescriptorsCount(41)
            .setGSSNodesCount(5)
            .setGSSEdgesCount(20)
            .setNonterminalNodesCount(15)
            .setTerminalNodesCount(9)
            .setIntermediateNodesCount(26)
            .setPackedNodesCount(51)
            .setAmbiguousNodesCount(10)
            .build();
    return new ParseSuccess(expectedSPPF3(registry), statistics, input1);
  }

  private NonterminalNode expectedSPPF3(GrammarGraph registry) {
    TerminalNode node0 = createTerminalNode(registry.getSlot("a"), 0, 1, input3);
    NonterminalNode node1 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node0, input3);
    TerminalNode node2 = createTerminalNode(registry.getSlot("+"), 1, 2, input3);
    IntermediateNode node3 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node1, node2);
    TerminalNode node4 = createTerminalNode(registry.getSlot("a"), 2, 3, input3);
    NonterminalNode node5 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node4, input3);
    TerminalNode node6 = createTerminalNode(registry.getSlot("*"), 3, 4, input3);
    IntermediateNode node7 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node5, node6);
    TerminalNode node8 = createTerminalNode(registry.getSlot("a"), 4, 5, input3);
    NonterminalNode node9 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node8, input3);
    IntermediateNode node10 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node9);
    NonterminalNode node11 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node10, input3);
    TerminalNode node12 = createTerminalNode(registry.getSlot("+"), 5, 6, input3);
    IntermediateNode node13 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node11, node12);
    TerminalNode node14 = createTerminalNode(registry.getSlot("a"), 6, 7, input3);
    NonterminalNode node15 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node14, input3);
    IntermediateNode node16 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node13, node15);
    IntermediateNode node17 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node9, node12);
    IntermediateNode node18 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node17, node15);
    NonterminalNode node19 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node18, input3);
    IntermediateNode node20 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node7, node19);
    NonterminalNode node21 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node16, input3);
    node21.addPackedNode(registry.getSlot("E ::= E * E ."), node20);
    TerminalNode node22 = createTerminalNode(registry.getSlot("*"), 7, 8, input3);
    IntermediateNode node23 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node21, node22);
    TerminalNode node24 = createTerminalNode(registry.getSlot("a"), 8, 9, input3);
    NonterminalNode node25 =
        createNonterminalNode(registry.getSlot("E"), registry.getSlot("E ::= a ."), node24, input3);
    IntermediateNode node26 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node15, node22);
    IntermediateNode node27 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node26, node25);
    NonterminalNode node28 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node27, input3);
    IntermediateNode node29 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node17, node28);
    IntermediateNode node30 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node19, node22);
    IntermediateNode node31 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node30, node25);
    NonterminalNode node32 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node29, input3);
    node32.addPackedNode(registry.getSlot("E ::= E * E ."), node31);
    IntermediateNode node33 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node23, node25);
    node33.addPackedNode(registry.getSlot("E ::= E * E ."), node7, node32);
    IntermediateNode node34 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node13, node28);
    NonterminalNode node35 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E * E ."), node33, input3);
    node35.addPackedNode(registry.getSlot("E ::= E + E ."), node34);
    IntermediateNode node36 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node11);
    IntermediateNode node37 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node5);
    NonterminalNode node38 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node37, input3);
    IntermediateNode node39 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node38, node6);
    IntermediateNode node40 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node39, node9);
    NonterminalNode node41 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node36, input3);
    node41.addPackedNode(registry.getSlot("E ::= E * E ."), node40);
    IntermediateNode node42 =
        createIntermediateNode(registry.getSlot("E ::= E + . E"), node41, node12);
    IntermediateNode node43 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node35);
    node43.addPackedNode(registry.getSlot("E ::= E + E ."), node42, node28);
    IntermediateNode node44 =
        createIntermediateNode(registry.getSlot("E ::= E + E ."), node3, node21);
    node44.addPackedNode(registry.getSlot("E ::= E + E ."), node42, node15);
    IntermediateNode node45 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node39, node19);
    NonterminalNode node46 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node44, input3);
    node46.addPackedNode(registry.getSlot("E ::= E * E ."), node45);
    IntermediateNode node47 =
        createIntermediateNode(registry.getSlot("E ::= E * . E"), node46, node22);
    IntermediateNode node48 =
        createIntermediateNode(registry.getSlot("E ::= E * E ."), node47, node25);
    node48.addPackedNode(registry.getSlot("E ::= E * E ."), node39, node32);
    NonterminalNode node49 =
        createNonterminalNode(
            registry.getSlot("E"), registry.getSlot("E ::= E + E ."), node43, input3);
    node49.addPackedNode(registry.getSlot("E ::= E * E ."), node48);
    return node49;
  }

  private Tree getTree3() {
    Tree t0 = createTerminal(0, 1, input3);
    Tree t1 = createRule(r3, list(t0), input3);
    Tree t2 = createTerminal(1, 2, input3);
    Tree t3 = createTerminal(2, 3, input3);
    Tree t4 = createRule(r3, list(t3), input3);
    Tree t5 = createRule(r2, list(t1, t2, t4), input3);
    Tree t6 = createTerminal(3, 4, input3);
    Tree t7 = createTerminal(4, 5, input3);
    Tree t8 = createRule(r3, list(t7), input3);
    Tree t9 = createTerminal(5, 6, input3);
    Tree t10 = createTerminal(6, 7, input3);
    Tree t11 = createRule(r3, list(t10), input3);
    Tree t12 = createRule(r2, list(t8, t9, t11), input3);
    Tree t13 = createTerminal(7, 8, input3);
    Tree t14 = createTerminal(8, 9, input3);
    Tree t15 = createRule(r3, list(t14), input3);
    Tree t16 = createRule(r1, list(t11, t13, t15), input3);
    Tree t17 =
        createAmbiguity(set(createBranch(list(t12, t13, t15)), createBranch(list(t8, t9, t16))));
    Tree t18 = createRule(r1, list(t4, t6, t8), input3);
    Tree t19 =
        createAmbiguity(set(createBranch(list(t4, t6, t12)), createBranch(list(t18, t9, t11))));
    Tree t20 =
        createAmbiguity(set(createBranch(list(t1, t2, t18)), createBranch(list(t5, t6, t8))));
    Tree t21 =
        createAmbiguity(set(createBranch(list(t20, t9, t11)), createBranch(list(t1, t2, t19))));
    Tree t22 = createAmbiguity(set(createBranch(list(t21)), createBranch(list(t5, t6, t12))));
    Tree t23 =
        createAmbiguity(set(createBranch(list(t5, t6, t17)), createBranch(list(t22, t13, t15))));
    Tree t24 =
        createAmbiguity(set(createBranch(list(t19, t13, t15)), createBranch(list(t4, t6, t17))));
    Tree t25 = createAmbiguity(set(createBranch(list(t24)), createBranch(list(t18, t9, t16))));
    Tree t26 =
        createAmbiguity(set(createBranch(list(t20, t9, t16)), createBranch(list(t1, t2, t25))));
    Tree t27 = createAmbiguity(set(createBranch(list(t26)), createBranch(list(t23))));
    return t27;
  }
}
 public static Matcher characterBackwardsMatcher(Character c) {
   return (input, i) -> i == 0 ? -1 : (input.charAt(i - 1) == c.getValue() ? 1 : -1);
 }
 public static Matcher characterMatcher(Character c) {
   return (input, i) -> input.charAt(i) == c.getValue() ? 1 : -1;
 }
Exemple #6
0
  @Test
  public void test() {
    Grammar grammar =
        Grammar.builder()

            // $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())
            // E ::= E ('+') E  {LEFT,1,LEFT_RIGHT_REC} PREC(1,1)
            .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(1)
                    .setPrecedenceLevel(PrecedenceLevel.from(1, 1, -1, false, 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, false, false, false, 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);
    System.out.println(grammar);

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

    Input input = Input.fromString("a+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);
  }
  @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);
  }